无法输入类型的值NSNull'到#NSString'

时间:2016-02-24 10:53:19

标签: ios swift uisearchcontroller uisearchresultscontroller

我有一个非常奇怪的问题,我无法弄清楚这里出了什么问题。

这是我的代码

func updateSearchResultsForSearchController(searchController: UISearchController) {
    filterTableData.removeAll(keepCapacity: false)
    let searchWord = searchController.searchBar.text!

    getCountriesNamesFromServer(searchWord)

    let searchPredict = NSPredicate(format: "SELF CONTAINS[c] %@", searchController.searchBar.text!)

     newTableData = [String]()

    for var i = 0; i < self.dict.count - 1; i++ {

        let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
       let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String

            print("countryName is \(countryName)")





    newTableData.append(cityName)
    }
    print("newTableData is \(newTableData)" )
    let array = (newTableData as NSArray).filteredArrayUsingPredicate(searchPredict)
    print("array is\(array)")
    filterTableData = array as! [String]
    self.tableView.reloadData()
}

程序在此行崩溃

let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String

当我在搜索框中输入第一个字符时,一切正常,但只要我在searchBox程序中输入第二个字符就会崩溃并且它会给我这个错误

无法转换类型的值&#39; NSNull&#39; (0x1a03c3768)到&#39; NSString&#39; (0x1a03cd798)。

并且您的信息countryNames存在于dict变量中,但我不知道为什么它给我空值以及为什么城市名称成功运行,因为国家/地区也存在于我所在的同一个数组中得到这个城市

更新

此行成功打印国家/地区名称

  print("countryName is \(countryName)")

3 个答案:

答案 0 :(得分:4)

好吧,他们告诉你问题是什么:你得到了NSNull类型的结果,并且NSNull 不能转换为NSString。

您很可能正在处理JSON,而JSON数据通常包含空值。

离开你的迷宫?和!

编写一些可以帮助您的代码。记住,任何!如果你没有达到你的期望,你的应用程序就会崩溃。

当你在字典中访问键“name”时,你需要处理有一个字符串的情况(很适合你),什么都没有(键不存在,非常常见),null(服务器告诉你显然没有,很常见),数字,bool,dict或数组。

对于每一种情况,请告诉我你想要的结果:崩溃?一个可选的字符串是零?一个空字符串?通常你想要一个字符串,如果它在那里,可能是一个数字转换为字符串,如果它是一个数字,如果键不存在则为nil或空字符串或null,如果你得到一个,则为崩溃或nil bool,字典或数组。

然后编写一个完全返回的函数。然后你用它。当你写(...作为?NSString)!你告诉编译器你想要崩溃,如果它不是一个字符串,那就是你得到的。

答案 1 :(得分:0)

您在此行收到了服务器上的国家/地区列表

getCountriesNamesFromServer(searchWord)

但我认为它会在没有完全设置所有数据的情况下返回一个列表。

for var i = 0; i < self.dict.count - 1; i++ {

            let cityName = (((self.dict["\(i)"] as?NSDictionary)!["City"] as?NSDictionary)!["name"] as?NSString)! as String
            let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as?NSString)! as String

            print("countryName is \(countryName)")

            newTableData.append(cityName)
        }

在循环的第一次迭代中,name值设置正确,因此它可以正常工作,但在第二次迭代中,在我看来,null并且您无法转换NSNullNSString,以便应用程序崩溃。

在转换为NSString之前,如果您不确定服务器响应,则必须尝试字典是否包含name密钥以及是否设置了值。如果是,你可以尝试施放它。

如果需要,您还可以使用外部库SwiftyJSON来简化JSON响应的解析。

答案 2 :(得分:0)

@ gnasher729讲得很好, 但是要解决您的问题,您应该使用“?”而不是“!”

所以在解析下面代码中的数据时

 let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as NSDictionary)!["name"] as?NSString)! as String

将代码用作

let countryName = (((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as? NSString)? as String ?? ""

let countryName = ((self.dict["\(i)"] as?NSDictionary)!["Country"] as?NSDictionary)!["name"] as? String ?? ""

谢谢