由于 'internal' 保护级别,初始化程序无法访问
Initializer is inaccessable due to 'internal' protection level
我有一些协议
登录策略
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
}
和两个类:
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)
}
}
在我的ViewController:
当我使用:
let facebookLoginProvider = LoginProvider(strategy: FacebookLoginStrategy())
它说:
'FacebookLoginStrategy' is inaccessable due to 'internal' protection
level
只需添加到您的 FacebookLoginStrategy:
public init() {}
只要你没有显式实现init(),默认情况下它被标记为内部的。您需要覆盖该权限级别才能从框架外部实例化。
如果您在 XCTestCase 中的代码中 运行,请确保您已将 @testable import My-Awesome-App
添加到测试文件的顶部。
添加初始化方法作为Public访问
public init() {}
如果有人在实施 Swift 包以构建可重复使用的 SwiftUI 视图时遇到此问题,请记住以下几点。
- 如果有从父组件设置的组件属性,不要忘记将它们添加到构造函数中
- 如果 属性 被
@State
包裹,则将状态分配给底层对象,如下所示。
public struct Layout: View {
@State var layout: NavType = .TOP
var navItems: [NavItemObject]
public init(layout: NavType, navItems: [NavItemObject]) {
_layout = State(initialValue: layout);
self.navItems = navItems;
}
}
我有一些协议
登录策略
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
}
和两个类:
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)
}
}
在我的ViewController:
当我使用:
let facebookLoginProvider = LoginProvider(strategy: FacebookLoginStrategy())
它说:
'FacebookLoginStrategy' is inaccessable due to 'internal' protection level
只需添加到您的 FacebookLoginStrategy:
public init() {}
只要你没有显式实现init(),默认情况下它被标记为内部的。您需要覆盖该权限级别才能从框架外部实例化。
如果您在 XCTestCase 中的代码中 运行,请确保您已将 @testable import My-Awesome-App
添加到测试文件的顶部。
添加初始化方法作为Public访问
public init() {}
如果有人在实施 Swift 包以构建可重复使用的 SwiftUI 视图时遇到此问题,请记住以下几点。
- 如果有从父组件设置的组件属性,不要忘记将它们添加到构造函数中
- 如果 属性 被
@State
包裹,则将状态分配给底层对象,如下所示。
public struct Layout: View {
@State var layout: NavType = .TOP
var navItems: [NavItemObject]
public init(layout: NavType, navItems: [NavItemObject]) {
_layout = State(initialValue: layout);
self.navItems = navItems;
}
}