核心数据 - 搜索具有给定标识符的单个对象
Core data - Searches for a single object that has a given identifier
我正在 SwiftUI 中创建一个应用程序,它将成为一本歌集。我想从我有歌曲内容的视图中单击一个按钮,以便 window 出现在我可以输入要切换到的歌曲编号的位置(每首歌曲都有自己的编号) .输入号码后,它应该会带我到该号码的歌曲内容所在的视图。我不太能够从数据库中提取具有给定编号的歌曲并将其显示在视图中。下面我发送我的代码。我指望你的帮助。
核心数据模型:
enter image description here
持久化控制器:
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "Model")
container.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Error \(error.localizedDescription)")
}
}
}
func save(completion: @escaping (Error?) -> () = {_ in}) {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
completion(nil)
} catch {
completion(error)
}
}
}
func delete(_ object: NSManagedObject, completion: @escaping (Error?) -> () = {_ in}) {
let context = container.viewContext
context.delete(object)
save(completion: completion)
}
func getSong(number: String) -> Song {
var song = Song()
let context = container.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Song")
request.predicate = NSCompoundPredicate(format: "number <> '\(number)'")
do {
song = try context.fetch(request) as? Song ?? Song()
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
return song
}
}
DetailView(我们有歌曲内容的视图):
struct DetailView: View {
@State var isSelected: Bool
var body: some View {
VStack{
Text(song.content ?? "No content")
.padding()
Spacer()
}
.navigationBarTitle("\(song.number). \(song.title ?? "No title")", displayMode: .inline)
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
HStack{
Button(action: {
song.favorite.toggle()
isSelected=song.favorite
}) {
Image(systemName: "heart.fill")
.foregroundColor(isSelected ? .red : .blue)
}
Button(action: {
searchView()
}) {
Image(systemName: "magnifyingglass")
}
}
}
}
}
func searchView(){
let search = UIAlertController(title: "Go to the song", message: "Enter the number of the song you want to jump to.", preferredStyle: .alert)
search.addTextField {(number) in
number.placeholder = "Song number"
}
let go = UIAlertAction(title: "Go", style: .default) { (_) in
let song = PersistenceController.shared.getSong(number: (search.textFields![0].text)!)
DetailView(song: song, isSelected: song.favorite)
}
let cancel = UIAlertAction(title: "Cancel", style: .destructive) { (_) in
print("Cancel")
}
search.addAction(cancel)
search.addAction(go)
UIApplication.shared.windows.first?.rootViewController?.present(search, animated: true, completion: {
})
}
}
getSong
方法不行,谓词错误,fetchreturn总是一个数组,强烈建议指定实体的静态类型而不是未指定NSFetchRequestResult
并且由于 song
显然是一个 NSManagedObject
子类,您不能使用默认初始化程序 Song()
创建实例。更好的 return 一个可选的
func getSong(number: String) -> Song? {
guard let songNumber = Int64(number) else { return nil }
let context = container.viewContext
let request = NSFetchRequest<Song>(entityName: "Song")
request.predicate = NSPredicate(format: "number == %ld", songNumber)
do {
return try context.fetch(request).first
} catch {
print(error)
return nil
}
}
我正在 SwiftUI 中创建一个应用程序,它将成为一本歌集。我想从我有歌曲内容的视图中单击一个按钮,以便 window 出现在我可以输入要切换到的歌曲编号的位置(每首歌曲都有自己的编号) .输入号码后,它应该会带我到该号码的歌曲内容所在的视图。我不太能够从数据库中提取具有给定编号的歌曲并将其显示在视图中。下面我发送我的代码。我指望你的帮助。
核心数据模型:
enter image description here
持久化控制器:
struct PersistenceController {
static let shared = PersistenceController()
let container: NSPersistentContainer
init() {
container = NSPersistentContainer(name: "Model")
container.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Error \(error.localizedDescription)")
}
}
}
func save(completion: @escaping (Error?) -> () = {_ in}) {
let context = container.viewContext
if context.hasChanges {
do {
try context.save()
completion(nil)
} catch {
completion(error)
}
}
}
func delete(_ object: NSManagedObject, completion: @escaping (Error?) -> () = {_ in}) {
let context = container.viewContext
context.delete(object)
save(completion: completion)
}
func getSong(number: String) -> Song {
var song = Song()
let context = container.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Song")
request.predicate = NSCompoundPredicate(format: "number <> '\(number)'")
do {
song = try context.fetch(request) as? Song ?? Song()
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
return song
}
}
DetailView(我们有歌曲内容的视图):
struct DetailView: View {
@State var isSelected: Bool
var body: some View {
VStack{
Text(song.content ?? "No content")
.padding()
Spacer()
}
.navigationBarTitle("\(song.number). \(song.title ?? "No title")", displayMode: .inline)
.toolbar {
ToolbarItemGroup(placement: .navigationBarTrailing) {
HStack{
Button(action: {
song.favorite.toggle()
isSelected=song.favorite
}) {
Image(systemName: "heart.fill")
.foregroundColor(isSelected ? .red : .blue)
}
Button(action: {
searchView()
}) {
Image(systemName: "magnifyingglass")
}
}
}
}
}
func searchView(){
let search = UIAlertController(title: "Go to the song", message: "Enter the number of the song you want to jump to.", preferredStyle: .alert)
search.addTextField {(number) in
number.placeholder = "Song number"
}
let go = UIAlertAction(title: "Go", style: .default) { (_) in
let song = PersistenceController.shared.getSong(number: (search.textFields![0].text)!)
DetailView(song: song, isSelected: song.favorite)
}
let cancel = UIAlertAction(title: "Cancel", style: .destructive) { (_) in
print("Cancel")
}
search.addAction(cancel)
search.addAction(go)
UIApplication.shared.windows.first?.rootViewController?.present(search, animated: true, completion: {
})
}
}
getSong
方法不行,谓词错误,fetchreturn总是一个数组,强烈建议指定实体的静态类型而不是未指定NSFetchRequestResult
并且由于 song
显然是一个 NSManagedObject
子类,您不能使用默认初始化程序 Song()
创建实例。更好的 return 一个可选的
func getSong(number: String) -> Song? {
guard let songNumber = Int64(number) else { return nil }
let context = container.viewContext
let request = NSFetchRequest<Song>(entityName: "Song")
request.predicate = NSPredicate(format: "number == %ld", songNumber)
do {
return try context.fetch(request).first
} catch {
print(error)
return nil
}
}