使用 Swift 3.0 将 CoreData 保存到 Web 服务器

Posted

技术标签:

【中文标题】使用 Swift 3.0 将 CoreData 保存到 Web 服务器【英文标题】:Saving CoreData to a Web Server with Swift 3.0 【发布时间】:2017-09-13 14:18:04 【问题描述】:

此问题与:Swift Core Data Sync With Web Server有关。

我已按照上述问题中提到的步骤进行操作,但是我无法将 第三个 步骤应用于我当前的项目。

我目前有一个名为 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
    

这是我在 tableViewController 上显示数据的方式。

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

我知道如何将数据保存到网络服务器,如本教程所述:https://www.simplifiedios.net/swift-php-mysql-tutorial/ 以及检查互联网连接。但是我不确定如何将它应用于涉及多个数据的 CoreData。 如果有人可以指导我找到解决方案或解释如何实现这一点,我将非常感激。

【问题讨论】:

第 3 步说使用NSPredicate 来获取数据。既然您的示例代码表明您已经知道如何获取数据,那么您在这一步遇到了什么问题? 但我只是不确定将 NSPredicate 放在哪里并让应用程序与 Web 服务器通信。这与codewithchris.com/iphone-app-connect-to-mysql-database 教程建议的方式相同吗? 我没有读过那个教程,所以我不能说。如果您的问题是知道如何使用谓词,您可以将它与您的 fetch 请求一起使用。 NSFetchRequest 有一个 predicate 属性。 好的,但这仍然没有告诉我如何使用它与 Web 服务器进行通信。我该怎么处理let isSynchedPredicate = NSPredicate(format: "synched = %@", false) 谓词不应该与与 Web 服务器的通信有任何关系。 NSPredicate 可以用作获取的一部分,以仅获取 synchedfalse 的条目。一旦你有了这些,将它们发送到网络服务器是一个单独的问题。 【参考方案1】:

您链接的问题不是试图解释如何与网络服务器通信。它解释了如何将数据存储在核心数据中并以您知道哪些记录已发送到 Web 服务器的方式对其进行标记/标记。

因此,谓词将获取所有尚未发送到 Web 服务器的记录,并允许您在有可用的 Internet 连接时发送它们。

与网络服务器通信可能是一个广泛的话题,并且取决于您的网络服务器和 API 设置,因此这里无法完全解释。我向您推荐一些免费的在线资源,这些资源将帮助您了解 Swift 中的网络。

Udacity - Networking with Swift Ray Wenderlich - Alamofire Tutorial Stack Overflow - Swift POST Request

这是来自上述 *** 答案的 POST 请求示例

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()

使用与此类似的代码,您应该能够将数据发送到您的网络服务器,然后您的网络服务器可以随心所欲地使用它。

更新:

要将您的参数编码为 JSON,您可以使用以下代码作为指导

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))

哪个会输出:

可选("\"用户名\":\"测试用户\",\"密码\":\"密码\"")

注意:您会将其作为数据发送,而不是字符串版本。因此您的代码可能如下所示:

request.httpBody = jsonData

【讨论】:

感谢您的回答。我只是想知道这种方法是否允许我一次将 CoreData 上的多个数据上传到 Web 服务器,而不是一次发送一个数据。我似乎无法理解在参数中包含多个数据的逻辑。 可以,但是您可能需要对对象列表进行 JSON 编码并将该数据发送到 request.httpBody。我链接的 Udacity 课程是免费的,它会教你如何做你想做的事并做好。 Alamofire 会更容易做/学习 对不起,如果这延迟了,但我想知道您是否可以演示如何以及在何处对项目中的对象进行 JSON 编码。我不断收到“JSON 写入中的***类型无效”错误。 抱歉耽搁了,我才看到这条评论,我已经用更多信息更新了答案。您可以在这里参考一个方便的类:github.com/martinjkelly/On-The-Map/blob/master/On%20The%20Map/…,但如果我没记错的话,它是用 Swift 2 编写的。这处理我项目的所有 HTTP 请求 抱歉这个延迟的评论,但我仍然无法将数据发送到服务器。我设法将我的数据转换为 JSON 格式。然而,尽管我已经解析了数据,但我的控制台日志正在打印 responseString = Optional("")。如果你想看看我是如何尝试的,我可以更新我的问题。

以上是关于使用 Swift 3.0 将 CoreData 保存到 Web 服务器的主要内容,如果未能解决你的问题,请参考以下文章

Swift 3.0 Coredata - Appdelegate & managedObjectContext 抛出 EXC_BAD_ACCESS 错误

浅谈SwiftUI 3.0新加入的CoreData动态FetchRequest过滤与排序特性

Swift 3.0 - 核心数据 / 意外发现 nil

Swift 3.0 使用Core Data

如何使用 Swift 将游戏的高分保存在排行榜上?

将 swift 3 项目转换为使用 CoreData