简体   繁体   中英

Compiling Swift source files hangs on large array reduce-combine + expressions

In my tests I'm used to write Strings in arrays in different lines like

    let jsonString = ["{"
        ,"\"url\": \"http://localhost:8090/rest/api/3\","
        , "\"id\": \"3\","
        , "\"description\": \"A test that needs to be done.\","
        , "\"name\": \"Test\","
        , "\"subtest\": false,"
        , "\"avatar\": 1"
        ,"}"].reduce("", combine: +)

That works fine, still my array get 145 lines for a large test json string. With 145 lines (or maybe less, didn't tried it line by line) the build task hangs while "Compiling Swift source files".

First, that is a bit crazy. 30 lines are ok, 145 not? What?

Second, what is a better solution to write a String in multiple lines in Swift? - I don't want to load a json and parse it from an external file.

This is probably because of type inference.

Try giving an explicit [String] type to an array variable to help the compiler figure it out, then apply reduce to the variable.

let arrayOfStrings: [String] = ["{"
    ,"\"url\": \"http://localhost:8090/rest/api/3\","
    , "\"id\": \"3\","
    , "\"description\": \"A test that needs to be done.\","
    , "\"name\": \"Test\","
    , "\"subtest\": false,"
    , "\"avatar\": 1"
    ,"}"] // etc

let jsonString = arrayOfStrings.reduce("", combine: +)

Anyway, to create JSON you should make a dictionary then serialize it with NSJSONSerialization, this is less error prone:

Swift 2

do {
    // Create a dictionary.
    let dict = ["url": "http://localhost:8090/rest/api/3", "id": "3"]  // etc

    // Encode it to JSON data.
    let jsonData = try NSJSONSerialization.dataWithJSONObject(dict, options: [])

    // Get the object back.
    if let jsonObject = try NSJSONSerialization.JSONObjectWithData(jsonData, options: []) as? [String:String] {
        print(jsonObject)
    }

    // Get it as a String.
    if let jsonString = String(data: jsonData, encoding: NSUTF8StringEncoding) {
        print(jsonString)
    }

} catch let error as NSError {
    print(error)
}

Swift 3

do {
    // Create a dictionary.
    let dict = ["url": "http://localhost:8090/rest/api/3", "id": "3"]  // etc

    // Encode it to JSON data.
    let jsonData = try JSONSerialization.data(withJSONObject: dict, options: [])

    // Get the object back.
    if let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options: []) as? [String:String] {
        print(jsonObject)
    }

    // Get it as a String.
    if let jsonString = String(data: jsonData, encoding: String.Encoding.utf8) {
        print(jsonString)
    }

} catch let error as NSError {
    print(error)
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM