質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

Q&A

0回答

1273閲覧

SwiftUIで画像を取得して変更があるたびに再線画

rikupi_70

総合スコア10

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

0グッド

0クリップ

投稿2020/10/20 04:33

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
swiftUIとDjangoで画像保存&画像取得を実装しています。(アプリのプロフィール画面)
アプリを起動した時にはしっかり保存した画像を取れているのですが、保存する画像を変更したあとその画面を閉じたらプロフィール画面もすぐ変わるような実装にしたいのですが、なかなかうまく行きません。

発生している問題・エラーメッセージ

エラーメッセージ

該当のソースコード

swiftUI

1import SwiftUI 2 3@main 4struct ImageReceptionApp: App { 5 var body: some Scene { 6 WindowGroup { 7 ContentView(container: ImageContainer(from:URL(string: 画像取得のURL)!)) 8 } 9 } 10}
import SwiftUI struct ContentView: View { @State var listTitle = ["プロフィール画像変更"] var setting:Bool = true var user_name:String = "third" let user_id:Int = 3 let user_image:String = "" let user_detail:String = "AAAAA" @ObservedObject var container:ImageContainer var body: some View { NavigationView{ VStack{ VStack{ HStack{ //画像を取得して表示 Image(uiImage: container.image) .resizable() .frame(width: 50, height: 50) Spacer() } .onAppear(){ self.container=ImageContainer(from: URL(string: "http://172.20.10.2:8000/app/fetch_image/third")!)//ここで画像をリロードしてviewを再線画したい } }.frame(maxWidth:.infinity, maxHeight: 300) Color.gray.frame(height:20) if setting{ List { Text("ユーザー情報").font(.system(size: 30)) ForEach(listTitle, id: .self) { title in NavigationLink(destination:DetailView(titleName: title)){ Text(title) } } } } Spacer() } } } }
import SwiftUI struct DetailView: View{ var titleName:String var accoutName:String = "third"//ダミー @State private var name = "" @State private var message = "" @State private var editting = false @State var showingDetail = false @State var image: UIImage? @State var showImagePicker: Bool = false func PutImage(image: Data,accountName:String){ let accountName = accoutName let fileName = "(accountName).JPG" let boundary = generateBoundaryString() let body = httpBody(image, fileName: fileName,boundary: boundary) let url = URL(string: 画像保存のurl)! var request = URLRequest(url: url) request.setValue("multipart/form-data; boundary=(boundary)", forHTTPHeaderField: "Content-Type") request.httpMethod = "POST" let task = URLSession.shared.uploadTask(with: request, from: body) {(data, response, error) in guard let data = data else { return } do { let object = try JSONSerialization.jsonObject(with: data, options: []) print(object) } catch let error{ print(error) print("通過") } } task.resume() } func httpBody(_ fileAsData: Data, fileName: String ,boundary: String) -> Data { var data = "--(boundary)\r\n".data(using: .utf8)! // サーバ側が想定しているinput(type=file)タグのname属性値とファイル名をContent-Dispositionヘッダで設定 data += "Content-Disposition: form-data; name=\"file\"; filename=\"(fileName)\"\r\n".data(using: .utf8)! data += "Content-Type: image/JPG\r\n".data(using: .utf8)! data += "\r\n".data(using: .utf8)! data += fileAsData data += "\r\n".data(using: .utf8)! data += "--(boundary)--\r\n".data(using: .utf8)! return data } func generateBoundaryString() -> String { return "Boundary-(NSUUID().uuidString)" } var body: some View{ VStack{ VStack(alignment: .center, spacing: 16) { if image == nil { Rectangle() .frame(width: 300, height: 300, alignment: .top) } else { Image(uiImage: image!) .resizable() .aspectRatio(contentMode: .fill) .frame(width: 300, height: 300, alignment: .top) .clipped() } Button(action: { self.showImagePicker = true }) { Text("Image Select") } }.sheet(isPresented: $showImagePicker) { ImagePickerView(image: self.$image).onDisappear(){ //ここでUIImageをdjangoに送信して保存 PutImage(image:self.image!.jpegData(compressionQuality: 0.5)!,accountName: self.accoutName) } } } } }

import

1import Combine 2final class ImageContainer: ObservableObject { 3 4 // @PublishedをつけるとSwiftUIのViewへデータが更新されたことを通知してくれる 5 @Published var image = UIImage(systemName: "photo")! 6 init(from resource:URL) { 7 // ネットワークから画像データ取得 8 let session = URLSession(configuration: .default) 9 let task = session.dataTask(with: resource, completionHandler: { [weak self] data, _, _ in 10 guard let imageData = data, 11 let networkImage = UIImage(data: imageData) else { 12 return 13 } 14 15 DispatchQueue.main.async { 16 // 宣言時に@Publishedを付けているので、プロパティを更新すればView側に更新が通知される 17 self?.image = networkImage 18 print("okdes") 19 print(self?.image) 20 21 } 22 session.invalidateAndCancel() 23 }) 24 task.resume() 25 } 26 27}

import

1 2class ImageDownloader : ObservableObject { 3 @Published var downloadData: Data? = nil 4 5 func downloadImage(url: String) { 6 print("download!!") 7 guard let imageURL = URL(string: url) else { return } 8 9 DispatchQueue.global().async { 10 let data = try? Data(contentsOf: imageURL) 11 DispatchQueue.main.async { 12 self.downloadData = data 13 } 14 } 15 } 16}

試したこと

イメージ説明
イメージ説明

onAppearで画像をもう一度django側に取りに行こうとしたのですが、onAppear内でself.containerがobservedObjectなのでエラーが出ます。
何かいい方法がありますでしょうか?

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問