4

Today I upgraded Xcode 6 to beta 5 (from beta 1) and as you can imagine I found my previously perfectly working Swift app full of errors of all kind (well, a lot changed from beta 1). Of all errors, there is one I just can't figure out how to fix. It's related to swift closures, in particular the enumerationBlock argument of the .enumerateGroupsWithTypes method. Here is the code:

assetLib.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupSavedPhotos), usingBlock: {
(group: ALAssetsGroup?, stop: CMutablePointer<ObjCBool>) in

...

}, failureBlock: {
  (error: NSError!) in

  ...

})

This did work perfectly in Swift (Xcode 6 beta 1). But now, I get 2 errors:

  1. " 'UnsafeMutablePointer' is not a subtype of 'error type' "

  2. " Use of undeclared type 'CMutablePointer' "

It was clear that CMutablePointer did not exist anymore, so I tried to modify the stop argument like:

..., stop: UnsafeMutablePointer<ObjCBool> ...

After this change, the second error obviously disappeared, but the first transformed in:

" Could not find an overload for 'init' that accepts the supplied arguments "

I even tried to change the UnsafeMutablePointer to a UnsafePointer, as suggested from this post.

EDIT:

Here is the full code of the enumerateGroupsWithTypes method:

assetLib.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupSavedPhotos), usingBlock: {
    (group: ALAssetsGroup?, stop: UnsafeMutablePointer<ObjCBool>) in
    if group != nil {
    group!.setAssetsFilter(ALAssetsFilter.allPhotos())
    group!.enumerateAssetsAtIndexes(NSIndexSet(index: group!.numberOfAssets()-1), options: nil, usingBlock: {
      (result: ALAsset!, index: Int, stop: UnsafeMutablePointer<ObjCBool>) in
      if result {
        var alAssetRapresentation: ALAssetRepresentation = result.defaultRepresentation()
        url = alAssetRapresentation.url()
      }
      })
    }
    else if group == nil {

      assetLib.assetForURL(url, resultBlock: {
        (asset: ALAsset!) in
        if asset != nil {
        var assetRep: ALAssetRepresentation = asset.defaultRepresentation()
        var iref = assetRep.fullResolutionImage().takeUnretainedValue()
        var image = UIImage(CGImage: iref)


        imageView.image = image

        self.view.addSubview(imageView)

          let mask = CAShapeLayer()
          mask.path = UIBezierPath(ovalInRect: CGRectMake(0, 0, 200, 200)).CGPath
          mask.frame = CGPathGetPathBoundingBox(mask.path)

          mapView.layer.mask = mask

          self.view.addSubview(mapView)

        }
        }, failureBlock: {
          (error: NSError!) in

          NSLog("Error!", nil)
        })
    }

    }, failureBlock: {
      (error: NSError!) in

      NSLog("Error!", nil)

    })
6
  • After replacing stop: CMutablePointer<ObjCBool> with stop: UnsafeMutablePointer<ObjCBool>, your code compiles in my project. Is there more code that might cause the problem? Commented Aug 5, 2014 at 20:47
  • First, thanks for your quick reply... There is a lot of stuff inside the block. If your code compiles, the error in my code is maybe hidden somewhere else. I'll post an update with the full method in a few minutes! Commented Aug 5, 2014 at 20:54
  • Perhaps you can reduce the "lot of stuff" to a minimal example demonstrating the problem :) Commented Aug 5, 2014 at 20:56
  • The problem is that I have no idea where in this "lot of stuff" the problem can be... I'm really new to ALAsset stuff and I'm not really familiar with closures either. I'll need some help :P Commented Aug 5, 2014 at 21:01
  • 1
    NSLog("Error!", nil) is wrong and should be NSLog("Error!"). Commented Aug 5, 2014 at 21:14

2 Answers 2

7

Here is a for me working example: This code looks for the album „projectname“ and safe the image „in“ this album. If the album do not exists, the album will be created.

Attention: If there WAS an album with the SAME name. You can NOT create a album with this name once again. You must use a new name. In this example the projectname will extent with date and time.

By the way, Apples apps could create a album with the same name.

    func saveImage(projectName : String) { // Return a new projectname  
                                      //  in the var self.newProjectName if the old one could not created
    if self.isSaved {  // was here bevor
        return
    }

    let library = ALAssetsLibrary()                 // This object will provide the access to to the library

    // List over all groups in the PhotoDirectory
    // ALAssetsGroupAll is the key to select the listed groups
    // possible change to type:Album
    library.enumerateGroupsWithTypes(ALAssetsGroupType(ALAssetsGroupAll),
        usingBlock: {(group : ALAssetsGroup!, stop : UnsafeMutablePointer<ObjCBool>) in
            if group != nil {                                   // The listing of the directory content has found an object
                // Did we search for this album?
                if group.valueForProperty(ALAssetsGroupPropertyName).isEqualToString(projectName) {
                    stop.initialize(true)                       // Stop the enumeration thread
                    library.writeImageToSavedPhotosAlbum(self.cgImage, metadata: self.ciImage?.properties(),
                        completionBlock: {(assetUrl, error: NSError?) -> Void in
                        if let theError = error?.code {
                            lapApp.logger.addLog("saved image failed, first try \(error?.localizedDescription) code \(theError)")
                        } else {
                            library.assetForURL(assetUrl,
                                resultBlock: { (asset: ALAsset!) -> Void in
                                group.addAsset(asset)
                                self.isSaved = true
                                return // Stop this process and leave
                                }, failureBlock: {
                                    (theError: NSError!) -> Void in
                                    lapApp.logger.addLog("error occurred, image to album at the first try: \(theError.localizedDescription) ")
                            })
                        }
                    })
                    return // write image to the found album
                } else {
                 // Album not found, enumeration will continue
               }
            }
            else { // The album was not found, so we will create an album
                if stop.memory.boolValue {  // The enumeration will go over the end of the list. The stop-signal comes some time to late?
                    return
                }
                library.addAssetsGroupAlbumWithName(projectName,
                    resultBlock: {(group: ALAssetsGroup?) -> Void in
                    if let thegroup = group {         // Check for a name conflict, possible was a album with the same name deleted. IOS8 will not create this album!
                        // The album was correct created, now we will add the picture to the album
                        library.writeImageToSavedPhotosAlbum(self.cgImage, metadata: self.ciImage?.properties(), completionBlock: {
                            (assetUrl, error: NSError?) -> Void in
                            if let theError = error?.code {
                                lapApp.logger.addLog("save image in new album failed. \(error?.localizedDescription) code \(theError)")
                            } else {
                                library.assetForURL(assetUrl,
                                    resultBlock: { (asset: ALAsset!) -> Void in
                                    thegroup.addAsset(asset)
                                    self.isSaved = true
                                    stop.initialize(true)                       // Stop the enumeration thread
                                    return
                                    }, failureBlock: {
                                        (theError: NSError?) -> Void in
                                        lapApp.logger.addLog("error occurred: \(theError?.localizedDescription)")
                                })
                            }
                        })
                        return

                    } else {                       // Name conflic with a deleted album.
                                                   // Work around: Create the Album with the Projectname an extend the name with Date and time
                        let formatter : NSDateFormatter = NSDateFormatter()
                        formatter.dateFormat = "yy.MM.dd hh:mm:ss"
                        let extensionDate = formatter.stringFromDate(NSDate())
                        self.newProjectName = projectName + " " + extensionDate // This is the new projectname
                        library.addAssetsGroupAlbumWithName(self.newProjectName,
                            resultBlock: {(group: ALAssetsGroup?) -> Void in
                            if let theGroup = group {
                                library.writeImageToSavedPhotosAlbum(self.cgImage, metadata: self.ciImage?.properties(), completionBlock: {
                                    (assetUrl, error: NSError?) -> Void in
                                    if let theError = error {
                                       lapApp.logger.addLog("save image with new album name failed. \(error?.localizedDescription) code \(theError) \(self.newProjectName)")
                                    } else {
                                       library.assetForURL(assetUrl, resultBlock: { (asset: ALAsset!) -> Void in
                                        theGroup.addAsset(asset)
                                        self.isSaved = true
                                        stop.initialize(true)                       // Stop the enumeration thread
                                        return
                                        }, failureBlock: {
                                            (theError: NSError?) -> Void in
                                            lapApp.logger.addLog("error at write image in new album occurred: \(theError?.localizedDescription)")
                                        })
                                    }
                                })
                            } else {
                                lapApp.logger.addLog("Problem adding albums with the name \(self.newProjectName)")
                            }
                        },
                        failureBlock: {
                                (error:NSError?) -> Void in
                                lapApp.logger.addLog("Problem adding albums: \(error)")
                        })
                    }
                    },
                    failureBlock: {
                        (error:NSError?) -> Void in
                        lapApp.logger.addLog("Problem loading albums: \(error)")
                })
            }
        }, failureBlock: { (error:NSError?) in lapApp.logger.addLog("Problem loading albums: \(error)") })
} // End SaveImage
Sign up to request clarification or add additional context in comments.

Comments

1

NSLog("Error!", nil) is wrong and should be NSLog("Error!"). (This seems to confuse the Swift compiler and causes unrelated error messages.)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.