我目前正在通过Twitter的Search API提取数据。
收到数据后,我正在尝试解析并将数据保存到我的TweetDetails类(这是保存作者的名字,他们的个人资料图片的网址,推文的文字,位置的推文,推文ID和用户ID)。
在某些情况下,推文没有位置(我认为如果他们转发的话就有事可做)和某个字典(这里是tweetsDict [" place"])否则将保留该信息,而不是返回NSNull。
在这些情况下,我收到此错误
无法转换类型的值' NSNull' (0x1093a1600)到' NSDictionary' (0x1093a0fe8)。
这是我的代码,因为我正在尝试解析数据并将其保存到TweetDetails类中的对象
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if connectionError != nil {
print("Error: \(connectionError)")
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
if let tweets = json["statuses"] as? [NSDictionary] {
for tweetsDict in tweets {
let text = tweetsDict["text"] as! String
let tweetID = tweetsDict["id_str"] as! String
let place = tweetsDict["place"] as! NSDictionary
// this line ^^ is where the error occurs
let city = place.valueForKey("full_name")
let user = tweetsDict["user"] as! NSDictionary
let userID = user.valueForKey("id_str")
let screenName = user.valueForKey("screen_name")!
let avatarImage = user.valueForKey("profile_image_url_https")!
let tweet = TweetDetails(authors: screenName as! String, profileImages: avatarImage as! String, tweetTexts: text, tweetLocations: city as! String , tweetIDs: tweetID , userIDs: userID as! String)
self.allTweets.append(tweet)
self.tweetTableView.reloadData()
}
}
} catch let jsonError as NSError {
print("json error: \(jsonError.localizedDescription)")
}
}
我试图制作一些“if-let'为这些场合提供替代方案的陈述,但没有任何效果。
当某些JSON数据作为NSNull返回时,有人可以帮我创建一个自定义替代方案。 (甚至可以简单地将我的" city"变量转换为字符串"未知位置"在数据返回NSNull的情况下)。
在此先感谢您,如果我还有其他任何内容可以添加,请与我们联系,以便更清楚地了解此问题。
答案 0 :(得分:2)
正如其他人所指出的,您可以使用可选绑定(@IBAction func buttonTapped(sender: UIButton) {
dispatch_async(dispatch_get_main_queue()) {
let vc = self.storyboard!.instantiateViewControllerWithIdentifier(self.SendViewControllerID) as! SendViewController
self.navigationController!.pushViewController(vc, animated: true)
}
}
),或者,在这种情况下,更简单,只需使用可选链接:
if let
这样,let city = tweetsDict["place"]?["full_name"] as? String
是可选的,即如果没有找到任何值,因为没有city
或place
条目,则它将是full_name
。
但是,似乎您的nil
强制TweetDetails
加注city
。它绝对需要一个城市吗?最好更改此方法,以便String
是可选的,并在那里优雅地处理city
值。或者,您可以将nil
的{{1}}值替换为其他字符串,例如使用nil
合并运算符:
city
如果找到,则返回城市,"未知城市"如果没有。
答案 1 :(得分:0)
我在你的代码中看到很多强制数据类型转换是非常危险的,特别是在解析JSON时。处理可空性的正确方法不是通过尝试我们在objective-c中做同样的事情来避免它,而是准备接收nil并做出相应的反应。您的数据模型应该表示某个推文有时没有位置的事实,因此TweetDetails的某些属性应该标记为可选项。
下面的代码示例完全没有经过测试,但是让您了解代码处理可空性的样子。
client.sendTwitterRequest(request) { (response, data, connectionError) -> Void in
if connectionError != nil {
print("Error: \(connectionError)")
}
do {
let json = try NSJSONSerialization.JSONObjectWithData(data!, options: [])
if let tweets = json["statuses"] as? [[String: AnyObject]] {
for tweetsDict in tweets {
if let text = tweetsDict["text"] as? String,
tweetID = tweetsDict["id_str"] as? String {
var city: String?
if let place = tweetsDict["place"] as? [String: AnyObject] {
city = place.valueForKey("full_name")
}
var userID: String?
var screenName: String?
var avatarImage: String?
if let user = tweetsDict["user"] as? [String: AnyObject] {
userID = user["id_str"] as? String
screenName = user["screen_name"] as? String
avatarImage = user["profile_image_url_https"] as? String
}
let tweet = TweetDetails(authors: screenName, profileImages: avatarImage, tweetTexts: text, tweetLocations: city, tweetIDs: tweetID, userIDs: userID)
self.allTweets.append(tweet)
}
}
self.tweetTableView.reloadData()
}
} catch let jsonError as NSError {
print("json error: \(jsonError.localizedDescription)")
}
}