0

每次应用程序运行时,它都会从服务器下载数据,如果数据已经在设备中,我该如何阻止它下载?

import UIKit
import CoreData

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {

    var window: UIWindow?


    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {

        preloadData()

        return true
    }

    func applicationWillResignActive(application: UIApplication) {
    }

    func applicationDidEnterBackground(application: UIApplication) {
    }

    func applicationWillEnterForeground(application: UIApplication) {
    }

    func applicationDidBecomeActive(application: UIApplication) {
    }

    func applicationWillTerminate(application: UIApplication) {
    }

    // MARK: - Core Data stack

    lazy var applicationDocumentsDirectory: NSURL = {
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.count-1]
        }()

    lazy var managedObjectModel: NSManagedObjectModel = {
        let modelURL = NSBundle.mainBundle().URLForResource("CoreDataDemo", withExtension: "momd")!
        return NSManagedObjectModel(contentsOfURL: modelURL)!
        }()

    lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = {
        let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
        let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("CoreDataDemo.sqlite")
        var failureReason = "There was an error creating or loading the application's saved data."
        do {
            try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil)
        } catch {
            // Report any error we got.
            var dict = [String: AnyObject]()
            dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data"
            dict[NSLocalizedFailureReasonErrorKey] = failureReason

            dict[NSUnderlyingErrorKey] = error as NSError
            let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict)

NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)")
            abort()
        }

        return coordinator
        }()

    lazy var managedObjectContext: NSManagedObjectContext = {
let coordinator = self.persistentStoreCoordinator
        var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
        managedObjectContext.persistentStoreCoordinator = coordinator
        return managedObjectContext
        }()

    // MARK: - Core Data Saving support

    func saveContext () {
        if managedObjectContext.hasChanges {
            do {
                try managedObjectContext.save()
            } catch {
let nserror = error as NSError
                NSLog("Unresolved error \(nserror), \(nserror.userInfo)")
                abort()
            }
        }
    }

    // MARK: - CSV Parser Methods

    func parseCSV (contentsOfURL: NSURL, encoding: NSStringEncoding) -> [(name:String, detail:String, price: String)]? {

        // Load the CSV file and parse it
        let delimiter = ","
        var items:[(name:String, detail:String, price: String)]?

        do {
            let content = try String(contentsOfURL: contentsOfURL, encoding: encoding)
            print(content)
            items = []
            let lines:[String] = content.componentsSeparatedByCharactersInSet(NSCharacterSet.newlineCharacterSet()) as [String]

            for line in lines {
                var values:[String] = []
                if line != "" {
                    // For a line with double quotes
                    // we use NSScanner to perform the parsing
                    if line.rangeOfString("\"") != nil {
                        var textToScan:String = line
                        var value:NSString?
                        var textScanner:NSScanner = NSScanner(string: textToScan)
                        while textScanner.string != "" {

                            if (textScanner.string as NSString).substringToIndex(1) == "\"" {
                                textScanner.scanLocation += 1
                                textScanner.scanUpToString("\"", intoString: &value)
                                textScanner.scanLocation += 1
                            } else {
                                textScanner.scanUpToString(delimiter, intoString: &value)
                            }

                            // Store the value into the values array
                            values.append(value as! String)

                            // Retrieve the unscanned remainder of the string
                            if textScanner.scanLocation < textScanner.string.characters.count {
                                textToScan = (textScanner.string as NSString).substringFromIndex(textScanner.scanLocation + 1)
                            } else {
                                textToScan = ""
                            }
                            textScanner = NSScanner(string: textToScan)
                        }

} else  {
                        values = line.componentsSeparatedByString(delimiter)
                    }
                    let item = (name: values[0], detail: values[1], price: values[2])
                    items?.append(item)
                }
            }

        } catch {
            print(error)
        }

        return items
    }

    func preloadData () {

        // Load the data file. For any reasons it can't be loaded, we just return
        guard let remoteURL = NSURL(string: "https://drive.google.com/open?id=0B4xB0m95siM2OVRCclRIRXZWZXM/menudata.csv") else {


"https://googledrive.com/host/0ByZhaKOAvtNGTHhXUUpGS3VqZnM/menudata.csv"
  return
        }

        // Remove all the menu items before preloading
        removeData()

        if let items = parseCSV(remoteURL, encoding: NSUTF8StringEncoding) {
            // Preload the menu items
            for item in items {
                let menuItem = NSEntityDescription.insertNewObjectForEntityForName("MenuItem", inManagedObjectContext: managedObjectContext) as! MenuItem
                menuItem.name = item.name
                menuItem.detail = item.detail
                menuItem.price = (item.price as NSString).doubleValue

                do {
                    try managedObjectContext.save()
                } catch {
                    print(error)
                }
            }

        }
    }

    func removeData () {
        // Remove the existing items
        let fetchRequest = NSFetchRequest(entityName: "MenuItem")

        do {
            let menuItems = try managedObjectContext.executeFetchRequest(fetchRequest) as! [MenuItem]
            for menuItem in menuItems {
                managedObjectContext.deleteObject(menuItem)
            }
        } catch {
            print(error)
        }
    }
}
4

1 回答 1

1

如果它总是完全相同的数据,那么您可以尝试获取一个实体...

对象...

NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"MyEntity"];
fetchRequest.fetchLimit = 1;
NSError *error;
NSArray *result = [context executeFetchRequest:fetchRequest error:&error];
if (result == nil) {
    // Handle error...
} else if (result.count == 0) {
    // You know you do not have any items, so download
}

但是,如果您的服务器数据可以更改,并且是大容量的,那么您可能需要计算数据的哈希值(SHA-1 或类似的)。您可以存储上次下载的批量数据的哈希值,并向服务器询问当前的哈希值。

如果值不同(或者如果您没有哈希值),则从服务器获取数据。

如果它是增量的,您可以使用相同的散列,或者只使用服务器上一次修改服务器数据的时间戳。客户端可以存储它。如果它们不同,则从最后一个时间戳开始下拉数据——(注意它不一定是时间戳......它很容易只是一个递增的数字)。

编辑

我还没有任何理由学习 swift(尽管您可能至少应该学习阅读 ObjC,因为绝大多数 iOS/OSX 代码都是用 ObjC 编写的),所以这只是一个微弱的、未编译的尝试。

特别是,我不确定“let”是否创建了一个无法更改变量绑定的常量,或者它是否在 C++ 意义上使它成为“const”,它不能接受变异方法,所以设置fetchLimit 可能有效,也可能无效。

let fetchRequest: NSFetchRequest = NSFetchRequest(entityName: "MyEntity")
fetchRequest.fetchLimit = 1        
do {
    let result = try context.executeFetchRequest(fetchRequest)
    // I assume this code only gets executed if there is no error
    if result.count == 0 {
        // You know you do not have any items, so download
    }
} catch let error as NSError {
    // Handle error
}
于 2015-11-05T22:37:05.717 回答