- 投稿日:2021-03-22T23:15:17+09:00
この素晴らしいSwiftUIにCoreDataを!【初期設定編】
こんにちは.
Sadmachineです.
いまさらながら,このすばを見始めました.
めぐみんかわいい.この記事ではアプリ開発の基礎...
Xcodeプロジェクトの開始〜CoreDataの初期設定までをわかりやすく解説します!
スクリーンショットも適宜つけるので参考にしてください!
CoreDataのことだけ知りてえよ! っていう君はSection 2から見るといいと思うよ.LGTMたくさんしてね!!!
そもそも「CoreData」ってなに?
CoreDataとは...
Xcode上から簡単にDBのようにデータ構造を設定できたり,アプリ上で扱うデータを保存,削除,更新するプログラムを簡単に書けるようになる仕組み
参考記事:やっとわかったSwift/CoreData入門 【part1:概念編】とのこと.
もっと簡単に言うと...アプリのデータをiPhoneの端末本体内のストレージに保存して永続化するために必要なもの!
って感じでしょうか.
ざっくりすぎたかな...とりあえず,詳しいことは参考記事を見てみてね!
目次
0. 開発環境
筆者の開発環境をめっちゃ簡単に紹介します.
- Xcode 12.3
- SwitfUI
以上.
もっと詳しく知りたい人はTwitterに凸して,どうぞ.1. プロジェクトを作ろう!
以下の項目はXcodeをインストールしてある前提で話していきます.
1-1 Xcodeの起動&プロジェクトファイルを作る
Xcodeを起動すると上のような画面が出てくるので,Create a new Xcode Projectを押してください.
そうするとこんな画面が出るので[App]を選択してNext.白抜きの部分も適当な名前をつけてください.
重要なのは赤く囲まれたUse CoreDataのチェックマークです.
忘れずにつけましょう.↑MugenMemoというプロジェクト名になっていますが,これがProduct Nameです.
人によって違います.プロジェクトの作成は完了です.
1-2 ContentView.swiftの修正
1-1の最後の画像の通り,エラーが吐かれています.
とりあえず「ContentView.swift」の中身を以下のようにすればOKです.ContentView.swiftimport SwiftUI import CoreData struct ContentView: View { var body: some View { NavigationView { List { Text("TEST") } } } } struct ContentView_Previews: PreviewProvider { static var previews: some View { ContentView() } }
ContentView.swiftの中身を変えればこんな感じでList形式でTESTという文字が出てくるはずです.
↑図ではResumeを使ってますが,エミュレーターでも同じように出ます.これでSection 1 プロジェクトを作ろうは完了です!
2. CoreDataの初期設定をしよう
CoreDataの初期設定を進めていきます.
2-1 Entityの新規追加
MugenMemo.xcdatamodeldを開いて,↑図のようにEntityを作ります.Entityを作るには,Add Entityを選択して適当な名前をつけます.
今回はMemoにしました.
Entityを作ったら,Attributeを追加します.
Attributes下の+を押して,Attribute:title Type:String にします.2-2 Entityのclass変更
ENTITESのMemoを押してDatamodelInspecter(右側の帯のいろいろな設定でるやつ)を表示させます.
↑図の赤く囲った部分Class CodegenのClass DefinitionをManual/Noneに変更します.2-3 CoreDataの管理に必要なコードを手動生成
Entity名+CoreDataClass.swift
Entity名+CoreDataProperties.swift
がないとCoreDataは使えないので手動で生成します.
ENTITESのMemoを選択した状態で,Editor/NSManagedObject Subclass...を選択.
Memo+CoreDataClass.swift
Memo+CoreDataProperties.swift
の2つができたはずです.Memo+CoreDataClass.swiftimport Foundation import CoreData @objc(Memo) public class Memo: NSManagedObject { }Memo+CoreDataProperties.swiftimport Foundation import CoreData extension Memo { @nonobjc public class func fetchRequest() -> NSFetchRequest<Memo> { return NSFetchRequest<Memo>(entityName: "Memo") } @NSManaged public var title: String? } extension Memo : Identifiable { }以上でSection 2 CoreDataの初期設定をしよう は完了です.
2-* もしもEntityにAttributeを追加したら...
Entityに別の属性のAttributeを追加した場合はEntity名+CoreDataProperties.swiftを編集します.
例えば,MemoにAttribute:text Type:Stringを追加した場合は以下のように編集しましょう.Memo+CoreDataProperties.swiftimport Foundation import CoreData extension Memo { @nonobjc public class func fetchRequest() -> NSFetchRequest<Memo> { return NSFetchRequest<Memo>(entityName: "Memo") } @NSManaged public var title: String? @NSManaged public var text: String? // ここを追加 } extension Memo : Identifiable { }「@NSManaged public var text: String?」を追加することで完了です.
まとめ
プロジェクトの開始〜CoreDataの初期設定までをわかりやすく解説しました.
長くなりそうだったので今回はここまで.次回は,
CoreDataの読み書きをしてみよう!
の予定です.
実際にSwiftUIを使いながらCoreDataに適当な文字列を追加し,保存するという一連の流れをやってみます.備忘録的なまとめですが,誰かの参考になれば嬉しいです.
少しでも参考になりましたらLGTMやフォロー,Twitterでの拡散をしていただければ幸いです.次回の記事:この素晴らしいSwiftUIにCoreDataを!【CoreData読み書き編】
参考サイト
- 投稿日:2021-03-22T12:44:49+09:00
複数行のUILabelのテキストを垂直方向に中央揃えにする方法(iOS)
- 投稿日:2021-03-22T11:18:16+09:00
Could not build the application for the simulator. Error launching application on iPhone xx と怒られたとき
flutterのversionを変えたりしてiOSシュミレーターが原因でビルドが通らなくなったときすること
fluuter ios build error の対処
①「flutter clean」を実行する
プロジェクトフォルダ内flutter_project_name % flutter clean Cleaning Xcode workspace... 3.0s Deleting build... 8ms Deleting .dart_tool... 0ms Deleting Generated.xcconfig... 0ms Deleting flutter_export_environment.sh... 0ms Deleting Flutter.podspec... 0ms Deleting .flutter-plugins-dependencies... 0ms Deleting .flutter-plugins... 0ms②「pod deintegrate」を実行する
プロジェクトフォルダ内flutter_project_name % pod deintegrate [!] A valid Xcode project file is required. Usage: $ pod deintegrate [XCODE_PROJECT] Deintegrate your project from CocoaPods. Removing all traces of CocoaPods from your Xcode project. If no xcodeproj is specified, then a search for an Xcode project will be made in the current directory. Options: --project-directory=/project/dir/ The path to the root of the project directory --allow-root Allows CocoaPods to run as root --silent Show nothing --verbose Show more debugging information --no-ansi Show output without ANSI codes --help Show help banner of specified command④このタイミングで「pub get」を実行してください
flutter_project_name % flutter pub get⑤iosフォルダに移動
flutter_project_name % cd ios⑥ iosフォルダ内で「pod install」
flutter_project_name/ios % pod install以上でシュミレーターでビルドが通るはずです。僕は通りました。
お役に立てれば幸いです?
- 投稿日:2021-03-22T10:44:29+09:00
Expo SDK39をejectしてAsyncStorageの内容が消えた時の対象法
Expo sdk39のReact-native アプリをejectしたら、AsyncStorageの内容がクリアされる問題に遭遇しました。
原因
Expo下で参照されるAsyncStorageのデータ保存場所と、Eject後のAsyncStorageの保存場所が異なることから発生する問題のようです
解決方法 ※2021年3月22時点
今回は@react-native-community/async-storageを使ってやってます。
iexplorer等のツールを利用して保存元のファイルがどこにあるのか
確認して保存元のファイル名を変更すると問題なく引き継がれます。例:expoでの保存先がRCTAsyncLocalStorageの場合
RNCAsyncStorage.mstatic NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1"; //保存先 static NSString *const RCTOldStorageDirectory = @"RNCAsyncLocalStorage_V1"; //保存元RNCAsyncStorage.mstatic NSString *const RCTStorageDirectory = @"RCTAsyncLocalStorage_V1"; //保存先 static NSString *const RCTOldStorageDirectory = @"RCTAsyncLocalStorage"; //保存元
- 投稿日:2021-03-22T01:10:36+09:00
UISceneDelegateをつかってUniversal Linkからの起動を制御する
概要
iOS13以降から
UISceneDelegateが導入されたのでUniversal Linkからアプリが起動された挙動もUISceneDelegateのライフサイクルで制御します。
遷移したURLによってiOS側で制御を行いたいと思いますので、そちらを試した結果を記します。実装
Universal Linkを利用するための
apple-app-site-associationの設置やAssociated Domainsの設定は完了しているものとします。
XCode11以降で作成されたプロジェクトにはSceneDelegate.swiftが含まれていてこちらにてライフサイクルの制御が管理されています。Universal LinkなどをつかってSafariなどから遷移してきたときは
scene(_:continue:)というDelegateメソッドで補足されます。
https://developer.apple.com/documentation/uikit/uiscenedelegate/3238056-scene
NSUserActivityにwebpageURLというプロパティが存在するのでこちらでURLを取得しURLによって表示する画面などを決めて遷移できます。以下は
hogehogeというパスのURLでアプリに遷移した際にHogeHogeViewControllerをモーダル表示するときの実装です。SceneDelegate.swiftfunc scene(_ scene: UIScene, continue userActivity: NSUserActivity) { guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else { return } guard let url = userActivity.webpageURL else { return } if url.scheme == "https" && url.host == "example.jp" && url.path == "hogehoge" { window?.rootViewController?.present(HogeHogeViewController(), animated: true, completion: nil) } }問題
上記の実装でUniversal Linkから遷移を制御できるのですが、こちらはアプリがバックグラウンドで起動中しか保続できません。
新規にアプリが起動するときを制御するにはscene(_:willConnectTo:options:)にて同様の処理を用意する必要があります。SceneDelegate.swiftfunc scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { // URLが存在するものを補足 guard let userActivity = connectionOptions.userActivities.first(where: { $0.webpageURL != nil }) else { return } guard userActivity.activityType == NSUserActivityTypeBrowsingWeb else { return } if url.scheme == "https" && url.host == "example.jp" && url.path == "hogehoge" { window?.rootViewController?.present(HogeHogeViewController(), animated: true, completion: nil) } }こちらでアプリが起動していない場合でも画面の制御を行うことができるようになります。
あとがき
scene(_:continue:)だけだと未起動時の制御を補足できないですが、起動していないので実装時に見落としてしまいがちなのとデバッグがしにくく、ハマってしまうこともあるかとも思います。
こちらが役に立てば。










