【问题标题】:Parse JSON Swift Subscript Error解析 JSON Swift 下标错误
【发布时间】:2023-04-06 13:38:01
【问题描述】:

我正在尝试快速解析一些 JSON,但出现“下标”错误。我试图转换为 AnyObject 而不是 NSDictinary 无济于事。很卡。任何帮助,将不胜感激。这是我的代码:

override func viewDidLoad() {
    super.viewDidLoad()

    splitViewController!.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible

    UINavigationBar.appearance().barTintColor = UIColor(red: 52.0/255.0, green: 170.0/255.0, blue: 220.0/255.0, alpha: 1.0)
    UINavigationBar.appearance().tintColor = UIColor.whiteColor()
    UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]


    let url = NSURL(string:"https://www.kimonolabs.com/api/7flcy3qm?apikey=gNq3hB1j0NtBdAvXJLEFx8JaqtDG8y6Y")!
    let session = NSURLSession.sharedSession()

    let task = session.dataTaskWithURL(url) { (data, response, error) -> Void in

        if error != nil {

            print(error)

        } else {

            if let data = data {

             //print(NSString(data: data, encoding: NSUTF8StringEncoding))

                do { let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary


                    if jsonResult!.count > 0 {


                        if let items = jsonResult["Date"] as? NSArray {


                            print(items)


                        }




                    }


                } catch {



                }

        }


    }


}


    task.resume()


}

【问题讨论】:

标签: ios json swift tableview subscript


【解决方案1】:

好吧,不要咬我的头,但是jsonResult中可能没有“Date”键吗?这就是我解释“下标”错误的方式。

另外,当我从您使用的 URL 获取数据时,没有“日期”对象。

...稍后...

唐,这是我为完成你在最近评论中所要求的内容而做出的:

// JSONTest
import UIKit

class ViewController: UIViewController {

    // MARK: Properties
    var events: [EventRecord] = []

    // MARK: Types
    struct EventRecord {

        struct Event {
            let href: NSURL?
            let text: String?
        }

        let event: Event
        let hasta: String?
        let location: String?
    }

    // MARK: View lifecycle

    override func viewDidLoad() {
        super.viewDidLoad()

        splitViewController!.preferredDisplayMode = UISplitViewControllerDisplayMode.AllVisible

        UINavigationBar.appearance().barTintColor = UIColor(red: 52.0/255.0, green: 170.0/255.0, blue: 220.0/255.0, alpha: 1.0)
        UINavigationBar.appearance().tintColor = UIColor.whiteColor()
        UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName : UIColor.whiteColor()]

        let url = NSURL(string:"https://www.kimonolabs.com/api/7flcy3qm?apikey=gNq3hB1j0NtBdAvXJLEFx8JaqtDG8y6Y")!
        let session = NSURLSession.sharedSession()

        let task = session.dataTaskWithURL(url) { (data, response, error) -> Void in

            if error != nil {

                print(error)

            } else {

                if let data = data {

                    //print(NSString(data: data, encoding: NSUTF8StringEncoding))

                    do {

                        let jsonResult = try NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers) as? NSDictionary

                        if jsonResult!.count > 0 {

                            if let results = jsonResult!["results"] as? NSDictionary, collection2 = results["collection2"] as? NSArray {

                                for entry in collection2 {
                                    if let dict = entry as? NSDictionary {
                                        self.events.append(self.processEntryDict(dict))
                                    }
                                    else {
                                        // BARF!
                                    }
                                }

                                print("events:\(self.events)")
                            }
                        }
                    } catch {
                        print("In catch block")
                    }
                }
            }
        }

        task.resume()
    }

    // MARK: Helper methods

    /// processEntryDict creates an `EventRecord` from the individual entry passed to the method and returns it to the caller.
    func processEntryDict(entry:  NSDictionary) -> EventRecord {

        // Each object in the "collection2" array is a dictionary of the form:
        //    {
        //        "Event": {
        //            "href": "http://www.vigolowcost.com/event/ceos-e-mares-de-felipe-aranda/?instance_id=31511",
        //            "text": "“Ceos e Mares” de Felipe Aranda"
        //        },
        //        "Hasta": "oct 23 todo el día",
        //        "Location": "Detrás do Marco, Vigo",
        //        "index": 2,
        //        "url": "http://www.vigolowcost.com/agenda/"
        //    },
        //

        let hasta = entry["Hasta"] as? String
        let location = entry["Location"] as? String

        var eventHref: NSURL?
        var eventText: String?

        if let eventDict = entry["Event"] as? NSDictionary {
            if let hrefText = eventDict["href"] as? String {
                eventHref = NSURL(string: hrefText)
            }

            eventText = eventDict["text"] as? String
        }

        let eventRecordEvent = EventRecord.Event(href: eventHref, text: eventText)
        return EventRecord(event: eventRecordEvent, hasta: hasta, location: location)
    }

}

请注意,我添加了一些东西以确保“结果”和“集合 2”存在,然后提供了一种方法来遍历“集合 2”中的条目。

我现在编写的课程更接近于我正在做我认为你正在尝试做的事情。不过,我也会将 session.dataTaskWithURL 调用的 completionHandler 拉到它自己的方法中。

以下几点需要注意:

  • 我使用// MARK: xxx 来隔离功能。这些 cmets 会在 Xcode 的类标识符下拉列表中生成命名分隔符。 (见下文)
  • 我创建了一个EventRecord 结构来保存有关每个事件的信息。这将使与事件数组的交互变得更加容易,因为它现在是 EventRecord 对象的 Swift Array。 (名为 events 的属性。)这还允许您自动利用 Swift 提供的所有严格类型检查。
  • 我使用新的processEntryDict(:) 函数处理collection2 中的每个条目。这是我尝试使用更短的方法来保持代码模块化的另一种方式。这简化了测试、维护、文档编制和故障排除。
  • processEntryDict 声明之前的行是一个特殊标记(注意三个斜杠)。如果您选择单击processEntryDict,您会注意到我在其中放置的描述。这些东西在 Objective-C 中非常强大。我不确定它是否与 Swift 一样有用。
  • 目前,当您运行程序时,它会将事件数组发送到调试控制台。显然,您会想要做一些与事件列表不同的事情,但这应该为您推进项目提供一个良好的开端。

如果您需要更多帮助或希望我向您解释其中的任何内容,请告诉我。

我在这里留下“collection2”内容的第一位的图像,因为它可以作为一个很好的参考。

【讨论】:

  • 谢谢马特,当然不会咬你的头,感谢您的帮助。好的,现在这是我的愚蠢问题:你能看到什么有效的密钥?我想测试,我尝试了“事件” - 仍然是一个错误。:)
  • 你可以试试“collection2”。它似乎有一个 Event 对象数组。所以你会做类似jsonResult!["collection2"]["Event"]的事情。不幸的是,我不能让它在操场上工作,而且我需要去赴约,所以我没有时间准备一个完整的项目。
  • 不过,实际上,我认为您应该执行 jsonResult!["collection2"] as? NSArray 并遍历它。
  • 非常感谢马特。 :) 真的很感激......现在看看它是否有效。如果它失败了,希望你在附近哈哈
  • 我会在几个小时后回来。如果你还没有弄清楚,我会进一步挖掘。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-04-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-02-24
相关资源
最近更新 更多