I am trying to make CloudKit Web service work by following the Apple Documentation at https://developer.apple.com/library/archive/documentation/DataManagement/Conceptual/CloudKitWebServicesReference/SettingUpWebServices.html
I am able to get the redirect URL from
curl --location 'https://api.apple-cloudkit.com/database/1/iCloud.Wasiq.Migraine/development/private/users/current?ckAPIToken=b440efde65bb8c1f45464598470f4cc73977f2c10d6c40587588ec9f1c1c56f0'
Now, with the redirect URL, if I login with Apple ID, I am expecting ckWebAuthToken
Documentations says If you did not specify a custom URL when creating the API token, register an event listener with the window object to be notified when the user signs in.
window.addEventListener('message', function(e) {
console.log(e.data.ckWebAuthToken);})
Here's a complete SwiftUI working project to reproduce the issue
import SwiftUI
import UIKit
import WebKit
struct ContentView: View {
@State private var loadWeb = false
@State private var url = ""
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundColor(.accentColor)
Text("Hello, world!")
.onTapGesture {
var request = URLRequest(url: URL(string: "https://api.apple-cloudkit.com/database/1/iCloud.Wasiq.Migraine/development/private/users/current?ckAPIToken=b440efde65bb8c1f45464598470f4cc73977f2c10d6c40587588ec9f1c1c56f0")!,timeoutInterval: Double.infinity)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { data, response, error in
guard let data = data else {
print(String(describing: error))
return
}
do {
let res = try JSONDecoder().decode(Root.self, from: data)
print("Getting URL")
self.url = res.redirectURL
self.loadWeb = true
print(res.redirectURL)
} catch let error {
print(error)
}
}
task.resume()
}
if(!loadWeb){
Spacer()
}
else{
WebView(url: $url)
}
}
.padding()
}
}
struct Root: Codable {
let redirectURL: String}
struct WebView: UIViewRepresentable {
@Binding var url: String
func makeCoordinator() -> WebView.Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> WKWebView {
let config = WKWebViewConfiguration()
let source = "window.addEventListener('message', function(e){ window.webkit.messageHandlers.logging.postMessage(e.data); })"
let script = WKUserScript(source: source, injectionTime: .atDocumentStart, forMainFrameOnly: false)
config.userContentController.addUserScript(script)
config.userContentController.add(context.coordinator, name: "logging")
let view = WKWebView(frame: UIScreen.main.bounds, configuration: config)
view.navigationDelegate = context.coordinator
view.load(URLRequest(url: URL(string: url)!))
return view
}
func updateUIView(_ uiView: WKWebView, context: Context) {
// you can access environment via context.environment here
// Note that this method will be called A LOT
}
class Coordinator: NSObject, WKNavigationDelegate, WKScriptMessageHandler {
func userContentController(_ userContentController: WKUserContentController, didReceive message: WKScriptMessage)
{
print("message: \(message.body)")
// and whatever other actions you want to take
}
let parent: WebView
init(_ parent: WebView) {
self.parent = parent
}
}}
When I tap on "Hello, World", the WebView gets loaded and asks the user to Sign in with Apple ID. After logging in, I do not see the ckWebAuthToken getting printed
Instead I see the following output
message: SOAuthorizationDidStart
message: {
authorization = {
"grant_code" = "ce619474218c0485182af8cf019684d2e.0.sruq.i5r0nMCZIKVEBma6p6FE5Q";
"id_token" = "";
state = "auth-sznjvrn0-6svd-pw2c-lwfy-47rd7n64";
};
event = AppSSOTakeoverDidComplete;
user = {
};}
message: {
event = WidgetBridgeComplete;
state = "auth-sznjvrn0-6svd-pw2c-lwfy-47rd7n64";}