0

This question is related to: Swift Core Data Sync With Web Server.

I have followed the steps that have been mentioned in the question above however I am unable to apply the third step to my current project.

I currently have a class called Records

class Records {

    static let shared = Records()

    var records = [Record]()
    let context = PersistenceServce.context
    let request = NSFetchRequest<Record>(entityName: "Record")

    func recordData() -> [Record] {

        do {
            records = try context.fetch(Record.fetchRequest())
        }catch {
            print("Error fetching data from CoreData")
        }

        return records
    }
}

and here is how I display the data on my tableViewController.

func getData() {
    records = Records.shared.recordData()
    self.tableView.reloadData()
}

I do know how save data to a web server as this tutorial explains: https://www.simplifiedios.net/swift-php-mysql-tutorial/ as well as check for internet connection. However I am unsure how to apply it to the CoreData where there are multiple data involved. If anyone could direct me to a solution or an explain how this can be achieved I'd very much appreciate it.

Chace
  • 561
  • 10
  • 28
  • Step 3 there says to use an `NSPredicate` to fetch data. Since your sample code indicates you already know how to fetch data, what problem are you having with that step? – Tom Harrington Sep 13 '17 at 14:46
  • But I am just unsure where to put the `NSPredicate` and get the app to communicate with the web server. Is that down in the same way that this https://codewithchris.com/iphone-app-connect-to-mysql-database/ tutorial suggests? – Chace Sep 13 '17 at 14:50
  • I haven't read that tutorial so I couldn't say. If your problem is knowing how to use the predicate, you use it with your fetch request. `NSFetchRequest` has a `predicate` property. – Tom Harrington Sep 13 '17 at 14:52
  • Ok, but that still doesn't tell me how to use it communicate with the web server. What do I do with `let isSynchedPredicate = NSPredicate(format: "synched = %@", false)`? – Chace Sep 13 '17 at 14:54
  • A predicate shouldn't have anything at all to do with communicating with a web server. `NSPredicate` can be used as part of your fetch, to get only those entries where `synched` is `false`. Once you have those, sending them to a web server is a separate problem. – Tom Harrington Sep 13 '17 at 14:56
  • I understand. So my question is irrelevant to what I am trying to achieve? Would you be able to direct me which way I could go about sending data to the web server? – Chace Sep 13 '17 at 14:58

1 Answers1

1

The question that you have linked is not trying to explain how to communicate with a web server. It is explaining how to store data in core data and tag/mark it in a way that you know which records have been sent to the web server or not.

So the Predicate will fetch all records that have not been sent to the web server and allow you to send them when you have an internet connection available.

Communicating with a web server can be a broad topic and will depend on your web server and API setup, so it is too much to explain here fully. I refer you to some free online resources that will help you understand networking in Swift.

Here is an example of a POST Request from the StackOverflow answer above

var request = URLRequest(url: URL(string: "http://test.tranzporthub.com/street45/customer_login.php")!)
request.httpMethod = "POST"
let postString = "user_id=chaitanya3191@gmail.com&password=123"
request.httpBody = postString.data(using: .utf8)
let task = URLSession.shared.dataTask(with: request) { data, response, error in
    guard let data = data, error == nil else {                                                 // check for fundamental networking error
        print("error=\(error)")
        return
    }

    if let httpStatus = response as? HTTPURLResponse, httpStatus.statusCode != 200 {           // check for http errors
        print("statusCode should be 200, but is \(httpStatus.statusCode)")
        print("response = \(response)")

    }

    let responseString = String(data: data, encoding: .utf8)
    print("responseString = \(responseString)")
}
task.resume()

Using code similar to this, you should be able to send data to your web server, then your web server can do whatever it likes with it.

UPDATE:

To encode your parameters to JSON you can use the following code as a guide

var dictionary = [
    "username": "Test User",
    "password": "Password"
]

if let jsonData = try? JSONSerialization.data(withJSONObject: dictionary, options: []) {
    // jsonData is a byte sequence, to view it you would need to convert to string
    print(String(bytes: jsonData, encoding: String.Encoding.utf8))
}

Which would output:

Optional("{\"username\":\"Test User\",\"password\":\"Password\"}")

Note: you would send it as data, not the string version. so your code might look like this:

request.httpBody = jsonData
Scriptable
  • 19,402
  • 5
  • 56
  • 72
  • Thank you for this answer. I just wanted to know if this method will allow me to upload multiple data that are on the CoreData to web server at once rather than sending one data at a time. I can't seem to get my head around the logic of having multiple data inside a parameter. – Chace Sep 13 '17 at 15:52
  • It would yes, but you would likely need to JSON encode the list of objects and send that data in the `request.httpBody`. The Udacity course I linked is free and will teach you how to do what you want and do it well. Alamofire would be easier to do/learn – Scriptable Sep 13 '17 at 15:56
  • Sorry if this is delayed, but I was wondering if you could demonstrate how and where I can JSON encode the objects in my project. I keep getting a "Invalid top-level type in JSON write'" error. – Chace Sep 15 '17 at 15:02
  • Sorry for the delay, I've only just seen this comment, i've updated the answer with some more information. There is a handy class you can reference here: https://github.com/martinjkelly/On-The-Map/blob/master/On%20The%20Map/OTMClient.swift but its written in Swift 2 if I remember rightly. This deals with all of the HTTP requests for my project – Scriptable Sep 17 '17 at 10:27
  • Sorry for this delayed comment but I'm still unable to send the data to the server. I have managed to convert my data into a JSON format. However my console log is printing `responseString = Optional("")` despite the fact I have parsed the data through. I can update my question if you wish to see how I am attempting this. – Chace Sep 21 '17 at 11:02
  • it would probably be best to create a new question, link it here and ill take a look once you have done it – Scriptable Sep 21 '17 at 11:10
  • Please see the link below: https://stackoverflow.com/questions/46342714/parsing-json-data-to-server-with-swift-3-0 – Chace Sep 21 '17 at 11:26