简体   繁体   中英

iOS swift - working with response from API

I am very new to Swift and iOS development. And I am wondering how to do something relatively simple if I was using JavaScript.

I am making a call to an API that is returning the following. Excuse the formatting but it is directly copied from the Xcode console.

["type": success, "value": <__NSArrayI 0x600000030340>(
       {
          categories = ();
          id = 155;
          joke = "Chuck Norris does not &quot;style&quot; his hair. It lays perfectly in place out of sheer terror.";
       },
       {
            categories = (nerdy);
            id = 69;
            joke = "Scientists have estimated that the energy given off during the Big Bang is roughly equal to 1CNRhK (Chuck Norris Roundhouse Kick).";
       }
    )
]

I want to loop over the response and add to an array. In JavaScript it would look like the following:

let jokes = [];
response.value.forEach(item => {
   jokes.push(item.joke)
})

It doesn't have to be exactly like the above. I am confident using loops in swift and appending to an array. What I am struggling to do is access the jokes in the value array returned from the API.

My controller looks like the following:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(string: "http://api.icndb.com/jokes/random/2")
        URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
            guard let data = data, error == nil else { return }
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
                print(json["value"])
                // not sure how to access each joke in the array here
            } catch let error as NSError {
                print(error)
            }
        }).resume()
    }
}

You can try

if let va = json["value"] as? [[String:Any]] {
   va.forEach { print($0["joke"]) }
}

I would prefer to write a Codable structs for this

struct Root: Codable {
    let type: String
    let value: [Value]
}

struct Value: Codable {
    let categories: [Category]
    let id: Int
    let joke: String
}

struct Category: Codable {
}

let res = try? JSONDecoder().decode(Root.self,from:data)
print(res.value)

As you can see from logs the variable json["value"] is of type NSArray so you can do something like this to get your data (there are so many ways to do that).

First of all you can create the object Joke you wanna take like this

class Joke: NSObject {
     var categories = [String]()
     var id: Int?
     var joke: String?

     init(json: [String: Any]) {
         if let categories = json["categories"] as? String {
             for category in categories {
                 self.categories.append(category)
             }
         }
         if let id = json["id"] as? Int {
             self.id = id
         }
         if let joke = json[""] as? String {
             self.joke = joke
         }
     }
}

And then you do this in your ViewController

class ViewController: UIViewController {


    var jokes = [Joke]()

    override func viewDidLoad() {
        super.viewDidLoad()

        let url = URL(string: "http://api.icndb.com/jokes/random/2")
        URLSession.shared.dataTask(with:url!, completionHandler: {(data, response, error) in
            guard let data = data, error == nil else { return }
            do {
                let json = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as! [String:Any]
                print(json["value"])
                // not sure how to access each joke in the array here
                let arrayOfObject = json["value"] as! NSArray
                for object in arrayOfObject {
                    if let json = object as? [String: Any] {
                        let object = Joke(json: json)
                        // Now you have your object containing the data from the JSON and you can insert it in your array of Object
                        jokes.append(object)
                    }
                }
            } catch let error as NSError {
                print(error)
            }
        }).resume()
    }
}

Remember, there are so many ways to do that, I showed you a simply way to do it, hope it will be helpful.

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