Using UIApplicationDelegateAdaptor to get callbacks from userDidAcceptCloudKitShareWith not working
In Scene-based
application the userDidAcceptCloudKitShareWith
callback is posted to Scene delegate, but in SwiftUI 2.0 App-based
application the scene delegate is used by SwiftUI itself to provide scenePhase
events, but does not provide native way to handle topic callback.
The possible approach to solve this is to find a window and inject own scene delegate wrapper, which will handle userDidAcceptCloudKitShareWith
and forward others to original SwiftUI delegate (to keep standard SwiftUI events working).
Here is a couple of demo snapshots based on https://stackoverflow.com/a/63276688/12299030 window access (however you can use any other preferable way to get window)
@main
struct athlyticSocialTestAppApp: App {
@StateObject var shareDataStore = ShareDataStore.shared
@UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate
let sceneDelegate = MySceneDelegate()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(shareDataStore)
.withHostingWindow { window in
sceneDelegate.originalDelegate = window?.windowScene.delegate
window?.windowScene.delegate = sceneDelegate
}
}
}
}
class MySceneDelegate : NSObject, UIWindowSceneDelegate {
var originalDelegate: UISceneDelegate?
func windowScene(_ windowScene: UIWindowScene, userDidAcceptCloudKitShareWith cloudKitShareMetadata: CKShareMetadata) {
// your code here
}
// forward all other UIWindowSceneDelegate/UISceneDelegate callbacks to original, like
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
originalDelegate?.scene(scene, willConnectTo: session, options: connectionOptions)
}
}
How to get appdelegate like thing in swiftUI
You can create a custom class that conforms to UIApplicationDelegate
, and then use the @UIApplicationDelegateAdaptor
to tell your SwiftUI app about it:
class MyAppDelegate: NSObject, UIApplicationDelegate {
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
// your code here
}
}
@main
struct MyApp: App {
@UIApplicationDelegateAdaptor(MyAppDelegate.self) var appDelegate
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
Flow for setting up a social component in an app using 100% CloudKit and SwiftUI?
You don't have to use UICloudSharingController
, no. You can set up your own CKShare
object manually. It has a url
property that is what a user needs to click on in order to gain access to the CKRecord
you are sharing. So you can display the url
in a custom way or pass it around however you like.
The CKShare docs show all the available properties:
https://developer.apple.com/documentation/cloudkit/ckshare
This article is a little old, but it helped me see the overall process of setting up a CKShare
: https://kwylez.medium.com/cloudkit-sharing-series-creating-the-ckshare-40e420b94ee8
Related Topics
Swift Sort Dictionary by Value
Why Is the Swift Compiler Marking This as an Error
Accessor Gives the Wrong Value in Swift 1.2/2.0 Release Build Only
Uialertview Is Crashing App on iOS 7
Swift: Using "/" Slash in Filename with Createdirectoryatpath
How to Generate a Binding for Each Array Element
How to Share Data Between Tab View Controllers
Difference Between Dispatchsourcetimer, Timer and Asyncafter
Environmentobject VS Singleton in Swiftui
Uitableview Scrolls to Top on Reload
Extend Generic Array<T> to Adopt Protocol
Swift 2.0 'Inout' Function Parameters and Computed Properties
How to Use Trailing Closure in If Condition
Converting Swift 2.3 to Swift 3.0 - Error, Cannot Invoke 'Datatask' with an Argument List of Type'
Call External Function Using Watchkit Force Touch Menuitem
Opposite of _Conversion in Swift to Assign to a Value of a Different Type