【问题标题】:Use JSON data offline Swift 3使用 JSON 数据离线 Swift 3
【发布时间】:2017-06-26 11:04:01
【问题描述】:

我是初学者,所以请温柔。 好的,所以我成功地从服务器解析了我的 JSON,并且可以访问它的所有内容,但我知道我有点卡在这里:

//Functionn for fetching API data
func fetchRates(){

    //Set EndPoint URL
    let url = URL(string: endPoint)

    URLSession.shared.dataTask(with: url!) { (data, response, error) in

        if error != nil {

            print(error as Any)

        }

        do {

            let json = try? JSONSerialization.jsonObject(with: data!, options: [])

            let dictonary = json as? [String: Any?]

            let ratesJson = dictonary?["rates"] as? [String: Double]

            print(ratesJson as Any)



        } catch let jsonError {

            print(jsonError)

        }

    }.resume()


}

现在我想从这个函数中取出我的 ratesJson 字典,并实际使用它的内容进行一些计算,但经过数小时的尝试和搜索,我仍然不知道如何。

我只想:

  • 获取预先存储的 JSON 数据(供离线使用)
  • 应用启动时更新数据并覆盖旧数据

到目前为止,我遇到的可能性是 CoreData,它看起来真的很混乱和复杂,还有 Realm,我根本不知道。

如果这看起来真的很愚蠢,我们将非常感谢和抱歉

【问题讨论】:

    标签: ios json core-data swift3


    【解决方案1】:

    既然您已经解析了 JSON,我将创建一个对象类来使用 Core Data 存储数据。一开始有很多关于核心数据使用的内容,但是如果您打算继续进行 iOS 开发,那么值得花时间学习。 Core Data Tuts

    我也不知道你打算用你的应用做什么,或者目的,根据你的目的,Core Data 可能有点矫枉过正,但你总是可以每次保存更新的 JSON,覆盖设备的文档目录,然后读回数据并再次解析。

    您可以使用以下方法将 JSON 数据写入输出流:

    JSONSerialization.writeJSONObject(_ obj: Any, to stream: OutputStream, options opt: JSONSerialization.WritingOptions = [], error: NSErrorPointer)
    //Write JSON data into a stream. The stream should be opened and configured. 
    //The return value is the number of bytes written to the stream, or 0 on error. 
    //All other behavior of this method is the same as the dataWithJSONObject:options:error: method.
    

    更新:好的,我想我现在看到了您的问题。有两种方法可以将数据返回到视图控制器: 1. 委托模式 2. 闭包。我个人喜欢使用代表而不是闭包。

    对于委托,您需要创建一个协议:

    protocol SessionDataTaskComplete {
        func dataDownloaded(parsedJson : [String : Double])
    }
    

    在您的 URLSession 类中,您将需要一个类变量来保存该协议委托:

    var dataTaskCompleteDelegate : SessionDataTaskComplete?
    

    然后您需要让您的视图控制器实现该协议:

    class MyViewController: UIViewController, SessionDataTaskComplete {
    
        override func viewDidLoad() {
            super.viewDidLoad()
            //Also assign your viewController as your URLSession's SessionDataTaskComplete delegate
            myURLSession.dataTaskCompleteDelegate = self
        }
    
        func dataDownloaded(parsedJson : [String : Double]) {
            //Handle data as you wish here
        }
    }
    

    现在在您的 fetchRates() 中,您可以使用该委托将数据传回您的 viewController:

    func fetchRates(){
    
    //Set EndPoint URL
    let url = URL(string: endPoint)
    
    URLSession.shared.dataTask(with: url!) { (data, response, error) in
    
        if error != nil {
    
            print(error as Any)
    
        }
    
        do {
    
            let json = try? JSONSerialization.jsonObject(with: data!, options: [])
    
            let dictonary = json as? [String: Any?]
    
            let ratesJson = dictonary?["rates"] as? [String: Double]
    
            //print(ratesJson as Any)
            if (dataTaskCompleteDelegate != nil) {
                dataTaskCompleteDelegate!.dataDownloaded(parsedJson: ratesJson)
            }
    
    
    
        } catch let jsonError {
    
            print(jsonError)
    
        }
    
    }.resume()
    
    
    }
    

    如果您不习惯使用委托模式,我建议您花时间学习其他方法,因为它在 iOS SDK 中被广泛使用。尝试将它们视为将职责/任务分配给另一个对象的对象。

    【讨论】:

    • 我已经阅读了代表,我真的很难理解任何东西......我已经尝试使用上面的代码,但我无法让它工作它不会让我在 ViewDid Load var dataTaskCompleteDelegate : SessionDataTaskComplete? 内执行我认为这是因为我的 fetchRates() 在 ViewController 类中(在 ViewDidLoad 之外)或其他东西,但我真的很难理解
    • 是的,这就是原因,通常你会有一个单独的类来处理会话任务和数据模型更改。在你的情况下,因为它都在你的视图控制器中,而不是调用:dataTaskCompleteDelegate!.dataDownloaded(parsedJson:ratesJson),并创建协议,只需调用另一个函数并传递数据。我强烈建议您研究并学习 MVC(模型-视图-控制器)架构。
    • 好吧,我会推迟这个,看看 MVC,因为我真的不知道该怎么做,谢谢帮助
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-06-14
    • 2014-02-22
    • 1970-01-01
    相关资源
    最近更新 更多