2015-11-05 21 views
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) 
     } 
    } 
} 
+0

商店標誌或檢查 – Wain

回答

1

如果它總是完全相同的數據,那麼你可以嘗試獲取一個實體......

ObjC ...

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或類似的)。您可以存儲您下載的最新批量數據中的散列值,並向服務器請求當前散列值。

如果值不同(或者如果沒有散列值),則從服務器獲取數據。

如果它是增量式的,可以使用相同的散列值,或者僅使用從服務器上次修改到服務器數據的時間戳。客戶端可以存儲它。如果它們不同,那麼從上次的時間戳開始下拉數據 - (注意它不一定是時間戳......它可能只是一個遞增的數字)。

編輯

我還沒有有任何理由要學會快速的(雖然你可能應該至少學會閱讀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 
} 
+0

謝謝您的解釋存儲項目的數量,該數據不會改變,也有在該塊最可能多的錯誤,是因爲我使用swift2我會揣摩差異,但如果你有迅速我非常感謝:) – Manolo

+2

延遲的抱歉工作得很好,我在你的代碼中做的唯一改變是「context」 - > managedObjectContext(swift2)。非常感謝。 – Manolo

相關問題