每次应用程序运行时,它都会从服务器下载数据,如果数据已经存在于设备中,如何停止下载?
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 :(得分: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或类似值)。您可以存储下载的最后一个批量数据的哈希值,并向服务器询问当前哈希值。
如果值不同(或者如果没有哈希值),则从服务器获取数据。
如果它是增量的,您可以使用相同的哈希,或者只使用服务器中从上次修改到服务器数据的时间戳。客户端可以存储它。如果它们不同,那么从上一个时间戳开始下拉数据 - (注意它不一定是时间戳......它可以很容易地只是一个递增的数字)。
修改强>
我还没有任何理由学习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
}