存储 1000 个 MapKit 注释的最佳方式 + 在 tableView 中显示注释
Best way to store 1000's of MapKit annotations + show annotations in tableView
问题:存储 1000 条 MapKit
注释的最佳方法是什么,这些注释将显示在地图上并且也应该可以在 tableView
中浏览?用户还应该能够将选定的注释标记为收藏,并将它们显示在单独的 tableView
.
中
背景:我正在学习 iOS 编程(通过 Udemy、Google 和 Stack Overflow)。我目前正在尝试制作一个基于 MapKit
的应用程序,它可以在地图上显示大量注释。每个注释代表一种特定类型的位置。出于测试目的,我制作了一个虚拟 GeoJSON 文件(位于应用程序中,而不是服务器上),它存储每个位置,如下所示:
{
"type" : "Feature",
"properties" : {
"location" : "Norway",
"title" : "Annotation Title",
"website" : "http://www.whosebug.com",
},
"geometry" : {
"type" : "Point",
"coordinates" : [10, 60]
}
},
这很好用;我的虚拟 objects 被解析并放在地图上就好了。但最终,我将拥有 1000 多个真实注释,而不仅仅是我的一些虚拟注释。
Map View
这是我的技能不足之处:我希望用户能够将特定位置标记为收藏夹,这当然应该通过应用程序更新、iOS 更新以及理想情况下在用户的多个设备之间持续存在.
Favorites view
用户还应该能够浏览所有注释,按国家和州排序。
Browse view
解决这个问题的好方法是什么?我试图将其分解为:
找到一种存储注释的好方法——鉴于第 2 点和(特别是)第 3 点,GeoJSON 可能并不理想?我应该查看数据库设置吗?
用数据库中的所有注释填充 tableView
,第一个 tableView
显示所有国家,然后点击一行进入另一个 tableView
该国家/地区的所有州,另一个进入第三个 tableView
,每个注释都在该州。
让用户将选定的注释标记为收藏,并仅使用标记为收藏的注释填充新的 tableView
。
在我回答这个问题之前,我想指出在地图上显示 1000 多个 MKAnnotationView
本身也是一个完整的问题,您可能想研究使用 dequeueReusableAnnotationViewWithIdentifier:
方法或MKClusterAnnotation
这些注释可以避免屏幕延迟。
现在回答您实际提出的问题,而不是考虑如何为您的应用中的一项功能存储数据。多想想应该如何为整个应用程序本身存储数据。
https://www.iosapptemplates.com/blog/ios-development/data-persistence-ios-swift - 此 link 讨论了持久数据存储的各种选项及其 advantages/disadvantages。正如您所说,您目前正在学习 iOS 课程 我建议使用 CoreData,因为它是一个原生的 IOS 特定框架,可以很好地补充您的学习和可能会被 Udemy 覆盖。另一个原因是 CoreData 很容易设置和学习 Apple 提供的大量文档,因此对于“新手”来说应该是一个好的开始。
核心数据示例
创建你的模型
创建 CoreData 管理器
class CoreDataManager {
static let shared = CoreDataManager()
private init() {}
private lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "PillReminder")
container.loadPersistentStores(completionHandler: { _, error in
_ = error.map { fatalError("Unresolved error \([=10=])") }
})
return container
}()
var mainContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
func backgroundContext() -> NSManagedObjectContext {
return persistentContainer.newBackgroundContext()
}
正在加载一组药丸
func loadPills() -> [Pill] {
let mainContext = CoreDataManager.shared.mainContext
let fetchRequest: NSFetchRequest<Pill> = Pill.fetchRequest()
do {
let results = try mainContext.fetch(fetchRequest)
return results
}
catch {
debugPrint(error)
}
保存一个新的 Pill 实体
func savePill(name: String) throws {
let context = CoreDataManager.shared.backgroundContext()
context.perform {
let entity = Pill.entity()
let pill = Pill(entity: entity, insertInto: context)
pill.name = name
pill.amount = 2
pill.dozePerDay = 1
pill.lastUpdate = Date()
try context.save()
}
}
问题:存储 1000 条 MapKit
注释的最佳方法是什么,这些注释将显示在地图上并且也应该可以在 tableView
中浏览?用户还应该能够将选定的注释标记为收藏,并将它们显示在单独的 tableView
.
背景:我正在学习 iOS 编程(通过 Udemy、Google 和 Stack Overflow)。我目前正在尝试制作一个基于 MapKit
的应用程序,它可以在地图上显示大量注释。每个注释代表一种特定类型的位置。出于测试目的,我制作了一个虚拟 GeoJSON 文件(位于应用程序中,而不是服务器上),它存储每个位置,如下所示:
{
"type" : "Feature",
"properties" : {
"location" : "Norway",
"title" : "Annotation Title",
"website" : "http://www.whosebug.com",
},
"geometry" : {
"type" : "Point",
"coordinates" : [10, 60]
}
},
这很好用;我的虚拟 objects 被解析并放在地图上就好了。但最终,我将拥有 1000 多个真实注释,而不仅仅是我的一些虚拟注释。
Map View
这是我的技能不足之处:我希望用户能够将特定位置标记为收藏夹,这当然应该通过应用程序更新、iOS 更新以及理想情况下在用户的多个设备之间持续存在.
Favorites view
用户还应该能够浏览所有注释,按国家和州排序。
Browse view
解决这个问题的好方法是什么?我试图将其分解为:
找到一种存储注释的好方法——鉴于第 2 点和(特别是)第 3 点,GeoJSON 可能并不理想?我应该查看数据库设置吗?
用数据库中的所有注释填充
tableView
,第一个tableView
显示所有国家,然后点击一行进入另一个tableView
该国家/地区的所有州,另一个进入第三个tableView
,每个注释都在该州。让用户将选定的注释标记为收藏,并仅使用标记为收藏的注释填充新的
tableView
。
在我回答这个问题之前,我想指出在地图上显示 1000 多个 MKAnnotationView
本身也是一个完整的问题,您可能想研究使用 dequeueReusableAnnotationViewWithIdentifier:
方法或MKClusterAnnotation
这些注释可以避免屏幕延迟。
现在回答您实际提出的问题,而不是考虑如何为您的应用中的一项功能存储数据。多想想应该如何为整个应用程序本身存储数据。
https://www.iosapptemplates.com/blog/ios-development/data-persistence-ios-swift - 此 link 讨论了持久数据存储的各种选项及其 advantages/disadvantages。正如您所说,您目前正在学习 iOS 课程 我建议使用 CoreData,因为它是一个原生的 IOS 特定框架,可以很好地补充您的学习和可能会被 Udemy 覆盖。另一个原因是 CoreData 很容易设置和学习 Apple 提供的大量文档,因此对于“新手”来说应该是一个好的开始。
核心数据示例
创建你的模型
创建 CoreData 管理器
class CoreDataManager {
static let shared = CoreDataManager()
private init() {}
private lazy var persistentContainer: NSPersistentContainer = {
let container = NSPersistentContainer(name: "PillReminder")
container.loadPersistentStores(completionHandler: { _, error in
_ = error.map { fatalError("Unresolved error \([=10=])") }
})
return container
}()
var mainContext: NSManagedObjectContext {
return persistentContainer.viewContext
}
func backgroundContext() -> NSManagedObjectContext {
return persistentContainer.newBackgroundContext()
}
正在加载一组药丸
func loadPills() -> [Pill] {
let mainContext = CoreDataManager.shared.mainContext
let fetchRequest: NSFetchRequest<Pill> = Pill.fetchRequest()
do {
let results = try mainContext.fetch(fetchRequest)
return results
}
catch {
debugPrint(error)
}
保存一个新的 Pill 实体
func savePill(name: String) throws {
let context = CoreDataManager.shared.backgroundContext()
context.perform {
let entity = Pill.entity()
let pill = Pill(entity: entity, insertInto: context)
pill.name = name
pill.amount = 2
pill.dozePerDay = 1
pill.lastUpdate = Date()
try context.save()
}
}