首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Swift3:通过AppGroups从监视扩展访问核心数据时的空取

Swift3:通过AppGroups从监视扩展访问核心数据时的空取
EN

Stack Overflow用户
提问于 2017-02-16 11:02:12
回答 1查看 582关注 0票数 7

目前,我正在为一个已经存在的应用程序进行更新(迁移到Swift 3)。我有今天的目标-,搜索,留言-和监视扩展。每个目标都需要访问我的应用程序的核心数据模型,所以我创建了一个AppGroup,并为每个目标启用了该功能。尽管我已经对NSPersistentStoreCoordinator进行了子类化,所以所有内容都存储在一个共享文件夹中:

代码语言:javascript
复制
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()
    }
}

这个类文件,以及我的核心数据模型和下面的类都是所有提到的目标的目标成员。实体的代码被设置为Class Definition。到目前为止,我使用的是Core Data的默认实现:

代码语言:javascript
复制
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)")
            }
        }
    }
}

现在奇怪的部分是:从“今日”访问这些数据--以及消息扩展--似乎很正常(我假设搜索扩展也能工作,但就开发人员而言,我无法测试它)。试图用同一个请求从Watch应用程序的扩展中获取它,结果会产生一个空Array。这是我的获取代码:

代码语言:javascript
复制
    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
    }

为了更好地理解,需要更多的上下文:POI Entitie包含位置的纬度和经度。在启动应用程序时,我预先计算出从当前用户位置到数据库中每个点的距离。当今天扩展试图将最近的x(在我的例子中是8)的POI获取到当前用户的位置时,获取所有15k的POI并计算它们的距离对内存非常明智。因此,我必须预先计算距离(存储在locationDistanceCalculated中),然后取一个给定的半径(静态SETTINGS_MAXIMUM_FETCH_DISTANCE),并在获取过程中计算出一个精确的距离(存储在瞬态属性locationDistanceTransient中)。

在Watch应用程序的ExtensionDelegate类中,当更新用户的位置时,将实现CLLocationManagerDelegate并调用代码:

代码语言:javascript
复制
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)
            }
        }
    }
}

在模拟器和设备上进行了测试。context.fetch总是返回一个空数组(是的,核心数据包含值,是的,我在没有谓词的情况下测试过它)。我是否遗漏了核心数据中的任何新内容,我还没有考虑过,或者它们在WatchOS3中是否有任何限制,为什么这不起作用呢?有人有线索吗?谢谢你的帮助。

更新:当使用监视框架目标访问数据时,就像描述的在这个项目中一样,获取始终是空的。也许这是正确的道路,但观察框架是错误的选择。会让你跟上时代的。

更新2: --我已经在API引用中检查了App编程指南 for WatchOS和transferFile:metadata: 函数,但它似乎不是将这些大量数据发送给AppleWatch的合适方法。我不能依赖于这样的情况,即用户检查应用程序的频率比他离开SETTINGS_MAXIMUM_FETCH_DISTANCE半径的频率还要高,对于具有高密度POI的位置,这些数据甚至更广泛。

更新3: --我已经为POI重新实现了其附近的特性,以便只在给定的半径中获取。如果这为您解决了一个问题,请查看这个公共要旨

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-02-23 08:25:01

因为Watch OS3,所以您不能使用AppGroup技巧访问CoreData库(因为手表应该在没有手机的情况下工作)。

所以您必须使用WatchConnectivity来获取数据。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/42272054

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档