SwiftUI - 在 watchOS 上登录 Apple 崩溃

Nik*_*kur 0 watchkit watchos swiftui apple-sign-in

我正在使用 SwiftUI 在 watchOS 上使用Apple实现登录

由于WKInterfaceAuthorizationAppleIDButton不符合 View 协议,我将它包装起来WKInterfaceObjectRepresentable用于在 SwiftUI 视图中使用它。

我已经实现了一个协调器来处理按钮上的点击,它还充当注册过程回调的委托。

下面是我的代码:

struct AppleLoginButton: WKInterfaceObjectRepresentable {

    typealias WKInterfaceObjectRepresentable = WKInterfaceObjectRepresentableContext<AppleLoginButton>

    func updateWKInterfaceObject(_ wkInterfaceObject: WKInterfaceAuthorizationAppleIDButton, context: WKInterfaceObjectRepresentableContext<AppleLoginButton>) {
        // No code required
    }

    class Coordinator: NSObject, ASAuthorizationControllerDelegate {

        @objc func buttonPressed(_ sender: WKInterfaceAuthorizationAppleIDButton) {

            let appleIDProvider = ASAuthorizationAppleIDProvider()
            let request = appleIDProvider.createRequest()
            request.requestedScopes = [.fullName, .email]

            let authorizationController = ASAuthorizationController(authorizationRequests: [request])
            authorizationController.delegate = self
            authorizationController.performRequests()
        }

        func authorizationController(controller: ASAuthorizationController, didCompleteWithAuthorization authorization: ASAuthorization) {
            if let appleIDCredential = authorization.credential as? ASAuthorizationAppleIDCredential {
                // Verify the user
            }
        }

        func authorizationController(controller: ASAuthorizationController, didCompleteWithError error: Error) {
            // Handle error.
        }

    }

    func makeCoordinator() -> Coordinator {
        return Coordinator()
    }

    func makeWKInterfaceObject(context: WKInterfaceObjectRepresentableContext<AppleLoginButton>) -> WKInterfaceAuthorizationAppleIDButton {
        return WKInterfaceAuthorizationAppleIDButton(target: context.coordinator, action: #selector(Coordinator.buttonPressed(_:)))
    }

}
Run Code Online (Sandbox Code Playgroud)

每当我点击登录按钮时,应用程序每次都会崩溃并显示以下错误,

线程 1:EXC_BAD_ACCESS(代码=1,地址=0x74747572)

如果我的代码或我实现协调器的方式有问题,有人可以帮助我吗?

但是,上面的代码在带有ASAuthorizationAppleIDButton按钮的SwiftUI 中适用于 iOS

此外,如果我在 WatchKit 中使用 Apple 实现登录,它可以毫无问题地工作。

因此,我似乎缺少一些实现细节,希望对此有所帮助。

更新: 我用谷歌搜索EXC错误,大多数答案都指出非法内存访问是这些崩溃的罪魁祸首。

进一步谷歌搜索目标操作崩溃显示,如果目标从内存池中释放,它会导致崩溃。

那么任何人都可以帮助我如何将协调器保留在内存中而不会被自动释放?

Nik*_*kur 7

我就这个问题向 Apple 提交了反馈,他们回复了以下修复程序。

WKInterfaceAuthorizationAppleIDButton 不会触发带有发件人参数的操作。此处的解决方法是停止在 buttonPressed 上指定发件人参数。所以:

@objc func buttonPressed(_ sender: WKInterfaceAuthorizationAppleIDButton)
Run Code Online (Sandbox Code Playgroud)

变成

@objc func buttonPressed()
Run Code Online (Sandbox Code Playgroud)

然后行:

WKInterfaceAuthorizationAppleIDButton(target: context.coordinator, action: #selector(Coordinator.buttonPressed(_:)))
Run Code Online (Sandbox Code Playgroud)

变成

WKInterfaceAuthorizationAppleIDButton(target: context.coordinator, action: #selector(Coordinator.buttonPressed))
Run Code Online (Sandbox Code Playgroud)

上述更改解决了我的问题,我已经在真实设备上进行了相同的测试。希望有人觉得这很有用。