简体   繁体   English

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

[英]SwiftUI App with Core Location and Core Data

I am working on an app that tracks the user's location and saves some data related to the location in CoreData.我正在开发一个应用程序来跟踪用户的位置并在 CoreData 中保存一些与该位置相关的数据。 I am new to SwiftUI, so my question is related to where/how is the best place in the app to save the location data into CoreData.我是 SwiftUI 的新手,所以我的问题与应用程序中将位置数据保存到 CoreData 的最佳位置/位置有关。

Currently, I have a setup that is very similar to the accepted solution here: How to get Current Location using SwiftUI, without ViewControllers?目前,我的设置与此处接受的解决方案非常相似: How to get Current Location using SwiftUI, without ViewControllers?

Therefore I won't repeat the code that is already in the above link but will make references to it.因此,我不会重复上面链接中已经存在的代码,但会引用它。 So you may want to take a look at the answer before reading the rest of my problem statement.所以你可能想在阅读我的问题陈述的rest之前先看看答案。

So in class LocationManager I have:所以在 class 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)
}

Therefore userLocations is what I would like to observe in my View and also save into my CoreData.因此 userLocations 是我想在我的视图中观察并保存到我的 CoreData 中的内容。

Now in my View I have:现在在我看来,我有:

@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.
}

So far everything that I mentioned above is working.到目前为止,我上面提到的一切都在工作。 I am getting the location updates, showing the path on a MapView.我正在获取位置更新,在 MapView 上显示路径。 I am able to create Segments (and save into CoreData) by pressing the Start button.我可以通过按开始按钮来创建分段(并保存到 CoreData)。 Now the piece I am looking for is for every location update that goes into userLocations, I would like to create a new instance of another CoreData Entity that is called PointOnPath that is associated with a Segment.现在我正在寻找的部分是针对进入 userLocations 的每个位置更新,我想创建另一个名为 PointOnPath 的 CoreData 实体的新实例,它与一个段关联。 So Segment has a one-to-many relationship to PointOnPath.所以 Segment 与 PointOnPath 是一对多的关系。 What I don't know is where I should call something like the following lines of code:我不知道我应该在哪里调用类似以下代码行的内容:

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

I thought about putting the above lines of code into:我想过将上面的代码行放入:

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

But I noticed this is being called many times.但我注意到这被多次调用。 It seems to me it should only be called whenever a new userLocations?.append(location) happens but that's not the case and it's called many more times than userLocations?.append(location) happens.在我看来,它应该只在发生新的 userLocations?.append(location) 时才被调用,但事实并非如此,它被调用的次数比 userLocations?.append(location) 发生的次数多得多。 And in general I am not sure if that's the best place to save the location data in PointOnPath.一般来说,我不确定这是否是在 PointOnPath 中保存位置数据的最佳位置。 Any insight is really appreciated.任何见解都非常感谢。

There still is absolutely no reason why the view should be responsible for saving entities to the database.仍然绝对没有理由让视图负责将实体保存到数据库中。 (or even accessing) Neither with Storyboard nor with SwiftUI. (甚至访问)既不使用 Storyboard 也不使用 SwiftUI。

Depending on your architecture, you could create a ViewModel which would have access to your LocationManager and a, let's say, DataManger.根据您的架构,您可以创建一个 ViewModel,它可以访问您的 LocationManager 和一个,比如说,DataManger。 This one would be responsible to save stuff to your database.这个负责将内容保存到您的数据库中。

You might want to check out this article.你可能想看看这篇文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM