20200922のiOSに関する記事は7件です。

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

参考

https://realm.io/jp/docs/swift/latest/

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

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:VCARD

Android

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:VCARD

PersonNameComponentsFormatterはサーバーサイドSwiftで使える?

使えませんでした。NSUnsupportedでした。
https://github.com/apple/swift-corelibs-foundation/blob/2a5bc4d8a0b073532e60410682f5eb8f00144870/Sources/Foundation/PersonNameComponentsFormatter.swift

Objective-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-windows

Appleのサンプルドキュメントもあります。
https://developer.apple.com/documentation/uikit/uiscenedelegate/restoring_your_app_s_state

Storyboardの分割

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は説明がいっぱいいっぱいだったので小粋なトークが挟めませんでした。
なんにせよ、見ていただいた方、ご清聴ありがとうございました!ご清聴?

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

Cordova開発環境をWindows10 + AndroidとMac + iOSでそれぞれ構築

Cordovaのインストール(共通)

Windows、Macともに共通で実施します。

npmが必要なので事前に入れておきます。
私はWindowsならnodist、MacならnodebrewでNode.js環境を作りました。

Cordova公式サイトの「Get Started」に沿って進めます。

> npm install -g cordova

> cordova --version
10.0.0

> cordova create MyApp
Creating a new cordova project.

> cd MyApp

Cordovaアプリをブラウザで動かす

プラットフォーム(Cordovaの実行環境)を追加して動かしてみます。
まずはブラウザで動かします。

> cordova platform add browser
Using cordova-fetch for cordova-browser@^6.0.0
Adding browser project...
Creating Cordova project for cordova-browser:
        Path: C:\Users\hoge\Desktop\MyApp\platforms\browser
        Name: HelloCordova
Installing "cordova-plugin-whitelist" for browser
6.0.0

> cordova run browser

ブラウザが開いて「Hello World」アプリが実行されれば成功です。

Androidアプリの実行環境構築

こちらはWindowsで実施します。

事前準備

JDKのインストール

JDK(Java Development Kit)8をインストールします。
https://www.oracle.com/jp/java/technologies/javase/javase-jdk8-downloads.html

> javac -version
javac 1.8.0_261

環境変数「JAVA_HOME」の設定

JDK8をインストールしたファルダ「C:\Program Files\Java\jdk1.8.0_261」を環境変数「JAVA_HOME」としてOSに設定します。

Gradleをインストール

ビルドツールのGradleをインストールします。
https://gradle.org/install/
ダウンロードしたら解凍し任意のフォルダに置いてパスを通します。

> gradle -v

Welcome to Gradle 6.6.1!

Here are the highlights of this release:
 - Experimental build configuration caching
 - Built-in conventions for handling credentials
 - Java compilation supports --release flag

For more details see https://docs.gradle.org/6.6.1/release-notes.html


------------------------------------------------------------
Gradle 6.6.1
------------------------------------------------------------

Build time:   2020-08-25 16:29:12 UTC
Revision:     f2d1fb54a951d8b11d25748e4711bec8d128d7e3

Kotlin:       1.3.72
Groovy:       2.5.12
Ant:          Apache Ant(TM) version 1.10.8 compiled on May 10 2020
JVM:          1.8.0_261 (Oracle Corporation 25.261-b12)
OS:           Windows 10 10.0 amd64

Android Studioをインストール

Android SDKとエミュレーターを使うためにAndroid Studioをインストールします。
https://developer.android.com/studio

環境変数「ANDROID_SDK_ROOT」の設定

Android Studioの「Tools > SDK Manager」から↓のような画面を開きSDKのパスを取得します。

1.png

環境変数「ANDROID_SDK_ROOT」に設定します。

ライセンスの同意

> cd C:\Users\hoge\AppData\Local\Android\Sdk\tools\bin
> sdkmanager --licenses

上記コマンドを実行し、全て「y」を入力します。

プラットフォーム追加

> cordova platform add android
Using cordova-fetch for cordova-android@^9.0.0
Adding android project...
Creating Cordova project for the Android platform:
        Path: platforms\android
        Package: io.cordova.hellocordova
        Name: HelloCordova
        Activity: MainActivity
        Android target: android-29
Subproject Path: CordovaLib
Subproject Path: app
Android project created with cordova-android@9.0.0
Discovered plugin "cordova-plugin-whitelist". Adding it to the project
Installing "cordova-plugin-whitelist" for android
Adding cordova-plugin-whitelist to package.json

エミュレーターで実行

Android Studioの「Tools > AVD Manager」からAVDを構成します。
エミュレーターを実行し、エミュレーターが立ちあがったら下記コマンドを実行。

> cordova emulate android

ビルドが成功すれば、↓のようにエミュレーターでアプリの実行が確認できます。

image.png

ビルドログを見るとAPKファイルもできているのが確認できます。

実機で実行

Androidの実機端末をUSBで接続します。
端末側で開発者向けオプションを有効化し、USBデバッグをオンにしておきます。

> cordova run android

ビルドが成功すれば、実機にアプリがインストールされます。

iOSアプリの実行環境構築

こちらはMacで実施します。

事前準備

Xcode

入ってなければインストールしておきましょう。

プラットフォーム追加

$ cordova platform add ios
Using cordova-fetch for cordova-ios@^6.1.0
Adding ios project...
Creating Cordova project for the iOS platform:
    Path: platforms/ios
    Package: io.cordova.hellocordova
    Name: HelloCordova
iOS project created with cordova-ios@6.1.1
Installing "cordova-plugin-whitelist" for ios

エミュレーターで実行

$ cordova emulate ios

ビルドが成功すれば、↓のようにエミュレーターでアプリの実行が確認できます。

image.png

実機で実行

Xcodeにアカウントを登録しておきます。

実機にデプロイするために ios-deploy が必要なのでこれもインストールしておきます。

$ npm install ios-deploy-g 

USBでiPhoneを接続してコンピューターを信頼します。

MyApp/platforms/ios/HelloCordova.xcodeproj をXcodeで開きます。
アプリに署名し、左上のデバイス選択から接続したiPhoneを選択します。

.png

$ cordova run ios

ビルドが成功すれば、実機にアプリがインストールされます。
IPAファイルも作成されます。

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

部品を画面の中央に配置する方法

スクリーンショット 2020-09-22 14.12.52.png

(1)AutoLayoutの部分の左から2番目のアイコンをクリックします。
(2)以下2つにチェックをいれる
Horizontally in Container (cf. Horizontal 水平な)
Vertically in Container  (cf. Vertical 垂直な)
(3) 「Add 2 Constraints」をクリック
→これで自動的に部品が画面の中央に配置されます

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

[WIP][iOS] [Xcode] IntirinsicContentSizeがない部品とScrollViewの付き合い方

はじめに

WIPです。
この記事ではUIScrollViewをStoryboardで使用する際に、スクロールのコンテンツにUIStackViewが含まれる場合の実装例を紹介します。

抽象的にはUIScrollViewのコンテンツにIntrinsicContentSizeが無効なビューを含んでいる場合の解決策を紹介します。

環境

Xcode: 12
Swift: 5.3
MacOS: Catalina

結論

UIStackViewは固有サイズ(intirinsicContentSize)が設定されていないためスクロールビューのコンテンツの大きさが自動で決定されません。
なので、ScollViewがスクロールできる高さの制約を設定する必要があります。

この記事で分かること

  • UIScrollViewって何?
  • UIStackViewって何?
  • 固有サイズって何?

UIScrollViewって何?

コンテンツをスクロールやズームができるビューです。
スクロールビュー自体の大きさの他に、コンテントサイズ(contentSize)という表示するコンテンツの大きさが存在します。

なお、コンテンツサイズがスクロールビュー自体のサイズよりも小さい場合はスクロールできません。

余談ですが、UITableViewUICollectionViewUIScrollViewを継承しているため、スクロール可能なビューとなっています。

UIStackViewって何?

1列または1行に部品を並べることに特化した部品です。StackViewの中には子ビューを入れることができます。
子ビューの大きさによってサイズを変えたり、子ビューの並び方や揃え方を統一することができます。

詳細なStackViewについては当記事では説明しないのでこちらの記事などを別の記事を参考にしてください。

固有サイズって何?

固有サイズとはビュー自体が持つコンテンツの大きさのことです。

例えば、UILabelを例に出します。

下の画像のように画面の中央に配置されるように設定したUILabelがあります。

制約は以下の通りに設定されています。

このUILabelにはこんにちはという文字列が表示されています。
ここで、こんにちはこんにちはでしょうか、こんばんはでしょうか?に変えてみます。

コンテンツの横幅が大きくなったため、UILabelの横幅もコンテンツに合わせて自動で大きくなりました。
これが固有サイズ(intrinsicContentSize)です。

また、固有サイズを有効にするにはAutoLayoutを縦・横それぞれ1つずつ設定しておく必要があります。
一方で、UITableViewCell UICollectionViewCellのコンテンツを可変サイズにしたい場合は縦・横それぞれ2つの制約が固有サイズの他に必要です。

固有サイズを持つ/持たないについて

intirinsicContentSizeUIViewのプロパティですが、固有サイズを持つものと持たないものが存在します。
例えば、先ほどの例であげたUILabelは固有サイズを持ちますが、UIScrollViewは固有サイズを持ちません。

下に固有サイズを持つものと持たないものを比較したテーブルを用意しました。

固有サイズを持つ 固有サイズを持たない
UILabel(numberOfLines = 1 UILabel(numberOfLines ≠ 1
UIButton UIView
UIPickerView, UIDatePicker UIStackView
UIImageView(image ≠ nil) UIImageView(image = nil)
UITextField UIScrollView(UITableView, UICollectionViewも同様)
UITextView(Scroll不可) UITextView(Scroll可能)

UILabelUITextViewなど、プロパティの状態によってIntirinsicContentSizeを持つか持たないかが変わることがあります。

標準実装だと、上のようにクラスごとに決まった固有サイズの種類を持っていますが、クラスを継承することによって、固有サイズを応用することができます。

固有サイズをカスタマイズする方法

固有サイズはそのビュー自身のintirinsicContentSizeをオーバーライドすることでカスタマイズすることができます。

例えば、固有サイズを持たせないビューに対しては、UIView. noIntrinsicMetricをwidth/heightに指定します。

class NoIntrinsicLabel: UILabel {
    override var intrinsicContentSize: CGSize {
        CGSize(width: UIView.noIntrinsicMetric, height: UIView.noIntrinsicMetric)
    }
}

一方で、あまり有効な場面が考えられないですが、固有サイズをハードコーディングすることもできます。ただ、この場合は固有サイズを使用せずにHeight/Widthの制約としてNSLayoutConstraintを使用したほうが良いと考えます。

class StaticIntrinsicLabel: UILabel {
    override var intrinsicContentSize: CGSize {
        CGSize(width: 120, height:120)
    }
}

最後に

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

iOSDC2020に参加しました

はじめに

iOSDC2020が昨日無事終了しました。
今回の開催はニコニコ生放送での初のオンラインということで、どういう感じになるのだろうと思っていたのですが、グリーンバックを使っていたり、ニコ生のコメント機能でリアルとはまた違った感じで盛り上がる、家でリラックスしながら見れるなど、オンラインならではのいいところがたくさんあり、とても良かったです。

以下自分の気になったセッションを簡単にまとめていきます

気になったセッション

サムネイルをクリックすることでスピーカーの皆様が上げてくださったSpeakerDeck/SlideShareへ移動できます。

今日から分かるAVAudioEngineの全て

Day0/TrackA
スピーカー:meteorさん

thumbnail

meteorさんのトークでは
・iOSのAudio周りをあまりしらない方のためのAudioUnit/AVFoundationの解説
・実際のコードを例に挙げながらAVAudioEngineなどの基本的な使い方
・RMSの取得
WORLDを使ってボイスチェンジャーを実装して(ラッパーであるWorldInAppleのポイントを解説)みるという高度な話をされていました。

最後の方は完全にはついていけていなかったのですが、自分も現在音声処理のアプリの案件に携わっているので、とても復習になり、またmeteorさんのトークは録画感を感じさせず実際に生放送で話されているみたいで、いいセッションでした。

iOSリジェクト戦記 ~リジェクトされないための課金ページ~

Day1/TrackA
スピーカー:HiromuTsurutaさん

thumbnail

HiromuTsurutaさんのトークでは
・課金ページで守らなければいけないこと
・課金ページにはどういうタイプがあるのか
・注意文言/金額表記/無料表記で実際にリジェクトされたときの問題点/対策など
・いろいろなアプリの過去と今の課金ページの比較
・リジェクトを切り抜けるための回避策(グレーゾーン)
をわかりやすく説明されていました。

個人的にはAppleの課金ページでは無料を大きくして、値段を小さくしているのでガイドラインを守っていないというオチが面白かったです。
課金(サブスクリプション)ページのリジェクト理由など、深く観察されている+スライドの作り込みすごい+トークの上手さもあり、とても完成度が高いセッションだと思いました。

スピーカーのHiromuTsurutaさんが以前書かれたアプリアイコンについての記事もとても完成度が高くおすすめなのでぜひ興味のある方は読んでみてください

「アプリアイコン」を考察してみたお話

エラーアーキテクチャ設計について考えてみる

Day1/TrackD
スピーカー:きちえもんさん

thumbnail

きちえもんさんのトークでは
・iOSアプリでエラーハンドリングの改善
・Androidアプリでエラーハンドリングの改善
・エラーアーキテクチャ設計について
を話されていました。

iOSでのエラー処理では共感できるところが多く、またその解決法もenumを使うなどなるほどな〜と勉強になるところが多かったです。エラーアーキテクチャについてどのような姿を目指すかの中でユースケースについての説明の時に、ついてユーザーが異なる操作を行った/何か悪いことが起こったに焦点を当てた事を雨の日のシナリオという表現/喩えがとてもわかりやすく、スライドも綺麗に纏まっていて、とても見易かったです。
ユースケース駆動については初めて知ったので、自分でも調べていこうと思いました。

Github ActionsでiOSアプリをCIする個人的ベストプラクティス

Day1/TrackB
スピーカー:uhooiさん

thumbnail

uhooiさんのトークでは
前半に
・CI
・Make
・GitHub Actions
の説明を行い、後半に実際にHANDSON形式で行ってみるという形でした。

CI,Make,GitHub Actionsなどをuhooiさんの言葉/イラストでわかりやすく説明してくれており、HANDSONではGitHubActionsの導入を実際にやってみるという形で見せながらわかりやすく解説してくれていました。実際にトークをみながら導入を試していた方もいらっしゃったようです。
個人的にはスライドの途中で出てきた手書きイラストが味があって好きでした。

Swiftで始める静的解析

Day2/TrackD
スピーカー:まつじさん

thumbnail

まつじさんのセッションでは
・そもそも静的解析とは
・静的解析はどのように行われているのか
・実際にSwiftSyntaxを用いて、構文木を解析してみる。
についてお話しされていました。

自分はこのセッションを聞くまではソフトウェア工学をあまり知らず、静的解析についてもなんとなくSwiftLintをがあるということしかわかっていなかったのですが、このセッションで静的解析がどのような仕組みで行われているのかというトークを聞いていて、これはどうなんだ?と思った所を次の話でまつじさんが解説してくれて、静的解析への理解が深まるセッションでした。

テストコードが増えるとバグは減るのだろうか? - 「0% → 60.3%」で見えた世界の話

Day2/TrackD
スピーカー:ahirustarrrさん

thumbnail

ahirustarrrさんのセッションでは
・テスト実装に至る背景
・テストコードがなかったプロダクトにテストが実装されて、感じたメリット/デメリット
・組織開発体制に適したテスト手法
・テストが増えるとバグは減るのか
についてお話しされていました。

トークの背景、内容などがとても共感できる内容であるあると思いながらトークを聞いていました。
テスト導入に近い話は普段、他の会社の話はあまり聞くことがなかったので、とてもいい機会でした
テストを導入するメリット/デメリットを詳しく解説してくれていて、これからテスト導入しようかなという人にもみて欲しいなというセッションです。
Twitterでテストコードを書いた経験がないとどうテストを書けばいいのかわからない的な意見もみられ、自分もまだ浅い方なのでなるほどなと思いました。

イベントを通しての感想

他にも良かったセッションやまだ見れてないセッションはいくつもありますのでこの後視聴しようと思います。
気になったかたは後日YouTubeに動画が上がるそうなので視聴して、来年参加してみてはどうでしょうか?

運営スタッフの皆様、スピーカーの皆様ありがとうございました。

参考リンク

Qiitaの記事にSpeaker DeckやSlideShareのサムネ付きリンクを貼る方法

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

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がとても優秀なのでそれ使った方が良いと思います。
あくまで上記は小規模アプリとかで、ライブラリ入れなくても良いくらいの規模感のアプリなら、上記で対応しても良さそうに思いました。

読んでいただきありがとうございました!
もっと良い実装とか他何かありましたらコメントいただけたら涙が出るくらい喜びます!!

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