CollectionViewを使って動画キャプチャーを作ってみる（２）


![collectionViewSample.gif](https://qiita-image-store.s3.amazonaws.com/0/40693/4fb31f85-14bc-317a-05b3-5d17cfb24079.gif "collectionViewSample.gif")


iPhoneで撮った写真や動画を操作するにはPhotos Frameworkを使うのですが、アップルが理想的なサンプルを用意してくれています。


[Example app using Photos framework](https://developer.apple.com/library/ios/samplecode/UsingPhotosFramework/Introduction/Intro.html)

Objective-Cで書かれているのでそれをswiftに変えて欲しいところだけ抽出。
正直、何やってんの？ってところもありましたが考えるより先に実装。

```
import Photos

class GridViewController: UICollectionViewController, PHPhotoLibraryChangeObserver {
  
```
Photsライブラリをimportし、写真の追加や削除を感知するPHPhotoLibraryChangeObserverを追加。


```
override func awakeFromNib() {
	let smartAlbums = PHAssetCollection.fetchAssetCollectionsWithType(PHAssetCollectionType.SmartAlbum, subtype: PHAssetCollectionSubtype.SmartAlbumVideos, options: nil)
	        
	let collection : PHCollection = smartAlbums[0] as! PHCollection
	assetCollection  = collection as! PHAssetCollection
	assetsFetchResults = PHAsset.fetchAssetsInAssetCollection(assetCollection, options: nil)
	
	self.collectionView?.backgroundColor = UIColor.whiteColor()
	imageManager = PHCachingImageManager()
	PHPhotoLibrary.sharedPhotoLibrary().registerChangeObserver(self)
}

deinit {
    PHPhotoLibrary.sharedPhotoLibrary().unregisterChangeObserver(self)
}

```

写真フォルダから動画をサブタイプで指定して取得。
ついでにオブサーバーの登録と解除もここに書いておく。

```
    override func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
        let asset : PHAsset = assetsFetchResults[indexPath.item] as! PHAsset
        
        let cell = collectionView.dequeueReusableCellWithReuseIdentifier("cell", forIndexPath: indexPath) as! CustomCell
        cell.representedAssetIdentifier = asset.localIdentifier
        
        imageManager.requestImageForAsset(asset,
            targetSize:CGSizeMake(80, 80),
            contentMode: PHImageContentMode.AspectFill,
            options: nil) { (result, info) -> Void in
                if(cell.representedAssetIdentifier == asset.localIdentifier){
                    cell.imageView.image = result
                }
        }
        
        return cell
    }
```

セルに画像をセットする箇所。PHCachingImageManagerというのが画像を表示用に編集してる箇所。
どうでもいいけどObjective-Cのブロックをswiftに書き換えるのは普段あまり使わない事もあって妙に難しい。慣れの問題だと思うけど。


```

    func photoLibraryDidChange(changeInstance: PHChange) {
            if let collectionChanges = changeInstance.changeDetailsForFetchResult(self.assetsFetchResults) {
            dispatch_async(dispatch_get_main_queue(), {
                self.assetsFetchResults = collectionChanges.fetchResultAfterChanges
                
                let collectionView : UICollectionView = self.collectionView!
                
                if(!(collectionChanges.hasIncrementalChanges) || (collectionChanges.hasMoves)){
                    collectionView.reloadData()
                } else {
                    
                    collectionView.performBatchUpdates({ () -> Void in
                        if (collectionChanges.removedIndexes != nil) {
                            let removedIndexes : NSIndexSet = collectionChanges.removedIndexes!
                            if(removedIndexes.count > 0){
                                collectionView.deleteItemsAtIndexPaths(removedIndexes.aapl_indexPathsFromIndexesWithSection(0) as! [NSIndexPath])
                            }
                        }
                        
                        if(collectionChanges.insertedIndexes != nil){
                            let insertedIndexes : NSIndexSet = collectionChanges.insertedIndexes!
                            if(insertedIndexes.count > 0){
                                collectionView.insertItemsAtIndexPaths(insertedIndexes.aapl_indexPathsFromIndexesWithSection(0) as! [NSIndexPath])
                            }
                        }
                        
                        if(collectionChanges.changedIndexes != nil) {
                            let changedIndexes = collectionChanges.changedIndexes!
                            if(changedIndexes.count > 0){
                                collectionView.reloadItemsAtIndexPaths(changedIndexes.aapl_indexPathsFromIndexesWithSection(0) as! [NSIndexPath])
                            }
                        }
                        }, completion: nil)
                }
            })
            
        } else {
            return
        }
    }
```

写真で動きがあったら呼び出されるメソッド。この場合は動画だけど。増えたり減ったり変化したりしたらその都度コレクションビューを再表示して最新を表示する・・・けど削除した場合、してないものまで表示されなくなったりするのでなんかおかしいのかも。
ちなみにchangedIndexes.aapl_indexPathsFromIndexesWithSectionはサンプルではカテゴリで追加してたメソッドだけどSwiftはextensionで実装。

```
extension NSIndexSet {
    func aapl_indexPathsFromIndexesWithSection(section : Int) -> NSArray{
        let indexPaths : NSMutableArray = NSMutableArray(capacity: self.count)
        self.enumerateIndexesUsingBlock { (idx, stop) -> Void in
            indexPaths.addObject(NSIndexPath(forItem: idx, inSection: section))
        }
        return indexPaths
    }
}
```

他は省略。とりあえず動かすだけならこれくらいで十分。これを前回のサンプルとくっつければとりあえずやりたい事は実現出来ました。個人的にはあってもいい機能ですが、アプリにする程の需要はなさそうかな・・・