Swift 4:解析JSON的正确方法

时间:2017-11-09 15:52:26

标签: json swift

由于我的技能很差,我可以想出这个。它很有用,如果你像我一样快乐的话,请随意使用它。感谢您的支持。

var jsonString = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20170517T154730Z.927d87b76de60242.7a92e4612778a4838d40ab192df5297d2a1af4ed&text=Hi&lang=ar"
        // [error 2:11] no viable alternative at input 'jsonString ='
        var components = NSURLComponents(string: jsonString)
        var url = components?.url
        var data = NSData(contentsOf: url!)
        var error = NSError.self
        var dictionary = try JSONSerialization.jsonObject(with: data! as Data, options: .allowFragments) as! NSDictionary
        let dict1 = dictionary["text"] as! NSArray
        let ps = Array(dict1.map{ $0 })

        print(ps[0])

实践与实践..

提出了将单词翻译成不同语言的想法,问题是,我是新手,我的首选语言Obj-c在过去的1。5年里,我总是使用这个代码,它完美地工作,但我今天看到一篇关于如何清洁swift的中篇文章,喜欢试一试,基本上我在事物的中间醒来,这就是我不得不问的原因

我的Obj-c代码是

NSString *jsonString = [NSString stringWithFormat:@"https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20170517T154730Z.927d87b76de60242.7a92e4612778a4838d40ab192df5297d2a1af4ed&text=%@&lang=ar",self.textField2.text];
jsonString = [jsonString stringByReplacingOccurrencesOfString:@" " withString:@"%20"];
NSURLComponents *components = [NSURLComponents componentsWithString:jsonString];
NSURL *url = components.URL;
NSData *data=[NSData dataWithContentsOfURL:url];
NSError *error=nil;
NSDictionary* dictionary = [NSJSONSerialization JSONObjectWithData:data
                                                           options:kNilOptions
                                                             error:&error];
if (error == nil) {
    NSArray *result = dictionary[@"text"];
    if (result.count > 0) {
        NSString *translattedSTR = result[0];
        self.txtview.text = translattedSTR;
    }
}

和我试过的快捷代码

var jsonString = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20170517T154730Z.927d87b76de60242.7a92e4612778a4838d40ab192df5297d2a1af4ed&text=\("Hello")&lang=ar"
jsonString = jsonString.replacingOccurrences(of: " ", with: "%20")
var components = URLComponents(string: jsonString)
var url: URL? = components?.url
var data = Data (contentsOf: url!)
var error: Error? = nil
var dictionary = (try? JSONSerialization.jsonObject(with: data ?? Data(), options: kNilOptions)) as? [AnyHashable: Any]
if error == nil {
    var result = dictionary["text"] as? [Any]
    if result?.count > 0 {
        var translattedSTR = result[0] as? String
        print(translattedSTR)
       // txtview.text = translattedSTR
    }
}

但不幸的是。我正在

  

来电可以投掷,但没有标记'尝试'

on Data

PS:json看起来像是this

1 个答案:

答案 0 :(得分:2)

你当然可以'端口' Swift的这个逻辑...... 这是我的超快速端口:

enum MyErrors: Error {
    case urlParsingError(String)
    case nonDictonaryObjectReturned(Any)
}

func fetchJson(textField text: String) throws -> String? {
    do {
        let jsonString = "https://translate.yandex.net/api/v1.5/tr.json/translate?key=trnsl.1.1.20170517T154730Z.927d87b76de60242.7a92e4612778a4838d40ab192df5297d2a1af4ed&text=\(text)&lang=ar"

        guard let url = URL(string: jsonString) else {
            throw MyErrors.urlParsingError(jsonString)
        }
        // Consider using AlamoFire or your favorite
        let data = try Data(contentsOf: url, options: Data.ReadingOptions())

        let jsonObject = try JSONSerialization.jsonObject(with: data,options: .allowFragments)
        guard let dictionary = jsonObject as? [AnyHashable: Any] else {
            throw MyErrors.nonDictonaryObjectReturned(jsonObject)
        }
        let result = dictionary["text"] as? [Any]
        let translattedSTR = result?.first as? String
        return translattedSTR
    } catch {
        print("caught error \(error)")
        throw error
    }
}

然而,真正的问题是你想用JSON做什么......

Swift 4引入了新的Codable功能,它特别增加了编译器生成功能。 JSON编码和解码逻辑。所以,如果'目标'您的JSON解析的目标是将其转换为Swift类或结构,而不是Encodable / Decodable是您的朋友。

https://medium.com/@ashishkakkad8/use-of-codable-with-jsonencoder-and-jsondecoder-in-swift-4-71c3637a6c65

如果您已经嵌入了'这非常有用。 JSON文档,您要映射到一组相关的Swift结构或类。它还为“日期”提供了良好的支持。翻译等。

如果您想要接受' Generic' JSON(可能事先不知道预期的返回结果......)你可以考虑SwiftyJSON。它给你一些快速的语法糖'在JSONSerialization.jsonObject周围,但它通常不如使用Codeable那样高效,但在你不想要类型安全时很有用。

另外:考虑使用一个漂亮的REST API包装器,例如AlamoFire而不是Data(contentsOf:options:)。甚至还有Codeable这样的CodableAlamofire扩展,可以很容易地说出这个URL并给我回复这个漂亮的Swift结构/类"。但它也会“失败”。好吧,让你深入了解'哪里'失败发生(网络连接,HTTP,安全性,JSON解析等)。