Delve into the world of built-in app and system services available to developers. Discuss leveraging these services to enhance your app's functionality and user experience.

Post

Replies

Boosts

Views

Activity

How to Test FinanceKit Transaction History in iOS?
Hello, I am currently developing an iOS application that leverages FinanceKit to access transaction history. I have already enabled FinanceKit in my developer account, but I am encountering challenges when trying to test the transaction history feature. Could anyone guide me on the best practices or specific steps needed to effectively test FinanceKit’s transaction history in a development environment? Any insights on mock data handling, API responses, or potential limitations during testing would be greatly appreciated. Thank you in advance for your help!
0
1
66
1w
How to Dynamically Obtain Device Models for App Store Users?
I'm currently pulling device-specific data for my app, and I'm manually listing 150 models like this: device_models = [ "iPhone1_1", "iPhone1_2", "iPhone2_1", ... "iPad16_6"] Is there an API endpoint or an automated method to dynamically retrieve a complete list of device models? I'm specifically looking to connect this with the performance metrics API to monitor launch times per device type. Any suggestions on how to streamline or automate this list would be greatly appreciated. Thanks!
2
0
119
1w
Compression LZMA2 (SWCompression)
Hi everyone, I am trying to compress my data using LZMA2 with the help of CocoaPods. Here are the steps I followed to achieve LZMA2 compression: Added the pod 'SWCompression', '~> 4.8' dependency to my Podfile and installed the pod using the terminal. When I try to compress the data using LZMA2, I am unable to do so because in SWCompression, LZMA2 compression is marked as TBD (To Be Determined). Here is the current status of SWCompression: Deflate BZip2 LZMA/LZMA2 LZ4 Decompression ✅ ✅ ✅ ✅ Compression ✅ ✅ TBD ✅ Zlib GZip XZ ZIP TAR 7-Zip Read ✅ ✅ ✅ ✅ ✅ ✅ Write ✅ ✅ TBD TBD ✅ TBD Since LZMA2 compression is still marked as TBD, is there any other way to achieve LZMA2 compression for my data in SwiftUI?
1
0
126
1w
PTT Bluetooth transmission does not work as expected
Hello, I've been working to implement PTT in the way recommended by the documentation. The main issue is that the bluetooth methods are opaque, so I cannot solve for what I need. The result will be that I will have to resort to hacky approaches that the PTT framework seems to be intended to solve (playing silent clips, playing custom notification sounds, having long running background audio sessions). I am testing with Anker soundcore mini as well as airpod pro. Here's the issue: there are 2 very different behaviours depending on whether I'm using a call/fullDuplex session and a halfDuplex session. halfDuplex Anchor mini Current behaviour long press activates siri pressing again after siri is active, starts transmission long press activates siri again pressing again after siri is active, stops transmission pause/play routes to the ongoing media session and plays music Expected behaviour play/pause should map to transmit/stopTransmit IF I have to use long press, it should at least not trigger siri AirPod pro Current behaviour long press changes noise cancellation pause/play routes to the ongoing media session and plays music Expected behaviour play/pause should map to transmit/stopTransmit fullDuplex/call Anchor mini: Current behaviour long press activates siri pressing again after siri is active, starts transmission long press activates siri again pressing again after siri is active, stops transmission pause/play routes to the ongoing media session and plays music Expected behaviour play/pause should map to transmit/stopTransmit IF I have to use long press, it should at least not trigger siri AirPod pro Current behaviour long press changes noise cancellation pause/play maps to mute/unmute (even if media is playing) Expected behaviour This makes sense for call behaviour, I wish it worked this well for PTT The intention here is to be able to fully interact with a channel hands-free. The current API seems to make that impossible. Is that by design? Reading all the docs seems to suggest its intended for transmit/stopTransmit to be doable just with the play/pause buttons, but even apple hardware seems to not support that.
0
0
118
1w
Bug with Transferable + AppEntity
Hello all, I'm finding myself with a compile error when trying to use a defined UTType for Transferable conformance when the type is also an AppEntity. The compiler error is Could not determine the identifier of `.todo`. Please use a UTType defined by the UniformTypeIdentifiers framework However, said compiler error only shows up after adding AppEntity conformance. So, in order to reproduce: Create any type, conform to Codable struct Todo: Codable { var id: UUID var title: String var completed: Bool } Create a UTType extension for the new type extension UTType { public static let todo: UTType = UTType(exportedAs: "org.nameghino.types.todo") } Add Transferable conformance extension Todo: Transferable { static var transferRepresentation: some TransferRepresentation { CodableRepresentation(contentType: .todo) ProxyRepresentation(exporting: \.title) } } At this point, the code compiles correctly on Xcode 16.2 beta 2 (16C5013f) Add AppEntity conformance extension Todo: AppEntity { static var typeDisplayRepresentation: TypeDisplayRepresentation = "todo_title" static var defaultQuery = Todo.Query() var displayRepresentation: DisplayRepresentation { DisplayRepresentation(title: "\(title)") } struct Query: EntityQuery { typealias Entity = Todo init() {} func entities(for identifiers: [UUID]) async throws -> [Todo] { return [] } func suggestedEntities() async throws -> [Entity] { return [] } } } Now the code is not compiling with the aforementioned error.
0
0
97
1w
MacCatalyst - How to share Userdefaults between widget and app
Hi, Firstly: The whole question is about MacCatalyst (in IOS it works as intended) In my Maccatalyst app I want to share Userdefaults between app and widget. I have added an app group to the widget and the app and have set up Userdefauls accordingly. Here is the problem: Xcode claims that the app group should start with "group.***" because Catalyst is based on iOS. If I do so, my Catalyst app rises the "App wants to access data from other apps" requester on EVERY launch. So, I can't use it in production. Even if I would accept the requester, the widget isn't able to access the defaults at all because it does not rise that requester, but silently ignores the access. In contrast, if I setup the app group name with our TeamID (instead of group.*) then the requester vanishes, but Xcode does not accept it, issuing a warning and displaying the app group in red. I don't think this is advisable 'state' for production code. Even then widget can't see the data either. What is the recommended way of sharing Userdefaults between Catalyst app and Catalyst Widget (not the iOS widget which displays the "open on iPhone warning" when clicked) on macOS ? Thanks
3
0
154
1w
How to navigate user to specific device settings programatically?
We have a requirement where we have to navigate user to specific section (Passwords) in device settings on tap of a button. I've seen other popular apps doing it & also seen some solutions where people provided an option of using "App-prefs". But as per documentation, this is a private API. What is the solution here if I want to open specific section in device settings without taking a chance of my app getting rejected while submission process?
2
0
67
1w
We were unable to review the app because it crashed on launch.
Hello, our app gets rejected as it crashes on launch. According to the logs, it happens because the app attempts to access private-sensitive data. We don't collect any of personal data, so it is probably done by Google Firebase embedded in the app (Core, Firestore, Auth). Maybe you have met similar cases and know any of Firebase settings that disable attempts of accessing privacy-sensitive data? We already set FirebaseDataCollectionDefaultEnabled to NO in info.plist, but it still not enough. Maybe error in facebook sdk? Before that it was written that there was an error when starting the ipad air 5 Log1 Log2 Log3
0
0
98
1w
"UID -2" in btmdump output
Within the output of command "sudo sfltool dumpbtm", in addition to records for UID 0/501/502/..., at the top of the output, there are also records for "UID -2" listed. ======================== Records for UID -2 : FFFFEEEE-DDDD-CCCC-BBBB-AAAAFFFFFFFE ======================== ServiceManagement migrated: true SharedFileList migrated: false LaunchServices registered: false Items: #1: UUID: FC60A3EA-E4B0-4D8C-BA07-1C6E2DF3AA52 Name: (null) Developer Name: (null) Type: developer (0x20) Flags: [ ] (0) Disposition: [disabled, allowed, visible, not notified] (0x2) Identifier: Unknown Developer URL: (null) Generation: 0 Embedded Item Identifiers: #1: 16.com.microsoft.teams.TeamsUpdaterDaemon But a uid with -2 should be invalid, and the guid "FFFFEEEE-DDDD-CCCC-BBBB-AAAAFFFFFFFE" followed looks also strange.
2
0
136
1w
Error: com.apple.AuthenticationServices.Authorization Error Code 1000
I am getting this error when trying to run the app on an actual IOS device using testFlight. It works well on simulators. I am using expo to build my app. I have done the following: Added Sign in with Apple in Xcode for all the profiles ( i.e. debug and release) Set expo.ios.usesAppleSignIn to true in my app.json ( I think due to this I see Synced capabilities: Enabled: Sign In with Apple while building my app using eas build. ) Make sure that the provision profile has Sign in with App capability. What I am not able to understand is how option provided in provision profile works. Expo creates the profile with type "App Store". I think this is because I am building the expo app with production profile. Does this have to take anything with it? Does the profile with type "App Store" not work when I am testing the app using testFlight? I am so confused right now. Can someone help me figure out the actual issue? I have seen almost all the posts regarding this error. None of those helped! Thanks in advance!
0
0
60
1w
Updating Widget from App Intent called by Live Activity is inconsistent
(Also have a case ID, 9879068) We have an app that user use to check in/out from work for example. We have a button in-app do do this. Now I'm trying to add buttons to our widgets and our new live activity so that users don't have to open the app. It's crucial that the live activity and widgets always show the exact same state. Otherwise it'll look pretty bad if a user has both a live activity and a widget showin at the same time. However, we have noticed that sometimes, pressing the button in the live activity, running the app intent, will not always make the widget update (we call reloadAllTimelines()). The other way around, i.e. press the button on widget to update live activity always works. (they both call the same app intent) When running it in debug mode on a phone from Xcode, it always works, but when running it just on the phone it's unreliable. My first thought was, of course, that's related to the widget "budget", but according to the docs HERE, it should not be applied when interacting with a widget, calling an app intent. My question: HOW can I make my widget reliably refresh using an app intent invoked from a live activity?? I have a ready small project with simple buttons and trace labels that display this issue that I'm happy to supply to someone.
5
0
171
1w
iOS 18.1 crash main_executable_path_missing
Incident Identifier: 81AB2E74-1895-4DA4-9362-AE9E20B13847 Distributor ID: com.apple.AppStore Hardware Model: iPhone16,2 Process: Uplus [16285] Path: /private/var/containers/Bundle/Application/F737D7AC-B933-4204-926C-9149AD377F4B/Uplus.app/Uplus Identifier: com.haier.uhome.Uplus Version: 9.0.0 (2024091802) AppStoreTools: 16A242b AppVariant: 1:iPhone16,2:18 Code Type: ARM-64 (Native) Role: Foreground Parent Process: launchd [1] Coalition: com.haier.uhome.Uplus [4813] Date/Time: 2024-10-29 11:43:30.8727 +0800 Launch Time: 2024-10-29 11:43:30.8707 +0800 OS Version: iPhone OS 18.1 (22B5045g) Release Type: Beta Baseband Version: 2.20.02 Report Version: 104 Exception Type: EXC_BAD_ACCESS (SIGKILL) Exception Subtype: KERN_PROTECTION_FAILURE at 0x00000001e95280e0 Exception Codes: 0x0000000000000002, 0x00000001e95280e0 VM Region Info: 0x1e95280e0 is in 0x1e9528050-0x1e956c050; bytes after start: 144 bytes before end: 278383 REGION TYPE START - END [ VSIZE] PRT/MAX SHRMOD REGION DETAIL mapped file 1e9528000-1e9528050 [ 80] r--/rw- SM=COW Object_id=f1de19db ---> __TPRO_CONST 1e9528050-1e956c050 [ 272K] r--/rw- SM=COW /usr/lib/dyld mapped file 1e956c050-1e9570000 [ 16K] r--/rw- SM=COW Object_id=f1de19db Termination Reason: <0x2A> 2 Triggered by Thread: 0 Thread 0 Crashed: 0 dyld 0x00000001ac079500 0x1ac03f000 + 238848 1 dyld 0x00000001ac072bcc 0x1ac03f000 + 211916 Thread 0 crashed with ARM Thread State (64-bit): x0: 0x2010003030100000 x1: 0x0000000fffffc0d0 x2: 0x0000000000000004 x3: 0x00000001ac047829 x4: 0x0000000000000000 x5: 0x0000000000000000 x6: 0x0000000000000000 x7: 0x0000000000000000 x8: 0x2010003030100000 x9: 0x2010003030100000 x10: 0x000000016b917dfd x11: 0x00000001ac0b4240 x12: 0x0000000000000050 x13: 0x0000000000000044 x14: 0x0000000000052010 x15: 0x0000000000000000 x16: 0x0000000000000000 x17: 0x0000000000000000 x18: 0x0000000000000000 x19: 0x0000000182bb0000 x20: 0x000000016b917b50 x21: 0x000000016b917af8 x22: 0x00000001e9528050 x23: 0x000000016b9177d8 x24: 0x0000000fffffc10c x25: 0x0000000000000000 x26: 0x0000000000000000 x27: 0x0000000000000000 x28: 0x0000000000000000 fp: 0x000000016b917870 lr: 0x84028001ac079380 sp: 0x000000016b9177d0 pc: 0x00000001ac079500 cpsr: 0x60001000 esr: 0x92000047 (Data Abort) byte write Translation fault Binary Images: 0x1044e8000 - 0x10795bfff main_executable_path_missing arm64 /main_executable_path_missing 0x1ac03f000 - 0x1ac0c29a3 dyld arm64e /usr/lib/dyld EOF 18.1.crash
1
0
161
1w
iOS did not update all widgets of an app when the user press a button on a widget
Hello, I have an app in AppStore "Counter Widget". https://apps.apple.com/app/id1522170621 It allows you to add a widget to your homescreen/lockscreen to count anything. Everything works fine except for one scenario. iOS 18+ I create 2 or more widgets for one counter. For example, medium and small widgets. I click on the widget button to increase or decrease the value. The button in the widget uses Button(intent: AppIntent) to update the value and calls WidgetCenter.shared.reloadAllTimelines() to update the second widget for the same counter. For iOS 18 in this particular scenario, you don't even have to call the WidgetCenter.shared.reloadAllTimelines(). iOS already knows that there is a widget with the same INIntent settings and will update it itself. Both widgets are updated and show the new value. Everything is correct. Now on the homescreen I open the widget configuration for one of the widgets to change the INIntent for the widget. For example, i change the background to wallpaper. This is just a skin for the widget, and the widget is associated with the same counter value as before. As in (2), I click the widget button to increase or decrease the value. But now only one widget is updated. iOS ignores my call to WidgetCenter.shared.reloadAllTimelines() and does not update the second widget connected to the same counter. As I found, iOS, when I call WidgetCenter.shared.reloadAllTimelines() from the widget itself, updates other widgets only if INIntent is absolutely equal for them. Overriding isEqual for them did not help. That is, I cannot specify which fields from my INIntent can be ignored during such an update and consider that widgets are equal and need to be updated. Obviously iOS make this compare outside my code. The main problem is that when the user adds a widget to the lock screen and increases and decreases the value there. After that, he opens the home screen and the widget there is not synchronized with the value from the widget on the lock screen. How to solve this problem?
3
0
146
1w
Is there a way for my macos app to run NSRunningApplication.terminate()?
When my macOS app (currently in TestFlight and set for Mac App Store distribution) tries to terminate another app, both terminate() and forceTerminate() consistently return false. However, I can retrieve a list of all running applications so some related APIs do work. I suspect this limitation is due to sandboxing. I have three questions: Is there any permission or entitlement I can add in Xcode to allow my app to terminate other applications? If no such permission exists, is there a way to guide users on how to launch my app (distributed through the Mac App Store) without sandboxing? For example, could they set it up to launch as a daemon or agent? If unsandboxing is impossible, would I need to create a separate target specifically without sandboxing? In other words, my MacOS app would communicate with my unsandboxed daemon that would do all the terminate()-ing?
1
0
96
1w
Pull data on iOS App Homescreen Widget
Hello fellow developers! I am interested in obtaining the following information regarding one of our Home Screen widgets: Pull the following data about the "my_app_widget" homepage widget in total and by month for the last 12 months (Sep '23 - Sep '24): Widget install events Unique widget installs Device type (iPad, iOS). Thus far, I am using AWS Lambda and have the proper credentials within a Secrets Manager and I keep getting a 409 error from this code: const AWS = require('aws-sdk'); const axios = require('axios'); const jose = require('jose'); const crypto = require('crypto'); const s3 = new AWS.S3(); const secretsManager = new AWS.SecretsManager(); const cloudwatchlogs = new AWS.CloudWatchLogs(); const logGroupName = '/aws/lambda/my_lambda_function'; const logStreamName = '2024/11/05/[$LATEST]XXXXXXXXXXXXXX'; const getSecret = async (secretName) => { const secret = await secretsManager.getSecretValue({ SecretId: secretName }).promise(); return JSON.parse(secret.SecretString); }; const logError = async (message) => { const params = { logGroupName, logStreamName, logEvents: [ { message: JSON.stringify(message), timestamp: Date.now() } ] }; try { await cloudwatchlogs.putLogEvents(params).promise(); } catch (error) { console.error('Failed to log to CloudWatch:', error); } }; const getJwtToken = async (keyId, issuerId, privateKeyPem) => { try { const privateKey = crypto.createPrivateKey({ key: privateKeyPem, format: 'pem', type: 'pkcs8' }); const payload = { iss: issuerId, exp: Math.floor(Date.now() / 1000) + 20 * 60, aud: 'appstoreconnect-v1' }; const token = await new jose.SignJWT(payload) .setProtectedHeader({ alg: 'ES256', kid: keyId }) .sign(privateKey); return token; } catch (error) { await logError({ error: 'Error generating JWT', details: error }); throw new Error('JWT generation failed'); } }; const fetchAndUploadReport = async (url, token, s3Key, isAnalytics = false, body = null) => { try { const headers = { 'Authorization': `Bearer ${token}`, 'Accept': isAnalytics ? 'application/json' : 'application/a-gzip', 'Content-Type': 'application/json' }; const response = await axios({ method: isAnalytics ? 'post' : 'get', url: url, headers: headers, data: body, responseType: isAnalytics ? 'json' : 'stream' }); if (response.status === 200) { let bodyContent = isAnalytics ? JSON.stringify(response.data) : response.data; await s3.upload({ Bucket: 'my_bucket_name', Key: s3Key, Body: bodyContent }).promise(); return { statusCode: 200, body: `${s3Key} fetched and uploaded successfully` }; } else { await logError({ error: 'API response error', status: response.status, statusText: response.statusText, url }); return { statusCode: response.status, body: response.statusText }; } } catch (error) { await logError({ error: 'Error fetching report', url, details: error }); return { statusCode: 500, body: JSON.stringify(`Error fetching ${s3Key}`) }; } }; exports.handler = async (event) => { const secretName = 'AppStoreConnectPrivateKey'; try { const secretData = await getSecret(secretName); const { keyId, issuerId, private_key: privateKeyPem } = secretData; const token = await getJwtToken(keyId, issuerId, privateKeyPem); const startDate = '2023-09-01'; const endDate = '2024-09-30'; const apiEndpoints = [ { url: `https://api.appstoreconnect.apple.com/v1/analyticsReportRequests`, // Changed to request report s3Key: 'my_folder/my_subfolder/unique_widget_installs.json', isAnalytics: true, body: { "data": { "type": "analyticsReportRequests", "attributes": { "accessType": "ONGOING", "name": "Home Screen Widget Installs", "category": "APP_USAGE" }, "relationships": { "app": { "data": { "type": "apps", "id": "YYYYYYYYYYYY" } } } } } } ]; Returns the following error : { "error": "Error fetching report", "url": "https://api.appstoreconnect.apple.com/v1/analyticsReportRequests", "details": { "message": "Request failed with status code 409", "name": "AxiosError", "stack": "AxiosError: Request failed with status code 409\n at settle (/var/task/node_modules/axios/dist/node/axios.cjs:2019:12)\n at IncomingMessage.handleStreamEnd (/var/task/node_modules/axios/dist/node/axios.cjs:3135:11)\n at IncomingMessage.emit (node:events:531:35)\n at IncomingMessage.emit (node:domain:488:12)\n at endReadableNT (node:internal/streams/readable:1696:12)\n at process.processTicksAndRejections (node:internal/process/task_queues:82:21)\n at Axios.request (/var/task/node_modules/axios/dist/node/axios.cjs:4287:41)\n at process.processTicksAndRejections (node:internal/process/task_queues:95:5)\n at async fetchAndUploadReport (/var/task/index.js:68:26)\n at async Promise.all (index 0)\n at async exports.handler (/var/task/index.js:174:25)", "config": { "transitional": { "silentJSONParsing": true, "forcedJSONParsing": true, "clarifyTimeoutError": false }, "adapter": [ "xhr", "http", "fetch" ], "transformRequest": [ null ], "transformResponse": [ null ], "timeout": 0, "xsrfCookieName": "XSRF-TOKEN", "xsrfHeaderName": "X-XSRF-TOKEN", "maxContentLength": -1, "maxBodyLength": -1, "env": {}, So I am not sure if the JSON body I am passing this URL endpoint are correct or if this is the correct API to be using to attempt to obtain this information. Please let me know when you have the chance and I look forward to hearing from you.
0
0
100
1w
macos Objective-C openURL failed
error: Error Domain=NSCocoaErrorDomain Code=256 "The application “Google Chrome” could not be launched because a miscellaneous error occurred." UserInfo={NSURL=file:///Applications/Google%20Chrome.app/, NSLocalizedDescription=The application “Google Chrome” could not be launched because a miscellaneous error occurred., NSUnderlyingError=0x6000038376c0 {Error Domain=RBSRequestErrorDomain Code=5 "Launch failed." UserInfo={NSLocalizedFailureReason=Launch failed., NSUnderlyingError=0x6000038349f0 {Error Domain=OSLaunchdErrorDomain Code=112 "Could not find specified domain" UserInfo={NSLocalizedFailureReason=Could not find specified domain}}}}}
1
0
76
1w
How to find renamed app using old name in Spotlight?
We are planning on renaming our app. The new name is not like the current name. It will be renamed in the App Store as well as the App display name. Yet, we still want new and existing users to be able to find the app by using the old name in search/spotlight under iOS. A great example of this is entering Twitter to find the X app and it shows up in the App section in the Spotlight search. Are there any guidelines, settings, or tricks for doing this? Some have suggested adding a Spotlight search term but that will not have it show up in the App section I fear.
1
0
97
1w