【问题标题】:Initializer is inaccessable due to 'internal' protection level由于“内部”保护级别,初始化程序不可访问
【发布时间】:2017-04-13 01:13:37
【问题描述】:

我有一些协议

登录策略

public protocol LoginStrategy {
    func login(_ viewController: UIViewController)
    func getUserInfo(withCompletionHandler completionHandler: @escaping (_ userInfo: [String: Any]?) -> ())
    func createLoginButton(_ frame: CGRect, withCompletionHandler completionHandler: @escaping (_ loginButton: UIView) -> ())
    func getUserId() -> String
}

还有两个类:

登录提供者

public class LoginProvider {

    public let strategy: LoginStrategy

    public func login(_ viewController: UIViewController) {
        return self.strategy.login(viewController)
    }

    public func getUserInfo(withCompletionHandler completionHandler: @escaping (_ userInfo: [String: Any]?) -> ()) {
        return self.strategy.getUserInfo(withCompletionHandler: completionHandler)
    }

    public func createLoginButton(_ frame: CGRect, withCompletionHandler completionHandler: @escaping (_ loginButton: UIView) -> ()) {
        return self.strategy.createLoginButton(frame, withCompletionHandler: completionHandler)
    }

    public func getUserId() -> String {
        return self.strategy.getUserId()
    }

    public init(strategy: LoginStrategy) {
        self.strategy = strategy
    }

}

FacebookLoginStrategy

import Foundation
import FacebookCore
import FacebookLogin

public class FacebookLoginStrategy: LoginStrategy {

    public var grantedPermissions: Set<Permission>? = nil

    public var declinedPermissions: Set<Permission>? = nil

    public var userId: String = ""

    public func login(_ viewController: UIViewController) {
        let loginManager = LoginManager()
        let permissions: [ReadPermission] = [.publicProfile, .userFriends, .email]
        loginManager.logIn(permissions, viewController: viewController) { loginResult in
            switch loginResult {
            case .failed(let error):
                print(error)
            case .cancelled:
                print("User cancelled login.")
            case .success(let grantedPermissions, let declinedPermissions, let accessToken):
                self.userId = accessToken.userId ?? ""
                self.grantedPermissions = grantedPermissions
                self.declinedPermissions = declinedPermissions
                print("Logged in!")
            }
        }
    }

    public func getUserId() -> String {
        return userId
    }

    public func getUserInfo(withCompletionHandler completionHandler: @escaping (_ userInfo: [String: Any]?) -> ()) {
        let request = GraphRequest(graphPath: "me", parameters: ["fields":"email, name"], accessToken: AccessToken.current, httpMethod: .GET, apiVersion: FacebookCore.GraphAPIVersion.defaultVersion)
        request.start { (response, result) in
            switch result {
            case .success(let value):
                print(value.dictionaryValue)
                completionHandler(value.dictionaryValue)
            case .failed(let error):
                print(error)
            }
        }
    }

    public func createLoginButton(_ frame: CGRect, withCompletionHandler completionHandler: @escaping (_ loginButton: UIView) -> ()) {
        let permissions: [ReadPermission] = [.publicProfile, .userFriends, .email]
        let loginButton = LoginButton(readPermissions: permissions)
        loginButton.frame = frame
        completionHandler(loginButton)
    }
}

在我的 ViewController 中:

当我使用时:

let facebookLoginProvider = LoginProvider(strategy: FacebookLoginStrategy())

上面写着:

“FacebookLoginStrategy”由于“内部”保护而无法访问 等级

【问题讨论】:

    标签: ios swift frameworks access-modifiers initializer


    【解决方案1】:

    将 init 方法添加为公共访问

    public init() {}
    

    【讨论】:

      【解决方案2】:

      如果您在 XCTestCase 中的代码中遇到此问题,请确保您已将 @testable import My-Awesome-App 添加到测试文件的顶部。

      【讨论】:

      • 非常感谢。
      【解决方案3】:

      只需添加到您的 FacebookLoginStrategy:

      public init() {}
      

      只要你没有显式地实现 init(),它就会被默认标记为内部的。您需要覆盖该权限级别才能从框架外部进行实例化。

      【讨论】:

      • 很好的答案!还要注意 Swift4,如果你不实现它实际上是一个错误。
      • 刚上课。
      • 这太愚蠢了,Swift 需要这个。如果我将整个类类型声明为公开,那么免费的 init() 也应该公开
      • 这应该是Swift 的错误。这不应该是编译器的错误,因为我们已经将public 标记为class/struct
      • 我在初始化之前添加了 public ,但我仍然收到相同的消息。还有其他保护措施吗?
      猜你喜欢
      • 1970-01-01
      • 2018-08-25
      • 1970-01-01
      • 1970-01-01
      • 2019-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-09-15
      相关资源
      最近更新 更多