9

I have an app that creates a unique photo gallery for each ticket on my app. I need to figure out how to loop through that gallery so I can upload the images to the server one at a time. I followed these tutorials on youtube. (Video) I am currently using Swift as my language. my ultimate goal would be to have something like the following pseudo code.

//I need the following for loop example
for photo in gallery
{
    uploadToServer(photo)
}

//this function works already

func uploadToServer(photo:UIImage)
{
    callRest
    postPhoto
}

here is my code so far cannot figure out how to loop through. them though.

let fetchOptions = PHFetchOptions()
fetchOptions.predicate = NSPredicate(format: "title = %@", self.albumName)?
let collection:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)

if let first_Obj:AnyObject = collection.firstObject{
    //found the album
    self.assetCollection = collection.firstObject as PHAssetCollection
    self.albumFound = true
}
else { albumFound = false }
var i = collection.count
self.photoAssets = PHAsset.fetchAssetsInAssetCollection(self.assetCollection, options: nil)


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

    if object is PHAsset{
        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, info)->Void in

                self.photo = image

                var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
                var server = defaults.objectForKey("imageServer") as String!
                var error: NSError? = nil

                var imageData = UIImageJPEGRepresentation(self.photo, 90)
                var url = NSURL(string: server)
                var request = NSMutableURLRequest(URL: url!)
                request.HTTPMethod = "POST"
                //request.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
                request.HTTPBody = imageData

                var response: NSURLResponse? = nil

                let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)

                let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
                println("API Response: \(results)")

                /*
                /* The image is now available to us */
                self.sendPhotos(image)
                println("enum for image, This is number 2")*/


        })
    }
}
Spikehockey75
  • 211
  • 1
  • 2
  • 6
  • Go right ahead. What's the hard part? – matt Mar 05 '15 at 19:08
  • I am having trouble of what to loop through, I am new to swift and iOS devlopment. I tried looping through my PHAssetCollection, wont let me so I tried looping throught my PHFetchResults same thing. Im not sure how the photos framework works. – Spikehockey75 Mar 05 '15 at 19:22
  • Did you watch the WWDC video about the Photos framework? It's pretty straightforward. – matt Mar 05 '15 at 21:39
  • I did watch the video, and again just now. It does not explain how to loop through images as if they are an array. At least i do not undertand how i can "fetch" them. I will add to my post with my code – Spikehockey75 Mar 05 '15 at 23:03
  • @matt After some research I came up with the above code using enumerateObjectsUsingBlock it seems to be working fine, but it is getting nil for the image data. Did I miss something? Thank you – Spikehockey75 Mar 06 '15 at 17:11
  • Your implementation of `requestImageForAsset` is madness. Keep in mind that the `resultHandler` is called (1) asynchronously and (2) multiple times for each image. Again, _watch the video_. They talk all about this. - Please note that your question has now completely morphed; you're asking something completely different now. – matt Mar 06 '15 at 17:44

2 Answers2

10

So after some research and guidance from Matt I have figured it out. Here is how to do this. Make sure you execute this on the main thread as well so you have to set the options.synchronous = true. If not for some reason it does not have any value for the photos.

func getSyncPhotos()
{
    self.albumName = String(self.ticket_id!)

    let fetchOptions = PHFetchOptions()
    fetchOptions.predicate = NSPredicate(format: "title = %@", self.albumName)?
    let collection:PHFetchResult = PHAssetCollection.fetchAssetCollectionsWithType(.Album, subtype: .Any, options: fetchOptions)

    if let first_Obj:AnyObject = collection.firstObject{
        //found the album
        self.assetCollection = collection.firstObject as PHAssetCollection
        self.albumFound = true
    }
    else { albumFound = false }
    var i = collection.count
    self.photoAssets = PHAsset.fetchAssetsInAssetCollection(self.assetCollection, options: nil)
    let imageManager = PHCachingImageManager()

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

        if object is PHAsset{
            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
            options.synchronous = true
            imageManager.requestImageForAsset(asset,
                targetSize: imageSize,
                contentMode: .AspectFill,
                options: options,
                resultHandler: {
                     image, info in
                    self.photo = image!
                    /* The image is now available to us */
                    self.sendPhotos(self.photo)
                    println("enum for image, This is number 2")


            })
        }
    }
}

func sendPhotos(uploadImage:UIImage)
{

    var defaults: NSUserDefaults = NSUserDefaults.standardUserDefaults()
    var server = defaults.objectForKey("imageServer") as String!
    var error: NSError? = nil

    var imageData = UIImageJPEGRepresentation(uploadImage, 90)
    var url = NSURL(string: server)
    var request = NSMutableURLRequest(URL: url!)
    request.HTTPMethod = "POST"
    //request.setValue("multipart/form-data", forHTTPHeaderField: "Content-Type")
    request.HTTPBody = imageData

    var response: NSURLResponse? = nil

    let reply = NSURLConnection.sendSynchronousRequest(request, returningResponse:&response, error:&error)

    let results = NSString(data:reply!, encoding:NSUTF8StringEncoding)
    println("API Response: \(results)")
}
Spikehockey75
  • 211
  • 1
  • 2
  • 6
  • Thanks a million buddy... I wasted two days searching this over the internet..!! – Irshad Qureshi Feb 03 '16 at 08:20
  • Using this code memory is not being released until all images get fetched. If I am closing the view controller before this task is done then it leads to a memory leak. – PinkeshGjr Dec 06 '21 at 13:30
6
func fetchVideoFromLibrary() {
       let fetchOptions: PHFetchOptions = PHFetchOptions()
       fetchOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: false)]
       let fetchResult = PHAsset.fetchAssetsWithMediaType(.Video, options: fetchOptions)
       fetchResult.enumerateObjectsUsingBlock { (object, index, stop) -> Void in
           let options = PHImageRequestOptions()
           options.synchronous = true
           options.deliveryMode = .HighQualityFormat
           PHImageManager.defaultManager().requestAVAssetForVideo(object as! PHAsset, options: .None) { (avAsset, avAudioMix, dict) -> Void in
               print(avAsset)
           }
       }
   }
Trupti
  • 284
  • 5
  • 7
  • How to fetch videos from 10 to 20 , for example i want to show video using pagination , so wanna fetch 0 to 10, 10 to 20 .... etc – Trupti May 03 '16 at 09:44