Không thể truy cập trình khởi tạo do mức bảo vệ 'nội bộ'


90

Tôi có một số giao thức

LoginStrategy

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
}

và hai lớp:

LoginProvider

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)
    }
}

Trong ViewController của tôi :

Khi tôi sử dụng:

let facebookLoginProvider = LoginProvider(strategy: FacebookLoginStrategy())

Nó nói rằng:

Không thể truy cập 'FacebookLoginStrategy' do cấp độ bảo vệ 'nội bộ'

Câu trả lời:


251

Chỉ cần thêm vào FacebookLoginStrategy của bạn:

public init() {}

Miễn là bạn không triển khai init () một cách rõ ràng, nó được đánh dấu là nội bộ theo mặc định. Bạn cần ghi đè mức quyền đó để có thể khởi tạo từ bên ngoài khuôn khổ của mình.


13
Câu trả lời chính xác! Và hãy coi chừng Swift4, nó thực sự là một lỗi nếu bạn không triển khai nó.
Paul Razvan Berg

2
Chỉ vào lớp.
jboi

13
điều này thật ngu ngốc mà Swift yêu cầu điều này. Nếu tôi khai báo toàn bộ loại lớp là công khai, thì init () miễn phí cũng sẽ công khai
LightningStryk

3
Đây sẽ là một lỗi của Swift. Nó không phải là một lỗi của trình biên dịch, vì chúng tôi đã đánh dấu publiccho class/struct.
lee

1
Tôi đã thêm công khai trước khi bắt đầu và tôi vẫn nhận được thông báo tương tự. Có bảo vệ khác không?
AndreG

8

Nếu bạn đang truy cập vào điều này trong mã trong XCTestCase, hãy đảm bảo rằng bạn đã thêm vào @testable import My-Awesome-Appđầu tệp thử nghiệm của mình.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.