watari開発 – Advent201923 –
目次
stage23: 画像を投稿できるようにする
お次は撮影した画像をlocalに投稿できるようにしよう。
ローカルの画像を表示する
まずは、今リストに表示しているところに選択した画像が出るようにしよう。
先日修正したところを一箇所戻す。
func makeUIViewController(context: Context) -> UIImagePickerController {
let imagePickerController = UIImagePickerController()
imagePickerController.sourceType = .photoLibrary
// imagePickerController.sourceType = .camera
imagePickerController.delegate = context.coordinator
return imagePickerController
}
こうする。
で、さらに選択後に保存ボタンを押すとCoreDataに保存できるように変更していく
Entitesの追加
EntryImage
の追加。bodyはbinaryを保存できるようにしておく。(これ多分設計ミスってる気がする。後で直そう。多分 Entryにして全部一つで管理した方が楽)
ImageViewの改修
import CoreData
...
@Environment(\.managedObjectContext) var managedObjectContext
@Environment(\.presentationMode) var presentationMode: Binding<PresentationMode>
...
Spacer()
Button("save image", action: {
if let image = self.image {
let entryImage = EntryImage(context: self.managedObjectContext)
entryImage.body = image.pngData()
entryImage.createdAt = Date()
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
self.image = nil
self.presentationMode.wrappedValue.dismiss()
}
})
これで画像を保存することができるようになる。
ContentViewの改修
Listの表示内容を変更する。
// ContentView
...
+ @FetchRequest(fetchRequest: getEntryImages()) var entryImages: FetchedResults<EntryImage>
...
// Listの中に
ForEach(self.entryImages, id: \.self) {entryImage in
VStack {
createImage(entryImage)
Text("\(entryImage.createdAt!)")
}
}.onDelete {indexSet in
let deleteEntry = self.entryImages[indexSet.first!]
self.managedObjectContext.delete(deleteEntry)
do {
try self.managedObjectContext.save()
} catch {
print(error)
}
}
...
// 最後の方に
func getEntryImages() -> NSFetchRequest<EntryImage> {
let request: NSFetchRequest<EntryImage> = EntryImage.fetchRequest()
let sortDescriptor = NSSortDescriptor(key: "createdAt", ascending: true)
request.sortDescriptors = [sortDescriptor]
return request
}
func createImage(_ entryImage: NSManagedObject) -> some View {
if let data = entryImage.value(forKey: "body") as? Data {
return AnyView(Image(uiImage: UIImage(data: data)!)
.resizable()
.aspectRatio(contentMode: .fill)
.frame(width: 100, height: 100, alignment: .top)
.clipped()
)
} else {
return AnyView(EmptyView().frame(alignment: .top))
}
}
これで保存した内容を表示するようになる。
結果
次回は
おそらくアドベントカレンダーの実装系は最後になりそう。
twitterへ画像を投稿してみよう!
- 前の記事
watari開発 – Advent201922 – 2019.12.22
- 次の記事
watari開発 – Advent201924 – 2019.12.24