SwiftでDocumentsディレクトリ内の画像が本当に読めないのか試してみた


## はじめに

先日Twitterを眺めていたら、ふと気になる記事がアップされていました。

<blockquote class="twitter-tweet" lang="ja"><p>【swift】swiftでは実機でデバイスに保存した画像が表示されない - Documentsディレクトリ内の画像を読み込む方法【CoffeeNote開発日記】 - とつろぐ <a href="http://t.co/9xSKWuUxex">http://t.co/9xSKWuUxex</a> <a href="https://twitter.com/hashtag/iPhone%E3%82%A2%E3%83%97%E3%83%AA%E9%96%8B%E7%99%BA?src=hash">#iPhoneアプリ開発</a></p>&mdash; iOS Dev Bot※Swift対応済 (@ios_dev_bot) <a href="https://twitter.com/ios_dev_bot/status/523678464612634624">2014, 10月 19</a></blockquote> <script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>


これほんとー？？
...と疑っていたのですが、何せブログ記事主の方への連絡方法が一切分からなかったので、こちらで適当に検証してみることにしました。

* Xcode 6.0.1
* iPad3 (iOS 8.0.2)
* iPad Air (iOS 7.1.2)
* iPhone6 Plus (iOS 8.0.2)

## 検証用の雑なコード

※エラーチェック等、全くやっていません。

```swift:
import UIKit

class CameraTestViewController: UIViewController, UIImagePickerControllerDelegate, UINavigationControllerDelegate {

    /// 画像ファイルの保存先パスを生成します（ドキュメントフォルダ直下固定）。
    var imagePath: String {
        let doc = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
        return doc.stringByAppendingPathComponent("img1.jpg")
    }
    
    override func loadView() {
        super.loadView()
        
        addButton("Camera and Save", frame: CGRectMake(0, 0, 200, 100), sel: "cameraAndSave")
        addButton("Load Image", frame: CGRectMake(200, 0, 200, 100), sel: "loadImage")
    }
    
    /// ボタンを生成します。
    private func addButton(title: String, frame: CGRect, sel: Selector) {
        var btn = UIButton.buttonWithType(.System) as UIButton
        btn.frame = frame
        btn.exclusiveTouch = true
        btn.setTitle(title, forState: .Normal)
        btn.addTarget(self, action: sel, forControlEvents: .TouchUpInside)
        btn.layer.borderColor = UIColor.blackColor().CGColor
        btn.layer.borderWidth = 1
        self.view.addSubview(btn)
    }
    
    /// カメラ撮影ボタンが押された時に呼ばれます。
    func cameraAndSave() {
        let picker = UIImagePickerController()
        picker.delegate = self
        picker.sourceType = .Camera
        presentViewController(picker, animated: true, completion: nil)
    }
    
    /// 画像読み込みボタンが押された時に呼ばれます。
    func loadImage() {
        let image = UIImage(contentsOfFile: imagePath)
        
        // 適当に表示します。
        let imageView = UIImageView(image: image)
        imageView.frame = CGRectMake(0, 150, 400, 400)
        self.view .addSubview(imageView)
    }
    
    // MARK: - UIImagePickerControllerDelegate
    
    /// カメラで写真を撮ってUse Photoボタンをタップされた後で呼ばれます。
    func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [NSObject : AnyObject]) {
        picker.dismissViewControllerAnimated(true, completion: nil)
        let image = info[UIImagePickerControllerOriginalImage] as UIImage
        let data = UIImageJPEGRepresentation(image, 0.9)
        data.writeToFile(imagePath, atomically: true)
        println("save: \(imagePath)")
    }
}
```

## 実行結果

1. 起動直後：
![IMG_0028.PNG](https://qiita-image-store.s3.amazonaws.com/0/31347/45f52cf7-31d8-ee4b-8718-bab229e3d163.png "IMG_0028.PNG")

2. Camera and Saveボタンタップ後：
![IMG_0029.PNG](https://qiita-image-store.s3.amazonaws.com/0/31347/54bd823f-4f49-74df-f372-45eb7a26fba0.png "IMG_0029.PNG")

3. 撮影ボタンタップ
ログに保存先パスを出力していますが、ドキュメントフォルダ直下を指し示しています。
`
save: /var/mobile/Applications/(省略)/Documents/img1.jpg
`


4. Load Imageボタンタップ後：
![IMG_0030.PNG](https://qiita-image-store.s3.amazonaws.com/0/31347/ce456593-77bd-2b6f-d7cb-d95bac6a9d6c.png "IMG_0030.PNG")
(UIImageViewのアス比の設定するの忘れてました)

ちゃんと読めていますね。

## 終わりに

iPadとiPhone両方で試しましたが、Swiftでも実機に写真を保存したり、それを読み込んだりということは問題なく動作しているように見えます。
少なくとも私の環境下では正常に動作しています。

もし特定の条件下で画像のロードに失敗するケースが本当にあるのでしたら、情報提供していただけると助かります。