Dictionary Now Gives Error 'Not Convertible to Booleanliteralconvertible' Since Updating to Swift 1.2

Dictionary now gives error 'not convertible to BooleanLiteralConvertible' since updating to Swift 1.2

From the Xcode 6.3 release notes:

The implicit conversions from bridged Objective-C classes
(NSString/NSArray/NSDictionary) to their corresponding Swift value
types (String/Array/Dictionary) have been removed, making the Swift
type system simpler and more predictable.

The problem in your case are the CFStrings like kCGImageSourceThumbnailMaxPixelSize. These are not automatically
converted to String anymore. Two possible solutions:

let options = [
kCGImageSourceThumbnailMaxPixelSize as String : maxSize,
kCGImageSourceCreateThumbnailFromImageIfAbsent as String : true
]

or

let options : [NSString : AnyObject ] = [
kCGImageSourceThumbnailMaxPixelSize: maxSize,
kCGImageSourceCreateThumbnailFromImageIfAbsent: true
]

Merging Dictionaries with multiple Types, or Any / AnyObject Type

You don't actually need to (and you can't) specify the Any type in the function declaration - you need to have the subtypes of the newValues dictionary match the dictionary it's extending:

extension Dictionary {
mutating func extend(newVals: Dictionary) {
for (key,value) in newVals {
self.updateValue(value, forKey:key)
}
}
}

var dict = ["one": 1, "two": 2, "hello": "goodbye"]
dict.extend(["three": 3])
dict.extend(["foo": "bar"])

Key and Value are type aliases within the Dictionary type that map to the specific key- and value-types of a particular instance.

Creating a CFDictionary

Here is your working code:

func processImage(jpgImagePath: String, thumbSize: CGSize) {

if let path = NSBundle.mainBundle().pathForResource(jpgImagePath, ofType: "") {
if let imageURL = NSURL(fileURLWithPath: path) {
if let imageSource = CGImageSourceCreateWithURL(imageURL, nil) {

let maxSize = max(thumbSize.width, thumbSize.height) / 2.0

let options : [NSString : AnyObject] = [
kCGImageSourceThumbnailMaxPixelSize: maxSize,
kCGImageSourceCreateThumbnailFromImageIfAbsent: true
]

let scaledImage = UIImage(CGImage: CGImageSourceCreateThumbnailAtIndex(imageSource, 0, options))

// do other stuff
}
}
}
}

From Docs:

The implicit conversions from bridged Objective-C classes
(NSString/NSArray/NSDictionary) to their corresponding Swift value
types (String/Array/Dictionary) have been removed, making the Swift
type system simpler and more predictable.

The problem in your case are the CFStrings like kCGImageSourceThumbnailMaxPixelSize. These are not automatically converted to String anymore.

reference from HERE.

Can Swift return value from an async Void-returning block?

You should employ asynchronous (ie, escaping) completion handler yourself:

class func checkIfUserExists(uid: String, completion: @escaping (Bool) -> Void) {
userRef.childByAppendingPath(uid).observeSingleEventOfType(.Value) { snapShot in
if snapShot.value is NSNull {
completion(false)
} else {
completion(true)
}
}
}

You can then call this like so:

MyClass.checkIfUserExists(uid) { success in
// use success here
}

// but not here

In your revised question, you demonstrate the use of dispatch groups to make this asynchronous method behave synchronously. (Semaphores are also often used to the same ends.)

Two issues:

  1. This will deadlock if they dispatch their completion handler back to the main queue (and in many cases, libraries will do this to simplify life for us), because you're coincidentally blocking the very same thread they're trying to use. I don't know if that's what they've done here, but is likely.

    If you want to confirm this, temporarily remove dispatch group and then examine NSThread.isMainThread and see if it's running in main thread or not.

  2. You never should block the main thread, anyway. They provided an asynchronous interface for good reason, so you should use asynchronous patterns when calling it. Don't fight the asynchronous patterns, but rather embrace them.



Related Topics



Leave a reply



Submit