ios core-data swift3 watch-os-3 appgroups

ios - Swift3: vaciar la búsqueda al acceder a los datos principales de Watch Extension a través de AppGroups



core-data watch-os-3 (1)

Actualmente estoy trabajando en una actualización para una aplicación ya existente (migración a Swift 3). Tengo objetivos para Today, Search, Message y Watch Extensions. Cada objetivo debe acceder al Modelo de Datos Básicos de mi Aplicación, así que creé un Grupo de Aplicaciones y habilité la Capacidad para cada objetivo. Aunque he subclasificado el NSPersistentStoreCoordinator, entonces todo está almacenado en una carpeta compartida:

import CoreData class PFPersistentContainer: NSPersistentContainer { override open class func defaultDirectoryURL() -> URL { if let url = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "add-groupname-here") { return url } // Fallback return super.defaultDirectoryURL() } }

Este archivo de clase, así como mi Core-Data-Model y la siguiente clase pertenecen todos a objetivos de todos los objetivos mencionados. El Codegen de las Entidades está configurado en Class Definition . Hasta ahora, estoy usando la implementación predeterminada para la Pila de datos básicos:

class DataManager { /** * Singleton Implementation */ internal static let sharedInstance:DataManager = { let instance = DataManager() return instance }() // MARK: - Core Data stack lazy var persistentContainer: PFPersistentContainer = { let container = PFPersistentContainer(name: "Data") container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { fatalError("Unresolved error /(error), /(error.userInfo)") } }) return container }() // MARK: - Core Data Saving support func saveContext () { let context = persistentContainer.viewContext if context.hasChanges { do { try context.save() } catch { let nserror = error as NSError fatalError("Unresolved error /(nserror), /(nserror.userInfo)") } } } }

Ahora la parte más extraña: acceder a estos datos desde la extensión de hoy y de mensaje parece funcionar con gracia (supongo que la búsqueda-extensión también está funcionando, pero por lo que respecta a un desarrollador, no puedo probar esto). Intentar buscarlo con la misma Solicitud desde la Extensión de la aplicación Watch resulta en una Matriz vacía. Aquí está mi código de búsqueda:

internal func getLimitedPOIsWithCalculatedDistance(andCurrentLocation currentLocation:CLLocation) -> Array<POI> { var poiArray:Array< POI > = [] guard let context = self.backgroundContext else { return [] } do { // Initialize Fetch Request let request:NSFetchRequest<NSFetchRequestResult> = NSFetchRequest(entityName: "POI") // Create Entity Description let entityDescription = NSEntityDescription.entity(forEntityName: "POI", in: context) // Configure Fetch Request request.entity = entityDescription // Configure Predicate let predicate = NSPredicate(format: "(disabled == NO) AND (locationDistanceCalculated <= /(SETTINGS_MAXIMUM_FETCH_DISTANCE))") request.predicate = predicate if let result = try context.fetch(request) as? Array<POI> { for poi in result { let poiLocation = CLLocation(latitude: poi.locationLatitude, longitude: poi.locationLongitude) let distance = currentLocation.distance(from: poiLocation) poi.locationDistanceTransient = Double(distance) } poiArray = result.filter({ (poi) -> Bool in return poi.locationDistanceTransient > 0.0 }) poiArray.sort { (first, second) -> Bool in return first.locationDistanceTransient < second.locationDistanceTransient } } } catch { print("Error in WatchDataInterface.getLimitedPOIsWithCalculatedDistance(): /(error.localizedDescription)") } return poiArray }

Un poco más de contexto para una mejor comprensión: la entidad POI contiene latitud y longitud de una ubicación. Al iniciar la aplicación, estoy calculando previamente la distancia a cada punto de la base de datos desde la posición del usuario actual. Cuando Today-Extension intenta obtener los puntos de interés de x (en mi caso 8) más cercanos a la posición actual de los usuarios, obtener todos los 15k POI y calcular su distancia es una cuestión de memoria. Así que tuve que calcular previamente la distancia (almacenada en la locationDistanceCalculated ), luego buscar en un radio determinado ( SETTINGS_MAXIMUM_FETCH_DISTANCE estático) y calcular una distancia precisa durante el proceso de recuperación (almacenado en una locationDistanceTransient propiedad transitoriaDistanceTransient).

En la clase ExtensionDelegate Watch App, se implementa CLLocationManagerDelegate se CLLocationManagerDelegate el código cuando se actualiza la ubicación del usuario:

extension ExtensionDelegate: CLLocationManagerDelegate { func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { OperationQueue.main.addOperation{ if let watchDataManager = self.watchDataManager { // getNearestPOIs() calls the getLimitedPOIsWithCalculatedDistance() function and returns only a numberOfPOIs self.nearbyPOIs = watchDataManager.getNearestPOIs(numberOfPOIs: 4) } } } }

Fue probado en simulador y en un dispositivo. The context.fetch siempre devuelve una matriz vacía (Sí, los datos centrales contienen valores y sí, los he probado sin el predicado). ¿Me falta algo nuevo en Core Data, que aún no he considerado o son sus limitaciones en WatchOS3 por qué esto no funciona? ¿Alguien tiene una pista? Gracias por tu ayuda.

Actualización: cuando se utiliza un objetivo de Watch Framework para acceder a Core Data, como se describe en este proyecto , la búsqueda permanece vacía. Tal vez este podría ser el camino correcto, pero un Marco de vigilancia es la selección incorrecta. Te mantendré al día.

Actualización 2: Ya revisé la Guía de programación de aplicaciones para WatchOS y la función transferFile:metadata: en las referencias de API, pero no parece ser una forma adecuada de enviar estas grandes cantidades de datos al AppleWatch. Simplemente no puedo confiar en la circunstancia de que el usuario esté revisando la aplicación con más frecuencia de lo que está viajando fuera del radio SETTINGS_MAXIMUM_FETCH_DISTANCE y para las ubicaciones con una alta densidad de puntos de interés, esta información es aún más extensa.

Actualización 3: He vuelto a implementar la característica cercana para los POIs para buscar solo en un radio dado. Si esto te soluciona un problema, mira este Gist público.


Desde Watch OS3, no puede acceder a una base CoreData utilizando el truco del grupo de aplicaciones (porque se supone que el reloj debe funcionar sin un teléfono.

Entonces debes usar WatchConnectivity para buscar tus datos