Post

Replies

Boosts

Views

Activity

Reply to Cannot upload lower build number after higher build submission is approved
After more reading, I realized the following fact: iOS has different version number strategy than macOS. Specifically, an iOS app's version number typically looks like major.minor.patch (build), whereas for macOS app it looks like major.minor.patch. No build number for macOS app due to historical reasons. On iOS, major.minor.patch = CFBundleShortVersionString, and build = CFBundleVersion on macOS, major.minor.patch = CFBundleVersion Which causes problem for a cross platform app that used to be iOS only, but recently start to support macOS via Mac Catalyst (exactly our case. =_=!) The app versioning used to work well with iOS versioning pattern major.minor.patch (build) where the "must contain a higher version" requirement only applies to the build part when the version number is the same. If the version is different, no need to compare build at all. But on macOS, because there is no build number, it directly compares the major.minor.patch version number, which unfortunately uses the same dict key CFBundleVersion as on iOS. Thus, the single component build number on iOS, becomes the sole number for macOS version comparison. That doesn't pose a problem if your app's build increases daily. But it causes huge problem if you assign the build manually when you do the App Store upload, like us. How to solve it? Well, I hope App Store Connect can add some special handling for cross-platform app that originated from iOS, to first compare the version number via CFBundleShortVersionString, so that CFBundleVersion can be treated as a build number to be used for further comparison. Otherwise, we have to discard the 20-million integers (20240801 to be exact) we've inadvertently wasted for the macOS version number. 😩
Aug ’24
Reply to Cannot upload lower build number after higher build submission is approved
Today we meet this problem again. The Mac App Store published version 200.5.0 (20240801) causes the daily build 200.6.0 (4318) to fail to upload. Which doesn't make sense in several ways: The version number of the daily build is greater, so the build number shouldn't even be compared! After submission got published, I have expired the TestFlight build for 20240801, so it shouldn't play a role in version comparison at all! Why does an approved and published app build should affect anything in TestFlight? Why iOS TestFlight doesn't have this problem, only MacOS does?? In case someone find this thread with the same problem, I'll try Feedback Assistant and see what Apple says. Likely that we need to adjust our build number pattern to cater them. πŸ₯€
Aug ’24
Reply to Why use async/await vs completion handlers?
I have a follow up question - I see many Apple APIs have auto-generated async counterparts of their old completion block/escaping closure version. Aside from the "sequential" vs "pyramid" styling differences, are there any other underlying differences, such as async/await is based upon Swift Concurrency vs escaping closure is using GCD/Dispatch? The reason I ask is that sometimes in our codebase people accidentally use the escaping closure version of the API in synchronous context, such as onAppear modifier of a view, while ideally the async version should really be used in a task modifier. Does using completion-block based API cause performance degradation or mess up the Swift Concurrency model? Are all the APIs with async wrappers have been bridged using continuation? Thanks.
Jul ’24
Reply to Memoization in SwiftUI views
We are actually using this pattern quite a lot in our framework and demo apps. As you may find, computing resource-intensive mapping related objects is time consuming! We have even written a doc - "Working with Geo Views | ArcGIS Documentation" (albeit concise) to explain the right pattern for using our framework. πŸ˜„ And your assessment is correct - State property wrapper and its initializer should not be used with an injected variable - it should only be used with a constant or created within the view. StateObject's initializer can be used, but with caution.
Jun ’24
Reply to Xcode 15.3 and iOS 17.4 generate a CPU spike when launching the app
I have seen similar log for ARKitCore. It seems to be an ARKit internal issue. Thread Performance Checker: Thread running at User-initiated quality-of-service class waiting on a lower QoS thread running at Default quality-of-service class. Investigate ways to avoid priority inversions PID: 14603, TID: 6216861 Backtrace ================================================================= 3 ARKitCore 0x00000001cb1bfd68 531C4275-B554-3D3A-88B7-3C9CE4D952C3 + 441704 4 libdispatch.dylib 0x0000000101f88f50 _dispatch_call_block_and_release + 32 5 libdispatch.dylib 0x0000000101f8ab34 _dispatch_client_callout + 20 6 libdispatch.dylib 0x0000000101f9298c _dispatch_lane_serial_drain + 832 7 libdispatch.dylib 0x0000000101f9375c _dispatch_lane_invoke + 460 8 libdispatch.dylib 0x0000000101f94d6c _dispatch_workloop_invoke + 2336 9 libdispatch.dylib 0x0000000101fa05f8 _dispatch_root_queue_drain_deferred_wlh + 328 10 libdispatch.dylib 0x0000000101f9fc2c _dispatch_workloop_worker_thread + 444 11 libsystem_pthread.dylib 0x0000000205f2f964 _pthread_wqthread + 288 12 libsystem_pthread.dylib 0x0000000205f2fa04 start_wqthread + 8
Mar ’24
Reply to Why does custom Binding not update UI
I have a similar problem. The root cause is not the custom binding, but is related to observation mechanism. While my understanding is the same as the accepted reply above - non-observable object won't trigger UI updates correctly, the behavior is unexpected on iOS vs Mac Catalyst. Consider the code snippet below import SwiftUI class BoolWrapper { var value = false { didSet { print("Value changed to \(value)") } } } struct ContentView: View { @State private var wrapper = BoolWrapper() var body: some View { Toggle("Toggle example", isOn: $wrapper.value) } } #Preview { ContentView() } The expected behavior for this snippet is not to change the UI when the toggle is turned on/off, because the BoolWrapper object is not observable. However… On iOS, the toggle work normally. When it turns on, the UI correctly shows the tinted control, and the value is set to true On Mac Catalyst, the toggle checkbox's UI doesn't update, whereas the value still changes between true/false when I click the checkbox. My question is: Is the behavior on iOS unexpected, or "by accident"? It shouldn't work on iOS, but somehow it works. FB13698944 is logged for this issue. The code with correct behavior is like below, where the ObservableObject protocol is used. import SwiftUI class BoolWrapper: ObservableObject { @Published var value = false { didSet { print("Value changed to \(value)") } } } struct ContentView: View { @StateObject private var wrapper = BoolWrapper() var body: some View { Toggle("Toggle example", isOn: $wrapper.value) } } #Preview { ContentView() }
Mar ’24
Reply to Finding device heading with ARKit and ARGeoTrackingConfiguration
Another finding during our test is that, regardless of geo-tracking or world-tracking configuration, when I first manually adjust the heading of our custom view to be aligned with the AR view, then start to turn quickly around 360 degrees, or several circles consecutively, the custom view's heading alignment will drift drastically. In order to restore the alignment, I had to reset the session and re-localize, or manually calibrate the heading according to some visual reference POIs. Is it due to the device electronic compass' intrinsical limitation? Also, if there isn't a good answer to the original question, we might just end up presenting a toast to guide the user to manually adjust the heading, whenever it is mis-aligned with the AR view. Thanks.
Feb ’24
Reply to Finding device heading with ARKit and ARGeoTrackingConfiguration
We still need the answer to this question. Our usecase in short: ❓ For ARGeoTrackingConfiguration, we want to set a custom view to have the same heading as the AR camera, so it can provide geo-referenced symbol with correct heading in real world. However, we couldn't find the right way to access AR camera's heading. βœ… For ARWorldTrackingConfiguration, setting the custom view heading to zero and AR config worldAlignment = gravityAndHeading makes their headings aligned. More details: I tried many approaches for the custom view's heading. Euler Angle seems to be the most promising, but we don't know how to exactly interpret that vector. i) setting heading to zero, ii) setting heading to the most recent compass heading, iii) using AR camera’s eulerAngles, iv) tinkering with the transformation matrix. When I used the recorded data following Recording and Replaying AR Session Data tutorial, I found that the initial heading deflection is almost always the same value, no matter when the AR session becomes localized. My assumption is that - when the geo-tracking gets localized, it provides additional tracking information so the AR frame is somehow geo-referenced. In contrast, the world tracking doesn’t have anchors, thus using zero as initial heading is fine. Apple's WWDC demo in San Francisco seems to have hardcoded the orientation of the 3D text? From the public demo projects in the documentation, I didn't find a way to get the heading for ARGeoTrackingConfiguration.
Feb ’24
Reply to Is ARGeoTrackingConfiguration always more accurate than ARWorldTrackingConfiguration for world scale AR?
Thanks for your response. That doesn't quite answer my question though. Before ARGeoTrackingConfiguration was available in ARKit 4, we used to use ARWorldTrackingConfiguration and a custom method to periodically calibrate/sync the location between the AR view and our 3D-map scene view, so our scene doesn't drift too much in regards to the AR camera feed, as the device move around 10+ meters. With the addition of ARGeoTrackingConfiguration and when street imagery/geo-anchors are available on the main streets, we now find the accuracy of ARFrame camera really good, resulting in smooth experience and much less calibration needed. πŸ‘ However, when street imagery aren't available, say we move from a main street into a neighborhood, so the geo-tracking accuracy drops from medium to low or even undetermined, we need to fallback to something. The question is: should we fallback to a new session with ARWorldTrackingConfiguration and use our old periodic calibration approach, or should we keep using ARGeoTrackingConfiguration and add some custom calibration logic to compensate for the low/undetermined accuracy? It largely depends on if the session(_:didUpdate:) method in geo-tracking configuration always provides the accuracy as good as or better than world tracking. In other words, is geo-tracking a superset of features of world tracking in this regard? From our own ad-hoc testing, we cannot tell for sure. 🫀 It almost seems like when street imagery isn't available, geo-tracking's accuracy sometimes is worse than world tracking, though only by a small margin. Also we found that when geo-tracking is trying to re-localize using street imagery, the ARFrame's camera might be unstable for a short period. To sum up, we want to smoothly handle the case when geo-tracking starts to become unstable, or street imagery based geo-tracking is completely unavailable, to use custom logics to keep our scene aligned with the AR view. Is it possible to achieve it solely with a session configure with ARGeoTrackingConfiguration?
Jan ’24