Swifty Json 变得不为人知但很长的路很好用?

Posted

技术标签:

【中文标题】Swifty Json 变得不为人知但很长的路很好用?【英文标题】:Swifty Json getting unknown but long way works fine? 【发布时间】:2015-04-09 08:50:20 【问题描述】:

我正在尝试使用 SwiftyJson 提取一些 JSON 数据。 不寻常的是“println(json)”表示“未知”,而如果我以常规方式提取 JSON 数据,它就可以正常工作——“println(pop)”表示“中等”,正如预期的那样。 下面是我正在使用的代码。我开始切割零件,直到我到达“println(json)”,然后决定尝试手动处理它,看看它是 SwiftyJson 还是我。 有什么建议么?我对 ios 编程相当陌生,所以我假设我在某种形式上很傻。

    var ghostlandsJsonUrl: NSURL = NSURL(string: "http://us.battle.net/api/wow/realm/status?realm=Ghostlands")!
    var jsonData: NSData!

    var request: NSURLRequest = NSURLRequest(URL: ghostlandsJsonUrl)
    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    let session = NSURLSession(configuration: config)

    let task : NSURLSessionDataTask = session.dataTaskWithRequest(request, completionHandler: (data, response, error) in
        jsonData = data
        if(jsonData != nil) 
            let json = JSON(jsonData)
            println(json)
         else 
            println("jsonData: nil value... net down again?")
        

        let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error: nil)
        if let statuses = jsonObject as? NSDictionary
            if let realms = statuses["realms"] as? NSArray
                if let realm = realms[0] as? NSDictionary
                    if let pop = realm["population"] as? NSString
                        println(pop)
                    
                
            
        

    );
    task.resume()

【问题讨论】:

【参考方案1】:

查看SwiftyJSON source code 我可以看到JSON 是一个简单的struct。它实现了Printable protocol。它支持print 方法。

public var description: String 
        if let string = self.rawString(options:.PrettyPrinted) 
            return string
         else 
            return "unknown"
        
    

这意味着由于某种原因rawString 方法返回nil

public func rawString(encoding: UInt = NSUTF8StringEncoding, options opt: NSJSONWritingOptions = .PrettyPrinted) -> String? 
        switch self.type 
        case .Array, .Dictionary:
            if let data = self.rawData(options: opt) 
                return NSString(data: data, encoding: encoding)
             else 
                return nil
            
        case .String:
            return (self.object as String)
        case .Number:
            return (self.object as NSNumber).stringValue
        case .Bool:
            return (self.object as Bool).description
        case .Null:
            return "null"
        default:
            return nil
        
    

由于您是 iOS 开发的新手,我会告诉您构造函数不期望 NSData 对象。

这里是来源:

public var object: AnyObject 
    get 
        return _object
    
    set 
        _object = newValue
        switch newValue 
        case let number as NSNumber:
            if number.isBool 
                _type = .Bool
             else 
                _type = .Number
            
        case let string as NSString:
            _type = .String
        case let null as NSNull:
            _type = .Null
        case let array as [AnyObject]:
            _type = .Array
        case let dictionary as [String : AnyObject]:
            _type = .Dictionary
        default:
            _type = .Unknown
            _object = NSNull()
            _error = NSError(domain: ErrorDomain, code: ErrorUnsupportedType, userInfo: [NSLocalizedDescriptionKey: "It is a unsupported type"])
        
    

所以你应该将未序列化的NSData 传递给它:

if let jsonData = data 
    //jsonData can't be nil with this kind of if

    let jsonObject : AnyObject! = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.MutableContainers, error: nil)
    let json = JSON(jsonObject)
    println(json)
    //...

【讨论】:

有趣。这当然可以解释为什么我试图访问内部数据的一切总是为零。假设我必须在这种情况下不使用 SwiftyJSON,直到我弄清楚为什么它对暴雪正在使用的类型不满意。谢谢! 我添加了我找到的解释。我从未使用过 SwiftyJSON,所以它可能不是那么正确,但你明白了。 您确实是正确的。我非常感谢您在这方面的帮助。我不会在任何合理的时间内自己提出这个问题。你,先生,摇滚!【参考方案2】:

JSON 的构造函数进行序列化。下面是来自 SwiftyJSON git repo 的构造函数代码,您可以在其中直接传递 NSData。

    public init(data:NSData, options opt: NSJSONReadingOptions = .AllowFragments, error: NSErrorPointer = nil) 
    do 
        let object: AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: opt)
        self.init(object)
     catch let aError as NSError 
        if error != nil 
            error.memory = aError
        
        self.init(NSNull())
    

简单来说,你可以在你的代码中直接使用NSURLSession数据任务的完成处理程序中返回的数据,如下所示。

let json = JSON(data: jsonData)

【讨论】:

以上是关于Swifty Json 变得不为人知但很长的路很好用?的主要内容,如果未能解决你的问题,请参考以下文章

浏览器中实现深度学习?有人分析了7个基于JS语言的DL框架,发现还有很长的路要走

使用 Swifty 在 Swift 中将 JSON 作为字符串返回

英特尔表示:元宇宙的路还很长

从 JSON 中提取很长的字符串到 CLOB

如何优化很长的JSON数据?

如何优化很长的 JSON 数据