     Remove all objects from the keychain for the current app. Only available on
     iOS and watchOS.
     */
-    public func resetKeychain() -> Bool {
-        let query = [kSecClass as String : kSecClassGenericPassword as String]
-        let status = SecItemDelete(query)
+    @discardableResult public func resetKeychain() -> Bool {
+        let query:[String: AnyObject] = [kSecClass as String : kSecClassGenericPassword]
+        let status = SecItemDelete(query as CFDictionary)
         if status != errSecSuccess {
             print("Latch failed to reset keychain, error: \(status)")
             return false

    /**
    Retreives the data for a given key, or returns nil.
    */
    public func dataForKey(key: String) -> NSData? {
        var query = baseQuery(forKey: key)
        query[kSecMatchLimit as String] = kSecMatchLimitOne as String
        query[kSecReturnData as String] = true

        var dataRef: CFTypeRef?
        let status = SecItemCopyMatching(query as CFDictionaryRef, &dataRef)
        if status != errSecSuccess && status != errSecItemNotFound {
            print("Latch failed to retrieve data for key '\(key)', error: \(status)")
        }

        return dataRef as? NSData
    }

    /**
    Retreives the string value for a given key. It will return nil if the data
    is not a UTF8 encoded string.
    */
    public func stringForKey(key: String) -> String? {
        guard let data = dataForKey(key) else { return nil }
        return NSString(data: data, encoding: NSUTF8StringEncoding) as? String
    }

    // MARK - Setters

        // If a SecItem contains an access group attribute, SecItemAdd and SecItemUpdate on the
        // simulator will return -25243 (errSecNoAccessForItem).

        if !state.accessGroup?.isEmpty {
            query[kSecAttrAccessGroup] = state.accessGroup
        }
        #endif

