hockeybro
hockeybro

Reputation: 1001

Expression was too complex to be solved in reasonable time Swift 3

I am trying to convert my project to Swift 3, but I am getting an error message that the expression is too complex to be solved in reasonable time. I am not sure why this is, since this expression was working fine in Swift 2.2, but now all of a sudden it is taking so long?

Does anyone know how I can fix this? Here is the expression. It is basically a dictionary that will be used later with SecItemCopyMatching to extract an item from the keychain that was saved with a key tag. It performs a touchID to do this, since it was saved with that locking parameter:

let query : [String: AnyObject] = [String(kSecClass) : kSecClassGenericPassword,
     String(kSecAttrService) : keyTag as AnyObject,
     String(kSecAttrAccount) : keyTag,
     String(kSecReturnData) : kCFBooleanTrue,
     String(kSecMatchLimit) : kSecMatchLimitOne,
     String(kSecUseOperationPrompt) : message]

Upvotes: 6

Views: 4521

Answers (2)

vacawama
vacawama

Reputation: 154513

Try casting all dictionary values to AnyObject. Unless they are already objects derived from NSObject (such as NSString, NSNumber, NSArray and NSDictionary), you need to cast them to AnyObject. Swift 3 has removed the automatic bridging to Foundation types.

let query: [String: AnyObject] = [String(kSecClass) : kSecClassGenericPassword as AnyObject,
                                   String(kSecAttrService) : keyTag as AnyObject,
                                   String(kSecAttrAccount) : keyTag as AnyObject,
                                   String(kSecReturnData) : kCFBooleanTrue as AnyObject,
                                   String(kSecMatchLimit) : kSecMatchLimitOne as AnyObject,
                                   String(kSecUseOperationPrompt) : message as AnyObject]

Upvotes: 2

mbachm
mbachm

Reputation: 444

Unfortunately, you have to have to define your query as var and assign the values separately. It seems that Swift 3.0 cannot handle expressions this long.

Your code will look like this:

var query = [String: AnyObject]()
query[String(kSecClass)] = kSecClassGenericPassword
query[String(kSecAttrService)] =  keyTag as AnyObject
query[String(kSecAttrAccount)] = keyTag
query[String(kSecReturnData)] = kCFBooleanTrue
query[String(kSecMatchLimit)] = kSecMatchLimitOne
query[String(kSecUseOperationPrompt)] = message

Upvotes: 7

Related Questions