Post

Replies

Boosts

Views

Activity

Reply to Multiple incoming connections on NWListener for single connection attempt
I am still not quite sure about the correct way to implement this. I want to establish a single working connection between my two devices and then shut down the NWListener and start using the established connection in my app. I was expecting only one of the incoming connections to enter the .ready state after accepting them, but they all do. They are also all reported as viable. My current solution is to send an initial message from the client over the connection and try to read from all the connections returned by the NWListener (once they are .ready ), and use the one connection through which I receive this message. This does work. But the warning messages the Network Framework prints to the console make me feel like I am doing it wrong?: [connection] nw_flow_add_read_request [C2 fe80::53:558d:8f79:9a0c%en2.60902 ready channel-flow (satisfied (Path is satisfied), viable, interface: en2, scoped)] already delivered final read, cannot accept read requests [connection] nw_read_request_report [C2] Receive failed with error "No message available on STREAM" Error receiving next message: POSIXErrorCode(rawValue: 96): No message available on STREAM. I am calling receiveMessage() on the connection immediately after it enters the .ready state. Is there a better way? Maybe wait for some amount of time, during which all but one connection should change from .ready to .cancelled? But what is the shortest time threshold that is guaranteed to be long enough?
Mar ’23
Reply to TCP + UDP connections via Bonjour
Allocate a TCP port dynamically, then try to allocate the same port on UDP, and loop on failure. Thank you. That sounds like a reasonable plan to me. What does 'loop on failure' mean? Repeatedly try to listen and connect on the same port? How likely is failure in this scenario (local connection between two devices with Bonjour providing the TCP connection).
Mar ’23
Reply to TCP + UDP connections via Bonjour
Thank you! Actually the second option sounds slightly easier to me. At least that way I am 100% guaranteed that both connections talk to the same device. Is there a downside to just picking some fixed port number (say 649) and using that for the UDP connection? Is there a risk that some wireless routers (I am just connecting locally) would block that port and Bonjour would find a non-blocked port?
Mar ’23
Reply to Getting PNG images from PHPicker currently broken in 15.1 beta
Yes, it is really unfortunate that it looks like this bug is going to ship in 15.1. I just confirmed that it is possible to work around this by getting the corresponding PHAsset via the assetIdentifier and then using the PHAssetResourceManager to request the PNG image data. Of course this requires asking for read access permission to the photo library, and dealing with all the complexities that come along with that.
Oct ’21
Reply to So, is SceneKit dead?
It is unfortunate that SceneKit appears to be abandoned. It would have been nice to get for example raytracing capabilities added into SceneKit. Feels like that would have been a fairly natural fit. I have always really liked SceneKit and want to thank the Apple engineers that worked on it. It is such a well designed system, especially for getting started quickly. When using plain OpenGL back in the days, the most painful painful and frustrating part of a project was often to get to the point when you could see a first triangle (or other 3D object) on screen. SceneKit made that so much faster and better by having smart defaults for automatic camera and light configuration. I think it probably fell short in its ambition to become a game engine able to compete with Unity, Unreal etc. I think the share of full-fledged games created in SceneKit compared to those engines has got to be tiny. But for just displaying some objects in 3D, making them look great and animating them in simple ways SceneKit still is fantastic. PS: Using SCNMaterialProperty.contents from type-safety obsessed Swift always amuses and delights me 😄 That's got to be one of the most promiscuous APIs Apple offers.
Jun ’21
Reply to Can you delete IAP entirely?
Were you successful in deleting the IAP and if yes, did it remove the "In App-Purchases" label on the App Store? I would love to know if this is possible, as I am currently considering adding IAPs to my app, and potentially removing them again later (while making sure no user will lose access to any features).
Oct ’20
Reply to UIMotionEffect Not Working in iOS 14?
Yes, UIMotionEffect is completely broken in iOS 14. I filed a bug report early on (FB8039897), but no reply or fix so far. Do file another bug report, - https://feedbackassistant.apple.com the more bug reports Apple gets about it, the more likely it is they are going to fix it.
Sep ’20
Reply to CloudKit watchOS 6 silent notification problem
In case you need to support current and/or earlier versions of watchOS, I received the following workaround through a TSI (tech support incident):To make CloudKit subscriptions / notifications work on your standalone WatchKit app, the app ID of your WatchKit app target has to be associated with the iCloud container ID. The current Xcode, however, doesn’t allow adding CloudKit capability to a WatchKit app target, and so you don’t have any way to make the association with Xcode.To work around this issue, you need to make the association manually, and the following steps should help you get to the point.1. Log in to the developer portal with your developer account and navigate to the App ID list page:Certificates, Identifiers & Profiles > Identifiers > App ID <developer.apple.com/account/resources/identifiers/list>2. Tap the app ID of your WatchKit app to navigate to the “Edit your App ID Configuration” page.The app ID should be something like <your_prefix>.watchkitapp. If you don’t see it, assuming you are using “Automatically manage signing”, which is highly recommended, follow these steps to let Xcode create it:a. Open your project with Xcode and pick your WatchKit app target.b. Tap Signing & Capabilities > + Capability and add App Group for the target.c. Uncheck the “Automatically manage signing” box, then check it back. This forces Xcode to synchronize with the portal.d. Refresh the App ID list page on the portal to find the app ID.Note that adding the App Group capability is to let Xcode create the app ID for you; you can remove the capability after seeing the app ID on the portal.Since you are with Xcode for now, please take this chance to make sure your WatchKit extension has the following capabilities:a. iCloud > CloudKit, with the right iCloud container picked.b. Push notifications. Xcode added this for you after you had added CloudKit capability.c. Background Modes > Remote notification, if you want to support silent notifications.3. On the “Edit your App ID Configuration” page, check the iCloud box, then click the “Configure” button to show the “iCloud Container Assignment” page, and check the iCloud container you would use on your app, then save the changes.4. On your testing devices, log out your iCloud account, and then log back in. This is very important because it forces watchOS to re-register the device for remote notification; without this step, watchOS may wrongly use a cached device token, which doesn’t reflect your manual association done above.You can do this with the following steps:a. Logging out iCloud on your paired iPhone.b. Make sure you see no iCloud account shown on your iPhone’s Watch app > General > App ID, and the Settings app on your watch.c. Log in to iCloud on your paired phone again; make sure the Watch app on your iPhone and Settings app on your watch showing the right status.d. Restart your iPhone and watch.5. Test CloudKit subscriptions / notifications with your app.a. On your Mac, go to “~/Library/MobileDevice/Provisioning Profiles” and remove all the profiles, which forces Xcode to download new ones from the portal.b. Remember to allow remote notification for your app. You can see that “Allow Notifications” is checked at iPhone Watch app > Notifications > Your app.c. Make sure WKExtensionDelegate’s didRegisterForRemoteNotifications(withDeviceToken:) is called with a device token every time your app is launched – If you don’t see the method being called, trying restarting Xcode and run again. I did see this method is not called sometimes, in which cases notifications won’t work.
Feb ’20