iOSアプリ開発:内蔵カメラで写真を撮る【UIImagePickerController編】

実機で動かしてみたくなったのでXCodeを使ってみます。

環境

ProでもAirでもないMacBookです。 持ち運び楽チンのお気に入りマシンです。

X無印です。 最新ではないですが処理能力などに不満はありません。

  • j5 create JCH346(USBハブ)

USBハブです。MacBookとiPhoneXを同期しながら充電することができます。

高めの給電能力が必要な機器向けにTypeCのコネクタが一本出ています。 その他、USB3.1 TypeCのポートが2つ(1つは給電専用)、USB3.0 TypeAのポートが3つあります。

必要十分です。

アプリの仕様

前回Playgroundsで作成した、内蔵カメラを使ったアプリをiPhoneで動かします。

schagerl.hatenablog.com

プロジェクト

XCodeを起動してiOSのSingle View Appを選択して作成します。

ソースコード

ViewController.swiftファイルに前回作成したコードをコピペします。 ただし、以下のPlaygrounds向けコードは除きます。

import PlaygroundSupport
PlaygroundPage.current.liveView = ViewController()

以下コード全体です。

import UIKit

class ViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate  {
    var imagePicker: UIImagePickerController?
    var mainView: UIView?
    var button: UIButton?
    override func viewDidLoad() {
        createElements()
        setAnchorConstraint()
    }
    func createElements() {
        self.imagePicker = UIImagePickerController()
        self.mainView = UIView()
        self.button = UIButton()
        guard
            let mainView = self.mainView,
            let button = self.button else {
                return
        }
        button.backgroundColor = UIColor.magenta
        button.addTarget(self, action:#selector(self.buttonEvent(_:)), for: UIButton.Event.touchUpInside)
        mainView.addSubview(button)
        self.view = mainView
    }
    func setAnchorConstraint() {
        guard
            let mainView = self.view,
            let button = self.button else {
                return
        }
        button.translatesAutoresizingMaskIntoConstraints = false
        button.centerXAnchor.constraint(equalTo:mainView.centerXAnchor).isActive = true
        button.bottomAnchor.constraint(equalTo:mainView.bottomAnchor, constant: -100).isActive = true
        button.widthAnchor.constraint(equalToConstant:60).isActive = true
        button.heightAnchor.constraint(equalToConstant:30).isActive = true
    }
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        // 撮影結果から画像データを取り出す
        if let image = info[UIImagePickerController.InfoKey.originalImage] as? UIImage {
            // アルバムへ保存
            UIImageWriteToSavedPhotosAlbum(image, self, #selector(self.imageSavingEvent(_:didFinishSavingWithError:contextInfo:)), nil)
        }
        // 遷移元へ戻る
        picker.dismiss(animated:true, completion:nil)
    }
    // カメラを起動するボタンのイベント
    @objc func buttonEvent(_ sender: UIButton) {
        guard let imagePicker = self.imagePicker else {
            return
        }
        // UIImagePickerControllerの設定
        imagePicker.sourceType = UIImagePickerController.SourceType.camera
        // protocolを設定
        imagePicker.delegate = self
        // 画面遷移
        present(imagePicker, animated:true, completion:nil)
    }
    // 画像をライブラリに保存したときのイベント(エラーの場合も呼ばれる)
    @objc func imageSavingEvent(_ image: UIImage, didFinishSavingWithError error: Error?, contextInfo: UnsafeRawPointer) {
    }
}

画像保存の部分だけ少し書き換えましたが換えなくても動きます。

ユーザー許可

前回も書きましたが、実機でカメラやフォトライブラリを使用する場合はユーザーに許可を求める必要があります。 (ユーザー許可の設定がない場合にはアプリが落ちます)

設定する場所はXCodeのInfo.plistファイルです。 ファイルにキーを追加してメッセージを追加することでユーザー許可を求めることができます。

今回は以下2つの項目を追加する必要があります。

  • Privacy - Camera Usage Description

カメラ機能許可についてのメッセージです

  • Privacy - Photo Library Additions Usage Description

フォトライブラリへのデータ追加許可についてのメッセージです。

Information Property Listの右クリック(?)メニューのAdd Row で項目を追加し、許可を求める時に表示するメッセージを記入してください。

実行

MacBookiPhoneを接続して上にある再生ボタンを押せば実行できます。

iPhoneのロックを解除しておくとアプリが自動的に起動します。 が、初めて実行した場合は多分起動しません。

iPhone側の設定→一般→プロファイルとデバイス管理→デベロッパAPP に表示されるXCodeで使用しているアカウントを選択し、「"XXXX"を信頼」をタップしてください。

感想

Playgroundsでコーディングに慣れておくと、開発環境周り等に労力が必要でも余裕がありますね。

コーディング&開発環境で引っかかりポイントが一気にくるより断然楽です。