4

我有一个 iOS 项目。

我今天提取了一些身份验证代码并将其移至自己的项目中。

该项目支持 macOS 和 iOS。

我创建了一个包含 iOS 项目和 Auth 项目的工作区,并通过面板将身份验证添加.framework到我的 iOS 项目中。Frameworks, Libraries, and Embedded Content

我可以构建和使用我的服务。我还设置了一个自定义方案CI_iOS,允许我为这些项目运行测试。

我现在已经在我的 auth 模块中添加了一些集成测试,所以我可以KeychainTokenStore针对真正的 Keychain 测试我的类。

这些在针对 macOS 测试我的模块时有效,但是尝试在 iOS 模拟器上运行它们都失败了。

我可以看到在尝试与钥匙串交互时返回错误代码-34018,我相信这表明errSecMissingEntitlement

我一直在阅读一些似乎建议我需要启用钥匙串共享的帖子。

然而,我似乎无法完成这项工作。

我的KeychainTokenStore长相是这样的


import Foundation


public protocol TokenStore {
  typealias DeleteCacheResult = Result<Void, Error>
  typealias DeleteCacheCompletion = (DeleteCacheResult) -> Void

  typealias InsertCacheResult = Result<Void, Error>
  typealias InsertCacheCompletion = (InsertCacheResult) -> Void

  typealias RetrieveCacheResult = Result<String?, Error>
  typealias RetrieveCacheCompletion = (RetrieveCacheResult) -> Void

  /// The completion handler can be invoked in any thread.
  /// Clients are responsible for dispatching to the appropriate thread, if needed.
  func insert(_ token: String, key: String, completion: @escaping InsertCacheCompletion)

  /// The completion handler can be invoked in any thread.
  /// Clients are responsible for dispatching to the appropriate thread, if needed.
  func delete(_ key: String, completion: @escaping DeleteCacheCompletion)

  /// The completion handler can be invoked in any thread.
  /// Clients are responsible for dispatching to the appropriate thread, if needed.
  func retrieve(_ key: String, completion: @escaping RetrieveCacheCompletion)
}


public final class KeychainTokenStore: TokenStore {

  public enum Error: Swift.Error {
    case saveFailed
  }

  public init() { }

  private lazy var queue = DispatchQueue(label: "KeychainTokenStore.queue", qos: .userInitiated, attributes: .concurrent)

  public func insert(_ token: String, key: String, completion: @escaping InsertCacheCompletion) {
    queue.async(flags: .barrier) {
      completion(Result {
        let query = [
          kSecClass: kSecClassGenericPassword,
          kSecAttrAccount: key,
          kSecValueData: Data(token.utf8)
          ] as CFDictionary

        SecItemDelete(query)

        guard SecItemAdd(query, nil) == noErr else { throw Error.saveFailed }
      })
    }
  }

  public func delete(_ key: String, completion: @escaping DeleteCacheCompletion) {
    queue.async(flags: .barrier) {
      completion(Result {
        let query = [
          kSecClass: kSecClassGenericPassword,
          kSecAttrAccount: key,
          ] as CFDictionary

        SecItemDelete(query)
      })
    }
  }

  public func retrieve(_ key: String, completion: @escaping RetrieveCacheCompletion) {
    queue.async {
      let query = [
        kSecClass: kSecClassGenericPassword,
        kSecAttrAccount: key,
        kSecReturnData: kCFBooleanTrue as Any,
        kSecMatchLimit: kSecMatchLimitOne
        ] as CFDictionary

      var result: AnyObject?
      let status = SecItemCopyMatching(query, &result)

      guard status == noErr, let data = result as? Data else {
        return completion(.success(.none))
      }

      completion(Result {
        String(decoding: data, as: UTF8.self)
      })
    }
  }
}

在我的 iOS 应用程序中,我启用了如下共享:

共享钥匙串

当我尝试在我的身份验证框架中启用共享时,我看到以下内容

错误

如何确保我的DigiAuth框架可以通过运行我的DigiApp项目来访问钥匙串?

4

0 回答 0