20200405のSwiftに関する記事は13件です。

【iOS】Realm Databaseは超簡単で高性能なモバイルデータベース

はじめに

Realm Databaseの簡単な解説とサンプルの記事です。
Realm自体、もう登場してから何年か経っているので
それなりに記事も出てきています!
なので特に目新しい事は無いかもしれませんが、
生暖かい目で見てくださいw

Realm Databaseとは

特徴はざっくり言うと次の通り

  • モバイル向けに作られたNoSQLのデータベース  (データの抽出はNSPredicateを利用する)
  • SQLite、CoreDataより高速!
  • 従来のテーブル定義がクラス定義になっている!
  • 1体多のリレーションが持てる
  • バックアップ、リストアが可能

この中でも「従来のテーブル定義がクラス定義になっている」という所が
私の中では一番のメリットだと思います!
このおかげてSwiftでアプリを作ってる方であれば
比較的抵抗無くデータベースを構築できると思います!

言葉だけではイメージが湧かないと思いますので、
さっそくサンプルを見ていきましょう!
ちなみに今回はRealmの導入方法は記載していません。
導入方法を探している方は他の記事をあたってください。すみませんm(_ _)m
CocoaPodsなりCarthageなり好きな方法でプロジェクトに追加してください!
私はCarthageで入れました!

サンプル

クラス定義(テーブル定義)

普通のデータベースでいうところのテーブル定義ですね。
人に見立てたPersonというクラスを定義します!

Person.swift
import RealmSwift
import Foundation

class Person: Object {
    /// 名前
    @objc dynamic var name: String = ""
    /// 年齢
    @objc dynamic var age: Int = 0
    /// ID
    @objc dynamic var id: String = NSUUID().uuidString
    /// 作成日時
    @objc dynamic var createDate: Date = Date()

    /// IDをプライマリキーに設定
    override static func primaryKey() -> String? {
        return "id"
    }
}

これだけでテーブル定義ができます。

プライマリキーの設定

プライマリキーの設定はprimaryKeyをoverrideして
プライマリキーに設定するプロパティ名を返すだけです。
ちなみにIDにはUUIDを設定するようにしています。

作成日時の設定

作成日時は現在日時を初期値で設定しています。

データの追加(レコードの追加)

データの追加もインスタンスを生成して
Realmのインスタンス(標準Realmと言ったらいいのか?)に追加するだけです。

hoge.swift
    /// Personを追加します
    private func addPerson() {
        do {
            let realm = try Realm()
            let newPerson = Person()
            try realm.write {
                realm.add(newPerson)
            }
        } catch {
            // 例外
        }
    }

プロパティも一緒に設定する場合は次の通りvalueに設定します。

hoge.swift
    /// 名前、年齢を設定したPersonを追加します
    private func addPerson(name: String, age: Int) {
        do {
            let realm = try Realm()
            let newPerson = Person(value: ["name": name, "age": age])
            try realm.write {
                realm.add(newPerson)
            }
        } catch {
            // 例外
        }
    }

注意点

データの操作(追加、更新、削除)をする場合は必ずrealm.writeのトランザクション内で行ってください。
じゃないとアプリが落ちます???

データの更新(レコードの更新)

データの更新はRealmからデータを取得して更新するだけです!
サンプルは名前を変更しています。

hoge.swift
    /// Personの名前を更新します
    private func updatePerson(id: String, name: String) {
        do {
            let realm = try Realm()
            let person = realm.objects(Person.self).filter(NSPredicate.init(format: "id == %@", argumentArray: [id])).first
            try realm.write {
                person?.name = name
            }
        } catch {
            // 例外
        }
    }

NSPredicateを利用してidを元に絞り込んだデータを
writeトランザクション内で名前を変更するだけです。
ほとんど普通のクラスのプロパティ操作と変わらない!素晴らしい!めちゃ簡単!

データの削除(レコードの削除)

更新のときと同じでRealmからデータを取得し、削除するだけです!

hoge.swift
    /// Personを削除します
    private func deletePerson(id: String) {
        do {
            let realm = try! Realm()
            let persons = realm.objects(Person.self).filter(NSPredicate.init(format: "id == %@", argumentArray: [id]))
            try realm.write {
                realm.delete(persons)
            }
        } catch {
            // 例外
        }
    }

最後に

いかがだったでしょうか!
今までiOSのデータベースはなんだか敷居が高いって思っていた方も
これを見れば意外と簡単やん!ってなったと思います!
どんどん使っていきましょう!
この記事読んでる方は大丈夫だと思いますが、
UserDefaultsでなんでもかんでもデータ持つのは絶対駄目ですよwww

まだまだ色々書きたい事があるので
今度は今回の内容と下記事項を含め、まとめ記事を書きたいと思います!
・導入方法
・1対1のリレーションシップ
・1対多のリレーションシップ
・バックアップ、リストアの方法
・マイグレーション(プロパティ(カラム)の追加)

間違いなどありましたがご指摘頂ければ幸いです。
最後までご覧いただき、ありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【iOS】Realm Database簡単解説&サンプル!超簡単で高性能なモバイルデータベース!みんな使お??

はじめに

Realm Databaseの簡単な解説とサンプルの記事です。
Realm自体、もう登場してから何年か経っているので
それなりに記事も出てきています!
なので特に目新しい事は無いかもしれませんが、
生暖かい目で見てくださいw

Realm Databaseとは

特徴はざっくり言うと次の通り

  • モバイル向けに作られたNoSQLのデータベース  (データの抽出はNSPredicateを利用する)
  • SQLite、CoreDataより高速!
  • 従来のテーブル定義がクラス定義になっている!
  • 1体多のリレーションが持てる
  • バックアップ、リストアが可能

この中でも「従来のテーブル定義がクラス定義になっている」という所が
私の中では一番のメリットだと思います!
このおかげてSwiftでアプリを作ってる方であれば
比較的抵抗無くデータベースを構築できると思います!

言葉だけではイメージが湧かないと思いますので、
さっそくサンプルを見ていきましょう!
ちなみに今回はRealmの導入方法は記載していません。
導入方法を探している方は他の記事をあたってください。すみませんm(_ _)m
CocoaPodsなりCarthageなり好きな方法でプロジェクトに追加してください!
私はCarthageで入れました!

サンプル

クラス定義(テーブル定義)

普通のデータベースでいうところのテーブル定義ですね。
人に見立てたPersonというクラスを定義します!

Person.swift
import RealmSwift
import Foundation

class Person: Object {
    /// 名前
    @objc dynamic var name: String = ""
    /// 年齢
    @objc dynamic var age: Int = 0
    /// ID
    @objc dynamic var id: String = NSUUID().uuidString
    /// 作成日時
    @objc dynamic var createDate: Date = Date()

    /// IDをプライマリキーに設定
    override static func primaryKey() -> String? {
        return "id"
    }
}

これだけでテーブル定義ができます。

プライマリキーの設定

プライマリキーの設定はprimaryKeyをoverrideして
プライマリキーに設定するプロパティ名を返すだけです。
ちなみにIDにはUUIDを設定するようにしています。

作成日時の設定

作成日時は現在日時を初期値で設定しています。

データの追加(レコードの追加)

データの追加もインスタンスを生成して
Realmのインスタンス(標準Realmと言ったらいいのか?)に追加するだけです。

hoge.swift
    /// Personを追加します
    private func addPerson() {
        do {
            let realm = try Realm()
            let newPerson = Person()
            try realm.write {
                realm.add(newPerson)
            }
        } catch {
            // 例外
        }
    }

プロパティも一緒に設定する場合は次の通りvalueに設定します。

hoge.swift
    /// 名前、年齢を設定したPersonを追加します
    private func addPerson(name: String, age: Int) {
        do {
            let realm = try Realm()
            let newPerson = Person(value: ["name": name, "age": age])
            try realm.write {
                realm.add(newPerson)
            }
        } catch {
            // 例外
        }
    }

注意点

データの操作(追加、更新、削除)をする場合は必ずrealm.writeのトランザクション内で行ってください。
じゃないとアプリが落ちます???

データの更新(レコードの更新)

データの更新はRealmからデータを取得して更新するだけです!
サンプルは名前を変更しています。

hoge.swift
    /// Personの名前を更新します
    private func updatePerson(id: String, name: String) {
        do {
            let realm = try Realm()
            let person = realm.objects(Person.self).filter(NSPredicate.init(format: "id == %@", argumentArray: [id])).first
            try realm.write {
                person?.name = name
            }
        } catch {
            // 例外
        }
    }

NSPredicateを利用してidを元に絞り込んだデータを
writeトランザクション内で名前を変更するだけです。
ほとんど普通のクラスのプロパティ操作と変わらない!素晴らしい!めちゃ簡単!

データの削除(レコードの削除)

更新のときと同じでRealmからデータを取得し、削除するだけです!

hoge.swift
    /// Personを削除します
    private func deletePerson(id: String) {
        do {
            let realm = try! Realm()
            let persons = realm.objects(Person.self).filter(NSPredicate.init(format: "id == %@", argumentArray: [id]))
            try realm.write {
                realm.delete(persons)
            }
        } catch {
            // 例外
        }
    }

最後に

いかがだったでしょうか!
今までiOSのデータベースはなんだか敷居が高いって思っていた方も
これを見れば意外と簡単やん!ってなったと思います!
どんどん使っていきましょう!
この記事読んでる方は大丈夫だと思いますが、
UserDefaultsでなんでもかんでもデータ持つのは絶対駄目ですよwww

まだまだ色々書きたい事があるので
今度は今回の内容と下記事項を含め、まとめ記事を書きたいと思います!
・導入方法
・1対1のリレーションシップ
・1対多のリレーションシップ
・バックアップ、リストアの方法
・マイグレーション(プロパティ(カラム)の追加)

間違いなどありましたがご指摘頂ければ幸いです。
最後までご覧いただき、ありがとうございました!

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】定数と変数の使い方

概要

Swiftの学習中の備忘録です。
基本の基本、変数と定数の使い方についてまとめています。

筆者環境

  • MacBook Pro (13-inch, 2019)
  • macOS Catalina(Version 10.15.4)
  • Xcode(Version 11.4)
  • Swift5.2

定数 let

定数は定義した初期値を”後から上書きすることがないもの”に使います。
不意にデータの書き換えが行われないように、
基本的には定数を使い、上書きが必要な値のみ変数で定義するのがいいようです。

let msg: String = "Hello!" 
//String型(データ型)のmsg(定数名)に"Hello!"(初期値)を代入

let msg = "Hello!"
//データ型を省略して書くことも出来る(型推論)

上書きしようとするとエラーが出る。

let msg = "Hello!"
msg = "Good Bye!"

//エラー文
Immutable value 'msg' may only be initialized once
//不変の値である"msg"は一度しか初期化できない(変更できない)。

変数 var

定数は定義した初期値を”後から変更する可能性のあるもの”に使います。

var msg: String = "Hello!" 
//String型(データ型)のmsg(定数名)に"Hello!"(初期値)を代入

var msg = "Hello!"
//データ型を省略して書くことも出来る(型推論)

定数と違い、上書き出来る。

var msg = "Hello!"
msg = "Good Bye!"

print(msg)
// Good Bye!

最後に

以上、簡単ですが定数と変数の使い方についてでした。
学習を進める中で、追加したい内容が出てきたら都度追記していきます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】ターミナルでバージョン確認

概要

Swiftの勉強をはじめました。
当たり前のことですが、自分が扱うSwiftのバージョンを把握しておかないと学習も進まない訳で…
という訳で、ここではターミナルを使ったバージョン確認の方法を備忘録としてまとめています。

筆者環境

  • MacBook Pro (13-inch, 2019)
  • macOS Catalina(Version 10.15.4)
  • Xcode(Version 11.4)

バージョン確認

ターミナルを起動し、以下のコマンドを入力することで、Swiftのバージョンを確認することができます。

 $ /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift -version

結果

Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29)
Target: x86_64-apple-darwin19.4.0

Swiftのバージョンが"5.2"であることが確認できました。

【おまけ】PATHを通す

上記の通りでもバージョン確認はできますが、一度PATHを通しておくと色々便利ですね。
僕はまだだったので以下の手順でPATHを通しました。

Swiftコマンド実行ファイルの格納場所を確認

ターミナルで以下を実行します。

$ which swift

結果

/usr/bin/swift

設定ファイルの編集

ターミナルで以下を実行します。

$ vi ~/.bash_profile

設定ファイルが開くので、以下を追加します。

# 編集開始 i

export PATH=$PATH:/usr/bin/swift

# 保存 esc → :wq
# 保存せずに終了 esc → :qa!

設定ファイルの更新

設定の変更を反映させるために以下を実行

$ source ~/.bash_profile

バージョン確認

PATHが通ったかの確認も含めて、バージョン確認します。

$ swift -version

結果

Apple Swift version 5.2 (swiftlang-1103.0.32.1 clang-1103.0.32.29)
Target: x86_64-apple-darwin19.4.0

これで完了です!

【おまけのおまけ】PATHを通した後のエラー

PATHを通して、一度目のバージョン確認の時、以下のようなエラーが出ました。

xcrun: error: invalid active developer path (/Library/Developer/CommandLineTools), missing xcrun at: /Library/Developer/CommandLineTools/usr/bin/xcrun

どうやら直前にmacOSをアップロードしていたのが原因のよう。
以下のコマンドを実行し、Xcodeをインストールすることで解決し、無事PATHが通りました。

 $ xcode-select --install
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】BitriseでSwiftformatが失敗し、それを成功させるまで

概要

SwiftFormatを導入したは良いけど、ローカルでは成功するがBitriseでなかなか成功してくれなかった話。

エラー内容

error: File not found at /Users/vagrant/git/modified:.

まず、SwiftFormatをどの様に導入したか

Cocoapodsでインストールし、 Build PhasesDependencies の直後にSwiftFormatを以下の様に設定しました。

SwiftFormat_before.sh
Pods/SwiftFormat/CommandLineTool/swiftformat `git status | egrep 'new file|modified'` [options...]

解決策

SwiftFormat_after.sh
for file in $(git diff --name-status | cut -f 2 | grep 'swift'); do
  Pods/SwiftFormat/CommandLineTool/swiftformat $file [options...]
done

残っている問題点

git diff だと新規追加ファイルが対象にならないのでこれを解決する方法を考えないとです。

色々

git status の出力は

$ git status
modified:       aaa/bbb/ccc.swift

となります。
この空白で区切られた二つの文字列がswiftformatコマンドの引数として渡ってしまい、 modified: なんてないよと怒られてました。
解決策としては、対象ファイル検索コマンドを正しく実行し、その内容を引数として渡す様にしてやればうまく行きました。
よくよく考えれば当たり前や。。。

備考

とはいえ、CIでSwiftFormatを実行する必要はないので、CIでは実行しないみたいに出来ればもっと良いなぁと思ったり。
そんな方法を知ってる方がいたらコメントなどで教えていただけると嬉しいです。

誰かのお役に立てば。

参考にしたサイト

https://pod.hatenablog.com/entry/2019/09/04/081801
https://www.yoheim.net/blog.php?q=20160302

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】Index out of rangeを回避

はじめに

業務でIndex out of rangeにならないように安全に要素を取得してあげたい!と思い、いろいろ調べた結果行きついたものを備忘録として残します。(ファイル名はてきとうです。。。)

Array.swift
var hoge = ["a", "b", "c", "d"]

hoge[3] //結果: d
hoge[4] //結果: Index out of range

これをどうやって防ぐのかというと、Arrayのsubscriptメソッドのsafeって言うのを使います。

ArraySubscriptSafe.swift
var hoge = ["a", "b", "c", "d"]

extension Array {
    subscript (safe index: Index) -> Element? {
        //indexが配列内なら要素を返し、配列外ならnilを返す(三項演算子)
        return indices.contains(index) ? self[index] : nil
    }
}

hoge[safe: 3] //結果: d
hoge[safe: 4] //結果: nil

まとめ

他にもやり方はいろいろとあると思うので、その度に更新していければと思います。
間違いなどがありましたら指摘お願いします。

参照

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[swift]ARkitでsampleデータをiphoneにビルドしようとしたら、ログインているのにアカウントが受け入れられずビルドできなかった解決例

1.エラー文

メッセージで下記のエラー文が出てきました

Showing All Messages
The operation couldn’t be completed. Unable to log in with account 'xxxxxxxx@icloud.com'. The login details for account 'xxxxxxxxxxxx@icloud.com' were rejected.

2.原因

Xcodeのログイン情報が期限切れ(expired)となっていました

3.解決方法

windowバーのXcodepreferenceアカウント→再度ログインしますか?ボタンをクリックで解決できます

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

初めてGrace Periodを導入する日に読む話

はじめに?

Grace Periodを導入するうえで色々と行き詰まる部分があったので備忘録としてまとめたいと思います。
これからGrace Periodを導入される方のお役に立てればと!

Grace Periodとは?

Grace Periodとは、サブスクリプション購読者に請求に関する問題(クレジットカードの有効期限切れなど)が発生した場合に、その時点では解約とせず、請求に関する問題を解消するための猶予期間を設ける仕組み、もしくは猶予期間そのものを指します。

これによりサブスクリプション購読者の非自発的解約を防ぐことができます。

※ちなみに、Grace Periodの設定をONにしていなくても即解約とはならず、有料サービスは利用できませんが、Appleは60日間、毎日請求を試みます。

猶予期間の日数?

猶予期間はサブスクリプションの登録期間が週単位の場合は6日、月単位以上の場合は16日が適用されます。猶予期間の設定はApp Store Connectから可能です。

有料サービス提供の義務?

猶予期間中は、請求に関する問題が生じた人もこれまでと同様に有料サービスにアクセスすることができます。正確には、デベロッパーは猶予期間中は有料サービスを提供することがAppleから求められています。つまり単純にGrace Periodの設定をONにすればいいわけでなく、アプリやサーバーサイドの開発も必要になります。

猶予期間中に請求に関する問題を解消した場合?

これだけでは無料で有料サービスを提供しているように思えるかもしれません。

大丈夫です!そんなことはありません!

もし請求に関する問題が生じた人が猶予期間中に問題を解消した場合、Appleによって請求に関する問題が生じた日まで遡って請求されます
つまり有料サービスの継続日数や収益の中断がなかったことになります。

これは収益の観点でもデベロッパーにとっては恩恵があります。
サブスクリプション購読者の有料サービスの継続日数が1年未満の場合は料金の30%、1年以上経過している場合は料金の15%がAppleに摂取されます。
つまり有料サービスの日数が中断されないほうが収益に繋がるのです。

猶予期間中に請求に関する問題を解消しなかった場合?

Grace Periodの設定をONにしていなくてもAppleは請求に関する問題が生じた日から60日間、毎日請求を試みます。
Grace Periodの設定をONにすると、この60日間の最初の6日間もしくは16日間は猶予期間としてデベロッパーが有料サービスの提供を続けます。

なので、猶予期間中に請求に関する問題を解消しなかった場合は有料サービスが利用できなくなります。また、有料サービスの継続日数も請求に関する問題が生じた日で中断され、請求に関する問題を解消したタイミングで再開となります。

そして、請求に関する問題が生じた日から60日が過ぎても問題が解消されなかった場合は、サブスクリプション自体が自動解約となります
再度サービスを利用したい場合は新規でサブスクリプションを登録する必要があります。

Grace Periodを導入するメリット?

上記の説明を踏まえて導入のメリットをおさらいしましょう。

  • サブスクリプション購読者の非自発的解約を防ぐことができる
  • 有料サービスの継続日数や収益の中断を防ぐことができる

参考資料?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Swift】配列内の要素の合計

使用例

配列内の要素を求めるときに、使えそうなものを備忘録として残しておこうと思いました。タプル型を例に以下に記述していきます。

Zoo.swift
//定義
var zoo:[(label: String, value: Int)] = [
    (label: "リンゴ", value: 100),
    (label: "ゴリラ", value: 200),
    (label: "ラッパ", value: 300)
]

var sumValue = 0

1. for文

for item in zoo {
    sumValue += item.value
}

print(sumValue) //結果: 600

2. forEach

zoo.forEach { (item) in
    sumValue += item.value
}

print(sumValue) //結果: 600

3. reduce

let sum = zoo.reduce(0) { (result, item) -> Int in
    return result + item.value
}

print(sum) //結果: 600

※reduce補足

どのようにresultに値が代入されていくかについて説明します。

let sum = zoo.reduce(0) { (result, item) -> Int in
    print("result", result)
    print("value", item.value)
    return result + item.value
}

print("sum", sum)

//実行結果
result 0
value 100

result 100
value 200

result 300
value 300

sum 600

まとめ

今回備忘録としてまとめました。間違ってる部分などがあればご指摘ください。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

カスタムViewをXibで作成する

いつもはStoryboardやXibは使わずにコードで全てレイアウトを組みます
久しぶりに共通ViewをカスタムViewとしてXibで切り出して使おうとしたら忘れてたのでメモ

ただもうまとめられているので参考になった記事を載せておしまいにします
http://tanihiro.hatenablog.com/entry/2015/10/13/092710
https://takasfz.hatenablog.com/entry/2018/08/10/151515
https://qiita.com/maebaru/items/90f915f82e3d6425cbdc

要点

  • Xibとそれに対応するSwiftファイルの作成
  • XibのFile's Owenerでカスタムクラス選択(これでファイルとXibが紐づくのでIBOutletでつなげられる)
  • 使用したいStoryboardのViewのclass Identifierをこのカスタムクラスにする

困ったこと

R.swiftを使っていたので R.nib.customView.firstView(owner: self)でカスタムクラスのインスタンスを取得できるかと思ったけど
取得できずに落ちました
結局この解決方法がわからなかったのでIBOutletで対応することにしました

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS app の習得日記 (1)

こちらの記事を参考に
実習中
(https://qiita.com/gomi_ningen/items/4e0e5bd98f08c4bcf93d)

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var lable: UILabel!

    @IBAction func buttonOnTouchUpInside(_ sender: Any) {
        let now = Date() // 現在時刻を取得
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "ja_JP") // ロケールを指定
        dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss" // 時刻表示のフォーマットを指定
        // 指定したフォーマットで現在時刻を取得してラベルに反映させる
        lable.text = dateFormatter.string(from: now)
    }


    }

シミュレーターでトライするも
日付がでない

(https://ediienote.com/Wp_ediieNote/2019/09/21/swiftsignalsgabrt/)

こちらの記事が参考になった。

どうやら 接続を何回もやったようで、
接続先が複数になってた。

一つにもどしたらできた

スクリーンショット 2020-04-05 2.30.04.png

しかし
レイアウトが重なるのはなんでだろう?
xcodeではちゃんと離れているのに、、、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

iOS app の習得日記

こちらの記事を参考に
実習中
(https://qiita.com/gomi_ningen/items/4e0e5bd98f08c4bcf93d)

import UIKit

class ViewController: UIViewController {


    @IBOutlet weak var lable: UILabel!

    @IBAction func buttonOnTouchUpInside(_ sender: Any) {
        let now = Date() // 現在時刻を取得
        let dateFormatter = DateFormatter()
        dateFormatter.locale = Locale(identifier: "ja_JP") // ロケールを指定
        dateFormatter.dateFormat = "yyyy/MM/dd HH:mm:ss" // 時刻表示のフォーマットを指定
        // 指定したフォーマットで現在時刻を取得してラベルに反映させる
        lable.text = dateFormatter.string(from: now)
    }


    }

シミュレーターでトライするも
日付がでない

(https://ediienote.com/Wp_ediieNote/2019/09/21/swiftsignalsgabrt/)

こちらの記事が参考になった。

どうやら 接続を何回もやったようで、
接続先が複数になってた。

一つにもどしたらできた

スクリーンショット 2020-04-05 2.30.04.png

しかし
レイアウトが重なるのはなんでだろう?
xcodeではちゃんと離れているのに、、、

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Swift データの保存と呼び出し

iOSのアプリでは、データの保存をしていないと、タスクキルをするたびに、行った操作がリセットされる。そのため、データの保存と呼び出しが必要となる。

データの保存のやり方

sample.swift
//objectsというデータを保存したい場合
UserDefaults.standrad.set(objects, forKey: String)

objectを定義している場所によっては、self.objectsとする。
[forKey: String]の部分は、[forKey: "Store1"]のように自分で名前をつける。
この場合だと、以下のように書く。

sample.swift
//objectsというデータを保存したい場合
UserDefaults.standrad.set(objects, forKey: "Store1")

これは、Store1にobjectsを保存するということである。
新しくobjectsを更新するたびに、同じように保存すれば、Store1も更新される。

同じキーに2回以上保存を行った場合は、古いデータは消え、一番最新のデータのみ保持する。

*UserDefaulsによるデータの保存は保持できる型は決まっている。そのため、保持できない型は型変換などを行って保持する必要がある。

*構造体の保存も可能である。(やり方は別方法)

データの呼び出し

sample.swift
//Store1の中身をString型で保持している場合
let load = UserDefauls.standard.object(forKey: "Store1")
if (load as? String != nil {
self.objects = load as! String
}

データの保存が1つだけというのは基本的に少ないと思うので、配列などを使うと思う。

sample.swift
var objects = [Any]()

配列を用いる場合は、以下のようにするだけである。

sample.swift
//Store1の中身をString型で保持している場合
let load = UserDefauls.standard.object(forKey: "Store1")
if (load as? [String] != nil {
self.objects = load as! [String]
}
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む