0

I started my iOS Journey just 2 weeks ago & I am faced with a Brick wall at the moment, I need save API responses directly into CoreData, Currently I have to loop my Object after Decoded so I can bring out the values individually & save them.

Is there a way I can do it without looping at all?

Let me show you what I have done already below:

I have my Structs named as Example:

struct Example: Codable {
    let data:[MyDataClass]

    enum CodingKeys: String, CodingKey {
        case data
    }
}

struct MyDataClass: Codable {
    let name: String
    let age: String
    let gender: String

    enum CodingKeys: String, CodingKey {
        case name
        case age
        case gender
    }
}

I also have my URLSession code below:

let parameters = ["page": 1] as [String : Any]
        let jsonData = try? JSONSerialization.data(withJSONObject: parameters)

        let url = URL(string: "http://example.com")
        var request = URLRequest(url: url!)
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpMethod = "POST" //set http method as POST
        request.httpBody = jsonData

        let task = URLSession.shared.dataTask(with: request) {(data, response, error) in
            guard error == nil else {
                print("returning error")
                return
            }
            guard let content = data else {
                print("not returning data")
                return
            }
            do {

                if let httpResponse = response as? HTTPURLResponse {
                    if(httpResponse.statusCode == 200){
                        let decoded = try JSONDecoder().decode(Example.self, from: content)

                        // Currently I am looping the data and saving it,
                        // But I want to save it directly with JSON.

                        let list = decoded.data.MyDataClass
                        if(!list.isEmpty){
                            for index in 0...list.count-1 {
                                    // call save method here
                            }
                        }


                    }
                }

            } catch {
                print("Got an Error", error.localizedDescription)
            }
        }
        task.resume()

I also have below my method which actually saves my data when I LOOP.

func saveMyList(name: String,
                         age: Int,
                         gender: String) {

        guard let appDelegate =
            UIApplication.shared.delegate as? AppDelegate else {
                return
        }

        let managedContext = appDelegate.persistentContainer.viewContext
        let entity = NSEntityDescription.entity(forEntityName: "ExampleEntity", in: managedContext)!
        let myList = NSManagedObject(entity: entity, insertInto: managedContext)
        myList.setValue(name, forKeyPath: "name")
        myList.setValue(age, forKeyPath: "age")
        myList.setValue(gender, forKeyPath: "gender")
        do {
            try managedContext.save()
        } catch let error as NSError {
            print("Could not save list. \(error), \(error.userInfo)")
        }
    }

I am new to this, so no Information is unnecessary please. I need someone to put me in right direction, Most tutorials I see online are either too advanced or doing something different.

truthsayer
  • 397
  • 2
  • 8
  • 22
  • I doubt that the line `decoded.data.MyDataClass` compiles. And the structs don't contain any array to iterate. – vadian Feb 16 '19 at 08:08
  • @vadian yes I missed that out when I needed to change my Struct name to "Example" just for the sake of this question. But my real question/issue was straight forward and understandable. – truthsayer Feb 16 '19 at 08:25
  • @vadian I am using this code in my project & I can guarantee you that it works, I just need to do things the proper way instead of looping. – truthsayer Feb 16 '19 at 08:26
  • What's wrong with a loop? – vadian Feb 16 '19 at 08:29
  • @vadian If I have 50 responses from API, it means I have to LOOP 50 times to save them. that takes memory time. So I am just looking for a way to save time & save directly. – truthsayer Feb 16 '19 at 08:30
  • Are you saying you want to store the entire json message in a Data or String attribute in CoreData? – Joakim Danielson Feb 16 '19 at 08:32
  • Before doing that I would clean up the existing code to *save time*. There are many redundant and unnecessary lines in it. – vadian Feb 16 '19 at 08:33
  • @vadian Ofcourse they are many redundant lines in it. I sincerely picked up iOS February 4th 2019, which is barely 2 weeks. I know nothing, If you can correct it. Please do. – truthsayer Feb 16 '19 at 08:36
  • Hi @JoakimDanielson I want to store the entire Json message in a Data. Not store it as a String attribute. – truthsayer Feb 16 '19 at 08:38
  • You cannot create multiple Core Data records simultaneously. So a loop is reasonable. You could use `map` but under the hood it uses a loop, too. – vadian Feb 16 '19 at 08:47
  • Are you sure this looping takes so much time? What about creating your objects in the loop but only calling `managedContext.save()` once after the loop? I still believe it is better to store proper objects than dumping the whole json message to disk. – Joakim Danielson Feb 16 '19 at 08:47
  • Okay @JoakimDanielson , that is a good idea. Do you have an example of that please, example of creating my objects in the loop? Thanks. I believe if I use "let myList = NSManagedObject(entity: entity, insertInto: managedContext)" I have to create them individually, I could be wrong. – truthsayer Feb 16 '19 at 08:55
  • Yes, basically what I meant is to move the save out of `saveMyList` and call it afterwards but continue calling `saveMyList` inside the loop. – Joakim Danielson Feb 16 '19 at 09:05
  • @JoakimDanielson Oh okay, thank you – truthsayer Feb 16 '19 at 09:07

0 Answers0