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

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

ただいまの
回答率

89.64%

NSDataに変換したUIImageをArrayにてUserDefaultに保存した後の読み込みが方法が分からない

解決済

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 1,585

Susanoo2442

score 147

実現したいこと

アプリを開発しておりまして
プロフィール設定画面で情報を入力して
保存ボタンを押すとその情報が保存されて
さらにその後遷移ボタンを押して
遷移するたびに
遷移先のページで先ほど入力した情報が載った
TableCellがひとつずつ増えていくといった感じの処理をしています。

そこで、テキストラベルだけでしたら
遷移するたびに、 TabelCellが増えていくのですが
これに写真も組み合わせて
遷移元で入力したテキスト内容と
選択した写真を保存して遷移ボタンを押して遷移するたびに

遷移先で先ほど入力した情報が載ったTableViewCellをひとつずつ増やしていくといったことがしたいです。

問題点

先ほども申しましたがテキストラベルに入力した内容は遷移するごとに
遷移先のTableCellにそのテキストを乗っけてひとつずつ増やしていくことはできております。

しかし、同じようなことを写真付きでやると
アプリがエラー落ちしてしまいます。

しかしながら原因は突き止めて
おります。

まず、最初に値は全てUserDefautsにて出し入れしております。

そして、値を引き渡すための変数はReciveDataで管理しています。
このうち二つのテキストラベルにはそれぞれReciveData1とReciveData2で管理しています。
UIImageに関しましては、ReciveData3で管理しております。

そして、エラーログで確認したのですが
二つのテキストラベルに関しては

ReciveData1とReciveData2それぞれ
どちらもValueが2でした。
しかしながらUIimageのReciveData3だけ、Valueが1のままでした。

つまりValueが全て噛み合ってないことが原因だと思っています。

それが証拠に、一回目の遷移時には問題なく
写真とテキストが両方のったCellが遷移先にてきちんと追加されておりました。

アドバイスして頂きたいこと

では、なぜ二回目からの遷移でアプリが
落ちてしまうのかと言いますとこれも断定は
出来ませんが、おそらく配列
としてきちんとUIImageを処理できてないからだと思います。

今回、二つのテキストラベルは配列として
処理をしております。

しかしながら、UIImageに関してましてはただNSDataに変換して
UserDefautに保存して
遷移先でUIImageに復元して、UserDefautsを読み込んで表示させるだけでした。

おそらくこれがいけなかったんだと思います。

そこで、UIimageをNSDataに変換した後
ArrayとしてNSDataをUserDefautsに保存しました。

ここまでは良かったのですが
次はこのNSDataをArrayとしてUserDefaultsから
読み込んでさらにUIImageに復元といった処理を書こうとしているのですが
どうも、ソースコードに赤字エラーや黄色エラーが出て

うまくいきません。

ですので、Arrayとして保存したNSDataを
Arrayとして読み込んだあとに、NSDataをUIImageに変換するといった書き方を
教えて頂ければと思います。

該当のソースコード

import Foundation
import UIKit




class FirstViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {




    var selectImage: UIImage!



    var stockimage: [Data] = []






    var ipc: UIImagePickerController!




    let userDefaults = UserDefaults.standard

    var Savehozon: String?

    var Savehozon2: String?





    @IBOutlet weak var MyText: UITextField!


    @IBOutlet weak var MyText2: UITextField!





     //UserDefaultsの値をまとめて削除する




    @IBAction func Deletkey(_ sender: AnyObject) {

       let appDomain:String = Bundle.main.bundleIdentifier!


        UserDefaults.standard.removePersistentDomain(forName: appDomain)



    }



    func pickImageFromLibrary() {

        if UIImagePickerController.isSourceTypeAvailable(UIImagePickerControllerSourceType.photoLibrary) {


            ipc = UIImagePickerController()


            ipc.delegate = self


            ipc.sourceType = UIImagePickerControllerSourceType.photoLibrary


            self.present(ipc, animated: true, completion: nil)




        }


    }




    @IBAction func AddPic(_ sender: AnyObject) {



        pickImageFromLibrary()




    }




    @IBAction func AddAction(_ sender: AnyObject) {



        Savehozon2 = MyText2.text!

        Savehozon = MyText.text!





        if var result = userDefaults.object(forKey: "ReciveSave") as? Array<String> {
            result.append(Savehozon!)

            userDefaults.set(result, forKey:"ReciveSave")
        } else {
            userDefaults.set([Savehozon!], forKey:"ReciveSave")
        }

        userDefaults.synchronize()






        if var result2 = userDefaults.object(forKey: "ReciveSave2") as? Array<String> {


            result2.append(Savehozon2!)


            userDefaults.set(result2, forKey: "ReciveSave2")

        }else {

            userDefaults.set([Savehozon2!], forKey:"ReciveSave2")

        }


        userDefaults.synchronize()




























    }



    override func viewDidLoad() {
        super.viewDidLoad()

    }





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

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }





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






        selectImage = info[UIImagePickerControllerOriginalImage] as! UIImage!







        if let henkan = UIImageJPEGRepresentation(selectImage!, 1){




            stockimage = [henkan]






            userDefaults.set([henkan], forKey: "imageData")



        }



        self.dismiss(animated: true, completion: nil )





    }





}
import Foundation
import UIKit



class SecondViewController: UIViewController, UITableViewDelegate, UITableViewDataSource {



    var ReciveData: [String] = []

    var ReciveData2: [String] = []

    var ReciveData3: [UIImage] = []

    var result3: [Data] = []

    var PassData: Data!









    let userDefaults = UserDefaults.standard



   func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {




    let cell = tableView.dequeueReusableCell(withIdentifier: "MyCell", for:indexPath)

         let label = cell.viewWithTag(2) as! UILabel

         label.text = ReciveData[indexPath.row]





    let label2 = cell.viewWithTag(3) as! UILabel

        label2.text = ReciveData2[indexPath.row]



    let imageset = cell.viewWithTag(4) as! UIImageView



    imageset.image = ReciveData3[indexPath.row]




















    return cell





    }







    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {


        return ReciveData2.count


    }




    override func viewDidLoad() {
        super.viewDidLoad()





        if let result = userDefaults.object(forKey: "ReciveSave") as? Array<String>{


        ReciveData = result

        }





            if let result2 = userDefaults.object(forKey: "ReciveSave2") as? Array<String>{



                ReciveData2 = result2


        }








        if let result3 = userDefaults.object(forKey: "imageData") as? Array<Data>{




            PassData = result3 as! Data




            let ActiveImage2: UIImage? = UIImage(data: PassData)



            ReciveData3.append(ActiveImage2!)





        }





    }






   override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()

    }


}

開発環境

Xcode8
Swift3
iMac Sierra

よろしくお願いいたします。

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

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    2016/10/12 15:19

    こちらの質問が他のユーザから「やってほしいことだけを記載した丸投げの質問」という指摘を受けました
    「質問を編集する」ボタンから編集を行い、調査したこと・試したことを記入していただくと、回答が得られやすくなります。

回答 2

checkベストアンサー

0

これはマズいです。

if let result3 = userDefaults.object(forKey: "imageData") as? Array<Data>{
        PassData = result3 as! Data  // ??? 


ReciveData3に画像のインスタンスを格納するにはこうすればOKかと。

if let result3 = userDefaults.object(forKey: "imageData") as? Array<Data>{
       for i in 0..<result3.count {
           let wk = UIImage(data:result3[i])!
           ReciveData3.append(wk)
       }


データ構造のイメージをしっかり掴んでください。がんばってください!

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/09 18:09

    おかげさまで

    無事できました!

    ありがとうございました!

    キャンセル

-1

パッと見なんですが、代入時にhenkanがなぜ配列になるのかな?と思いました。

if let henkan = UIImageJPEGRepresentation(selectImage!, 1){
            stockimage = [henkan]
            userDefaults.set([henkan], forKey: "imageData")


もしかしてこうなのでは?

if let henkan = UIImageJPEGRepresentation(selectImage!, 1){
            stockimage.append(henkan)
            userDefaults.set(stockimage, forKey: "imageData")

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

  • 2016/10/04 14:13

    回答ありがとうございます!

    エローログは出ませんでしたよ!

    []←これつけて、Array< 〇〇 > の形で読み込まないと

    UserDefaultで配列として保持できないから
    結果的に、Cellを遷移するたびに動的に追加するっていうことが
    出来ないみたいなんですよ

    私のそれ以前のコーディングが悪くて出来ないのか
    それとも、Swiftの仕様的な問題で出来ないのかは分からないですけど・・・

    しかしながら、今度はその逆でUIImageを
    扱う時は、[]を外さないといけないのかもしれません。

    少しやってみてみます。



    キャンセル

  • 2016/10/04 14:21

    誤解を与えてすいません。エラーログはuserDefaults.set([result3], forKey: "imageData")に対するものでなく、本件全般に関してです。setの第一引数はAnyObjectだったと思うのでここでは出ないです。

    キャンセル

  • 2016/10/04 14:51

    回答ありがとうございます。

    おっしゃる通りでした。


    result3のみに戻したら前と同じように

    遷移時にCellが追加されるようになりました。

    しかしながら
    遷移先から再び遷移元に戻り

    同じようにテキストに文字をし、
    写真を選択して
    保存ボタンを押して

    遷移ボタンを押して二回目の遷移を行うところで
    アプリがエラー落ちしてしまいます。

    エラーログをみると
    テキストフィールドはValueがそれぞれ2に増えていたのに対して
    UIImageはValueが1のままでした。

    やはり、UIImageも
    遷移のたびにValueを増やそうとしたら
    配列ReciveData3としてUserDefautに保存する必要があるのでしょうか??

    もう少しアドバイス頂けたら嬉しいです。

    キャンセル

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

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

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