如何在swift中保存Json数据和脱机显示

时间:2018-05-30 06:01:43

标签: ios json swift

我试图保存我的json文件并将其显示为脱机状态。我试过这段代码,但它对我不起作用..

let myData = NSKeyedArchiver.archivedData(withRootObject: self.data)
             UserDefaults.standard.set(myData, forKey: "userJson")
             UserDefaults.standard.synchronize()

任何人都可以建议我更好地保存数据和离线显示吗?

2 个答案:

答案 0 :(得分:2)

您不应该在UserDefault中保存JSON,而是将其保存在文档目录

中的文件中

我创建了一个允许轻松完成的泛型类

//
//  OfflineManager.swift
// 
//
//  Created by Prashant on 01/05/18.
//  Copyright © 2018 Prashant. All rights reserved.
//

import UIKit

class OfflineManager: NSObject {

    static let sharedManager = OfflineManager()
    let LocalServiceCacheDownloadDir        = "LocalData"

    enum WSCacheKeys {
        case CampignList
        case CampignDetail(id:String)
        case ScreenShotList

        var value:String {
            switch self {
            case .CampignList:
              return  "CampignList"
            case .CampignDetail(let id):
                return id
            case .ScreenShotList :
                return "ScreenShotList"
            }

        }
    }

    func getBaseForCacheLocal(with fileName:String) -> String? {

        let filePath = FileManager.default.getDocumentPath(forItemName: self.LocalServiceCacheDownloadDir)
        if FileManager.default.directoryExists(atPath: filePath) {
            return filePath.stringByAppendingPathComponent(fileName)
        } else {
            if  FileManager.default.createDirectory(withFolderName: self.LocalServiceCacheDownloadDir) {
                return filePath.stringByAppendingPathComponent(fileName)
            }
        }
        return nil
    }



    //------------------------------------------------------------

    @discardableResult
    func cacheDataToLocal<T>(with Object:T,to key:WSCacheKeys) -> Bool {
        let success = NSKeyedArchiver.archiveRootObject(Object, toFile: getBaseForCacheLocal(with: key.value)!)
        if success {
            print( "Local Data Cached\(String(describing: getBaseForCacheLocal(with: key.value)))")
        } else {
            print("Error")
        }

        return success

    }

    //------------------------------------------------------------

    func loadCachedDataFromLocal<T>(with key:WSCacheKeys ) -> T? {
        return NSKeyedUnarchiver.unarchiveObject(withFile: getBaseForCacheLocal(with: key.value)!) as? T
    }


    //------------------------------------------------------------


    func removeAllCacheDirs () {
        do {
            try FileManager.default.removeItem(atPath: self.getBaseForCacheLocal(with: "")!)

        } catch {
            print("error in remove dir \(error.localizedDescription)")
        }

    }

    //--------------------------------------------------------------------------------


}

以下是extension FileManager

的一些辅助方法
public var getDocumentDirectoryPath: String {
    let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
    return documentDirectory
}

public func getDocumentPath(forItemName name: String)-> String {
    return getDocumentDirectoryPath.stringByAppendingPathComponent(name)
}

public func directoryExists(atPath filePath: String)-> Bool {
    var isDir = ObjCBool(true)
    return FileManager.default.fileExists(atPath: filePath, isDirectory: &isDir )
}

public func createDirectory(withFolderName name: String)-> Bool {
    let finalPath = getDocumentDirectoryPath.stringByAppendingPathComponent(name)
    return createDirectory(atPath: finalPath)
}

这是String扩展的方法

public func stringByAppendingPathComponent(_ path: String) -> String {
    let fileUrl = URL.init(fileURLWithPath: self)
    let filePath = fileUrl.appendingPathComponent(path).path
    return filePath
}

如何使用它?

保存

   OfflineManager.sharedManager.cacheDataToLocal(with: object as! [String:Any], to: .CampignList)

阅读数据

    DispatchQueue.global().async {
        // GET OFFLINE DATA
        if let object:[String:Any] = OfflineManager.sharedManager.loadCachedDataFromLocal(with: .CampignList) {
            do {
                let data = try  JSONSerialization.data(withJSONObject: object, options: [])
                let object = try CampaignListResponse.init(data: data)
                self.arrCampignList = object.data ?? []
                DispatchQueue.main.async {
                    self.tableVIew.reloadData()
                }
            } catch {
            }
        }
      }

注意:您可以为json的类型定义自己的WSCacheKeys,例如我正在获取一些广告系列列表

答案 1 :(得分:1)

您可以使用Realm或CoraData保存数据并在离线时显示数据。 这是Realm的官方链接。您可以从这里学习。 https://realm.io/docs/swift/latest