- 投稿日:2020-09-22T21:58:45+09:00
SwiftでRealmを使用する方法について
Realmをインストールする
Realmを使用するために、CocoaPodsを使用してインストールを行います。
PodFileにpod 'RealmSwift'
を追記し、pod install
でインストールします。pod 'RealmSwift'Swiftでは
import RealmSwift
でインポートします。import RealmSwiftモデル定義
class モデル名: Object { }
でモデル定義を行います。
@objc dynamic var
で、プロパティ定義を行います。import UIKit import RealmSwift class モデル名: Object { @objc dynamic var プロパティ名1 : 型名 = 初期値 @objc dynamic var プロパティ名2 : 型名 = 初期値 }データの追加
realm.add(モデル名(value: 値))
で、データを追加できます。
事前に、プロパティに対する値を入れている必要があります。let realm = try! Realm() let object = モデル名() object.プロパティ名1 = 値1 object.プロパティ名2 = 値2 try! realm.write { realm.add(モデル名(value: object)) }データの更新
.filter
等で対象のObjectを取得し、write()
でデータの更新を行います。let realm = try! Realm() let results = realm.objects(dayList.self).filter("プロパティ名1 == 値1 AND プロパティ名2 == 値2").first try! realm.write { results!.プロパティ名1 = 値3 }データの削除
.filter
等で対象のObjectを取得し、write()
でデータを削除を行います。
.delete()
で対象のみdeleteAll()
で全て削除します。let realm = try! Realm() let results = realm.objects(toDoList.self).filter("name == 'Michael Jeffrey Jordan'") // try! realm.write { realm.delete(results) }データが全くない場合初期値を追加する
データがない場合、データを読み込みに失敗します。
そのため、以下のようにして、データがない場合のみ初期値の追加をする必要があります。let realm = try! Realm() // データが1つもない場合 if realm.objects(モデル名().self).first == nil { let object = モデル名() object.プロパティ名1 = 値1 object.プロパティ名2 = 値2 try! realm.write { realm.add(モデル名(value: object)) } }モデルの変更をした場合
プロパティ名の追加等を行った場合、Realmの呼び出しでエラーになります。
そのため、変更があった場合スキーマの情報を更新させエラーが発生しないようにする必要があります。// プロパティ名の変更があった場合、schemaVersionの値を変更する let config = Realm.Configuration( schemaVersion: 1, migrationBlock: { migration, oldSchemaVersion in}) Realm.Configuration.defaultConfiguration = config config = Realm.Configuration() config.deleteRealmIfMigrationNeeded = true参考
- 投稿日:2020-09-22T21:21:10+09:00
iOSDC「あなたの知らない連絡先の世界」「詳解Storyboard」補足&参加した感想
iOSDC Japan 2020で発表してきた内容でいくつか受けた質問の答えや補足&参加した感想になります
あなたの知らない連絡先の世界
はてなブックマークで紹介されたらしく、えらい数見ていただいてます。
https://speakerdeck.com/coe/anatafalsezhi-ranailian-luo-xian-falseshi-jie
vCard 3.0(iOS)と vCard 2.1(Android)
Androidで取得したvCardは、Quoted-printableがかかっています。
iOS
BEGIN:VCARD VERSION:3.0 PRODID:-//Apple Inc.//iPhone OS 13.6//EN N:日向;強;搩;ドクター;三世 FN:ドクター 強 搩 日向 三世 END:VCARDAndroid
BEGIN:VCARD VERSION:2.1 N;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=E6=97=A5=E5=90=91=E7=81=98;=E5=BC=B7;=46;=44=72;=4A=72 FN;CHARSET=UTF-8;ENCODING=QUOTED-PRINTABLE:=44=72=20=E6=97=A5=E5=90=91=E7=81=98=20=46=20=E5=BC=B7=20=4A=72 END:VCARDPersonNameComponentsFormatterはサーバーサイドSwiftで使える?
使えませんでした。NSUnsupportedでした。
https://github.com/apple/swift-corelibs-foundation/blob/2a5bc4d8a0b073532e60410682f5eb8f00144870/Sources/Foundation/PersonNameComponentsFormatter.swiftObjective-Cでしか使えないメソッド
本編で紹介した
enumeratorForChangeHistoryFetchRequest:error:
の他にも、
連絡先を取得するenumeratorForContactFetchRequest:error:
もObjective-Cでしか使えません。
SwiftUI? Combine? 甘
https://developer.apple.com/documentation/contacts/cncontactstore/3294191-enumeratorforcontactfetchrequest?changes=_3&language=objc詳解storyboard
https://speakerdeck.com/coe/xiang-jie-storyboard
SceneDelegateのリストア
今回発表されていた
iPadOSDC: Multiple Windows
で解説されています。
https://speakerdeck.com/hironytic/ipadosdc-multiple-windowsAppleのサンプルドキュメントもあります。
https://developer.apple.com/documentation/uikit/uiscenedelegate/restoring_your_app_s_stateStoryboardの分割
WWDC 19の
Great Developer Habits
にてStoryboardの分割に触れています。
その他にもエンジニアにとって重要な話をしているので、このセッションは非常におすすめです。
https://developer.apple.com/videos/play/wwdc2019/239/まばたきの検出
本編では省略したまばたきの検出コードですが、例えば
AVCaptureVideoDataOutputSampleBufferDelegate
でCMSampleBufferから顔を検出し、目を閉じている、開いているを検出して判定するとまばたきの検出が行えます。
以下のコードは、両目を閉じている人を検出してアクションを起こす例です。まばたき検出はもうちょっとコードが必要になります。// MARK: - AVCaptureVideoDataOutputSampleBufferDelegate func captureOutput(_ output: AVCaptureOutput!, didOutputSampleBuffer sampleBuffer: CMSampleBuffer!, from connection: AVCaptureConnection!) { let pixelBuffer: CVPixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer)! let ciImage: CIImage = CIImage(cvPixelBuffer: pixelBuffer) guard let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: nil, options: [CIDetectorAccuracy:CIDetectorAccuracyHigh]) else { return } let faceFeatures = faceDetector.features(in: ciImage, options: [ CIDetectorSmile:true, CIDetectorEyeBlink:true ]) as! [CIFaceFeature] let closedEyes = faceFeatures.filter { (faceFeature) -> Bool in return faceFeature.leftEyeClosed && faceFeature.rightEyeClosed } if !closedEyes.isEmpty { self.sendActions(for: .primaryActionTriggered) } }個人的な感想
よかったら二つやりませんか?との打診を受けて、Storyboardだけやろうかなと思ったんですが、せっかくだから俺はどちらとも選ぶぜという勢いのみでやってみました。
結果的には本命のStoryboardではなく連絡先が好評?だったので、フェイルセーフが働いて良かったです。
セッションは20分コースと40分コースがあって、40分喋り続けるのきついなと思ってチキって20分にしたんですが、「持ち時間が40分もらえる」という考えであれば、次出られるのであれば長い時間はありかな、と思いました。Storyboardは説明がいっぱいいっぱいだったので小粋なトークが挟めませんでした。
なんにせよ、見ていただいた方、ご清聴ありがとうございました!ご清聴?
- 投稿日:2020-09-22T14:24:12+09:00
部品を画面の中央に配置する方法
(1)AutoLayoutの部分の左から2番目のアイコンをクリックします。
(2)以下2つにチェックをいれる
Horizontally in Container (cf. Horizontal 水平な)
Vertically in Container (cf. Vertical 垂直な)
(3) 「Add 2 Constraints」をクリック
→これで自動的に部品が画面の中央に配置されます
- 投稿日:2020-09-22T12:28:05+09:00
iOSDC2020に参加しました
はじめに
iOSDC2020が昨日無事終了しました。
今回の開催はニコニコ生放送での初のオンラインということで、どういう感じになるのだろうと思っていたのですが、グリーンバックを使っていたり、ニコ生のコメント機能でリアルとはまた違った感じで盛り上がる、家でリラックスしながら見れるなど、オンラインならではのいいところがたくさんあり、とても良かったです。以下自分の気になったセッションを簡単にまとめていきます
気になったセッション
サムネイルをクリックすることでスピーカーの皆様が上げてくださったSpeakerDeck/SlideShareへ移動できます。
今日から分かるAVAudioEngineの全て
Day0/TrackA
スピーカー:meteorさんmeteorさんのトークでは
・iOSのAudio周りをあまりしらない方のためのAudioUnit/AVFoundationの解説
・実際のコードを例に挙げながらAVAudioEngineなどの基本的な使い方
・RMSの取得
・WORLDを使ってボイスチェンジャーを実装して(ラッパーであるWorldInAppleのポイントを解説)みるという高度な話をされていました。最後の方は完全にはついていけていなかったのですが、自分も現在音声処理のアプリの案件に携わっているので、とても復習になり、またmeteorさんのトークは録画感を感じさせず実際に生放送で話されているみたいで、いいセッションでした。
iOSリジェクト戦記 ~リジェクトされないための課金ページ~
Day1/TrackA
スピーカー:HiromuTsurutaさんHiromuTsurutaさんのトークでは
・課金ページで守らなければいけないこと
・課金ページにはどういうタイプがあるのか
・注意文言/金額表記/無料表記で実際にリジェクトされたときの問題点/対策など
・いろいろなアプリの過去と今の課金ページの比較
・リジェクトを切り抜けるための回避策(グレーゾーン)
をわかりやすく説明されていました。個人的にはAppleの課金ページでは無料を大きくして、値段を小さくしているのでガイドラインを守っていないというオチが面白かったです。
課金(サブスクリプション)ページのリジェクト理由など、深く観察されている+スライドの作り込みすごい+トークの上手さもあり、とても完成度が高いセッションだと思いました。スピーカーのHiromuTsurutaさんが以前書かれたアプリアイコンについての記事もとても完成度が高くおすすめなのでぜひ興味のある方は読んでみてください
エラーアーキテクチャ設計について考えてみる
Day1/TrackD
スピーカー:きちえもんさんきちえもんさんのトークでは
・iOSアプリでエラーハンドリングの改善
・Androidアプリでエラーハンドリングの改善
・エラーアーキテクチャ設計について
を話されていました。iOSでのエラー処理では共感できるところが多く、またその解決法もenumを使うなどなるほどな〜と勉強になるところが多かったです。エラーアーキテクチャについてどのような姿を目指すかの中でユースケースについての説明の時に、ついてユーザーが異なる操作を行った/何か悪いことが起こったに焦点を当てた事を雨の日のシナリオという表現/喩えがとてもわかりやすく、スライドも綺麗に纏まっていて、とても見易かったです。
ユースケース駆動については初めて知ったので、自分でも調べていこうと思いました。Github ActionsでiOSアプリをCIする個人的ベストプラクティス
Day1/TrackB
スピーカー:uhooiさんuhooiさんのトークでは
前半に
・CI
・Make
・GitHub Actions
の説明を行い、後半に実際にHANDSON形式で行ってみるという形でした。CI,Make,GitHub Actionsなどをuhooiさんの言葉/イラストでわかりやすく説明してくれており、HANDSONではGitHubActionsの導入を実際にやってみるという形で見せながらわかりやすく解説してくれていました。実際にトークをみながら導入を試していた方もいらっしゃったようです。
個人的にはスライドの途中で出てきた手書きイラストが味があって好きでした。Swiftで始める静的解析
Day2/TrackD
スピーカー:まつじさんまつじさんのセッションでは
・そもそも静的解析とは
・静的解析はどのように行われているのか
・実際にSwiftSyntaxを用いて、構文木を解析してみる。
についてお話しされていました。自分はこのセッションを聞くまではソフトウェア工学をあまり知らず、静的解析についてもなんとなくSwiftLintをがあるということしかわかっていなかったのですが、このセッションで静的解析がどのような仕組みで行われているのかというトークを聞いていて、これはどうなんだ?と思った所を次の話でまつじさんが解説してくれて、静的解析への理解が深まるセッションでした。
テストコードが増えるとバグは減るのだろうか? - 「0% → 60.3%」で見えた世界の話
Day2/TrackD
スピーカー:ahirustarrrさんahirustarrrさんのセッションでは
・テスト実装に至る背景
・テストコードがなかったプロダクトにテストが実装されて、感じたメリット/デメリット
・組織開発体制に適したテスト手法
・テストが増えるとバグは減るのか
についてお話しされていました。トークの背景、内容などがとても共感できる内容であるあると思いながらトークを聞いていました。
テスト導入に近い話は普段、他の会社の話はあまり聞くことがなかったので、とてもいい機会でした
テストを導入するメリット/デメリットを詳しく解説してくれていて、これからテスト導入しようかなという人にもみて欲しいなというセッションです。
Twitterでテストコードを書いた経験がないとどうテストを書けばいいのかわからない的な意見もみられ、自分もまだ浅い方なのでなるほどなと思いました。イベントを通しての感想
他にも良かったセッションやまだ見れてないセッションはいくつもありますのでこの後視聴しようと思います。
気になったかたは後日YouTubeに動画が上がるそうなので視聴して、来年参加してみてはどうでしょうか?運営スタッフの皆様、スピーカーの皆様ありがとうございました。
参考リンク
- 投稿日:2020-09-22T11:54:56+09:00
VSCodeでSwiftの環境構築をする方法
はじめに
VSCodeでSwiftを使うための環境設定の方法を丁寧に紹介します。
競技プログラミングでSwiftを使いたい、見慣れたVSCodeで使いたい、Xcodeで標準入力の仕方がよくわからないといった方におすすめです。開発環境
OS: macOS Catalina Version 10.15.6
Visual Studio Code (VSCode): Version 1.49.1手順
- Xcodeのインストール
- VSCodeのインストール
- NodeとNPMのインストール
- SourceKit-LSP Extension for Visual Studio Codeのインストールとビルド
- SourceKit-LSPの設定
1. Xcodeのインストール
Xcodeがすでにインストールされている場合は飛ばして構いません。
Xcodeのインストール方法: https://techacademy.jp/magazine/14092. VSCodeのインストール
VSCodeがすでにインストールされている場合は飛ばして構いません。
VSCodeのインストール方法: https://qiita.com/watamura/items/51c70fbb848e5f956fd63. NodeとNPMのインストール
Homebrewを使ってnodeをインストールします。同時にnpmもインストールされます。
$ brew install nodeインストールされたことを確認するために以下のコマンドを実行してみてください。
$ npm --version 6.14.84. SourceKit-LSP Extension for Visual Studio Codeのインストールとビルド
コマンドラインからSourceKit-LSPをクローンします。
$ git clone https://github.com/apple/sourcekit-lsp.git次にインストールされたフォルダへ移動します。
$ cd sourcekit-lsp/Editors/vscode/拡張パックをビルドします。
$ npm run createDevPackageビルドしたものをインストールします。
$ code --install-extension out/sourcekit-lsp-vscode-dev.vsix5. SourceKit-LSPの設定
VSCodeでSwiftのファイルを実行しようとした際に以下のエラーが出た場合には、VSCodeの設定を変更します。
Couldn't start client SourceKit Language ServerCmd+Shift+Pでコマンドパレットを開いたあとに
基本設定: 設定(JSON)を開く (Preferences: Open Settings (JSON)"
を選択します。
そしたら、すでにあるJSONに以下の文章を追加しましょう。(書き換えではなく追加です。)"sourcekit-lsp.serverPath": "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/sourcekit-lsp"6. 確認
hello_world.swiftというファイルを作成しましょう。
作成したファイルに以下のコードを記入してみます。hello_world.swiftprint("Hello, world!")ターミナルで以下のように書くと実行することができます。
swift hello_world.swiftまたは、Control+Option+nでも実行することができます。
ちなみに実行結果はHello, world!です。
7. 型推論
今のままでは型推論がされない(と思う)ので、以下のように実行してください。ファイルをまず開きます。左下に
(HDの名前) > ユーザ > (あなたのユーザ名) > ...と表示されていると思います。その中から、
(あなたのユーザ名)
をクリックします。以下順番にファイルを開いていきます。
sourcekit-lsp
を開きます。
Editors
を開きます。
vscode
を開きます。
out
を開きます。
sourcekit-lsp-vscode-dev.vsix
というファイルが有ることを確認してください。
確認できたらこのページを開きっぱなしにしておきます。
VSCodeの拡張機能タブから右上の・・・
を選択し、VSIXからのインストール
をクリックします。
すると、インストールするファイルを選ぶ画面が表示されるので先程開いたsourcekit-lsp-vscode-dev.vsix
をドラッグ&ドロップします。
最後に、開いたファイルをインストールしましょう。
これで型推論ができるようになりました!8.C言語やC++のコンパイルにsourcekit-lspを用いたくない人へ
lsp-sourcekitのページには以下のように、Swiftだけでなく、C、C++、Objective-Cにも対応していると書かれています。
lsp-sourcekit is a client for SourceKit-lsp, a Swift/C/C++/Objective-C language server created by Apple.
そのため、今までC言語やC++で使っていたコンパイラでは動くのにlsp-sourcekitでは動かないということが発生する可能性があります。そんなときは、Swiftを使うファイルをC言語、C++を使うファイルとは分けた上で、Swiftを使うワークスペースだけでlsp-sourcekitの拡張機能を有効にしましょう。
① SourceKit-LSPを無効にする
② 再読み込みを行う
③ 拡張機能→SourceKit-LSP→有効にする→有効にする(ワークスペース)
9. 参考文献
https://nshipster.com/vscode/
https://medium.com/swlh/ios-development-on-vscode-27be37293fe1
https://scior.hatenablog.com/entry/2019/10/27/21582710. 終わりに
私は、まだまだ初心者なのですが参考文献に上げた3つのページを参考にVSCodeに導入してみたらうまく行ったので、共有させていただきました。
間違っているところがあったらご指摘ください。また、詳しい人がいたらぜひ記事を書いてください。私は、日本語でまとまっている記事を見つけ出すことができず、苦労しました...!
- 投稿日:2020-09-22T02:18:22+09:00
enumを使ってリテラルをまとめる
こんにちは。
最近自分が書いているCodeの品質を上げるために日々模索中です。
最近よく思うのは stringの文言とか、identifierを直書きしたりとか、そういうのしたくないなと思うようになり、
良い書き方ないかなと考えてCode読みあさって考えてみたら良さげな実装を思いついたので、記事にしようと思いました。結論
enumで定義してしまえばまとまっててわかりやすいんじゃね?
よくある実装1
- UITableViewのidentifierとか
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) as! TableViewCell /// ... return cellよくある実装2
private let cellId = "hogeCell" /// ... func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! TableViewCell /// ... return cell上記のよな感じで実装するとなんかいけてないし、個人的に直書きしたくないので(よきせぬ不具合を出したくない)ので以下の実装にしてみました。
実装
enum IdentifierType { static let segueId = "hogeSegue" static let cellId = "fugaCell" static let nibId = "HogeFugaTableViewCell" }こんな感じで定義して、
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: IdentifierType.fugaCell, for: indexPath) as! TableViewCell /// ... return cellとか
let nib = UINib(nibName: IdentifierType.nibId, bundle: nil) hogeTableView.register(nib, forCellReuseIdentifier: IdentifierType.cellId)みたいにして定義してあげれば、どこの何が定義してあるのかとてもわかりやすいし、直書きしなくてより安全なのではと思いこのような実装にしてみました。
まとめ
今回は、さくっとできてそれなりにまとめられて、すっきりできて、より安全に、より可読性も上がるなと個人的に思い上記の実装をしてみました。
しかし、より大規模アプリとかになると上記のような実装だけだといろいろ足りないし、より広範囲でまるっとサポートしてくれたらと思うので、より安全性や品質を高めて行ったり、楽したかったりしたらR.swiftがとても優秀なのでそれ使った方が良いと思います。
あくまで上記は小規模アプリとかで、ライブラリ入れなくても良いくらいの規模感のアプリなら、上記で対応しても良さそうに思いました。読んでいただきありがとうございました!
もっと良い実装とか他何かありましたらコメントいただけたら涙が出るくらい喜びます!!