Madogiwa Blog

主に技術系の学習メモに使っていきます。

Swift4.2で画像アップロード周りの仕様が変わっててハマったのでメモ🎑

こんばんは、まどぎわです(・∀・)
最近、下記の本でiosアプリの勉強を軽くしてたのですが、Swiftの画像アップロード周りの実装仕様が書籍と自分の環境では変わっていて本の通りに書いても上手いこといかなかったので、やりかたをメモしておきます✍

作って学ぶ iPhoneアプリの教科書 【Swift4&Xcode 9対応】 ~人工知能アプリを作ってみよう! ~(特典PDF付き)

作って学ぶ iPhoneアプリの教科書 【Swift4&Xcode 9対応】 ~人工知能アプリを作ってみよう! ~(特典PDF付き)

前提

私の環境は、下記の通りです。

name version
xcode 10.1
swift 4.2.1

書籍のサンプル実装(Swift4想定)

最初に書いた書籍に記載されていたサンプルの実装を記載しました。概要としては、ボタン押下時に画像を選択して画面上のUIImageに反映するという機能です🙇‍♂️
info[UIImagePickerControllerOriginalImage]の部分でCannot subscript a value of type '[String : Any]' with an index of type 'UIImagePickerController.InfoKey'が発生して、上手く動かなかった。。。😢

import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
  @IBOutlet weak var myImageView: UIImageView!

  var imagePicker: UIImagePickerController!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    imagePicker = UIImagePickerController()
    imagePicker.delegate = self
  }
  
  @IBAction func tapButton(_ sender: Any) {
    imagePicker.sourceType = .photoLibrary
    present(imagePicker, animated: true, completion: nil)
  }
  
  func imagePickerController(
    _ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [String : Any]
  ) {
    imagePicker.dismiss(animated: true, completion: nil)
    // ERROR: Cannot subscript a value of type '[String : Any]' with an index of type 'UIImagePickerController.InfoKey'
    guard let image = info[UIImagePickerControllerOriginalImage] as? UIImage else {
      return
    }
    myImageView.image = image
  }
}

Swift4.2の実装

下記のように実装を変更したら上手く動くようになりました🙌
変更点は下記です。

  • imagePickerControllerの引数をinfo: [UIImagePickerController.InfoKey : Any]に変更
  • info[.originalImage]で選択した画像を取得するように変更
import UIKit

class ViewController: UIViewController, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
  @IBOutlet weak var myImageView: UIImageView!

  var imagePicker: UIImagePickerController!
  
  override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.
    imagePicker = UIImagePickerController()
    imagePicker.delegate = self
  }
  
  @IBAction func tapButton(_ sender: Any) {
    imagePicker.sourceType = .photoLibrary
    present(imagePicker, animated: true, completion: nil)
  }
  
  func imagePickerController(
    _ picker: UIImagePickerController,
    didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]
  ) {
    imagePicker.dismiss(animated: true, completion: nil)
    guard let image = info[.originalImage] as? UIImage else {
      return
    }
    myImageView.image = image
  }
}

どうやらSwift 4.2からUIImagePickerControllerの仕様が変わったみたいですね💦

参考資料

qrunch.net

developer.apple.com