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

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

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

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

iOS

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Swift

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

Q&A

解決済

1回答

199閲覧

Publishing changes from background threads is not allowed; ...略 の解決方法

Kimura

総合スコア9

Firebase

Firebaseは、Googleが提供するBasSサービスの一つ。リアルタイム通知可能、並びにアクセス制御ができるオブジェクトデータベース機能を備えます。さらに認証機能、アプリケーションのログ解析機能などの利用も可能です。

iOS

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

MacOS(OSX)

MacOSとは、Appleの開発していたGUI(グラフィカルユーザーインターフェース)を採用したオペレーションシステム(OS)です。Macintoshと共に、市場に出てGUIの普及に大きく貢献しました。

Swift

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

0グッド

0クリップ

投稿2024/03/07 07:27

実現したいこと

国別で電話番号を選択する機能

発生している問題・分からないこと

開発したアプリにバックエンド開発をFirebaseでしていた時に国別で電話番号を選択機能を実装するときに起こりました。

エラー内容: Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.

エラーメッセージ

error

1Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.

該当のソースコード

Swift

1import SwiftUI 2import Firebase 3 4class AuthenticationViewModel: ObservableObject { 5 6 @Published var name = "" 7 @Published var year = Year(day: "",month: "",year: "") 8 @Published var country: Country = Country(isoCode: "US") 9 @Published var phoneNumber = "" 10 11 @Published var otpTet = "" 12 13 @Published var navigationTag: String? 14 15 @Published var isLoading: Bool = false 16 @Published var verificationCode: String = "" 17 18 @Published var errorMessage = "" 19 @Published var showAlert = false 20 21 func sendOtp()async { 22 if isLoading {return} 23 24 do { 25 isLoading = true 26 let result = try await PhoneAuthProvider.provider().verifyPhoneNumber("+\(country.phoneCode)\(phoneNumber)", uiDelegate: nil) 27 DispatchQueue.main.async { 28 self.isLoading = false 29 self.verificationCode = result 30 self.navigationTag = "VERIFICATION" 31 } 32 } 33 catch { 34 handleError(error: error.localizedDescription) 35 } 36 } 37 38 39 func handleError(error: String) { 40 DispatchQueue.main.async { 41 self.isLoading = false 42 self.errorMessage = error 43 self.showAlert.toggle() 44 } 45 } 46 47} 48

試したこと・調べたこと

  • teratailやGoogle等で検索した
  • ソースコードを自分なりに変更した
  • 知人に聞いた
  • その他
上記の詳細・結果

Google検索等で出てきたDispatchQueue.main.asyncで囲めも試しましたがうまくいきませんでした。
どなたかご教授お願いします。

補足

Swift Xcode Mac

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

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

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

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

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

guest

回答1

0

ベストアンサー

Google検索等で出てきたDispatchQueue.main.asyncで囲めも試しましたがうまくいきませんでした。

あともう少しだったかなと思いました。
該当のソースコードの25行目の isLoading = true も必要そうですね。

下のようなコードで再現確認してみました。
// *** のようなコメントが修正ポイントです。

swift

1import SwiftUI 2 3struct ContentView: View { 4 @ObservedObject private var obj: AuthenticationViewModel = AuthenticationViewModel() 5 var body: some View { 6 VStack { 7 Image(systemName: "globe") 8 .imageScale(.large) 9 .foregroundStyle(.tint) 10 Text("Hello, world!") 11 Button("tap", action: action) 12 } 13 .padding() 14 } 15 func action() { 16 Task { 17 await obj.sendOtp() 18 } 19 } 20} 21 22#Preview { 23 ContentView() 24} 25 26class AuthenticationViewModel: ObservableObject { 27 @Published var isLoading: Bool = false 28 @Published var verificationCode: String = "" 29 @Published var navigationTag: String = "" 30 func sendOtp() async { 31 if isLoading { return } 32 do { 33 DispatchQueue.main.async { // *** 追加 34 self.isLoading = true 35 } // *** 追加 36 let result = try await verifyPhoneNumber("test1", uiDelegate: nil) 37 DispatchQueue.main.async { 38 self.isLoading = false 39 self.verificationCode = result 40 self.navigationTag = "VERIFICATION" 41 } 42 } catch { 43 handleError(error: error.localizedDescription) 44 } 45 } 46 func handleError(error: String) { 47 print(error) 48 } 49 func verifyPhoneNumber(_ value: String, uiDelegate: (() -> Void)?) async throws -> String { 50 print(value) 51 return value 52 } 53}

*mainの非同期が分割されて動きそうですので、実際の動きのタイミングとして大丈夫そうかどうか、確認してみてください。

投稿2024/03/07 09:20

退会済みユーザー

退会済みユーザー

総合スコア0

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

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

Kimura

2024/03/07 10:02

回答ありがとうございます。 試したところ問題が解決しました! Firebaseでバックエンド開発をするのにあまり慣れていなかった為とても参考になりました。 ベストアンサーに選ばせていただきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.46%

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

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

質問する

関連した質問