2012-06-10 31 views

Trả lời

46

SecItemCopyMatching là cuộc gọi phù hợp cho điều đó. Đầu tiên chúng ta xây dựng từ điển truy vấn của chúng tôi để các thuộc tính của các mặt hàng được trả về trong từ điển, và rằng tất cả các mặt hàng được trả về:

NSMutableDictionary *query = [NSMutableDictionary dictionaryWithObjectsAndKeys: 
    (__bridge id)kCFBooleanTrue, (__bridge id)kSecReturnAttributes, 
    (__bridge id)kSecMatchLimitAll, (__bridge id)kSecMatchLimit, 
    nil]; 

Như SecItemCopyMatching đòi hỏi ít nhất lớp của trở SecItem s, chúng ta tạo ra một mảng với tất cả các lớp học…

NSArray *secItemClasses = [NSArray arrayWithObjects: 
          (__bridge id)kSecClassGenericPassword, 
          (__bridge id)kSecClassInternetPassword, 
          (__bridge id)kSecClassCertificate, 
          (__bridge id)kSecClassKey, 
          (__bridge id)kSecClassIdentity, 
          nil]; 

... và cho mỗi lớp, hãy đặt lớp trong truy vấn của chúng tôi, gọi và đăng nhập kết quả.

for (id secItemClass in secItemClasses) { 
    [query setObject:secItemClass forKey:(__bridge id)kSecClass]; 

    CFTypeRef result = NULL; 
    SecItemCopyMatching((__bridge CFDictionaryRef)query, &result); 
    NSLog(@"%@", (__bridge id)result); 
    if (result != NULL) CFRelease(result); 
} 

Trong mã sản xuất, bạn nên kiểm tra xem OSStatus trả về bởi SecItemCopyMatching là một trong hai errSecItemNotFound (không có mục nào được tìm thấy) hoặc errSecSuccess (ít nhất một mục đã được tìm thấy).

+0

Cảm ơn! Chưa thử nghiệm, nhưng trông giống như câu trả lời đúng. – noamtm

+2

Đó là. Tôi đã thử nghiệm nó :) –

+0

Tôi nhận được tất cả null trong in ra cả trong iPhone và giả lập. Tôi có nên làm gì nữa không? – karim

3

Swift 3+ phiên bản trả về cũng là chìa khóa (kSecAttrAccount):

open func getAllKeyChainItemsOfClass(_ secClass: String) -> [String:String] { 

     var query: [String: Any] = [ 
      kSecClass : secClass, 
      kSecReturnData : kCFBooleanTrue, 
      kSecReturnAttributes : kCFBooleanTrue, 
      kSecReturnRef : kCFBooleanTrue, 
      kSecMatchLimit : kSecMatchLimitAll 
     ] 

     var result: AnyObject? 

     let lastResultCode = withUnsafeMutablePointer(to: &result) { 
      SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) 
     } 

     var values = [String:String]() 
     if lastResultCode == noErr { 
      let array = result as? Array<Dictionary<String, Any>> 

      for item in array! { 
       if let key = item[kSecAttrAccount] as? String, 
        let value = item[kSecValueData] as? Data { 
        values[key] = String(data: value, encoding:.utf8) 
       } 
      } 
     } 

     return values 
    } 
+0

Sử dụng Swift 3 trên Xcode 9.2 điều này đang gặp lỗi tại 'let key: String = item [kSecAttrAccount] as! Chuỗi' với 'Không thể truyền giá trị của loại '__NSCFData' (0x109b30348) đến 'NSString' (0x1069030d0) .'. Tôi cung không chăc tại sao. –

+1

Thay đổi các dòng thiết lập khóa và giá trị thành điều này khiến cho sự cố không xảy ra, mặc dù nó loại bỏ một số đối tượng mà tôi không biết cách kéo ra: 'if let key = item [kSecAttrAccount] là? Chuỗi, hãy đặt giá trị = item [kSecValueData] là? Dữ liệu {' –

0

Swift 3 phiên bản với xcode 9,1

func getAllKeyChainItemsOfClass(_ secClass: String) -> [String:String] { 

    var query: [String: Any] = [ 
     kSecClass as String : secClass, 
     kSecReturnData as String : kCFBooleanTrue, 
     kSecReturnAttributes as String : kCFBooleanTrue, 
     kSecReturnRef as String : kCFBooleanTrue, 
     kSecMatchLimit as String : kSecMatchLimitAll 
    ] 

    var result: AnyObject? 

    let lastResultCode = withUnsafeMutablePointer(to: &result) { 
     SecItemCopyMatching(query as CFDictionary, UnsafeMutablePointer($0)) 
    } 

    var values = [String:String]() 
    if lastResultCode == noErr { 
     let array = result as? Array<Dictionary<String, Any>> 

     for item in array! { 
      if let key = item[kSecAttrAccount as String] as? String, 
       let value = item[kSecValueData as String] as? Data { 
       values[key] = String(data: value, encoding:.utf8) 
      } 
     } 
    } 

    return values 
} 

có thể được gọi như:

debugPrint(getAllKeyChainItemsOfClass(kSecClassGenericPassword as String)) 
Các vấn đề liên quan