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

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

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

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

Q&A

解決済

2回答

287閲覧

swift singleton pattern

tosi_1211

総合スコア138

Swift

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

0グッド

0クリップ

投稿2017/08/08 16:38

現在アプリ作成中で、Userモデルをシングルトンパターンを使って複数の画面にユーザー情報を共有したいと思っています。
モデルの持つフィールドで非オプショナルで扱いたいフィールドなどがある場合シングルトンはどのように定義すればいいのでしょうか?

class User { static let shared = User() //Error let id: Int let email: String let accessToken: String init(json: Any) { guard let dictionary = json as? [String : Any] else { throw JSONDecodeError.invalidFormat(json: json) } guard let id = data["id"] as? Int else { throw JSONDecodeError.missingValue(key: "id") } guard let email = data["email"] as? String else { throw JSONDecodeError.missingValue(key: "email") } guard let email = data["accessToken"] as? String else { throw JSONDecodeError.missingValue(key: "accessToken") } self.id = id self.email = email self.accessToken = accessToken } }
class ViewController: UIViewController { let user = User.shared func fetchUser() { API.shared.request(_ params: ["id" : user.id]) { result in switch result { case .success: case .failure: } } } }
class ViewController2: UIViewController { let user = User.shared func fetchUser() { API.shared.request(_ params: ["accessToken" : user.accessToken]) { result in switch result { case .success: case .failure: } } } }

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

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

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

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

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

fuzzball

2017/08/09 01:48

なぜシングルトンを使っているのでしょうか?
tosi_1211

2017/08/09 02:38 編集

複数の画面でUserの値を使用したいから使用しています
guest

回答2

0

ベストアンサー

こんなんじゃダメなんかな。

swift

1class User { 2 private(set) static var id: Int = -1 3 private(set) static var email: String = "(empty)" 4 private(set) static var accessToken: String = "(empty)" 5 6 static func set(json: Any) { 7 User.id = 100 8 User.email = "email" 9 User.accessToken = "token" 10 } 11} 12 13print(User.id, User.email, User.accessToken) 14//=> -1 (empty) (empty) 15 16User.set(json: "") 17print(User.id, User.email, User.accessToken) 18//=> 100 email token

【追記】
イニシャライザ使ってるから話がややこしくなっているような気がしてきたので書き直しました。

投稿2017/08/09 02:41

編集2017/08/09 03:02
fuzzball

総合スコア16731

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

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

0

idとかemailとか具体的なメンバはどうでもいいのでおいておいて
概念的に言うと以下の感じかなと。

質問で言ってることとソースから読み取れる困ってることの本質がたぶん違ってて

staticで保持したいsharedに対して shared = User()としてしまうと
引数を取らないコンストラクタが存在しないのでエラーになってしまう、だけど初期化するには外からjsonを渡したい、ってことかなと勝手に予想。

staticのinitialize()メソッドにjsonを渡す。
initializeメソッドは初期化が完了したら初期化完了フラグを立てて
二回目以降はブロックする。
つまり1回だけ処理することを保障する。
コンストラクタはprivateにしておいて外から実行できないようにする。

sharedはUser!で宣言しておいて初期化しないでアクセスするとエラーで落ちる。

swift

1class User { 2 private static var initialized = false; 3 static func initialize(json:Any) { 4 //初期化が完了していたらreturn; 5 if User.initialized { return; } 6 7 shared = User(json) 8 initialized = true; 9 } 10 static let shared: User! 11 12 private init(json: Any) { 13 //property初期化 14 } 15}

投稿2017/08/08 17:27

編集2017/08/08 17:29
Tak1016

総合スコア1408

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問