具有核心位置和核心数据的SwiftUI应用

时间:2020-08-14 02:18:40

标签: ios swift core-data swiftui core-location

我正在开发一个跟踪用户位置并在CoreData中保存一些与位置有关的数据的应用程序。我是SwiftUI的新手,所以我的问题与应用中将位置数据保存到CoreData的最佳位置在哪里/如何有关。

当前,我的设置与此处接受的解决方案非常相似: How to get Current Location using SwiftUI, without ViewControllers?

因此,我不会重复上面链接中已经存在的代码,但是会对其进行引用。因此,在阅读其余的问题陈述之前,您可能需要先看看答案。

所以在LocationManager类中,我有:

@Published var userLocations: [CLLocation]? {
    willSet {
        objectWillChange.send()
    }
}


func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    guard let location = locations.last else { return }
    let howOldIsTheLastLocationData = abs(location.timestamp.timeIntervalSinceNow)
    if howOldIsTheLastLocationData < 15 && location.horizontalAccuracy > 0 && location.horizontalAccuracy < 15 {
        if userLocations == nil {
            userLocations = []
        }
        userLocations?.append(location)
    }
    print(#function, location, location.latitudeString, location.longitudeString, location.altitude, howOldIsTheLastLocationData)
}

因此,userLocations是我想在View中观察的内容,并且还保存到CoreData中。

现在在我看来,我有:

@Environment(\.managedObjectContext) var context
@State var segment: Segment?
@ObservedObject var locationManager = LocationManager()

var userPath: [CLLocationCoordinate2D]? {
    if let userLocations = locationManager.userLocations {            
        return userLocations.map( { $0.coordinate })
    }
    return nil
}

var body: some View {
    // A MapView Uses userPath to show the path on a MKMapView        
    MapView(pathCoordinates: userPath ?? [])
    
    // There is a button that by pressing it, it creates a Segment which is an Entity in my CoreData with time data.
}

到目前为止,我上面提到的所有内容都有效。我正在获取位置更新,在MapView上显示路径。我可以通过按“开始”按钮来创建细分(并保存到CoreData中)。现在,我要寻找的内容是针对userLocations中的每个位置更新,我想创建另一个CoreData Entity的新实例,该实例称为PointOnPath,该实体与Segment关联。因此,Segment与PointOnPath具有一对多关系。我不知道应该在哪里调用以下代码行:

  let point = PointOnPath(context: context)
  point.latitude = location.coordinate.latitude
  point.longitude = location.coordinate.longitude
  point.segment = segment
  try? context.save()

我考虑过将以上代码行放入:

var userPath: [CLLocationCoordinate2D]? {
    if let userLocations = locationManager.userLocations {  
        // Maybe add to CoreData for PointOnPath here?
        return userLocations.map( { $0.coordinate })
    }
    return nil
}

但是我注意到这被多次调用。在我看来,仅当出现新的userLocations?.append(location)时才应调用它,但事实并非如此,它的调用次数比userLocations?.append(location)发生的次数多。通常,我不确定这是否是在PointOnPath中保存位置数据的最佳位置。真心感谢任何见识。

1 个答案:

答案 0 :(得分:0)

绝对没有理由,为什么视图应该负责将实体保存到数据库。 (甚至访问) 没有Storyboard或SwiftUI。

根据您的体系结构,您可以创建一个ViewModel,该ViewModel可以访问您的LocationManager和一个DataManger。这将负责将内容保存到您的数据库中。

您可能想查看this文章。