Post

Replies

Boosts

Views

Activity

CFBundleTypeIconFiles or UTTypeIconFiles?
Dear Experts, I'm attempting to make a custom icon appear in the iOS Files app, etc., for my file type. I've found a couple of bits of documentation for Info.plist keys: https://developer.apple.com/documentation/bundleresources/information_property_list/utexportedtypedeclarations/uttypeiconfiles describes UTTypeIconFiles, to be included in UTImportedTypeDeclarations. This documentation is very sparse! Older document https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/TP40009249-SW9 describes CFBundleTypeIconFiles, to be included in CFBundleDocumentTypes. Which of these should I be using? (Both? Neither?) Nothing I've tried so far has worked. I wonder if I need to, for example, power-cycle to make the Files app pick up the new icons. Also, in Xcode, I've found the Imported Type Identifiers section of the Info settings which has a box labelled "Add imported type identifiers here" - but clicking + and choosing a file does nothing; the box remains empty. Anyone else have that problem? What size should the icons be? The older document suggests some rather small sizes, e.g. 22x29; the newer doc says nothing. Suggestions anyone?
3
1
1.9k
Aug ’23
US Govt Agency asking to pay for app "outside the Apple payment process"
Dear All, I've just received an email from a user of my paid app who says he is no longer able to use it on his work phone. He works for a US government agency which I'll abbreviate to GOV below. Apparently they have started using Microsoft Intune for device management and as a result they need the following work-around: This app is not free to download, so it cannot be added to Intune app catalog through this tool. Reach out to the app developer and explain that GOV uses Apple Business Manager (ABM) and MDM for delivering managed apps to devices. Payment through ABM is not supported by GOV, so the app developer will need to provide a version of the app that's free to download but take payment outside of the Apple ID payment process. GOV's Custom App Store can be access by developers by advertising their app to Organization ID 12345678. I don't know much about MDM, ABM and Intune, and I would more or less consider this a scam except that I am confident that the person who has sent it really does work for this government agency and does use my app on his personal device. Is there any possibility that what they are asking for is legitimate? I suspect that the crucial part is: "Payment through ABM is not supported by GOV", i.e. fundamentally ABM/MDM/Intune can support paid apps, but the financial people at GOV AGENCY have chosen not to support that. Has anyone else experienced anything like this?
0
0
748
Aug ’23
App is terminated when user changes language
Dear Experts, NSLocale has a notification NSCurrentLocaleDidChangeNotification and a property autoupdatingCurrentLocale ("A locale which tracks the user’s current preferences"). These suggest that an app should be able to detect when the user changes their language preference while running, or when it is resumed from the background. In practice, when I change language in the Settings app (either globally or just for my app), the app is terminated by iOS and restarts with new locale. Is this the expected behaviour? I am wondering if there is something I need to do to advertise that the app can adopt language changes without restarting, or something. Maybe only date-time formats, etc., trigger the notification but language changes don't?
2
0
1.5k
Jul ’23
Thread QOS class
I see this warning when my app runs: Thread running at QOS_CLASS_USER_INTERACTIVE waiting on a lower QoS thread running at QOS_CLASS_DEFAULT. Investigate ways to avoid priority inversions This is true; I know what is going on. I'd like this other thread to have a higher priority. But how do I set the "QOS class" for a thread? Searching developer.apple.com for QOS_CLASS_USER_INTERACTIVE doesn't find much. It seems that dispatch queues have priorities, but in this case I have a thread, not a dispatch queue. Any ideas?
8
0
5.5k
Jul ’23
Make a new Xcode target that's a copy of an existing one
Dear Experts, Is there a way to create a new target in Xcode that is a copy of an existing target? Specifically, I have a standard iOS app target in the project. I'd like to build a second iOS app by adding a second target to the same project. I'd like it to start as a copy of the first target, and then I'll add and remove source files and frameworks, change assets and settings etc. It seems to me that I have to create a new target and then add all the source files etc to it, and then replicate all the settings. I've tried to do this, but it isn't working - bizarrely I just see a black screen, though log messages suggest that the app is running. I am unsure about whether the two targets are sharing e.g. the Info.plist file, etc. Any advice? Thanks.
2
0
2.7k
Jun ’23
How to update in-app purchase prices using the app store connect API
Documentation for the App Store Connect API is poor, especially in comparison to the good documentation for the now-defunct XML-based "transporter" API. In the hope that it will be useful to others trying to do this in the future, here is how I was able to do a bulk update of my in-app purchases' prices using the API. Step 1: get the IDs for the IAPs, if you don't already know them: GET v1/apps/$app/inAppPurchasesV2 If you have a lot of IAPs, follow any links/next URL to get subsequent pages. The ids are in data/id . Step 2: get the current prices, if you don't already know them. I believe you need to do a separate request for each IAP (right?). GET v1/inAppPurchasePriceSchedules/$iap/manualPrices?include=inAppPurchasePricePoint,territory The price and currency are in included/attributes/customerPrice and included/attributes/currency (I generally only have one "manual" price). Step 3: look up the available price points: GET v2/inAppPurchases/$iap/pricePoints?filter[territory]=$territory The prices and IDs are in data/attributes/customerPrice and data/id. Note this query takes the specific IAP ID. I don't know why. Are the price points specific to the IAPs? Can I reuse a price point ID that I've looked up for one IAP with another IAP for the same app? Step 4: choose your new prices. Step 5: Submit the new prices: POST v1/inAppPurchasePriceSchedules { "data" : { "relationships" : { "baseTerritory" : { "data" : { "id" : "$territory", "type" : "territories" } }, "inAppPurchase" : { "data" : { "id" : "$iap", "type" : "inAppPurchases" } }, "manualPrices" : { "data" : [ { "id" : "$random_id", "type" : "inAppPurchasePrices" } ] } }, "type" : "inAppPurchasePriceSchedules" }, "included" : [ { "attributes" : { "startDate" : null, "endDate" : null }, "id" : "$random_id", "relationships" : { "inAppPurchasePricePoint" : { "data" : { "id" : "$price_point_id", "type" : "inAppPurchasePricePoints" } }, "inAppPurchaseV2" : { "data" : { "id" : "$iap", "type" : "inAppPurchases" } } }, "type" : "inAppPurchasePrices" } ] } In that, $iap is the IAP ID from step 1, $territory is probably a three-letter string like GBR, $random_id is a random identifier that you generate (using the same value in the two places) (I'm not sure what the scope of this is; do I have to check that I don't accidentally send the same value in the future, or does it only exist while this submission is processed?), and $price_point_id is the ID for the price point from step 3. I believe it is necessary to send a separate submission for each IAP (right?) That example makes the change immediately (start and end dates are both null). Note that if you want to schedule a future change, you need to include both the current period and price and the future period and price in the submission. I would like to thank @Efun whose posts in this thread: https://developer.apple.com/forums/thread/727159 helped a lot with understanding this.
0
2
2k
Jun ’23
Debugging API JWT authorization problems - any suggestions?
Dear All, I have working code that talks to the App Attest receipt refresh API using JWT authorization. I'm now trying to talk to the App Store Connect API, and I'm trying to use essentially the same code for the JWT generation - but it doesn't work. It's frustrating that the API just returns a non-specific 401 "Not Authorized" response, without giving any further clue about what's wrong. I am creating a JWT as follows for App Store Connect; yes I'm aware that the required fields are slightly different for the two APIs: header = {"alg":"ES256","kid":"12345YZSX8","typ":"JWT"} payload = {"iss":"1234567-1234-1234-1234-123456789012","iat":1687379230,"exp":1687379530,"aud":"appstoreconnect-v1"} Using the resulting encoded token, with my own code or with curl, fails with a 401 error: Status: 401 { "errors": [{ "status": "401", "code": "NOT_AUTHORIZED", "title": "Authentication credentials are missing or invalid.", "detail": "Provide a properly configured and signed bearer token, and make sure that it has not expired. Learn more about Generating Tokens for API Requests https://developer.apple.com/go/?id=api-generating-tokens" }] } Doing essentially the same thing, with the slightly different JSON fields and a different .p8 key file, does work with the App Attest API - so I'm probably not creating complete garbage. I've wasted hours on this now. Does anyone have any debugging hints?
1
0
1.5k
Jun ’23
iOS-on-macOS app receipt not saved in recent macOS versions
Dear All, My iOS app used to work OK on macOS, but since a macOS update in-app purchases have stopped working. It seems that the storekitagent process is no longer able to save the receipt to the filesystem. Here is what I see in the system log after I do a "refresh receipt": default 22:03:47.822657+0100 storekitagent [58C16E76_SK1] Writing receipt (83905 bytes) to file:///Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt error 22:03:47.823539+0100 kernel Sandbox: storekitagent(1382) deny(1) file-write-unlink /Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt error 22:03:47.824306+0100 storekitagent [58C16E76_SK1] Error writing receipt (83905 bytes) to file:///Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt: Error Domain=NSCocoaErrorDomain Code=513 "You don’t have permission to save the file “sandboxReceipt” in the folder “StoreKit”." UserInfo={NSFilePath=/Users/phil/Library/Containers/0407ACA7-9EE2-4E32-AA3E-101A1B38EE70/Data/StoreKit/sandboxReceipt, NSUnderlyingError=0x145c19f80 {Error Domain=NSPOSIXErrorDomain Code=1 "Operation not permitted"}} Note that is a sandboxReceipt on my development system, but I have a report from a user who seems to be suffering the same problem with the app store version of the app. Is anyone else seeing this? Is there a "quick hack" I can do to grant the storekitagent process permission to write to that folder?
3
0
946
Jun ’23
Memory-mapped files in Allocations instrument
Dear Experts, Where do memory-mapped files appear in the Allocations instrument, if at all? In the screenshot below, the green "all anonymous VM" graph is almost completely explained by the purple "IO Accelerator" graph (GPU buffers, textures etc) - but there are periods at the start of each cycle (such as at the cursor position) where there is some other contribution. I have not been able to find this in the other more-specific graphs. Any ideas anyone? I have been trying to make this app better behaved memory-wise and have made a lot of progress, in particular by removing periods when two large memory allocations co-exist, and by breaking work up into chunks. It now bothers me that there is 150 MB of "anonymous VM" that I cannot explain!
1
0
1.2k
May ’23
Screenshots for 5.5" iPhone
I have a new app which requires iOS 16. App Store Connect wants me to upload screenshots of various sizes, mostly optional - but 5.5" with square corners and physical home button is required. As I understand it, the only device that can run iOS 16 and that has a 5.5" screen is the iPhone 8 plus. I have an iPhone 6 plus, which has the right dimensions, but it doesn't run iOS 16. The newer phones with physical home buttons (i.e. the SE 2 and 3) have 4.7" screens. Apple won't sell me anything older than an iPhone 12, even refurbished. Do I need to buy an iPhone 8 plus from eBay? Is there something that I can do to prevent the app from running on this device, and thereby make this screenshot size not required?
4
1
4.6k
Apr ’23
NSFilePresenter gets presentedItemDidChange every second when iOS app runs on Mac
When I run my iOS app on my Mac using "designed for iPad", it seems to get presentedItemDidChange for files it is displaying once every second. There don't seem to be any changes to the files in the filesystem. Is there any way to debug what is causing the app to receive the presentedItemDidChange callback?
0
0
520
Mar ’23
Can't simulator run same executable as device, now they are both ARM?
Dear Experts, Now that Macs have ARM processors - and in some cases, the exact same ARM processors as some iOS devices - why can't XCode's simulators run the same executables as the devices? Specifically, I can build my iPad app and run it on my iPad, and I can then run the exact-same app on my Mac, using the "My Mac - designed for iPad" target. So in that case, the Mac OS does whatever mapping is needed to run the iOS executable. But if I want to run on the Mac simulating a particular iPad device, I need to build a different executable. (This obviously made sense when the Mac was x86 and the iPad was ARM.) It's time consuming for me to create simulator builds mainly because of the third-party (i.e. mostly open-source) libraries that I link with, which need to be re-built for the simulator; often, cross-compiling these things is difficult enough to do once, let alone twice. My only use for the simulator is to test on devices with different screen sizes than the physical devices that I have. Running in "designed for iPad" mode and resizing the window is almost sufficient, but it doesn't let me see the effect of notch / round-corner safe area insets, and the display scale may be different. Thoughts anyone?
0
0
659
Mar ’23