Swift,Objective-Cプログラミング ~ iOS ~

Objective-C,Swift,Apple Watchなどのプログラミング

【iOS Swift入門 #310】enumですべてのcaseを返す方法

はじめに

enumのすべてのcaseを返したい場合があります。Swift4.1までの場合、そのためのメソッドやプロパティを作成して対応していました。

下記の例のように実装していました。

import Foundation

enum Device {
    case iPhoneXr
    case iPhoneXs
    case iPhoneXsMax
    
    static var all: [Device] {
        return [
            .iPhoneXs, .iPhoneXs, .iPhoneXsMax
        ]
    }
}

for phone in Device.all {
    print(phone)
}

その問題点は、caseを追加した時に、そのメソッドやプロパティにも追加しないといけないことが漏れてしまい不具合が発生してしまうことでした。

不具合を含んだままリリースすることはなかったとしても、ソースレビューで指摘されたりなどしていました。

CaseIterableプロトコル

Swift4.2になり、CaseIterableプロトコルが提供され、採用していれば、allCasesプロパティで全てのcaseが返されます。

使い方は下記の例の通りです。

import Foundation

enum Device: CaseIterable {
    case iPhoneXr
    case iPhoneXs
    case iPhoneXsMax
}

for phone in Device.allCases {
    print(phone)
}

Swift4.2でのうれしい更新です。

【iOS Swift入門 #309】Instrumentsを使ったFPSの計測

はじめに

iOSのUITableViewやUICollectionView、UIScrollViewを使っているアプリで素早くスクロールしたときにスクロールがゆっくりになったり、一瞬固まったようになることがあります。これはメインスレッドでの処理が多くなっていることが原因であることが多いです。一般的には60FPS以上であれば快適にスクロールできます。スクロールがゆっくりになったり、固まるときには60FPSをだいぶ下回っています。

FPSの計測

Xcode付属のInstrumentsを使います。 Instrumetsは[Xcode] - [Open Developer Tool] - [Instruments]で開けます。

f:id:fjswkun:20180919152033p:plain

Instruments起動時の画面でCore Animationを開きます。 計測に使用するデバイスと計測するアプリを選択し、赤丸のボタンをタップすると計測が開始されます。

f:id:fjswkun:20180919152057p:plain

結果はこのように表示されます。

f:id:fjswkun:20180919152125p:plain

Healthデータのアクセス権限チェック

Healthデータのアクセス権限の取得

iOSではHealthデータのアクセス権限の取得にはHKHealthStoreクラスのrequestAuthorization(toShare:read:completion:)メソッドを使います。 Healthデータに書込する権限を取得する場合にはtoShare引数、また、読込権限を取得する場合にはread引数にデータタイプを指定します。

Healthデータへのアクセス権限チェック

書込や読込をする場合、まずはアクセス権限があるのかチェックした後で、実行するというように実装することがあると思います。

HealthKitではアクセス権限チェックのため、HKHealthStoreクラスにauthorizationStatus(for:)メソッドが用意されています。

結果はHKAuthorizationStatus列挙型で返ってきます。

  • notDetermined
  • sharingDenied
  • sharingAuthorized

Healthデータへのアクセス権限チェックの注意点

アクセス権限チェックする際の注意なのですが、上記authorizationStatus(for:)メソッドは下記3つの状態しかチェックできません。

  • まだ許可も拒否もしていない(notDetermined)
  • 書込権限と読込権限の片方しか許可していない(sharingDenied)
  • 書込権限と読込権限の両方を許可しているか(sharingAuthorized)

注意すべきは書込権限だけ許可されている、読込権限だけ許可されているというのがチェックできないことです。

Healthデータの読込が必要なアプリについて

ユーザーに読込権限だけを許可してもらい、authorizationStatus(for:)メソッドを実行した場合、常にsharingDeniedが返されます。authorizationStatus(for:)メソッドでは権限があるのかチェックできないのです。

もし権限がない状態でデータフェッチした場合、どうなるのか?その場合、エラー等発生せず、空配列が返されます。そのため、データが無いのか、権限がないのか区別できません。

Healthデータの読込だけが必要なアプリでの権限チェック対応

下記2つの対応が考えました。他にもあるかもしれません。

  • 対応方法としてはデータフェッチして空配列が返されたら、「権限拒否していませんか?」というアラートなどを表示して、設定画面に遷移させる
  • 読込権限だけが必要であっても、ユーザーに書込権限も許可してもらう。その上で、HKAuthorizationStatusを使って権限チェックする。(必要がない書込権限をユーザーに求めることになるので、AppStoreの審査に通るかは不明です)

Healthデータの書き込みが必要なアプリについて

調べていません。必要になったら調べます。

【iOS Swift入門 #308】パフォーマンス・実行速度改善のために処理時間を計測する

はじめに

大量のデータを扱う場合、パフォーマンス・実行速度が遅く、原因追求のために処理時間を計測することがあります。

自分は今まで処理前と処理後にNSDateを取得し、計測していました。

でも、ずっと前にXCTestで処理時間計測のための機能が追加されていることに気づきました。

処理時間計測のメソッド

XCTestフレームワークのXCTestCaseクラスのメソッドとして実装されています。 下記2つのメソッドです。

  1. measureBlock:
  2. measureMetrics:automaticallyStartMeasuring:forBlock:

ブロック内に書いた処理の処理時間を計測してくれます。2つ目のmeasureMetrics:automaticallyStartMeasuring:forBlock:を使うと、計測の開始と終了を指定することができます。

サンプル

実装

ViewControllerに指定した回数ループするメソッドを作りました。

import UIKit

class ViewController: UIViewController {
    func loop(_ times: UInt) {
        for _ in 0..<times {
            let _ = Date()
        }
    }
}

このメソッドの処理時間をXCTestで計測します。

import XCTest
@testable import SampleCalculatePerformance

class SampleCalculatePerformanceTests: XCTestCase {
    // 単純にブロック内の処理の時間を計測
    func testCalculatePerformance() {
        measure {
            let viewController = ViewController()
            viewController.loop(100000)
        }
    }
    
    // 計測対象からViewControllerの初期化を除外する
    func testCalculatePerfomanceManual() {
        measureMetrics([.wallClockTime], automaticallyStartMeasuring: false) {
            let viewController = ViewController()
            
            startMeasuring()
            viewController.loop(500000)
            stopMeasuring()
        }
    }
}

結果

XCTestのテストを実行しました。結果は下記のスクリーンショットの通りとなります。

f:id:fjswkun:20180212123331p:plain

サンプルのダウンロード

Google Driveに保存しています。

SampleCalculatePerformance.zip - Google ドライブ

Swift

入門書籍

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第5版
プログラミングが初めて!という人が小さなアプリを作ることで、アプリ開発を学ぶことができます。
「Swiftだけでなく、プログラミング自体が初めてなんだけど、どの本が良い?」と聞かれたときには、
この書籍をおすすめしています。

本気ではじめるiPhoneアプリ作り Xcode 8.x+Swift 3.x対応 (ヤフー黒帯シリーズ)
アプリ開発からApp Storeへの公開までの一通りを学ぶことができます。
入門書を2冊、3冊を読んだあとでこの書籍を読むとかなりの実力アップを感じることができます。

ただし、一通り学ぶことができますが、プログラミング初めてでこの書籍を選ぶことはオススメできません。
最初の方の内容はプログラミング初心者には理解が難しく、そこで勉強をやめてしまう可能性がありそうだと感じます。

Swiftポケットリファレンス
辞書として1冊は持ってても良い。

仕事でやれるレベルになるために

初心者から仕事でやれるレベルになるためにオススメできる日本語書籍がみつかりませんでした。
英語は苦手でも、書籍に書かれているソースはやさしく、読み進めることができます。

The iOS Apprentice (英語サイト・英語書籍)
Swift Apprentice (英語サイト・英語書籍)

平均的プログラマーを超えるために

詳解Swift 第3版
Swift3の書籍。第1版、第2版にもお世話になっています。
Swiftの文法についてとても詳しく書いてあります。

Ray Wenderlich | Tutorials for iPhone / iOS Developers and Gamers
QiitaのSwiftに関する記事

【iOS Swift入門 #307】Viewの一部の角だけを角丸にする

はじめに

iOS11からViewの一部の角だけを角丸にすることができるようになった。今までは、一部の角だけを角丸にしようとすると、CALayerをいろいろ操作して作る必要があった。面倒なので、画像を作って対応してしまうこともあったと思います。

Viewの一部の角だけを角丸にする

CALayerにmaskedCornersプロパティが追加されました。CACornerMaskの配列を設定することができます。CACornerMaskは下記4つが用意されています。

CACornerMask

  • layerMaxXMaxYCorner 右下の角
  • layerMaxXMinYCorner 右上の角
  • layerMinXMaxYCorner 左下の角
  • layerMinXMinYCorner 左上の角

例えば、下記のように設定します。

// 右上の角と左上の角を丸くする
subview.layer.cornerRadius = 50
subview.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]

サンプル

実際に使ってます。 Single Page Viewでプロジェクトを作成し、角丸のサブビューを画面に追加します。追加はviewDidLoadメソッドの中に追加しました。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        view.backgroundColor = UIColor.darkGray
    
        let subview = UIView(frame: CGRect(origin: CGPoint.zero, size: CGSize(width: 100, height: 100)))
        subview.center = view.center
        subview.backgroundColor = UIColor.yellow
        
        // 右上の角と左上の角を丸くする
        subview.layer.cornerRadius = 50
        subview.layer.maskedCorners = [.layerMaxXMinYCorner, .layerMinXMinYCorner]
        
        view.addSubview(subview)
    }
}

実行すると下記の画面が表示されます。 f:id:fjswkun:20180127130201p:plain

サンプルダウンロード

下記のリンクからダウンロードできます。

SamplePartialCornerRadius.zip - Google ドライブ

Swift

入門書籍

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第5版
プログラミングが初めて!という人が小さなアプリを作ることで、アプリ開発を学ぶことができます。
「Swiftだけでなく、プログラミング自体が初めてなんだけど、どの本が良い?」と聞かれたときには、
この書籍をおすすめしています。

本気ではじめるiPhoneアプリ作り Xcode 8.x+Swift 3.x対応 (ヤフー黒帯シリーズ)
アプリ開発からApp Storeへの公開までの一通りを学ぶことができます。
入門書を2冊、3冊を読んだあとでこの書籍を読むとかなりの実力アップを感じることができます。

ただし、一通り学ぶことができますが、プログラミング初めてでこの書籍を選ぶことはオススメできません。
最初の方の内容はプログラミング初心者には理解が難しく、そこで勉強をやめてしまう可能性がありそうだと感じます。

Swiftポケットリファレンス
辞書として1冊は持ってても良い。

仕事でやれるレベルになるために

初心者から仕事でやれるレベルになるためにオススメできる日本語書籍がみつかりませんでした。
英語は苦手でも、書籍に書かれているソースはやさしく、読み進めることができます。

The iOS Apprentice (英語サイト・英語書籍)
Swift Apprentice (英語サイト・英語書籍)

平均的プログラマーを超えるために

詳解Swift 第3版
Swift3の書籍。第1版、第2版にもお世話になっています。
Swiftの文法についてとても詳しく書いてあります。

Ray Wenderlich | Tutorials for iPhone / iOS Developers and Gamers
QiitaのSwiftに関する記事

【iOS Swift入門 #306】ライトニングケーブルが無くても実機でビルドできるようになった(Xcode9、ワイヤレスビルド)

はじめに

Xcode9でライトニングケーブルが無くても実機でビルドできるようになりました。Wifiで同じネットワークに接続して入ればビルドできます。つまり、ワイヤレスでビルドできるようになったということです。これで開発作業のためにライトニングケーブルを持ち歩く必要がなくなりました。

準備

ただし、初回はライトニングケーブルで実機をつなぎ、設定をしてあげる必要があります。

  1. 実機をMacとライトニングケーブルでつなぎます

  2. Xcodeの[Window] - [Devices and Simulators]を開きます f:id:fjswkun:20171222175641p:plain

  3. 接続している実機を選択し、[connect via network]にチェックをいれます f:id:fjswkun:20171222175804p:plain

これでライトニングケーブルなしで、Wifi経由でビルドできます。 ビルドする実機(or シミュレータ)を選択するところで、ワイヤレスを表すマークが表示されます。

f:id:fjswkun:20171222180803p:plain

Swift

入門書籍

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第5版
プログラミングが初めて!という人が小さなアプリを作ることで、アプリ開発を学ぶことができます。
「Swiftだけでなく、プログラミング自体が初めてなんだけど、どの本が良い?」と聞かれたときには、
この書籍をおすすめしています。

本気ではじめるiPhoneアプリ作り Xcode 8.x+Swift 3.x対応 (ヤフー黒帯シリーズ)
アプリ開発からApp Storeへの公開までの一通りを学ぶことができます。
入門書を2冊、3冊を読んだあとでこの書籍を読むとかなりの実力アップを感じることができます。

ただし、一通り学ぶことができますが、プログラミング初めてでこの書籍を選ぶことはオススメできません。
最初の方の内容はプログラミング初心者には理解が難しく、そこで勉強をやめてしまう可能性がありそうだと感じます。

Swiftポケットリファレンス
辞書として1冊は持ってても良い。

仕事でやれるレベルになるために

初心者から仕事でやれるレベルになるためにオススメできる日本語書籍がみつかりませんでした。
英語は苦手でも、書籍に書かれているソースはやさしく、読み進めることができます。

The iOS Apprentice (英語サイト・英語書籍)
Swift Apprentice (英語サイト・英語書籍)

平均的プログラマーを超えるために

詳解Swift 第3版
Swift3の書籍。第1版、第2版にもお世話になっています。
Swiftの文法についてとても詳しく書いてあります。

Ray Wenderlich | Tutorials for iPhone / iOS Developers and Gamers
QiitaのSwiftに関する記事

【iOS Swift入門 #305】アプリ独自の色(Color)定義をAssetCatalogで管理する

はじめに

Xcode9になり、色の定義をAssetCatalogで管理できるようになりました。

これにより以下のメリットがあります。

  • 色定義の管理方法の選択肢が増えた
  • どのような色なのか一目でわかります

どのような色なのか一目でわかるという点についての補足

Asset Catalog上の表示

f:id:fjswkun:20171210123319p:plain

StoryboardやXIBファイルで色のプロパティを設定するときに選択肢に表示されます

f:id:fjswkun:20171210123513p:plain

実装例

  1. AssetCatalogにColor Setを追加します f:id:fjswkun:20171210122927p:plain

  2. 色を定義します f:id:fjswkun:20171210123052p:plain

  3. 色を使う UIColor(named:)で初期化して使います。
    ナビゲーションバーの色に使ってみました。

import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.navigationController?.navigationBar.barTintColor = UIColor(named: "appBlue")
    }
}

また、Storyboardで指定することもできます。 f:id:fjswkun:20171210124617p:plain

  1. 結果を確認する f:id:fjswkun:20171210123858p:plain

注意

UIColor(named:)で初期化する際に引数に色定義の名前文字列で指定します。指定が間違っていた場合、nilとなります。色定義の名前はenumで管理し、実装時に間違えないようにするなどの工夫は必要です。

また、depoyment targetが11.0以上でなければなりません。

Swift

入門書籍

絶対に挫折しない iPhoneアプリ開発「超」入門 増補改訂第5版
プログラミングが初めて!という人が小さなアプリを作ることで、アプリ開発を学ぶことができます。
「Swiftだけでなく、プログラミング自体が初めてなんだけど、どの本が良い?」と聞かれたときには、
この書籍をおすすめしています。

本気ではじめるiPhoneアプリ作り Xcode 8.x+Swift 3.x対応 (ヤフー黒帯シリーズ)
アプリ開発からApp Storeへの公開までの一通りを学ぶことができます。
入門書を2冊、3冊を読んだあとでこの書籍を読むとかなりの実力アップを感じることができます。

ただし、一通り学ぶことができますが、プログラミング初めてでこの書籍を選ぶことはオススメできません。
最初の方の内容はプログラミング初心者には理解が難しく、そこで勉強をやめてしまう可能性がありそうだと感じます。

Swiftポケットリファレンス
辞書として1冊は持ってても良い。

仕事でやれるレベルになるために

初心者から仕事でやれるレベルになるためにオススメできる日本語書籍がみつかりませんでした。
英語は苦手でも、書籍に書かれているソースはやさしく、読み進めることができます。

The iOS Apprentice (英語サイト・英語書籍)
Swift Apprentice (英語サイト・英語書籍)

平均的プログラマーを超えるために

詳解Swift 第3版
Swift3の書籍。第1版、第2版にもお世話になっています。
Swiftの文法についてとても詳しく書いてあります。

Ray Wenderlich | Tutorials for iPhone / iOS Developers and Gamers
QiitaのSwiftに関する記事