2015-04-16 4 views
0

Я поделился тем же .sqilte между двумя приложениями с помощью App groups.Обновление основного хранилища данных в applicationWillEnterForeground

Когда я добавляю запись в приложение A и открываю приложение B (первый запуск), приложение B получает правильные данные.

Я хотел бы синхронизировать данные, когда добавляю запись в приложения А и приложение В (уже запущенное в backrgound), приложение B может извлекать данные, когда оно возвращается на передний план.

Именно поэтому, когда приложение B возвращается на передний план, я обновляю Core Data Sack в applicationWillEnterForeground. Какой путь правильный?

let directory = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.com.sl.sharedData"); 

     let url = directory?.URLByAppendingPathComponent("sharedData.sqlite") 
     let store = self.persistentStoreCoordinator?.persistentStoreForURL(url!) 
     var error : NSError? 
     if false == self.persistentStoreCoordinator?.removePersistentStore(store!, error: &error) 
     { 
      println("error = \(error!.localizedDescription)") 
      return 
     } 
     let options = [ 
      NSMigratePersistentStoresAutomaticallyOption: true, 
      NSInferMappingModelAutomaticallyOption: true, 
      // Adding the journalling mode recommended by apple 
      NSSQLitePragmasOption: ["journal_mode": "DELETE"] 
     ] 
     var failureReason = "There was an error creating or loading the application's saved data." 
     if self.persistentStoreCoordinator?.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: options, error: &error) == nil { 
      // 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 
      error = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict) 
      // Replace this with code to handle the error appropriately. 
      // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. 
      NSLog("Unresolved error \(error), \(error!.userInfo)") 
      abort() 
     } 
     _persistentStoreCoordinator = nil 
     _managedObjectContext = nil 
     let rootViewController = self.window!.rootViewController as ViewController 
     rootViewController.context = self.managedObjectContext 

К сожалению, это не работает так, как я хочу. Полученные данные дублируются каждый раз, когда я вхожу в applicationWillEnterForeground. Какой путь правильный?

// Редактировать 2014/04/17: Покушение раствором Мунди

Я попытался с NSManagedObjectContextObjectsDidChangeNotification

func applicationWillEnterForeground(application: UIApplication) { 

     NSNotificationCenter.defaultCenter().addObserver(
      self, 
      selector: "mergeContextChangesForNotification:", 
      name: NSManagedObjectContextObjectsDidChangeNotification, 
      object: managedObjectContext) 

     let rootViewController = self.window!.rootViewController as ViewController 
     rootViewController.context = managedObjectContext 
     } 
    } 

func mergeContextChangesForNotification(notification : NSNotification){ 
     let otherContext: NSManagedObjectContext = notification.object as NSManagedObjectContext 

     if((otherContext != managedObjectContext) && (otherContext.persistentStoreCoordinator == managedObjectContext.persistentStoreCoordinator)){ 

      managedObjectContext.performBlockAndWait{() -> Void in 

       self.managedObjectContext.mergeChangesFromContextDidSaveNotification(notification) 
      } 
     } 
    } 

mergeContextChangesForNotification был вызван, но я никогда не вступал в этом состоянии: if otherContext != managedObjectContext) && (otherContext.persistentStoreCoordinator == managedObjectContext.persistentStoreCoordinator

+0

Что здесь означает «дублировать»? –

+0

«Дублированная запись», возможно, более уместна. – Hobbes

ответ

0

Вы не должны настраивать постоянный координатор хранилища, если приложение уже активно. Стандартная ленивая инициализация, используемая в шаблоне Xcode, является достаточной и предпочтительной.

Вместо этого вы можете прослушать NSManagedObjectContextObjectsDidChangeNotification и обновить свой интерфейс.

+0

Я отредактировал свое сообщение, потому что это не читается в комментариях. Thx для вашего ответа. – Hobbes

+0

Итак, какое из двух условий не выполняется? Вы должны выполнить код в отладчике и проанализировать, почему вы не получаете ожидаемого результата. С моей точки зрения, я ответил на ваш вопрос, вы должны принять этот ответ. Для вашей другой проблемы вы можете задать новый вопрос SOF. – Mundi

+0

Первое условие: otherContext! = ManagedObjectContext'. Я использую разные контексты управляемых объектов, которые не могут связываться через уведомления. Поэтому публикация уведомления, такого как NSManagedObjectContextObjectsDidChangeNotification, не работает, потому что NSNotificationCenter не отправляет уведомление из моего приложения. Приложение в мое приложение B, поскольку они оба разные процессы работают в разных пространствах памяти. – Hobbes

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