Post

Replies

Boosts

Views

Activity

Detecting Local Network issues with NWListener
I have an application that uses Bonjour to communicate with other instances of the app on other devices. If I start an NWBrowser and the user has "Local Network" turned off for my app, the stateUpdateHandler for the browser gets .waiting with an error containing the string "PolicyDenied." This lets me show an alert to the user explaining what's happening, with a link to the app's Settings screen. But if I use NWListener (the counterpart of NWBrowser) and have "Local Network" turned off, there's no indication of any problem. After I start the listener, stateUpdateHandler is called with .ready as the state - even though it's not really ready to listen at all. The FAQ for Local Network Privacy suggests that any Bonjour operation will raise kDNSServiceErr_PolicyDenied if Local Network is off. However, in my application, that only seems to be true for browsing, not listening. Is there a way to detect a missing Local Network entitlement for NWListener? I know there are solutions involving sending a message to localhost, etc, but ideally there would be something simpler.
1
0
108
1w
Sendability for Stream, InputStream, etc.
I have a project with some legacy networking code that uses the Stream (formerly NSStream) family of classes, including Stream, InputStream, OutputStream, and StreamDelegate. None of these are sendable, so I get a lot of warnings when implementing delegate methods in a @MainActor class. These classes seem like they could be sendable. Is this something that will happen soon? Is it a bug I should report? The networking code that uses these classes runs great, and hasn't needed changes for years, so my current solution is to just mark these unchecked: extension Stream: @unchecked Sendable { } extension InputStream: @unchecked Sendable { } extension OutputStream: @unchecked Sendable { } This makes the compiler happy, but makes me feel kind of bad. Is there something else I could do?
1
0
115
1w
How do I handle changes from sync with Swift Data?
In Core Data, you can use a pinned query generation to make sure that your app is working from a consistent view of the data store. If you have CloudKit sync turned on, and new changes come in that invalidate relationships, your app won't see them right away as long as it's looking at a pinned query generation. Since Swift Data doesn't yet support query generations, how do I deal with this issue in Swift Data apps? For example, let's say I have an address book app. I open a particular contact, and then tap a control on the screen that opens a list of images for that contact. While looking at the images, CloudKit sync retrieves changes made by other devices, which have completely removed the parent contact. How does my app know this has happened? Suppose the image browser screen needs to refer to the parent contact, or make changes to it, but the contact is no longer there because a background sync removed it.
1
0
167
2w
Show a UIMenu on double-tap?
Is there a way to programmatically show a UIMenu on iOS on a double-tap event? I have an app that's been around for over a decade, so there are some UX patterns that I'm reluctant to mess around with. There is a view in my app with the following properties: Tapping the view once focuses it and brings it to the front Double-tapping it shows a view controller as a sheet, with several operations you can perform on that object Instead of the sheet, I'd like to move to context menus - they look better, and they're more familiar for users. Obviously, adding a context menu for long-press is straightforward (just use UIContextMenuInteraction). But there does not seem to be a way to show the context menu on double-tap. I've discovered that you can use UIButton with showsMenuAsPrimaryAction to show the menu on single-tap, but that doesn't quite work for me. My users expect a single tap to do something else (focus the view) and will be annoyed if single taps start showing menus instead. So, is there a way to show a context menu on double tap in iOS?
1
0
160
2w
How do I resolve conflicts with SwiftData?
SwiftData includes support for CloudKit sync. However, I don't see any way to add conflict resolution behavior. For example, if different devices set different values for a field, or if a relationship is orphaned because of a deletion on another device, the application has to handle this somehow. In Core Data (which SwiftData wraps), you can handle this with the conflict resolution system (docs) and classes like NSMergePolicy. Is any of this accessible in SwiftData? If not, how do you deal with conflicts when syncing a SwiftData model with the cloud?
2
1
357
May ’24
Run UI tests on multiple devices in succession?
The new test report, with the automatic video recording and scrubber, is great. I'm setting up different configurations for different languages to improve localization testing, but I was wondering if it was possible to make the simulator device type part of the configuration. For example, I'd like to have a single test plan with an "iPhone 14" test plan, an "iPad Air" test plan, etc. Then I would just press Cmd-U, and Xcode would run through each device in sequence, leaving me with videos of each test run that I could review in the test report. Is that possible?
2
0
1.6k
Jun ’23
How do I use Xcode Previews in an app that has to support iOS 16?
Xcode Previews are a great new feature, and I've been adding #Preview blocks to some of my more complex UIKit files so I can tweak their UI without running the app. It's been a blast so far. The only problem is that I apparently have to set my project deployment target to iOS 17.0 to use them at all. If I set it to iOS 16.0, I get these errors: 'Preview' is only available in iOS 17.0 or newer 'init (_:traits:body:' is only available in iOS 17.0 or newer 'UVPreviewRegistry' is only available in iOS 17.0 or newer 'Preview' is only available in iOS 17.0 or newer 'init (_:traits:body:' is only available in iOS 17.0 or newer I tried surrounding #Preview with an @availability block for iOS 17, but got the same errors. My goal is to be able to leave useful #Preview blocks in my source code, but still set my deployment target to iOS 16. Is this possible?
1
1
2.5k
Jun ’23
How can I tell if NetService#publish is failing because it lacks permissions?
I'm testing my app on iOS 14. One of its features involves listening for Bonjour connections on the local network using NetService#publish. When my app calls this method for the first time, I get the new iOS 14 popup asking the user if my app should have access to the local network. If they allow access, everything is fine. However, if the user denies access, my NetService delegate never receives netService(didNotPublish:). I was hoping to get an error code here that I could use to inform the user that the feature isn't working specifically because they disabled the Local Network permission. Unfortunately, this is not treated as an error condition - the only way I've found to detect this situation at all is that my netService(didPublish:) method never gets called if the Local Network permission has been disabled. Is there a better way to detect this situation and inform the user that the app needs Local Network access to continue?
6
0
1.7k
Aug ’20