How enumerate work when we get image from PHAsset.? (Swift)

2.8k Views Asked by At

I try to understand "enumerate" to get image from PHAsset. This is a sample code from a book (which allow any one to use). I added println to show the lines of what I though it would shown up as loop but surprised me it return result at the end. Question why the line number 2 came out the last as result from this code instead of 1,2,3,4. Would be appreciated if anyone can explain.

enumerateObjectsUsingBlock result

And here the source code:

//
//  ViewController.swift
//  Searching for and Retrieving Images and Videos
//
//  Created by Vandad Nahavandipoor on 7/10/14.
//  Copyright (c) 2014 Pixolity Ltd. All rights reserved.
//
//  These example codes are written for O'Reilly's iOS 8 Swift Programming Cookbook
//  If you use these solutions in your apps, you can give attribution to
//  Vandad Nahavandipoor for his work. Feel free to visit my blog
//  at http://vandadnp.wordpress.com for daily tips and tricks in Swift
//  and Objective-C and various other programming languages.
//
//  You can purchase "iOS 8 Swift Programming Cookbook" from
//  the following URL:
//  http://shop.oreilly.com/product/0636920034254.do
//  If you have any questions, you can contact me directly
//  at [email protected]
//  Similarly, if you find an error in these sample codes, simply
//  report them to O'Reilly at the following URL:
//  http://www.oreilly.com/catalog/errata.csp?isbn=0636920034254

import UIKit
import Photos

class ViewController: UIViewController {

/* Just a little method to help us display alert dialogs to the user */
/* But once it's get ok from the device, the message will never shown up again !*/

func displayAlertWithTitle(title: String, message: String){
    let controller = UIAlertController(title: title,
        message: message,
        preferredStyle: .Alert)

    controller.addAction(UIAlertAction(title: "OK",
        style: .Default,
        handler: nil))

    presentViewController(controller, animated: true, completion: nil)

}

override func viewDidAppear(animated: Bool) {

    super.viewDidAppear(animated)

    PHPhotoLibrary.requestAuthorization{
        [weak self](status: PHAuthorizationStatus) in

        dispatch_async(dispatch_get_main_queue(), {

            switch status{
            case .Authorized:
                self!.retrieveImage()
            default:
                self!.displayAlertWithTitle("Access",
                    message: "I could not access the photo library")
            }
        })

    }

}

func retrieveImage() {
    super.viewDidLoad()

    /* Retrieve the items in order of modification date, ascending */
    let options = PHFetchOptions()
    options.sortDescriptors = [NSSortDescriptor(key: "modificationDate",
        ascending: true)]

    /* Then get an object of type PHFetchResult that will contain
    all our image assets */
    let assetResults = PHAsset.fetchAssetsWithMediaType(.Image,
        options: options)

    if assetResults == nil{
        println("Found no results")
        return
    } else {
        println("Found \(assetResults.count) results")
    }

    let imageManager = PHCachingImageManager()

    assetResults.enumerateObjectsUsingBlock{(object: AnyObject!,
        count: Int,
        stop: UnsafeMutablePointer<ObjCBool>) in

        if object is PHAsset{How
            let asset = object as PHAsset
            println("Inside  If object is PHAsset, This is number 1")

            let imageSize = CGSize(width: asset.pixelWidth,
                height: asset.pixelHeight)

            /* For faster performance, and maybe degraded image */
            let options = PHImageRequestOptions()
            options.deliveryMode = .FastFormat

            imageManager.requestImageForAsset(asset,
                targetSize: imageSize,
                contentMode: .AspectFill,
                options: options,
                resultHandler: {(image: UIImage!,
                    info: [NSObject : AnyObject]!) in

                    /* The image is now available to us */

                    println("enum for image, This is number 2")


            })

            println("Inside  If object is PHAsset, This is number 3")
        }
        println("Outside If object is PHAsset, This is number 4")

    }

  }

}
1

There are 1 best solutions below

3
linimin On BEST ANSWER

Because requestImageForAsset executes asynchronously by default, and the resultHandler is queued on main thread. These queued result handlers will not be executed until your enumeration is completed.