[英]Swift JSON with Alamofire - Unexpectedly found nil while unwrapping an Optional value
I'm trying to parse a JSON in my app and it's not working. 我正在尝试在我的应用程序中解析JSON,但无法正常工作。 Here is a look at the JSON I'm trying to parse: 这是我尝试解析的JSON:
Check out the following screenshots. 查看以下屏幕截图。 I get the error "Unexpectedly found nil while unwrapping an optional value" on the line 我在行上收到错误“在展开可选值时意外发现nil”
editorialElement.title = nodeElement!.valueForKey("title") as! String
Can anyone help me properly parse this JSON ? 谁能帮助我正确解析此JSON?
EDIT 1: Here is more code. 编辑1:这是更多的代码。 It shows what class I'm using (ie what objects I am creating based on the JSON file). 它显示了我正在使用的类(即我根据JSON文件创建的对象)。 I imagine this is what you meant by where I initialize JSON objects. 我想这就是初始化JSON对象的意思。
Here is my router as well (build using Alamofire). 这也是我的路由器(使用Alamofire构建)。 I feel like something might be wrong with it but at the same time, it makes a lot of sense and I don't know what missing: 我觉得它可能有问题,但与此同时,这很有意义,我也不知道缺少了什么:
EDIT 2: Here is the actual code: 编辑2:这是实际的代码:
func populateEditorials() {
if populatingEditorials {
return
}
populatingEditorials = true
Alamofire.request(GWNetworking.Router.Editorials(self.currentPage)).responseJSON() { response in
if let JSON = response.result.value {
/*
if response.result.error == nil {
*/
/* Creating objects for every single editorial is long running work, so we put that work on a background queue, to keep the app very responsive. */
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0)) {
/*
// Making an array of all the node IDs from the JSON file
let nodeIDArray : [String]
var nodeCounter : Int = 0 */
for node in JSON as! NSDictionary {
var nodeElement = JSON.valueForKey(String(node))
self.nodeIDArray.addObject(String(node.key))
var editorialElement : EditorialElement = EditorialElement(title: "init", nodeID: 0, timeStamp: 0, imageURL: "init", author: "init", issueNumber: "init", volumeNumber: "init", articleContent: "init")
editorialElement.title = nodeElement!.valueForKey("title") as! String
editorialElement.nodeID = nodeElement!.valueForKey("nid") as! Int
editorialElement.timeStamp = nodeElement!.valueForKey("revision_timestamp") as! Int
editorialElement.imageURL = nodeElement!.valueForKey("image_url") as! String
editorialElement.author = nodeElement!.valueForKey("author") as! String
editorialElement.issueNumber = nodeElement!.valueForKey("issue_int") as! String
editorialElement.volumeNumber = nodeElement!.valueForKey("volume_int") as! String
editorialElement.articleContent = nodeElement!.valueForKey("html_content") as! String
self.editorialObjects.addObject(editorialElement)
/*
nodeIDArray[nodeCounter] = jsonValue{nodeCounter}.string
let editorialInfos : EditorialElement = ((jsonValue as! NSDictionary).valueForKey("\(nodeIDArray[nodeCounter])") as! [NSDictionary]).map { EditorialElement(title: $0["title"] as! String, nodeID: $0["nid"] as! Int, timeStamp: $0["revision_timestamp"] as! Int, imageURL: $0["image_url"] as! String, author: $0["author"], issueNumber: $0["issue_int"] as! Int, volumeNumber: $0["volume_int"] as! Int, articleContent: $0["html_content"] as! String) /* I am going to try to break this line down to simplify it and fix the build errors */
*/
}
print(self.editorialObjects)
}
/* Sorting the elements in order of newest to oldest (as the array index increases) */
self.editorialObjects.sort({ $0.timeStamp > $1.timeStamp })
let lastItem = self.editorialObjects.count
let indexPaths = (lastItem..<self.editorialObjects.count).map { NSIndexPath(forItem: $0, inSection: $0) }
dispatch_async(dispatch_get_main_queue()) {
self.editorialsTableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: UITableViewRowAnimation.Automatic) // Animation implemented for testing, to be removed for version 1.0
}
self.currentPage++
/* } */
}
self.populatingEditorials = false
}
}
Here is the code for my Class and Router: 这是我的班级和路由器的代码:
class EditorialElement: NSObject {
var title: String // title
var nodeID: Int // nid
var timeStamp: Int // revision_timestamp
var imageURL: String? // image_url
var author: String // author
var issueNumber: String // issue_int
var volumeNumber: String // volume_int
var articleContent: String // html_content
/* To get an NSDate objec from Unix timestamp
var date = NSDate(timeIntervalSince1970: timeStamp) */
init(title: String, nodeID: Int, timeStamp: Int, imageURL: String, author: String, issueNumber: String, volumeNumber: String, articleContent: String) {
self.title = title
self.nodeID = nodeID
self.timeStamp = timeStamp
self.imageURL = imageURL
self.author = author
self.issueNumber = issueNumber
self.volumeNumber = volumeNumber
self.articleContent = articleContent
}
override func isEqual(object: AnyObject!) -> Bool {
return (object as! EditorialElement).nodeID == self.nodeID
}
override var hash: Int {
return (self as EditorialElement).nodeID
}
}
enum Router : URLRequestConvertible {
static let baseURLString = MyGlobalVariables.baseURL
case Issue
case Editorials(Int)
case News(Int)
case Random(Int)
case Pictures(Int)
var URLRequest: NSMutableURLRequest {
let path : String
let parameters: [String: AnyObject]
(path) = {
switch self {
case .Issue:
return ("/issue")
case .Editorials (let editorialsSection): /* If section == 0, this will return the first ten editorials. If section == 1, then section * 10 = 10, and we will get the ten editorials after that. */
return ("/list/editorials/\(editorialsSection * 10)")
case .News (let newsSection):
return ("/list/news/\(newsSection * 10)")
case .Random (let randomSection):
return ("/list/random/\(randomSection * 10)")
case .Pictures (let page):
return ("/list/pictures/\(page)")
}
}()
let URL = NSURL(string: Router.baseURLString)
let GoldenWordsURLRequest = NSMutableURLRequest(URL: URL!.URLByAppendingPathComponent(path))
/* let encoding = Alamofire.ParameterEncoding.URL */
return GoldenWordsURLRequest
/* return encoding.encode(URLRequest, parameters: parameters).0 */
}
}
}
That's because you take an optional reference ( editorialElement
returned from a failable initializer) and call valueForKey("title")
on it. 那是因为你有一个可选的参考( editorialElement
从failable初始化返回),并调用valueForKey("title")
就可以了。 It stumbles over the access to "title" because it goes first in you code while the target of the call is nil. 它绊倒了对“ title”的访问,因为它在您的代码中排在第一位,而调用的目标是nil。 I would recommend organizing your code as follows: 我建议按以下方式组织您的代码:
if let editorialElement = EditorialElement(title:..., nodeID: and such)
{
... assigning new values to the properties
}
and you will notice that you don't enter the if-let scope. 并且您会注意到您没有输入if-let范围。 You will avoid the crash and make sure the problem is inside the arguments you initialize the editorialElement
with. 您将避免崩溃,并确保问题出在用于初始化editorialElement
的参数内。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.