Posts

Post not yet marked as solved
0 Replies
126 Views
I have a container view implementation that reads preference values from child views: public struct Reader<Content>: View where Content: View { public var content: () -> Content public init(@ViewBuilder content: @escaping () -> Content) { self.content = content } public var body: some View { content() .onPreferenceChange(NumericPreferenceKey.self) { value in // ... } } } This works fine until the content passed in to the container view is a Group. At that point the onPreferenceChanged modifier is applied to every child of the group, which leads to bugs in my situation. One thing I can do is simply put the content in a VStack: public var body: some View { VStack(content: content) .onPreferenceChange(NumericPreferenceKey.self) { value in // ... } } And that works fine to "Ungroup" before applying the onPreferenceChanged modifier. However, is this best practice? Is there a better way to apply a modifier to content as a whole instead of to each member of a potential group? Is it concerning that I might have an extra VStack in the view hierarchy with this fix?
Posted
by rolson.
Last updated
.
Post not yet marked as solved
3 Replies
833 Views
I am working on an app where I need to orient a custom view depending on the device heading. I am using ARKit and ARSCNView with the ARGeoTrackingConfiguration in order to overlay my custom view in real world geographic coordinates. I've got a lot of it working, but the heading of my custom view is off. Once the ARSession gets a ARGeoTrackingStatus.State of .localized, I need to be able to get the devices heading (0-360) so that I can orient my view. I'm having trouble figuring out how to do this missing piece. Any help is appreciated.
Posted
by rolson.
Last updated
.
Post not yet marked as solved
3 Replies
4k Views
I am working on a library, a Swift package. We have quite a few properties on various classes that can change and we think the @Published property wrapper is a good way to annotate these properties as it offers a built-in way to work with SwiftUI and also Combine. Many of our properties can change on background threads and we've noticed that we get a purple runtime issue when setting the value from a background thread. This is a bit problematic for us because the state did change on a background thread and we need to update it at that time. If we dispatch it to the main queue and update it on the next iteration, then our property state doesn't match what the user expects. Say they "load" or "start" something asynchronously, and that finishes, the status should report "loaded" or "started", but that's not the case if we dispatch it to the main queue because that property doesn't update until the next iteration of the run loop. There also isn't any information in the documentation for @Published that suggests that you must update it on the main thread. I understand why SwiftUI wants it on the main thread, but this property wrapper is in the Combine framework. Also it seems like SwiftUI internally could ask to receive the published updates on the main queue and @Published shouldn't enforce a specific thread. One thing we are thinking about doing is writing our own property wrapper, but that doesn't seem to be ideal for SwiftUI integration and it's one more property wrapper that users of our package would need to be educated about. Any thoughts on direction? Is there anyway to break @Published from the main thread?
Posted
by rolson.
Last updated
.
Post not yet marked as solved
1 Replies
562 Views
I am working on a project where we have a UIViewRepresentable View in the background of a SwiftUI View, and the preferences for the foreground view are getting clobbered. If I put the UIViewRepresentable View in the foreground (overlay), then preferences on the SwiftUI view are honored. If I use a native SwiftUI View in the background then the preferences are honored. Consider this code: import SwiftUI struct ContentView: View { var body: some View { MyView() .background() { BackgroundView() } .onPreferenceChange(MyPreferenceKey.self) { value in if let value { print("-- preference changed: \(value)") } else { print("-- preference changed to `nil`") } } } } struct MyView: View { var body: some View { Text("Hello") .preference(key: MyPreferenceKey.self, value: "Hello World") } } struct MyPreferenceKey: PreferenceKey { static func reduce(value: inout String?, nextValue: () -> String?) {} } struct BackgroundView: UIViewRepresentable { func makeUIView(context: Context) -> UIButton { UIButton() } func updateUIView(_ uiView: UIButton, context: Context) { } func makeCoordinator() -> Coordinator { Coordinator() } class Coordinator { init() {} } } BackgroundView is a UIViewRepresentable View. In this case the printed output is: -- preference changed to `nil` However, if you use .overlay instead of .background: MyView() .overlay { BackgroundView() } Then it prints: -- preference changed: Hello World Which is what it should. Is there a way to workaround this?
Posted
by rolson.
Last updated
.
Post marked as solved
2 Replies
553 Views
I’m trying to debug background session workflows. I read the excellent article Quinn wrote here: https://developer.apple.com/forums/thread/14855 I’m not seeing the call to exit(0) work for relaunching an app when a background URL Session completes. I’m also not getting the UIApplication.willTerminateNotification in that case. I am testing on an actual device and not hooked up to the debugger. Has anything changed since that article was published? Are there new tips for debugging background URLSession relaunch workflows?
Posted
by rolson.
Last updated
.
Post marked as solved
2 Replies
2.4k Views
Trying to implement a type that conforms to ASWebAuthenticationPresentationContextProviding. This is now causing errors with Xcode 14. With the following implementation:         final class PresentationContextProvider: NSObject, ASWebAuthenticationPresentationContextProviding {             func presentationAnchor(for session: ASWebAuthenticationSession) -&gt; ASPresentationAnchor {                 return ASPresentationAnchor()             }         } I get this compilation error: Call to main actor-isolated initializer 'init()' in a synchronous nonisolated context So I can annotate the class or method with @MainActor, but then I get this warning: Main actor-isolated instance method 'presentationAnchor(for:)' cannot be used to satisfy nonisolated protocol requirement Is there a way to fix this?
Posted
by rolson.
Last updated
.
Post marked as solved
3 Replies
1.6k Views
We build and deploy a dynamic framework that contains objective-c code. It consumes a "core" static library that contains C/C++ code. But we only consume it through the C interfaces. We don't have any Objective-C++ that we use to consume any of the C++ interfaces. It's all Objective-C in our framework consuming and linking in a static library through pure C headers. We are wondering if it is safe to consume the "core" static library if we build it with an older version of Xcode (LLVM). And if so, is it safe even for major version differences of compiler or minor only? thanks
Posted
by rolson.
Last updated
.