【问题标题】:Swift: Error - Initializer for conditional binding must have Optional type, not 'Void' (aka '()')Swift:错误 - 条件绑定的初始化程序必须具有 Optional 类型,而不是“Void”(又名“()”)
【发布时间】:2017-07-03 18:03:34
【问题描述】:

使用 Swift 3,博客阅读器应用程序使用 JSON 和 PHP 从 MYSQL 数据库中读取。用户可以使用关注按钮(以及取消关注按钮)保存他们想要继续获取更新的博客。不是保存整个数组,而是尝试保存关注的博客 ID,以便应用找到博客 ID 并显示用户关注的特定博客。

这是我在加载用户默认值时遇到的错误

条件绑定的初始化器必须具有可选类型,而不是“Void”(又名“()”)

此错误出现在func loadUserDefaults() 中的MainController.swift 第一行if let data = UserDefaults. 中。 用户单击跟随按钮后,我在数组之间、表格视图中的部分之间移动单元格,然后调用saveUserDefaults()

这是MainController.swift

var mainArray = [Blog]()
var followedArray = [Blog]()
var filteredArray = [Blog]()
var followedIdentifiers = Set<String>()

override func viewDidLoad() {
    super.viewDidLoad()

    // Receiving Data from Server
    retrieveDataFromServer()

    // NSCoding - Unarchiving Data (followedID)
    loadUserDefaults()
}

// NSCoding: Archiving UserDefaults
func saveUserDefaults() {

    // Saving to UserDefaults
    let encodedData = NSKeyedArchiver.archivedData(withRootObject: self.followedIdentifiers)
    UserDefaults.standard.setValue(encodedData, forKey: "followedID")
    UserDefaults.standard.synchronize()
}

// NSCoding: Unarchiving UserDefaults *** ERROR IS HERE ***
func loadUserDefaults() {

    // Unarchiving Data -- ERROR: THIS FIRST LINE --
    if let data = UserDefaults.standard.setValue(Array(self.followedIdentifiers), forKey: "followedID"),

        let myFollowedList = NSKeyedUnarchiver.unarchiveObject(with: data) as? [Blog] {

        self.followedIdentifiers = myFollowedList
        self.followedIdentifiers = Set(UserDefaults.standard.stringArray(forKey: "followedID")!)

    } else {
        print("Error/ Empty: (Loading UserDefaults (followedID))")
    }
}

// Retrieving Data from Server
func retrieveDataFromServer() {

    let getDataURL = "http://example.com/receiving.php"
    let url: NSURL = NSURL(string: getDataURL)!

    do {
        let data: Data = try Data(contentsOf: url as URL)
        let jsonArray = try JSONSerialization.jsonObject(with: data, options: .mutableContainers) as! NSMutableArray

        // Clear the arrays
        self.followedArray = [Blog]()
        self.mainArray = [Blog]()

        // Looping through jsonArray
        for jsonObject in jsonArray {

            if let blog = Blog(jsonObject:jsonObject as! [String : Any]) {

                // Check if identifiers match
                if followedIdentifiers.contains(blog.blogID) {
                    self.followedArray.append(blog)
                } else {
                    self.mainArray.append(blog)
                }
            }
        }
    } catch {
        print("Error: (Retrieving Data)")
    }
    myTableView.reloadData()
}

这是Blog.swift,它处理所有博客对象和 NSCoding

class Blog: NSObject, NSCoding {

var blogName: String
var blogStatus1: String
var blogStatus2: String
var blogURL: String
var blogID: String
var blogType: String
var blogDate: String
var blogPop: String


private init (name: String,status1: String,status2: String,url: String,id: String,type: String,date: String,pop: String) {
    blogName = name
    blogStatus1 = status1
    blogStatus2 = status2
    blogURL = url
    blogID = id
    blogType = type
    blogDate = date
    blogPop = pop
    super.init()
}

convenience init?(jsonObject: [String:Any]) {

    guard let bID = jsonObject["id"] as? String,
        let bName = jsonObject["blogName"] as? String,
        let bStatus1 = jsonObject["blogStatus1"] as? String,
        let bStatus2 = jsonObject["blogStatus2"] as? String,
        let bURL = jsonObject["blogURL"] as? String,
        let bType = jsonObject["blogType"] as? String,
        let bDate = jsonObject["blogDate"] as? String,
        let bPop = jsonObject["blogPop"] as? String

        else {
            print("Error: (Creating Blog Object)")
            return nil
    }

    self.init(name: bName, status1: bStatus1, status2: bStatus2, url: bURL, id: bID, type: bType, date: bDate, pop: bPop)

}

convenience required init?(coder aDecoder: NSCoder) {
    guard let blogName = aDecoder.decodeObject(forKey: "blogName") as? String,
        let blogStatus1 = aDecoder.decodeObject(forKey: "blogStatus1") as? String,
        let blogStatus2 = aDecoder.decodeObject(forKey: "blogStatus2") as? String,
        let blogURL = aDecoder.decodeObject(forKey: "blogURL") as? String,
        let blogID = aDecoder.decodeObject(forKey: "blogID") as? String,
        let blogType = aDecoder.decodeObject(forKey: "blogType") as? String,
        let blogDate = aDecoder.decodeObject(forKey: "blogDate") as? String,
        let blogPop = aDecoder.decodeObject(forKey: "blogPop") as? String else {
            print("Error: (Creating Blog Object)")
            return nil
    }
    self.init(name: blogName, status1: blogStatus1, status2: blogStatus2, url: blogURL, id: blogID, type: blogType, date: blogDate, pop: blogPop)
}

func encode(with aCoder: NSCoder) {
    aCoder.encode(blogName, forKey: "blogName")
    aCoder.encode(blogStatus1, forKey: "blogStatus1")
    aCoder.encode(blogStatus2, forKey: "blogStatus2")
    aCoder.encode(blogURL, forKey: "blogURL")
    aCoder.encode(blogID, forKey: "blogID")
    aCoder.encode(blogType, forKey: "blogType")
    aCoder.encode(blogDate, forKey: "blogDate")
    aCoder.encode(blogPop, forKey: "blogPop")
 }
}

【问题讨论】:

    标签: ios swift nsuserdefaults optional nskeyedarchiver


    【解决方案1】:

    代码行:

    let data = UserDefaults.standard.setValue(Array(self.followedIdentifiers), forKey: "followedID")
    

    没有意义,因为 setValue 方法不返回任何值。 看起来你需要用(Swift 3)替换它:

    let data = UserDefaults.standard.data(forKey: "followedID") 
    

    更新 @closetCoder 评论

    【讨论】:

    • 或者更好地使用:let data = UserDefaults.standard.data(forKey: "followedID")
    【解决方案2】:

    setValue 函数是一个 void 函数,因此不能将它分配给变量数据,因为它没有返回值。

    这是来自 Apple 的 UserDefaults 文档:https://developer.apple.com/documentation/foundation/userdefaults

    【讨论】:

      猜你喜欢
      • 2018-03-05
      • 2015-10-19
      • 2016-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-28
      • 2021-04-26
      • 2016-01-27
      相关资源
      最近更新 更多