見出し画像

【徒然DB】気ままにUIKit-CoreData編6〜NGサンプル エンティティの属性の型、範囲、初期値を設定〜

概要

このマガジンは四十を過ぎたおっさんが、

を参考にStoryboardでiOSアプリを完全に趣味で楽しんでいるだけな記事を気ままに上げてます。

今回

をハイ、レッツゴ🕺

前準備

念の為、

  1. バックアップ

  2. 新規クラスを追加

  3. メニュービューと新規ビューを追加

をやってから本題へ💃

一旦、てな感じかな💦

本題

今回は、

の設定項目がメインなので

恒例の一覧表を作ってから〜〜〜〜
記事では、コードのところだけ、機能を作って動かす
👉いつものスタイル🕺

毎回、言ってるけど、それ以外は、

自分で色々、動かして遊ぶ

が一番近道なので、やってみてね〜〜〜

一覧表

とまあ、一覧表にまとめるとこんな感じ👀
長いねえ〜〜〜
長いってことは = 結構なんでもできるってこと🕺

以下は、試してみても正常に動かないのでもはや参考ってことで💦

⒈テスト用プロジェクトを参考に準備

と思ったんだけど、

かなり面倒臭いな藁🤣

ダウンロードするとわかるけど、

Xprojファイル自体が存在しないから、

読み解くのに苦労したわw

てな
てな
てなおな感じで〜〜〜
myBinaryDataデータのとこだけ字を間違えたから直した〜〜〜

今回のコード(事前準備)

class AttributeSettingCoreDataViewController: UIViewController, UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource {

    @IBOutlet weak var myTextField: UITextField!
    @IBOutlet weak var myLabel: UILabel!
    let dataList = ["Integer 16","Integer 32","Integer 64","Decimal","Double","Float","String","Boolean","Date", "Binary Data", "Transformable"]
    var selectStr:String = "Integer 16"
    //管理オブジェクトコンテキスト
    var managedContext:NSManagedObjectContext!
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //管理オブジェクトコンテキストを取得する。
        let applicationDelegate = UIApplication.shared.delegate as! AppDelegate
        managedContext = applicationDelegate.persistentContainer.viewContext
        //デリゲート先に自分を設定する。
        myTextField.delegate = self
    }
    //コンポーネントの個数を返すメソッド
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    //コンポーネントに含まれるデータの個数を返すメソッド
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return dataList.count
    }
    //データを返すメソッド
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return dataList[row]
    }
    //データ選択時の呼び出しメソッド
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        //選択されたデータを取得する。
        selectStr = self.pickerView(pickerView, titleForRow: pickerView.selectedRow(inComponent: 0), forComponent: 0)!
    }
    //Returnキー押下時の呼び出しメソッド
    func textFieldShouldReturn(_ textField:UITextField) -> Bool {
        //キーボードをしまう
        self.view.endEditing(true)
        return true
    }
    @IBAction func myPush(_ sender: UIButton) {
        do {
            //新しいオブジェクトを管理オブジェクトコンテキストに格納する。
            let player = NSEntityDescription.insertNewObject(forEntityName: "Player", into: managedContext) as! Player
            switch selectStr {
            case "Integer 16":
                player.myInteger16 = Int16(myTextField.text!)!
            case "Integer 32":
                player.myInteger32 = Int32(myTextField.text!)!
            case "Integer 64":
                player.myInteger64 = Int64(myTextField.text!)!
            case "Decimal":
                player.myDecimal = Decimal(Double(myTextField.text!)!)
            case "Double":
                player.myDouble = Double(myTextField.text!)!
            case "Float":
                player.myFloat = Float(myTextField.text!)!
            case "String":
                player.myString = String(myTextField.text!)
            case "Boolean":
                player.myBoolean = NSString(string:myTextField.text!).boolValue
            case "Date":
                let formatter = DateFormatter()
                formatter.locale = Locale(identifier: "ja")
                formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
                player.myDate = formatter.date(from: String(describing: myTextField.text!))!
            case "Binary":
                let data = NSData(data: String(myTextField.text!).data(using: String.Encoding.utf8)!)
                player.myBinaryData = data as Data
            case "Transformable":
                player.myTransformable = String(myTextField.text!) as AnyObject
            default:
                print("とりあえずそれ以外")
            }
            //管理オブジェクトコンテキストに格納したデータを保存する。
            try managedContext.save()
            //Playエンティティで保存されているデータを取得する。
            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
            let result = try managedContext.fetch(fetchRequest) as! [Player]
            print(result)
        } catch {
            print(error)
        }
    }
}

までは出来たんだけど、Dateなんかが致命的に怪しいんだよね〜〜〜

⒉読み込みボタンを配置してアクション接続

てな感じで〜〜〜
て感じで〜〜〜

⒊コード組み込み

do {
    //保存データを取得する。
    let fetchRequest = NSFetchRequest(entityName: "Player")
    let result = try managedContext.executeFetchRequest(fetchRequest) as! [Player]
    //取得結果を出力する。
    let data = result.last!
    print("testInteger16=\(data.testInteger16!)")
    print("testInteger32=\(data.testInteger32!)")
    print("testInteger64=\(data.testInteger64!)")
    print("testDecimal=\(data.testDecimal!)")
    print("testDouble=\(data.testDouble!)")
    print("testFloat=\(data.testFloat!)")
    if let test = data.testString {
        print("testString=\(test)")
    }
    if let test = data.testBoolean {
        print("testBoolean=\(test)")
    }
    if let test = data.testDate {
        print("testDate=\(test)")
    }
    if let test = data.testBinaryData {
        print("testBinaryData=\(test)")
    }
    if let test = data.testTransformable as? TestObject {
        print("testTransformable=\(test.message)")
    }
    print("")
} catch {
    print(error)
}

//Transformableテスト用
class TestObject: NSObject, NSCoding {
    var message:String!
    override init() {
        super.init()
    }
    //デコード
    required init?(coder aDecoder: NSCoder) {
        message = aDecoder.decodeObjectForKey("message")! as! String
    }
    //エンコード
    func encodeWithCoder(aCoder: NSCoder) {
        aCoder.encodeObject(message, forKey: "message")
    }
}

を参考に〜〜〜作ってみたんだけど、

今回のコード(没)

class AttributeSettingCoreDataViewController: UIViewController, UITextFieldDelegate,UIPickerViewDelegate,UIPickerViewDataSource {
    
    @IBOutlet weak var myTextField: UITextField!
    @IBOutlet weak var myLabel: UILabel!
    let dataList = ["Integer 16","Integer 32","Integer 64","Decimal","Double","Float","String","Boolean","Date", "Binary Data", "Transformable"]
    var selectStr:String = "Integer 16"
    //管理オブジェクトコンテキスト
    var managedContext:NSManagedObjectContext!
    //最初からあるメソッド
    override func viewDidLoad() {
        super.viewDidLoad()
        //管理オブジェクトコンテキストを取得する。
        let applicationDelegate = UIApplication.shared.delegate as! AppDelegate
        managedContext = applicationDelegate.persistentContainer.viewContext
        //デリゲート先に自分を設定する。
        myTextField.delegate = self
    }
    //コンポーネントの個数を返すメソッド
    func numberOfComponents(in pickerView: UIPickerView) -> Int {
        return 1
    }
    //コンポーネントに含まれるデータの個数を返すメソッド
    func pickerView(_ pickerView: UIPickerView, numberOfRowsInComponent component: Int) -> Int {
        return dataList.count
    }
    //データを返すメソッド
    func pickerView(_ pickerView: UIPickerView, titleForRow row: Int, forComponent component: Int) -> String? {
        return dataList[row]
    }
    //データ選択時の呼び出しメソッド
    func pickerView(_ pickerView: UIPickerView, didSelectRow row: Int, inComponent component: Int) {
        //選択されたデータを取得する。
        selectStr = self.pickerView(pickerView, titleForRow: pickerView.selectedRow(inComponent: 0), forComponent: 0)!
    }
    //Returnキー押下時の呼び出しメソッド
    func textFieldShouldReturn(_ textField:UITextField) -> Bool {
        //キーボードをしまう
        self.view.endEditing(true)
        return true
    }
    @IBAction func myPush(_ sender: UIButton) {
        do {
            //新しいオブジェクトを管理オブジェクトコンテキストに格納する。
            let player = NSEntityDescription.insertNewObject(forEntityName: "Player", into: managedContext) as! Player
            switch selectStr {
            case "Integer 16":
                player.myInteger16 = Int16(myTextField.text!)!
            case "Integer 32":
                player.myInteger32 = Int32(myTextField.text!)!
            case "Integer 64":
                player.myInteger64 = Int64(myTextField.text!)!
            case "Decimal":
                player.myDecimal = Decimal(Double(myTextField.text!)!)
            case "Double":
                player.myDouble = Double(myTextField.text!)!
            case "Float":
                player.myFloat = Float(myTextField.text!)!
            case "String":
                player.myString = String(myTextField.text!)
            case "Boolean":
                player.myBoolean = NSString(string:myTextField.text!).boolValue
            case "Date":
                let formatter = DateFormatter()
                formatter.locale = Locale(identifier: "ja")
                formatter.dateFormat = "yyyy/MM/dd HH:mm:ss"
                player.myDate = formatter.date(from: String(describing: myTextField.text!))!
            case "Binary":
                let data = NSData(data: String(myTextField.text!).data(using: String.Encoding.utf8)!)
                player.myBinaryData = data as Data
            case "Transformable":
                player.myTransformable = String(myTextField.text!) as AnyObject
            default:
                print("とりあえずそれ以外")
            }
            //管理オブジェクトコンテキストに格納したデータを保存する。
            try managedContext.save()
            //Playエンティティで保存されているデータを取得する。
            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
            let result = try managedContext.fetch(fetchRequest) as! [Player]
            print(result)
        } catch {
            print(error)
        }
    }
    
    //読込ボタン押下時の呼び出しメソッド
    @IBAction func myRead(_ sender: UIButton) {
        do {
            //保存データを取得する。
            let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Player")
            let result = try managedContext.fetch(fetchRequest) as! [Player]
            //取得結果を出力する。
            let data = result.last!
            print("myInteger16=\(data.myInteger16)")
            print("myInteger32=\(data.myInteger32)")
            print("myInteger64=\(data.myInteger64)")
            print("myDecimal=\(data.myDecimal)")
            print("myDouble=\(data.myDouble)")
            print("myFloat=\(data.myFloat)")
            if let mine = data.myString {
                print("myString=\(mine)")
            }
            if var mine: Bool? = data.myBoolean {
                print("myBoolean=\(mine)")
            }
            if let mine: Date? = data.myDate {
                print("myDate=\(mine)")
            }
            if let mine: Any?  = data.myBinaryData {
                print("myBinaryData=\(mine)")
            }
            if let mine = data.myTransformable as? MyAttributeCoreDataObject {
                print("myTransformable=\(String(describing: mine.message))")
            }
            print("")
        } catch {
            print(error)
        }
    }
}

//Transformableテスト用
class MyAttributeCoreDataObject: NSObject, NSCoding {
    var message:String!
    override init() {
        super.init()
    }
    //デコード
    required init?(coder aDecoder: NSCoder) {
        message = (aDecoder.decodeObject(forKey: "message")! as! String)
    }
    //エンコード
    func encode(with aCoder: NSCoder) {
        aCoder.encode(message, forKey: "message")
    }
}

いきなりこんなに全部のデータ型を読み込ませるみたいなのって、
すでにオプショナル型の許容範囲も変わっているし、
正直、複雑すぎる💦
テストプロジェクトもよくわからないファイル構成だけしか残ってないしね(~_~;)

なので、

今回は一覧表のみ参考ってことでよろしく〜〜〜🙇

ブラッシュアップ

地球儀ボタン追加

てな感じで👀

記事公開後、

ハイ、完了💃
実機も問題なし🕺

今回のEntityって、まさに

教室事例って感じで、

データタイプの型を示したかっただけでしょ👀

こんな名前のデータテーブルなんて実際には作らないからね。

  • Int型👉ID

  • String型👉名前や住所、勤務先

  • Double型👉消費税計算後の端数切り捨て前の実数を格納

。。。

みたいな感じで、普通は意味のあるカラム(CoreDataでいうAttribute)名を付けるからね。

うーむ、、、いよいよ乖離が激しくなって来そうな予感🤔
先が思いやられるなあ。

Apple公式

さてと、次回は

をレッツゴする🕺

う〜〜〜む

今回の操作は何がしたのかよくわからなかったし、
Apple公式ドキュメントだけをみた方が参考になりそう👀
バージョン古いときの一覧表だしね💦

何かの参考までに〜〜〜記事自体は公開しとく。


この記事が気に入ったらサポートをしてみませんか?