Post

Replies

Boosts

Views

Activity

Reply to UIDocumentPickerViewController -initForOpeningContentTypes: gives URL to app without permission to read it in Release mode only
What do you mean by “debug mode”? I mean in Debug mode on my iPhone (not the simulator) running iOS 15.6.1 if I selected a file via UIDocumentPickerViewController (using -initForOpeningContentTypes:) I was able read/load the selected file without issue (a call to -startAccessingSecurityScopedResource was not required). However, when I archived and Airdropped a release build to the iPhone the sandbox denied permission to read the file. This made it hard to catch the issue during development. By your reply this sounds like this would be considered a bug?
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’22
Reply to SKOverlay frame size
What about on orientation change? Delegate method isn't called when the orientation changes. If my current view controller has an overlay feels like I should be able to access the frame at anytime...to make sure my content doesn't overlap the overlay? Perhaps something like this? @interface UIWindowScene (SKOverlay) @property (nullable,nonatomic,strong,readonly) SKOverlay *presentedOverlay; @end @interface SKOverlay (FrameInView) -(void)overlayFrameConvertedToView:(UIView*)view; @end //From my view controller... -(void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; UIWindowScene *scene = self.view.window.windowScene; SKOverlay *presentedOverlay = scene.presentedOverlay; if (presentedOverlay == nil) { //No overlay...layout } else { //overlay is showing...don't place anything inside its rect... CGRect overlayRect = [presentedOverlay overlayFrameConvertedToView:self.view]; } } Why doesn't SKOverlay provide a frame/API to convert its current rect into any arbitrary view in the same window scene? I'm assuming the SKOverlay is being shown in a different UIWindow....showing the SKOverlay doesn't even cause -viewSafeAreaInsetsDidChange to be called. Seems like this object can only be used in the simplest of view controllers.
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’22
Reply to UIDocumentPickerViewController -initForOpeningContentTypes: gives URL to app without permission to read it in Release mode only
Using -initForOpeningContentTypes:asCopy: and passing in YES for the asCopy parameter seems to work. I guess I have to use -startAccessingSecurityScopedResource and -stopAccessingSecurityScopedResource if I use -initForOpeningContentTypes: (haven't tried yet). Would be great if this behavior was consistent in debug and release mode.
Topic: UI Frameworks SubTopic: UIKit Tags:
Sep ’22
Reply to Both ios-x86_64-simulator and ios-arm64-simulator represent two equivalent library definitions. XCFramework for iOS simulator on M1 & Intel Mac? How?
So I ended up using lipo to combine the Simulator builds into one (M1 and Intel), then created the XCFramework and everything worked fine. Every post from Apple on the developer forums seems to strongly recommend against using lipo but I could not find another way to make this work. Since I build OpenSSL from Terminal, I'm not sure if there is an option I could use to build for both M1/Intel iOS simulators in one shot. Do command line tool provide a way to build for the Intel simulator even on an M1 Mac? I built the library for the simulator on the Intel machine and Air dropped it over so I could lipo them together. Feels like this should be easier though.
Topic: App & System Services SubTopic: General Tags:
Aug ’22
Reply to Are in-app purchase receipts included in the App Store receipt on initial install on a new device?
To your question, yes, the app receipt after a new install on a 2nd device after you had already subscribed would contain the past purchase. Note that if the 2nd device already has the app installed before the 1 set device made the purchase, then it would not. Thanks a lot for sharing this information. I had no idea using using server receipt validation also implicitly refreshed the receipt. For the case of Auto renewable subscriptions especially this is a bit of a bummer. I was expecting/hoping StoreKit would push an auto-renewable subscription purchase to all devices logged in with the same Apple ID via SKPaymentQueue, but it does not until at least the first iAP receipt for the subscription is active on the device. Couldn't a manual call to -restoreCompletedTransactions on SKPaymentQueue achieve the same thing at launch (if determined that no iAP receipt is present). This is a single method call and the code would be way simpler. I'm aware that using server side receipt validation has other benefits but I'm specifically referring to proactively restoring in app purchases. Local receipt validation wasn’t discussed specifically because it won’t have the latest purchase status reliably, therefore you can’t create this experience accurately. Therefore to create such an experience you will either need to adopt StoreKit2 or use verifyReceipt with app receipts. I can still think of a way that this won't provide exactly the user experience I was hoping for. On app launch use server-side receipt validation. Install the app both on two devices, an iPhone and an iPad. Launch the app on both devices. Subscribe to an auto renewable subscription on an iPhone. Since the app is already running on the iPad, server side receipt validation already finished before the purchase made on the iPhone completed, so the user still needs to use the "Restore in app purchases button" manually If the server pushed auto renewable subscription purchases to all devices logged in with the same Apple ID developers wouldn't have to worry about such timing issues. I suppose it would be possible for developers to manually implement this with either with their own server or CloudKit, but it would be really nice if StoreKit just did it.
Topic: App & System Services SubTopic: StoreKit Tags:
Jul ’22
Reply to Are WatchOS storyboards forbidden now ?
But having to develop in the same app, iOS part with UIKit storyboard and WatchOS part with SwiftUI, with completely different design logic, remain problematic. +1. And plus Objective-C can't be used to make Watch apps anymore? That's just awful. They are jumping the shark.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Jul ’22
Reply to I can't log out of iCloud in Simulator
This bug has been around for a long time. I also would like to test how my app behaves when the user signs out of iCloud while my app is running in memory. I'd rather not test this on my real device because logging out of my iCloud account has side effects with tons of apps using iCloud and I don't want to accidentally lose data. Would be great if we got better simulator support. I can sign in, but can't sign out.
Jun ’22
Reply to Are in-app purchase receipts included in the App Store receipt on initial install on a new device?
@endecotp I'm not sure why they recommend a server side approach to proactively restore in app purchases since that can be affected by network conditions if the receipt includes previous app purchases on initial install. Would be nice to know officially if this is the case or not. There may be some odd corner-cases where you don’t, so do have a “restore purchases” button. Indeed I do have a restore in app purchase button. Back when iTunes backups included apps I assume the receipt would need to be refreshed when installed on a new device. I assume this is still true if the the user installs the app using third party backup software instead of downloading from the App Store.
Topic: App & System Services SubTopic: StoreKit Tags:
Jun ’22
Reply to NSDocument, callback when renaming document from title bar
Try overriding -moveToURL:completionHandler: on NSDocument - (void)moveToURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler { [super moveToURL:url completionHandler:^(NSError * _Nullable theError) { if (theError == nil)         { //no error, file was moved.... } else { //error..... } //Call the original completion handler         if (completionHandler != nil) { completionHandler(theError); } }]; }
Topic: UI Frameworks SubTopic: AppKit Tags:
Jun ’22
Reply to Run CloudKit App Using the Production Environment From Xcode?
Right. But my question was about running from Xcode with the debugger attached. Apparently you can't run the app from Xcode (anymore?) using the entitlement I linked in my previous answer (I saw an old answer on Stackoverflow that seemed to indicate that using this entitlement was possible at some point). When I try I get a code signing error: "Provisioning profile "iOS Team ProvisioningProfile: My.ProfileName" doesn't match the entitlements file value for "com.apple.developer.icoud-container-environment entitlement. I tried creating a provisioning profile manually but with no luck.
Topic: Code Signing SubTopic: Entitlements Tags:
Jun ’22
Reply to UINavigationController's interactivePopGestureRecognizer sometimes causes the popped view controller to never be released (memory leak)
Just to add (for anyone else out there interested), reproducing the issue is a bit tricky. You have to invoke the interactive pop gesture a certain way to get the table view delegate method to be called, and then just pop it off in one motion. For me I set a log in -(nullable UISwipeActionsConfiguration*)tableView:(UITableView*)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath*)indexPath { NSLog(@"-leadingSwipeActionsConfigurationForRowAtIndexPath called"); UISwipeActionsConfiguration *theConfig; //make the object and return it.. return theConfig; } I also set a log in dealloc to verify whether or not the view controller is released. So I have to play with it a few times, push and pop the view controller. But when I see the log in -leadingSwipeActionsConfigurationForRowAtIndexPath: and I still have my finger down (and the interactive pop gesture is still recognizing my touch) and I pop off the view controller, my log in dealloc does not show up and the view controller leaks. I carefully went through each UIContextualAction I pass to the UISwipeActionsConfiguration and do a __weak and __strong dance like this: __weak MyViewController *weakSelf = self;    UIContextualAction *myAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal                                                                                          title:actionTitle                                                                                        handler:^(UIContextualAction *action,                                                                                                  UIView *sourceView,                                                                                                  void (^completionHandler)(BOOL))  { __strong MyViewController *strongSelf = weakSelf; //do whatever to respond to the action using strongSelf. }]; I believe this has now allowed my view controller to be released when I reproduce the issue, since the UIContextualActions don't retain the view controller in their action handlers. I think the UISwipeActionsConfiguration is still leaking though....with no obvious way for me to clear it when the view controller gets popped off the navigation stack (UISwipeActionController is private API). But at least the leak is not as bad. Instruments leak tool never picked up this leak I only found it by unexpectedly hitting breakpoints on a view controller that wasn't supposed to be in memory.
Topic: UI Frameworks SubTopic: UIKit Tags:
Jun ’22
Reply to UIDocumentPickerViewController -initForOpeningContentTypes: gives URL to app without permission to read it in Release mode only
What do you mean by “debug mode”? I mean in Debug mode on my iPhone (not the simulator) running iOS 15.6.1 if I selected a file via UIDocumentPickerViewController (using -initForOpeningContentTypes:) I was able read/load the selected file without issue (a call to -startAccessingSecurityScopedResource was not required). However, when I archived and Airdropped a release build to the iPhone the sandbox denied permission to read the file. This made it hard to catch the issue during development. By your reply this sounds like this would be considered a bug?
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to SKOverlay frame size
What about on orientation change? Delegate method isn't called when the orientation changes. If my current view controller has an overlay feels like I should be able to access the frame at anytime...to make sure my content doesn't overlap the overlay? Perhaps something like this? @interface UIWindowScene (SKOverlay) @property (nullable,nonatomic,strong,readonly) SKOverlay *presentedOverlay; @end @interface SKOverlay (FrameInView) -(void)overlayFrameConvertedToView:(UIView*)view; @end //From my view controller... -(void)viewDidLayoutSubviews { [super viewDidLayoutSubviews]; UIWindowScene *scene = self.view.window.windowScene; SKOverlay *presentedOverlay = scene.presentedOverlay; if (presentedOverlay == nil) { //No overlay...layout } else { //overlay is showing...don't place anything inside its rect... CGRect overlayRect = [presentedOverlay overlayFrameConvertedToView:self.view]; } } Why doesn't SKOverlay provide a frame/API to convert its current rect into any arbitrary view in the same window scene? I'm assuming the SKOverlay is being shown in a different UIWindow....showing the SKOverlay doesn't even cause -viewSafeAreaInsetsDidChange to be called. Seems like this object can only be used in the simplest of view controllers.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to UIDocumentPickerViewController -initForOpeningContentTypes: gives URL to app without permission to read it in Release mode only
Using -initForOpeningContentTypes:asCopy: and passing in YES for the asCopy parameter seems to work. I guess I have to use -startAccessingSecurityScopedResource and -stopAccessingSecurityScopedResource if I use -initForOpeningContentTypes: (haven't tried yet). Would be great if this behavior was consistent in debug and release mode.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Sep ’22
Reply to Subscriptions Status Stuck "Developer Action Needed" "Submit for Review" button grayed out in App Store Connect. Cannot submit revised app.
Someone else reported this on Stackoverflow: https://stackoverflow.com/questions/73483102/appstoreconnect-developer-action-needed-status-wont-go-away Guess I'm stuck waiting on Apple to respond to my case number.
Replies
Boosts
Views
Activity
Aug ’22
Reply to Both ios-x86_64-simulator and ios-arm64-simulator represent two equivalent library definitions. XCFramework for iOS simulator on M1 & Intel Mac? How?
Thanks a lot for clarifying!
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’22
Reply to Both ios-x86_64-simulator and ios-arm64-simulator represent two equivalent library definitions. XCFramework for iOS simulator on M1 & Intel Mac? How?
So I ended up using lipo to combine the Simulator builds into one (M1 and Intel), then created the XCFramework and everything worked fine. Every post from Apple on the developer forums seems to strongly recommend against using lipo but I could not find another way to make this work. Since I build OpenSSL from Terminal, I'm not sure if there is an option I could use to build for both M1/Intel iOS simulators in one shot. Do command line tool provide a way to build for the Intel simulator even on an M1 Mac? I built the library for the simulator on the Intel machine and Air dropped it over so I could lipo them together. Feels like this should be easier though.
Topic: App & System Services SubTopic: General Tags:
Replies
Boosts
Views
Activity
Aug ’22
Reply to Are in-app purchase receipts included in the App Store receipt on initial install on a new device?
To your question, yes, the app receipt after a new install on a 2nd device after you had already subscribed would contain the past purchase. Note that if the 2nd device already has the app installed before the 1 set device made the purchase, then it would not. Thanks a lot for sharing this information. I had no idea using using server receipt validation also implicitly refreshed the receipt. For the case of Auto renewable subscriptions especially this is a bit of a bummer. I was expecting/hoping StoreKit would push an auto-renewable subscription purchase to all devices logged in with the same Apple ID via SKPaymentQueue, but it does not until at least the first iAP receipt for the subscription is active on the device. Couldn't a manual call to -restoreCompletedTransactions on SKPaymentQueue achieve the same thing at launch (if determined that no iAP receipt is present). This is a single method call and the code would be way simpler. I'm aware that using server side receipt validation has other benefits but I'm specifically referring to proactively restoring in app purchases. Local receipt validation wasn’t discussed specifically because it won’t have the latest purchase status reliably, therefore you can’t create this experience accurately. Therefore to create such an experience you will either need to adopt StoreKit2 or use verifyReceipt with app receipts. I can still think of a way that this won't provide exactly the user experience I was hoping for. On app launch use server-side receipt validation. Install the app both on two devices, an iPhone and an iPad. Launch the app on both devices. Subscribe to an auto renewable subscription on an iPhone. Since the app is already running on the iPad, server side receipt validation already finished before the purchase made on the iPhone completed, so the user still needs to use the "Restore in app purchases button" manually If the server pushed auto renewable subscription purchases to all devices logged in with the same Apple ID developers wouldn't have to worry about such timing issues. I suppose it would be possible for developers to manually implement this with either with their own server or CloudKit, but it would be really nice if StoreKit just did it.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Jul ’22
Reply to Are WatchOS storyboards forbidden now ?
But having to develop in the same app, iOS part with UIKit storyboard and WatchOS part with SwiftUI, with completely different design logic, remain problematic. +1. And plus Objective-C can't be used to make Watch apps anymore? That's just awful. They are jumping the shark.
Topic: UI Frameworks SubTopic: SwiftUI Tags:
Replies
Boosts
Views
Activity
Jul ’22
Reply to My Mac App Crashing on ARM-64 Devices After Calling NSURL -getResourceValue:forKey: with
I opened FB10445753 Any help is much appreciated. Thanks in advance.
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to I can't log out of iCloud in Simulator
This bug has been around for a long time. I also would like to test how my app behaves when the user signs out of iCloud while my app is running in memory. I'd rather not test this on my real device because logging out of my iCloud account has side effects with tons of apps using iCloud and I don't want to accidentally lose data. Would be great if we got better simulator support. I can sign in, but can't sign out.
Replies
Boosts
Views
Activity
Jun ’22
Reply to Are in-app purchase receipts included in the App Store receipt on initial install on a new device?
@endecotp I'm not sure why they recommend a server side approach to proactively restore in app purchases since that can be affected by network conditions if the receipt includes previous app purchases on initial install. Would be nice to know officially if this is the case or not. There may be some odd corner-cases where you don’t, so do have a “restore purchases” button. Indeed I do have a restore in app purchase button. Back when iTunes backups included apps I assume the receipt would need to be refreshed when installed on a new device. I assume this is still true if the the user installs the app using third party backup software instead of downloading from the App Store.
Topic: App & System Services SubTopic: StoreKit Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to NSDocument, callback when renaming document from title bar
Try overriding -moveToURL:completionHandler: on NSDocument - (void)moveToURL:(NSURL *)url completionHandler:(void (^)(NSError *))completionHandler { [super moveToURL:url completionHandler:^(NSError * _Nullable theError) { if (theError == nil)         { //no error, file was moved.... } else { //error..... } //Call the original completion handler         if (completionHandler != nil) { completionHandler(theError); } }]; }
Topic: UI Frameworks SubTopic: AppKit Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Run CloudKit App Using the Production Environment From Xcode?
Right. But my question was about running from Xcode with the debugger attached. Apparently you can't run the app from Xcode (anymore?) using the entitlement I linked in my previous answer (I saw an old answer on Stackoverflow that seemed to indicate that using this entitlement was possible at some point). When I try I get a code signing error: "Provisioning profile "iOS Team ProvisioningProfile: My.ProfileName" doesn't match the entitlements file value for "com.apple.developer.icoud-container-environment entitlement. I tried creating a provisioning profile manually but with no luck.
Topic: Code Signing SubTopic: Entitlements Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to Run CloudKit App Using the Production Environment From Xcode?
Ah, found the entitlement. com.apple.developer.icloud-container-environment. Documented here: https://developer.apple.com/documentation/bundleresources/entitlements/com_apple_developer_icloud-container-environment
Topic: Code Signing SubTopic: Entitlements Tags:
Replies
Boosts
Views
Activity
Jun ’22
Reply to UINavigationController's interactivePopGestureRecognizer sometimes causes the popped view controller to never be released (memory leak)
Just to add (for anyone else out there interested), reproducing the issue is a bit tricky. You have to invoke the interactive pop gesture a certain way to get the table view delegate method to be called, and then just pop it off in one motion. For me I set a log in -(nullable UISwipeActionsConfiguration*)tableView:(UITableView*)tableView leadingSwipeActionsConfigurationForRowAtIndexPath:(NSIndexPath*)indexPath { NSLog(@"-leadingSwipeActionsConfigurationForRowAtIndexPath called"); UISwipeActionsConfiguration *theConfig; //make the object and return it.. return theConfig; } I also set a log in dealloc to verify whether or not the view controller is released. So I have to play with it a few times, push and pop the view controller. But when I see the log in -leadingSwipeActionsConfigurationForRowAtIndexPath: and I still have my finger down (and the interactive pop gesture is still recognizing my touch) and I pop off the view controller, my log in dealloc does not show up and the view controller leaks. I carefully went through each UIContextualAction I pass to the UISwipeActionsConfiguration and do a __weak and __strong dance like this: __weak MyViewController *weakSelf = self;    UIContextualAction *myAction = [UIContextualAction contextualActionWithStyle:UIContextualActionStyleNormal                                                                                          title:actionTitle                                                                                        handler:^(UIContextualAction *action,                                                                                                  UIView *sourceView,                                                                                                  void (^completionHandler)(BOOL))  { __strong MyViewController *strongSelf = weakSelf; //do whatever to respond to the action using strongSelf. }]; I believe this has now allowed my view controller to be released when I reproduce the issue, since the UIContextualActions don't retain the view controller in their action handlers. I think the UISwipeActionsConfiguration is still leaking though....with no obvious way for me to clear it when the view controller gets popped off the navigation stack (UISwipeActionController is private API). But at least the leak is not as bad. Instruments leak tool never picked up this leak I only found it by unexpectedly hitting breakpoints on a view controller that wasn't supposed to be in memory.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Jun ’22