iT邦幫忙

2024 iThome 鐵人賽

DAY 21
0
Mobile Development

自己的 app 自己寫系列 第 21

[Day21] 一片漆黑的筆電螢幕應該換掉嗎

  • 分享至 

  • xImage
  •  

悲報:用了兩年多的筆電螢幕陣亡了。
外接螢幕倒是沒什麼問題,但是螢幕本體感覺完全掛了。是該花錢修好還是要轉型桌電QQ。


core data 是 iOS 用來儲存的框架,當中有 entity,attributes 和 relationships。我自己認為這比較適合用 object 的概念來理解,會有很多個 entity,每個 entity 可能有多種 attributes,而 entity 之間的關係則用 relation 來描述。

  • NSManagedObjectModel 用來定義 entity, attributes, relationship
    • NSManagedObject 定義了一個 entity
  • NSManagedObjectContext 是在 memory 中的暫存區,操作完成後要 save 才會同步到 persistent storage 中

下面是 by Claude 老師的範例,CoreDataStack 通常包含幾個部分:

  • NSPersistentContainer 用來管理 data model 和 persistent storage
  • NSManagedObjectContext 用來處理 CRUD
  • NSPersistentStoreCoordinator 用來處理 NSManagedObjectModel 和 NSPersistentStore 之間的交互
import CoreData
import Foundation

// MARK: - Core Data stack
class CoreDataStack {
    static let shared = CoreDataStack()
    
    lazy var persistentContainer: NSPersistentContainer = {
        let container = NSPersistentContainer(name: "BookModel")
        container.loadPersistentStores { (storeDescription, error) in
            if let error = error as NSError? {
                fatalError("Unresolved error \(error), \(error.userInfo)")
            }
        }
        return container
    }()
    
    var context: NSManagedObjectContext {
        return persistentContainer.viewContext
    }
}

在下面的 CoreDataStack 中,NSPersistentContainer 不一定會直接寫到 NSPersistentStoreCoordinator 和 NSManagedObjectModel 這兩個東西,但這塊會被自動處理,也可以透過 .persistentStoreCoordinator 和 .managedObjectModel 去曝露出來,就像以下內容:

import CoreData
import Foundation

// MARK: - Core Data stack
class CoreDataStack {

    // ...
 
    var persistentStoreCoordinator: NSPersistentStoreCoordinator {
        return persistentContainer.persistentStoreCoordinator
    }
    
    
    var managedObjectModel: NSManagedObjectModel {
        return persistentContainer.managedObjectModel
    }
}

而 NSManagedObjectContext 包含 viewContext 和 backgroundContext,差別是 viewContext 會用在 main thread 上,background context 則用在 bg thread 上,可以考量到需要操作時改動到的資料量大小而決定要在哪邊執行。

實際的操作例子如下(created by Claude):

// MARK: - Book Entity
class Book: NSManagedObject {
    @NSManaged var title: String
    @NSManaged var author: String
    @NSManaged var year: Int16
}

// MARK: - CRUD Operations
class BookStore {
    let context: NSManagedObjectContext
    
    init() {
        self.context = CoreDataStack.shared.context
    }
    
    // Create
    func createBook(title: String, author: String, year: Int16) {
        let book = Book(context: context)
        book.title = title
        book.author = author
        book.year = year
        
        do {
            try context.save()
        } catch {
            print("Failed to save book: \(error)")
        }
    }
    
    // Read
    func fetchAllBooks() -> [Book] {
        let fetchRequest: NSFetchRequest<Book> = Book.fetchRequest()
        
        do {
            let books = try context.fetch(fetchRequest)
            return books
        } catch {
            print("Failed to fetch books: \(error)")
            return []
        }
    }
    
    // Update
    func updateBook(book: Book, newTitle: String?, newAuthor: String?, newYear: Int16?) {
        if let title = newTitle {
            book.title = title
        }
        if let author = newAuthor {
            book.author = author
        }
        if let year = newYear {
            book.year = year
        }
        
        do {
            try context.save()
        } catch {
            print("Failed to update book: \(error)")
        }
    }
    
    // Delete
    func deleteBook(book: Book) {
        context.delete(book)
        
        do {
            try context.save()
        } catch {
            print("Failed to delete book: \(error)")
        }
    }
}

// Usage example
let bookStore = BookStore()

// Create books
bookStore.createBook(title: "1984", author: "George Orwell", year: 1949)
bookStore.createBook(title: "To Kill a Mockingbird", author: "Harper Lee", year: 1960)

// Fetch and print all books
let allBooks = bookStore.fetchAllBooks()

// Update a book
if let bookToUpdate = allBooks.first {
    bookStore.updateBook(book: bookToUpdate, newTitle: nil, newAuthor: nil, newYear: 1950)
    print("Updated book: \(bookToUpdate.title), Year: \(bookToUpdate.year)")
}

// Delete a book
if let bookToDelete = allBooks.last {
    bookStore.deleteBook(book: bookToDelete)
}

// Fetch and print all books again to see the changes
let updatedBooks = bookStore.fetchAllBooks()
for book in updatedBooks {
    print("Title: \(book.title), Author: \(book.author), Year: \(book.year)")
}

上一篇
[Day20] 炸雞拿錯了老闆對不起
下一篇
[Day22] 韓國人是不是特別會拍綜藝
系列文
自己的 app 自己寫30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言