【发布时间】:2022-06-11 02:58:49
【问题描述】:
我是 SwiftUI 和 Realm 的新手(使用灵活同步),如果这听起来像一个基本问题,请原谅 我将位置数据保存在 MongoDB Atlas 集合中 - 中心
class Centre: Object, ObjectKeyIdentifiable {
@Persisted var _id: ObjectId = ObjectId.generate()
@Persisted var centreName = ""
@Persisted var centreDesc = ""
@Persisted var centreLocation: Coordinates?
override static func primaryKey() -> String? {
return "_id"
}
convenience init(centreName: String, centreDesc: String, centreLocation: Coordinates) {
self.init()
self.centreName = centreName
self.centreDesc = centreDesc
self.centreLocation = centreLocation
}
}
坐标是嵌入对象,其中“x”是经度,“y”是纬度
class Coordinates: EmbeddedObject, ObjectKeyIdentifiable {
@Persisted var x: Double?
@Persisted var y: Double?
}
我创建了一个符合 MapAnnotation 协议要求的结构 -
struct CustomAnnots: Identifiable {
let id: UUID
var nameCentreLoc: String
var descCentreLoc: String
let latitude: Double
let longitude: Double
var coordinate: CLLocationCoordinate2D {
CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
}
}
我正在尝试从 Atlas 集合中的数据填充此结构 我的 LocationView - 不工作
import SwiftUI
import MapKit
import RealmSwift
struct LocationView: View {
@Environment(\.realm) var realm
@ObservedResults(Centre.self) var centres
@ObservedRealmObject var centre: Centre
@State private var nameCentreLoc = ""
@State private var descCentreLoc = ""
@State private var latitude = 0.0
@State private var longitude = 0.0
@State private var annots = []
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 24.681_858, longitude: 81.811_623),
span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)
)
var body: some View {
Map(coordinateRegion: $region, annotationItems: annots, annotationContent: { locations in
MapPin(coordinate: locations.coordinate)
})
.onAppear {
setSubscription()
initData()
}
}
private func setSubscription() {
let subscriptions = realm.subscriptions
subscriptions.write {
if let currentSubscription = subscriptions.first(named: "all_centres") {
currentSubscription.update(toType: Centre.self) { centre in
centre.centreName != ""
}
} else {
subscriptions.append(QuerySubscription<Centre>(name: "all_centres") { centre in
centre.centreName != ""
})
}
}
}
private func initData() {
nameCentreLoc = centre.centreName
descCentreLoc = centre.centreDesc
latitude = (centre.centreLocation?.y)!
longitude = (centre.centreLocation?.x)!
let annots = [for centre in centres {
CustomAnnots(id: UUID(), nameCentreLoc: nameCentreLoc, descCentreLoc: descCentreLoc, latitude: latitude, longitude: longitude)
}]
}
}
如何使用 Center 集合中的数据填充 Struct?
更改为(Xcode 中没有错误)-
var body: some View {
let annots = [CustomAnnots(id: UUID(), nameCentreLoc: centre.centreName, descCentreLoc: centre.centreDesc, latitude: (centre.centreLocation?.y)!, longitude: (centre.centreLocation?.x)!)]
Map(coordinateRegion: $region, annotationItems: annots, annotationContent: { locations in
MapPin(coordinate: locations.coordinate)
})
.onAppear {
setSubscription()
}
}
现在出现运行时错误“强制展开 nil 值”
使用此功能,我可以将结果打印到控制台
func getLoc() {
for centre in centres {
var annots = [CustomAnnots.init(id: UUID(), nameCentreLoc: centre.centreName, descCentreLoc: centre.centreDesc, latitude: (centre.centreLocation?.y)!, longitude: (centre.centreLocation?.x)!)]
print(annots)
}
}
我把这个打印出来了—— [ACCv5.CustomAnnots(id:67E9DADA-0BCC-4D30-8136-8B666881E82D,nameCentreLoc:“HO”,descCentreLoc:“Head Office Artemis Cardiac Care Gurgaon”,纬度:28.438694893842058,经度:77.10845294294181) [ACCv5.CustomAnnots(id: 26DC0C63-5A17-49C7-B4BF-FD3AA1ABF65E, nameCentreLoc: "Panipat", descCentreLoc: "Artemis Heart Center at Ravindra Hospital", 纬度: 29.388306713854682, 经度: 76.95889693063663)] [ACCv5.CustomAnnots(id: D3A70E58-6B65-4F5D-A398-3394B7FB04DF, nameCentreLoc: "Ranchi", descCentreLoc: "Artemis Heart Center at Raj Hospital", latitude: 23.35731237118492, longitude: 85.32288933068195)]
但我无法用这个显示 MapAnnotations -
@Environment(\.realm) var realm
@ObservedResults(Centre.self) var centres
@State public var annots: [CustomAnnots]
@State private var region = MKCoordinateRegion(
center: CLLocationCoordinate2D(latitude: 24.681_858, longitude: 81.811_623),
span: MKCoordinateSpan(latitudeDelta: 10, longitudeDelta: 10)
)
var body: some View {
ForEach (centres) { centre in
var annots = [CustomAnnots.init(id: UUID(), nameCentreLoc: centre.centreName, descCentreLoc: centre.centreDesc, latitude: (centre.centreLocation?.y)!, longitude: (centre.centreLocation?.x)!)]
}
// Text("\(annots.count)")
Map(coordinateRegion: $region, annotationItems: annots, annotationContent: { locations in
MapMarker(coordinate: locations.coordinate)
})
【问题讨论】:
-
欢迎来到 SO。告诉我们一些事情 - 不起作用 - 是模糊的。有什么不好的?哪条线路没有按预期工作?你做了哪些故障排除?此外,您似乎正在处理大量重复数据。最后,为什么不将数据存储在 Realm 对象中并拥有一个直接返回 CustomAnnot 对象的函数呢?另外,请注意MapAnnotation Protocol Documentation 中的这一点不要创建符合此协议的类型。请改用 MapAnnotation 框架。
-
感谢您的回复,杰。 “let annots = [for center...”这一行抛出“容器文字中的预期表达式”和“annotationItems:annots”初始“在范围内找不到它。然后我创建了一个空数组”@State private var annots = [ ]”,错误是“协议'Any'作为一种类型不能符合'Identifiable'”
-
是的 - 我希望这些错误基于代码。根据描述,您尝试执行的操作似乎过于复杂。在这个用例中不需要协议,您的对象实际上只是重复数据。我认为您可以使用一个返回所需 MapAnnotation 数据的对象来完成整个任务。
-
我已经简化了代码并设法检索符合结构的数据但仍然无法显示 MapAnnotations - 更新的代码在上面
标签: swiftui realm mongodb-atlas mapkitannotation