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

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

ただいまの
回答率

90.47%

  • Swift

    8943questions

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

  • Xcode

    5042questions

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

ユーザー認証について

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 219

sam3457

score 44

プロフィール画面を作っています。
イメージ説明

ユーザー認証画面でゲスト閲覧か認証(新規登録orログイン)をするかで、userdefaultに"login"もしくは"guest"の文字列をcheckとして保存し、それを読み込むことでプロフィール画面にcheckの値が"login"ならばuserdefaultにすでに保存しておいたプロフィール情報をimageviewやtextfieldにセットする。(+それらへの入力操作を許可する)
またはcheckの値が"guest"ならば入力操作を許可せず、名前に”ゲスト閲覧”と表示、imageviewには初期画像を表示する機能を作っております。

⑴ 現在、前述した処理をviewWillApearに書いております。しかしここに書くとアイコン画像を変更するために画像をタップし、画像を選択し終わるとまたviewWillApearの中の処理が呼ばれてせっかく変えたアイコン画像が、元からuserdefaultに保存されていた画像に変わってしまいます。

⑵ この挙動を直すためにviewWillApearの中の処理をviewDidLoadに丸々移し替えたところ、上記の問題点は解決されたものの、ビューがロードされた一度しか呼ばれないためか、下記の画面外の認証画面で他アカウントに変えてログインしたり、新規登録し直した後にまたプロフィール画面に戻ってくると前回のアカウント情報が表示されたままになってしまいます。

⑴、⑵の問題点を同時に両方解決する方法はないでしょうか?

以下が現在のコードです

import UIKit
import Firebase
import KRProgressHUD

class EditProfile: UIViewController, UITextFieldDelegate, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    @IBOutlet var iconImageView: UIImageView!
    @IBOutlet var nameTextField: UITextField!
    @IBOutlet var tapImage: UITapGestureRecognizer!
    @IBOutlet var changeProfButton: UIButton!

    var ref: DatabaseReference!
    let userDefault = UserDefaults.standard


    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(true)

        let check = userDefault.object(forKey: "check") as! String

        //ゲスト閲覧ならばプロフ変更を許可しない
        if check == "guest" {
            nameTextField.text = "ゲスト閲覧"
            nameTextField.isEnabled = false
            iconImageView.image = UIImage(named: "user.png")
            tapImage.isEnabled = false
            changeProfButton.isHidden = true

        //正規ユーザーの場合の名前と画像をセット
        } else if check == "login" {
            nameTextField.isEnabled = true
            tapImage.isEnabled = true
            changeProfButton.isHidden = false

            let username = userDefault.object(forKey: "username")
            nameTextField.text = username as? String

            if let encodedData = userDefault.object(forKey: "usericon") {
                let decodedData = Data(base64Encoded: encodedData as! String, options: Data.Base64DecodingOptions.ignoreUnknownCharacters)
                let decodedImage = UIImage(data: decodedData! as Data)
                iconImageView.image = decodedImage
            }

        }


    }

    override func viewDidLoad() {
        super.viewDidLoad()

        nameTextField.delegate = self

    }

    @IBAction func changeIcon(_ sender: UITapGestureRecognizer) {
        //画像をセット
        if UIImagePickerController.isSourceTypeAvailable(.photoLibrary) {

            let pickerView = UIImagePickerController()
            pickerView.sourceType = .photoLibrary
            pickerView.delegate = self
            self.present(pickerView, animated: true)

        }
    }

    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {

        let image = info[UIImagePickerControllerOriginalImage] as! UIImage
        iconImageView.image = image
        dismiss(animated: true)


    }

    //userdefaultとサーバに送る
    @IBAction func changeProfile(_ sender: Any) {



        //userdefaultに保存

        //名前
        let username = nameTextField.text
        userDefault.set(username, forKey: "username")

        //アイコン画像
        var data: Data = Data()
        if let image = iconImageView.image {
            data = UIImageJPEGRepresentation(image, 0.1)! as Data
        }
        let encodedIcon = data.base64EncodedString(options: Data.Base64EncodingOptions.lineLength64Characters) as String
        userDefault.set(encodedIcon, forKey: "usericon")


        //サーバに保存
        let uid = Auth.auth().currentUser?.uid

        //名前はRDBに保存
        let RDBref = Database.database().reference()
        let prof: Dictionary = ["username": username]
        RDBref.child("profs").child(uid!).setValue(prof)

        //アイコンは(初期画像でなければ)Storageに保存
        if iconImageView.image != UIImage(named: "user.png") {
            let storageRef = Storage.storage().reference()
            storageRef.child("usericons").child(uid!).putData(data, metadata: nil)
        }
        KRProgressHUD.showSuccess(withMessage: "変更しました")

    }

    //空文字はボタンを隠す
    func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool {

        if textField.text == "" {
            changeProfButton.isHidden = true
        } else {
            changeProfButton.isHidden = false
        }
        return true
    }

    func textFieldShouldReturn(_ textField: UITextField) -> Bool {
        textField.resignFirstResponder()
        return true
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        nameTextField.resignFirstResponder()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


    /*
    // MARK: - Navigation

    // In a storyboard-based application, you will often want to do a little preparation before navigation
    override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
        // Get the new view controller using segue.destinationViewController.
        // Pass the selected object to the new view controller.
    }
    */

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

下記の方法だといかがでしょうか?

⑴ 写真を変更したかを判定するフラグを変数として保持し、新しくプロフィール画像が選択された場合は、userdefaultからデータを表示しない。(didFinishPickingMediaWithInfoで判定をtrueにする)

例えば、
EditProfileで

var isChanged: Bool = false

を宣言しておき、

func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
    isChanged = true
    dismiss(animated: true)        
}


とすれば、viewWillAppearの処理時に判定ができませんでしょうか?

(2)ログインし直した場合や新規登録された場合はuserdefaultの情報をクリアして設定し直す

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/03/31 14:39

    回答ありがとうございます!いつもお世話になっております。
    ⑴のviewWillApearに処理を書き、その上でnewmt様にお教えいただいた方法で修正していく方法でいこうと思い、didFinishPickingMediaWithInfoの記述の仕方を調べたり、QuickHelpを見ながら修正しようとしたのですがどう記述すれば良いかわかりませんでした、、
    didFinishPickingMediaWithInfoで判定をtrueにするにはどの様な記述をすれば良いのでしょうか?
    連続の質問となって申し訳ありませんが、よろしくお願いいたします

    キャンセル

  • 2018/03/31 14:52

    追記しました。このような方法だといかがでしょうか?

    キャンセル

  • 2018/03/31 18:08

    ありがとうございます!
    imagepickerのメソッドにBoolの値を変える処理を追加するってことなんですね!
    その後にviewWillAppearの処理をif isChanged == false { }で包んで解決しました。
    ありがとうございますm(_ _)m

    キャンセル

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

  • ただいまの回答率 90.47%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Swift

    8943questions

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

  • Xcode

    5042questions

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