13, 14

  • 13: Publisher, CloudKit, CoreData
  • 14: App Architecture, Document Architecture, Undo

Publisher

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

// fetch the url backgroundImageFetchStatus = .fetching DispatchQueue.global(qos: .userInitiated).async { let imageData = try? Data(contentsOf: url) DispatchQueue.main.async { [weak self] in if self?.emojiArt.background == EmojiArtModel.Background.url(url) { self?.backgroundImageFetchStatus = .idle if imageData != nil { self?.backgroundImage = UIImage(data: imageData!) } } } }
// fetch the url backgroundImageFetchStatus = .fetching let session = URLSession.shared let publisher = session.dataTaskPublisher(for: url) .map { (data, urlResponse) in UIImage(data: data) } .replaceError(with: nil) .receive(on: DispatchQueue.main) backgroundImageFetchCancellable = publisher .sink { [weak self] image in self?.backgroundImage = image self?.backgroundImageFetchStatus = image != nil ? .idle : .failed(url) }
  1. 取得 Publisher (subscription)
  2. Publisher 設定
    • .map(_:) 改變產物
    • .receive(on: DispatchQueue.main)
  3. Publisher 資料接收
    • .sink(receiveValue:) 處理產出的資料
  4. Cancellable 保存與使用

Publisher 有很多 method 很像 array 的 method,.map(_:)

  • URLSession
  • Timer
  • NotificationCenter

CoreData

  • @ObservedObject
  • @FetchRequest

App Architecture

  • App protocol
  • Scene protocol
    • WindowGroup { }
    • DocumentGroup(newDocument:) { }
    • DocumentGroup(viewing:) { }
  • @SenceStorage
  • @AppStorage
  • @ScaledMetric

Image Not Showing Possible Reasons
  • The image file may be corrupted
  • The server hosting the image is unavailable
  • The image path is incorrect
  • The image format is not supported
Learn More →

@SceneStorage("EmojiArtDocument.steadyStatePanOffset") var steadyStatePanOffset: CGSize = .zero @SceneStorage("EmojiArtDocumentView.steadyStateZoomScale") var steadyStateZoomScale: CGFloat = 1 @AppStorage("username") var username: String = "Anonymous"
  • 被存在 UserDefaults.standard
    • 所以不推薦存大量資料
    • 所以不要存機敏性資料

7:48 Code

app icon -> Asset.xcassets

19:56 RawRepresentable

每次開啟 app 後 load backgroundImage 完成又去 zoomToFit

28:02 Document Architecture

  • FileDocument
  • ReferenceFileDocument
  • UTType
  • Document Types
  • 39:05 Undo
func undoablyPerform(operation: String, with undoManager: UndoManager?) { let oldModel = model doIt() undoManager?.registerUndo(withTarget: self) { mySelf in mySelf.model = oldModel } undoManager?.setActionName(operation) }

43:14 Back To Code

  • 49:50 讓 ViewModel conform to ReferenceFileDocument
  • 1:02:16 undo imple
  • 1:12:01 support document

https://github.com/skkimeo/CS193p-Spring-2021