【问题标题】:Nil Value encountered when unwrapping optional in Swift 3在 Swift 3 中展开可选时遇到 Nil 值
【发布时间】:2018-05-19 04:45:32
【问题描述】:

我对 Swift 编程很感兴趣,并试图在 iOS 应用程序中显示 JSON 对象,但在运行代码时不断收到错误“在展开可选值时意外发现 nil”。

这是显示 JSON 的代码:

import Foundation
import UIKit

class EventList
{
    static var listOfEvents = [Event]()

    static var eventService:EventService?

    static func getEventsFromWebService()->[Event]
        // _ siteURL:String, _ searchTerm:String    
    {
        let searchURL = "http://api.eventful.com/json/events/search?
        date=2018&app_key=wjwMpjZWRD7JXHPQ"
        print ("Web Service call = \(searchURL)")

        eventService = EventService(searchURL)

        let operationQ = OperationQueue()

        operationQ.maxConcurrentOperationCount = 1

        operationQ.addOperation(eventService!)

        operationQ.waitUntilAllOperationsAreFinished()


        listOfEvents.removeAll()

        let returnedJSON = eventService!.jsonFromResponse
        let JSONObjects = returnedJSON?["event"] as! [[String:String]]

        for eachJSONObject in JSONObjects
        {
            print("Creating Movie object from JSON: \(eachJSONObject)")
            listOfEvents.append(Event(eachJSONObject))
        }

        return listOfEvents
    }

    private static func showCreatedList()
    {
        for evt in listOfEvents
        {
            print(evt.displayEvent())
        }

    }
}

class Event
{
    private (set)var title:String
    private (set)var city_name:String
    private (set)var country_name:String
    private (set)var venue_name:String
    private (set)var venue_address:String
    private (set)var start_time:String
    private (set)var url:String
    private (set)var isSaved:Bool

    init?(_ t:String, _ ci:String, _ co:String, _ vn:String, _ va:String, _ 
s:String, _ u:String)
    {
        if ((t == "") || (va == "") || (s == ""))
        {
            return nil
        }
        else
        {
            title = t
            city_name = ci
            country_name = co
            venue_name = vn
            venue_address = va
            start_time = s
            url = u
            isSaved = false
        }
    }

    convenience init(_ JSONObject:[String:String])
    {
        let title = JSONObject["title"]
        let city = JSONObject["city_name"]
        let country = JSONObject["country_name"]
        let venue = JSONObject["venue_name"]
        let address = JSONObject["venue_address"]
        let time = JSONObject["start_time"]
        let url = JSONObject["url"]

        self.init(title!,city!,country!,venue!,address!,time!,url!)!
    }

    func displayEvent()->String
    {
        let strEvent = "\(title) will take place at \(venue_name)"
        return strEvent
    }
}

class EventService:Operation
{
    var urlReceived: URL?

    var jsonFromResponse: [String:Any]?

    init(_ incomingURLString:String)
    {
        urlReceived = URL(string: 
incomingURLString.addingPercentEncoding(withAllowedCharacters: 
CharacterSet.urlQueryAllowed)!)
    }

    override func main()
    {
        var responseData:Data?

        do
        {
            responseData = try Data(contentsOf: urlReceived!)
            print("Service call (request) successful! Returned: \
(responseData)")
        }
        catch
        {
             print("Service call (request) failed")
        }

        do
        {
            jsonFromResponse = try JSONSerialization.jsonObject(with: 
responseData!,options: .allowFragments) as? [String:Any]
            print("JSON Parser successful. Returned: \(jsonFromResponse!)")
        }
        catch
        {
            print("JSON Parser failed")
        }
    }
}

这是我正在使用的 JSON 的一部分:

{
"last_item": null,
"total_items": "3983377",
"first_item": null,
"page_number": "1",
"page_size": "10",
"page_items": null,
"search_time": "0.129",
"page_count": "398338",
"events": {
  "event": [
    {
      "watching_count": null,
      "olson_path": "America/New_York",
      "calendar_count": null,
      "comment_count": null,
      "region_abbr": "VA",
      "postal_code": "23229",
      "going_count": null,
      "all_day": "0",
      "latitude": "37.5949",
      "groups": null,
      "url": "http://richmond.eventful.com/events/lettermen-/E0-001-
102252139-0?utm_source=apis&utm_medium=apim&utm_campaign=apic",
      "id": "E0-001-102252139-0",

JSON 继续显示不同的事件对象。 错误被标记就行了:

let JSONObjects = returnedJSON?["event"] as! [[String:String]]

我正在与使用类似代码但使用不同 JSON 数据集的人合作,因此我不确定是我的 JSON 数据还是我的代码有问题。

提前感谢您的帮助。

【问题讨论】:

  • 试试let JSONObjects = returnedJSON?["event"] as? [String:Any]
  • @D.Desai 试过了,我得到了同样的错误,但是在for eachJSONObject in JSONObjects!这个线上
  • 打印 JSONObjects 你得到什么或它只是零
  • 不要使用!。你告诉编译器“这个值不会是零”,但它是!您的 JSON 无法转换为 [[String: String]],因为某些值为空。试试[[String: Any]][[String: String?]]
  • JSONObjects 出现在输出控制台中,后跟错误代码。模拟器也会崩溃。

标签: ios json swift api web-services


【解决方案1】:

乍一看,您的 JSON 上似乎有空值,但在初始化类 Event 时,您说所有字段都是必需的。

self.init(title!,city!,country!,venue!,address!,time!,url!)!

这些都是必填字段,据我所知,您的 JSON 只有 url 字段,除非您自己初始化该类,否则从 JSON 到您的类的翻译会重现错误

【讨论】:

    猜你喜欢
    • 2020-04-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-22
    • 2015-10-06
    • 1970-01-01
    相关资源
    最近更新 更多