2015-11-05 5 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 или аналогичный). Вы можете сохранить хэш из последних загруженных объемных данных и запросить у сервера текущее значение хэш-функции.

Если значения разные (или если у вас нет значения хэш-функции), то получите данные с сервера.

Если это инкрементально, вы можете использовать один и тот же хэш или просто использовать временную метку с сервера от последней модификации до данных сервера. Клиент может сохранить это. Если они отличаются друг от друга, тогда вытащите данные с последней отметки времени (обратите внимание, что это не значит, что это временная метка ... она может просто просто увеличиваться).

EDIT

Я до сих пор не было никаких причин, чтобы узнать быстры (хотя вы, вероятно, должны, по крайней мере, научиться читать ObjC, так как подавляющее большинство всего кода IOS/OSX написано в ObjC), так что это всего лишь слабая, несжатая попытка.

В частности, я не уверен, что «let» создает константу, где привязка переменной не может быть изменена или если она делает ее «const» в смысле C++, где она не может принимать мутирующие методы , поэтому установка 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

Смежные вопросы