Prioritize user privacy and data security in your app. Discuss best practices for data handling, user consent, and security measures to protect user information.

Posts under General subtopic

Post

Replies

Boosts

Views

Activity

Load network/security extension skip the finish callback
Hi, i'm working on an endpoint security extension loader and implement several callbacks from delegate object OSSystemExtensionRequestDelegate the callback i'm interested in is : public func request(_ request: OSSystemExtensionRequest, didFinishWithResult result: OSSystemExtensionRequest.Result); public func requestNeedsUserApproval(_ request: OSSystemExtensionRequest); I've noticed that if I manually approve the extension long time after it was activated, the extension process goes up, but the callback isn't being called. The requestNeedUserApproval callback always gets called. I see in the unified logs that when the extension goes from activated_waiting_for_user -> activated_enabling -> activated_enabled Than the request callback doesn't get called. But whenever the extension goes activated_waiting_for_user -> activated_disabled The request callback gets called. (this is counter intuitive since we expected the state activated_disabled may hint that the extension failed to be activated somehow) Any Idea why my callback doesn't gets called if the extension gets approved long after it was activated ?
1
0
386
Dec ’24
Help! My computer shut of while I was trying to save my PN Key File
I am trying to finish my very first app. I went to save the PN key file and my computer shut off. I went to Certificates, Identifiers, and profiles and it says that I have reached the maximum allowed. I dont know what to do. I cant do anything with my app this is so stupid how could they make it so something like this was even possible. I am totally screwed. Please help me!
1
0
275
Oct ’24
Swift how to add password to the `Passwords App`
I added a password to Keychain using Swift on macOS. All works well, and I can see it using Keychain Access, it is stored under iCloud -> Passwords. How can I see this password on the Passwords App. Is there something I need to do, maybe in Swift, to have this password in the Passwords App, not just in Keychain Access Note, I have turn on iCloud Keychain on my Mac: https://support.apple.com/en-us/109016
1
0
521
Oct ’24
Sicherheit App
Option 1: Kurz und prägnant "Hilfe in jeder Situation! Unsere App alarmiert schnell und unkompliziert die Rettungskräfte. Egal wo du bist, wir helfen dir in Notfällen." Option 2: Detaillierter "Schnelle Hilfe für alle! Mit unserer App hast du rund um die Uhr einen zuverlässigen Helfer an deiner Seite. Ob du selbst in Not bist oder Zeugen eines Unfalls werden – mit nur einem Klick alarmierst du die Rettungskräfte und erhältst wichtige Informationen. Funktioniert für iOS und Android." Option 3: Fokus auf die Zielgruppe "Alle" "Für jeden ein Lebensretter! Egal, ob jung oder alt, sportlich oder weniger beweglich – unsere App ist für alle gedacht, die in einer Notlage schnell Hilfe benötigen. Einfach, intuitiv und immer für dich da." Option 4: Betonung der Notfallfunktion "Dein persönlicher Notfallhelfer! In kritischen Situationen zählt jede Sekunde. Unsere App sorgt dafür, dass die Rettungskräfte schnellstmöglich bei dir sind. Perfekt für unterwegs, zu Hause oder am Arbeitsplatz." Option 5: Hervorhebung der Plattformunabhängigkeit "Hilfe ohne Grenzen! Unsere App ist für iOS und Android Geräte verfügbar und sorgt dafür, dass du immer und überall Hilfe bekommst. Egal, welches Smartphone du hast, wir sind für dich da." Möchtest du, dass ich einen Text entwerfe, der alle deine Punkte vereint? Oder hast du weitere Wünsche oder Vorstellungen?
0
0
500
Oct ’24
TouchID on the Mac when FaceID is called on iOS when using iPhone Mirroring?
When using Apple's Journal app through iPhone Mirroring, the user is allowed to authenticate via TouchID on the Mac instead of requiring you to unlock your phone, authenticate and then re-lock it to access it again in iPhone Mirroring. Any other app that's using a call to authenticate via FaceID can't do this under iPhone Mirroring. Is there a new API call for this, or is it still a private API for Apple only?
0
0
493
Dec ’24
Declare user data tracking if it's disabled completely in third-party SDK
I have an app where I'm integrating the Branch.io SDK for deeplinks. I plan to use it just for deeplinks and that's it. The SDK provides it's own privacy manifest file with privacy tracking domains defined and some collected data types with "Used for Tracking" set to YES. Does anyone know if I can keep tracking disabled in the App Store Connect - App Privacy section in case if I'll configure the SDK to disable tracking completely without asking users with the ATT permission request?
0
0
467
Nov ’24
Device check validation API request to apple development server failed with error code 500
Our application uses device check api to validate the device token in staging server. We are using "https://api.development.devicecheck.apple.com/v1/validate_device_token"for this.But the response is 500 internal server error. Our production build is working fine.We pointed the build to "https://api.devicecheck.apple.com/v1/validate_device_token" url.We are using the same device check key for both development and production server. Device check was working fine in development server also.Suddenly it started to failed with out making any changes in our code.
2
0
376
Mar ’25
ASCredentialProviderExtensionContext completeRequestWithTextToInsert:completionHandler: sometimes fails to return text
completeRequestWithTextToInsert is used to return text into an arbitrary textfield via the context menu AutoFill/Passwords from a 3rd party password manager (or presumably the Passwords App) in iOS 18. While testing this feature in the debugger, it would often fail on the first invocation. It also appears to happen intermittently in the released app extension. Subsequent testing using the Passwords App shows it too may fail to return a value. I have confirmed this behaviour is repeatable with the Passwords App on an iPhone running iOS 18.3.1 Reboot the iPhone. Show the App Library, and right click Autofill. Select Passwords Select Passwords (App) Select a password. Nothing will be inserted (intermittently). Feedback assistant report: FB16788563
0
0
328
Mar ’25
Which type should I use in manifest?
I use activeInputModes in my app. I require the users to use English keyboard on one view controller in my app. At that page, I access the activeInputModes and return the English system keyboard. I don't customize the keyboard. Which one should I choose? In your NSPrivacyAccessedAPITypeReasons array, supply the relevant values from the list below. 3EC4.1 Declare this reason if your app is a custom keyboard app, and you access this API category to determine the keyboards that are active on the device. Providing a systemwide custom keyboard to the user must be the primary functionality of the app. Information accessed for this reason, or any derived information, may not be sent off-device. 54BD.1 Declare this reason to access active keyboard information to present the correct customized user interface to the person using the device. The app must have text fields for entering or editing text and must behave differently based on active keyboards in a way that is observable to users.
2
0
333
Dec ’24
Can I still use the private email address if I disable Sign in with Apple?
We currently have an app that uses Sign in with Apple (SIWA), and we are planning to discontinue the SIWA feature. Specifically, we intend to disable SIWA from the app's Capabilities in the Apple Developer Center. My question is, if we disable SIWA, can we continue to use the private email addresses of users who registered using SIWA? Or will disabling SIWA also invalidate the users' private email addresses? We are considering asking users to change to a different, valid email address in our app. However, if the private email addresses are invalidated, we will not be able to disable SIWA until all users have completed the email address change. If anyone has knowledge about these behaviors, please let us know.
0
0
207
Mar ’25
App Crash on Lock Screen During Biometrics Permission Prompt Using LAContext()
I am using LAContext(), canEvaluatePolicy, and evaluatePolicy in my project, and I've encountered a crash under a specific scenario. When the permission prompt appears asking, "Do you want to allow [App Name] to use biometrics in your app?" and the user locks the device without selecting "Allow" or "Don't Allow," the app crashes at that point. Has anyone else experienced this issue or tested this scenario? Any insights would be appreciated!
1
0
448
Oct ’24
Background Location Indicator Remains Active Despite "Never" Permission Setting in iOS 18+
Hi everyone, I'm encountering an issue where the background location indicator remains visible on the status bar even though I have set the location permissions to Never for my app in the system settings. Despite taking all the necessary steps to stop location tracking (including stopping updates, geofencing, and other location-related services), the indicator still appears. This seems to be a bug since everything has been turned off on my end. Here’s what I’ve already tried: Setting location permissions to Never in the settings. Stopping startUpdatingLocation(), stopMonitoringSignificantLocationChanges(), and geofencing (using locationManager.stopMonitoringRegions()). Calling locationManager.showsBackgroundLocationIndicator = false. Ensuring that the CLLocationManager is fully invalidated. Despite all of this, the background location indicator still remains in the status bar. I’ve tested it on real devices, as well as in the simulator, with no improvement. Has anyone experienced something similar, or can suggest why this might be happening? Could this be related to an iOS 18+ issue? Any insights or guidance would be greatly appreciated.
0
0
351
Dec ’24
invalid_client Sign In With Apple
I'm trying to set up Sign In With Apple on my .NET 7 Web App (Not sure how many people here use this). I followed the guide by Scott Brady here: https://www.scottbrady91.com/openid-connect/implementing-sign-in-with-apple-in-aspnet-core It reaches Apple Sign In OK, authenticates, and passes back to my server, but the callback responds with this error. OpenIdConnectProtocolException: Message contains error: 'invalid_client', error_description: 'error_description is null', error_uri: 'error_uri is null'. Googling hasn't helped much, other than I saw a post saying to wait 48 hours, which I have now done (not that that makes sense anyway). Any idea whats been done wrong? Code below, replacing sensitive data. Startup.cs .AddOpenIdConnect("apple", async options => { options.Authority = "https://appleid.apple.com"; // disco doc: https://appleid.apple.com/.well-known/openid-configuration options.ClientId = "com.rackemapp.applelogin"; // Service ID options.CallbackPath = "/signin-apple"; // corresponding to your redirect URI options.ResponseType = "code id_token"; // hybrid flow due to lack of PKCE support options.ResponseMode = "form_post"; // form post due to prevent PII in the URL options.UsePkce = false; // apple does not currently support PKCE (April 2021) options.DisableTelemetry = true; options.Scope.Clear(); // apple does not support the profile scope options.Scope.Add("openid"); options.Scope.Add("email"); options.Scope.Add("name"); options.Events.OnAuthorizationCodeReceived = context => { context.TokenEndpointRequest.ClientSecret = AppleTokenGenerator.CreateNewToken(); return Task.CompletedTask; }; }); Apple Token Generator public static class AppleTokenGenerator { public static string CreateNewToken() { const string iss = "[MyTeamId]"; // your account's team ID found in the dev portal const string aud = "https://appleid.apple.com"; const string sub = "com.rackemapp.applelogin"; // same as client_id var now = DateTime.UtcNow; // contents of your .p8 file const string privateKey = "[MyKey]"; var ecdsa = ECDsa.Create(); ecdsa?.ImportPkcs8PrivateKey(Convert.FromBase64String(privateKey), out _); var handler = new JsonWebTokenHandler(); return handler.CreateToken(new SecurityTokenDescriptor { Issuer = iss, Audience = aud, Claims = new Dictionary<string, object> { { "sub", sub } }, Expires = now.AddMinutes(5), // expiry can be a maximum of 6 months - generate one per request or re-use until expiration IssuedAt = now, NotBefore = now, SigningCredentials = new SigningCredentials(new ECDsaSecurityKey(ecdsa), SecurityAlgorithms.EcdsaSha256) }); } } Also attached, images of my keys and setp in developer portal
1
0
1.1k
Nov ’24
The Case for Sandboxing a Directly Distributed App
I’ve explained this point many times on the forums, so I figured I’d write it up properly once and for all. If you have questions or comments, start a new thread in Privacy & Security > General and add the App Sandbox tag. That way I’ll be sure to see it. Share and Enjoy — Quinn “The Eskimo!” @ Developer Technical Support @ Apple let myEmail = "eskimo" + "1" + "@" + "apple.com" The Case for Sandboxing a Directly Distributed App Many folks consider the App Sandbox to be a binary choice: “My app ships in the Mac App Store, so I must sandbox it.” “I directly distribute my app, so I’ll ignore the App Sandbox.” However, those are not your only options. In many cases it makes sense to sandbox a directly distributed app. Sandboxing your app has at least three benefits: It enables app container protection. See Trusted Execution Resources for a link to more info on that. If your app includes any app extensions, it simplifies your development experience because your app and its extensions run in a similar environment. It improves your app’s security (although the actual benefits vary based on the specifics of your app). Sandboxing some apps can be tricky because of the additional security limits applied by the sandbox. However, in a directly distributed app you have access to two techniques that are not available to Mac App Store apps: Temporary exception entitlements Non-sandboxed XPC services Temporary exception entitlements Use temporary exception entitlements to selectively disable specific sandbox security limits. Imagine, for example, that you’re creating a simple document-based app that’s generally compatible with the sandbox. However, that app needs to send an Apple event to Music to create a playlist. That Apple event is blocked by the sandbox. You don’t need to disable the entire App Sandbox just to get around this security limit. Instead, use the com.apple.security.temporary-exception.apple-events entitlement to open a small hole in the sandbox. There are temporary exception entitlements to disable most sandbox security limits. For more information about them, follow the link in App Sandbox Resources. IMPORTANT Don’t be alarmed by the temporary in temporary exception entitlements. That word makes sense when you view this from the Mac App Store perspective. Back in the early days of the Mac App Store, some apps were allowed to use temporary exception entitlements because of limitations in the App Sandbox. Once App Sandbox was sufficiently enhanced, these temporary exception entitlements were no longer allowed in the Mac App Store. However, there’s nothing temporary about the implementation of these entitlements. They work today and are expected to continue working in the future. Using them in a directly distributed app is not a problem. Non-sandboxed XPC services Not all sandbox security limits have a corresponding temporary exception entitlement. For example, the sandbox prevents you from sending a Unix signal to other processes, and there’s no temporary exception entitlement to allow that. If you run into such a limit, move that code to a non-sandboxed XPC service, then have the main app request that the XPC service perform the operation on its behalf. An XPC service can be useful even when there is a temporary exception entitlement to disable a specific sandbox security limit. Continuing the Apple event example from above, if you put the code that sends the Apple event into an XPC service, you only need to apply the temporary exception entitlement to that service, not to your app as a whole. Conclusion If you directly distribute your app, consider enabling the App Sandbox. It has some important benefits, and it might be more feasible than you think.
0
0
383
Mar ’25
Sign in with Apple Keychain savedEmail Stored Incorrectly
Using personal physical iPhone for simulations. Can't get Keychain to read or store AppleID name/email. I want to avoid hard reseting physical phone. Logs confirm Keychain is working, but userIdentifier and savedEmail are not being stored correctly. 🔄 Initializing UserManager... ✅ Saved testKeychain to Keychain: Test Value ✅ Retrieved testKeychain from Keychain: Test Value 🔍 Keychain Test - Retrieved Value: Test Value ⚠️ Keychain Retrieve Warning: No stored value found for userIdentifier ⚠️ Keychain Retrieve Warning: No stored value found for savedEmail 🔍 Debug - Retrieved from Keychain: userIdentifier=nil, savedEmail=nil ⚠️ No stored userIdentifier in Keychain. User needs to sign in. 📦 Converting User to CKRecord: Unknown, No Email ✅ User saved locally: Unknown, No Email ✅ User saved to CloudKit: Unknown, No Email Below UserManager.swift if someone can help troubleshoot. Or step by step tutorial to configure a project and build a User Login &amp; User Account creation for Apple Only app. import Foundation import CloudKit import AuthenticationServices import SwiftData @MainActor class UserManager: ObservableObject { @Published var user: User? @Published var isLoggedIn = false @Published var errorMessage: String? private let database = CKContainer.default().publicCloudDatabase init() { print("🔄 Initializing UserManager...") // 🔍 Keychain Debug Test let testKey = "testKeychain" KeychainHelper.shared.save("Test Value", forKey: testKey) let retrievedValue = KeychainHelper.shared.retrieve(forKey: testKey) print("🔍 Keychain Test - Retrieved Value: \(retrievedValue ?? "nil")") fetchUser() // Continue normal initialization } // ✅ Sign in &amp; Save User func handleSignIn(_ authResults: ASAuthorization) { guard let appleIDCredential = authResults.credential as? ASAuthorizationAppleIDCredential else { errorMessage = "Error retrieving Apple credentials" print("❌ ASAuthorization Error: Invalid credentials received") return } let userIdentifier = appleIDCredential.user let fullName = appleIDCredential.fullName?.givenName ?? retrieveSavedName() var email = appleIDCredential.email ?? retrieveSavedEmail() print("🔍 Apple Sign-In Data: userIdentifier=\(userIdentifier), fullName=\(fullName), email=\(email)") // 🔄 If Apple doesn't return an email, check if it exists in Keychain if appleIDCredential.email == nil { print("⚠️ Apple Sign-In didn't return an email. Retrieving saved email from Keychain.") } // ✅ Store userIdentifier &amp; email in Keychain KeychainHelper.shared.save(userIdentifier, forKey: "userIdentifier") KeychainHelper.shared.save(email, forKey: "savedEmail") let newUser = User(fullName: fullName, email: email, userIdentifier: userIdentifier) saveUserToCloudKit(newUser) } func saveUserToCloudKit(_ user: User) { let record = user.toRecord() Task { do { try await database.save(record) DispatchQueue.main.async { self.user = user self.isLoggedIn = true self.saveUserLocally(user) print("✅ User saved to CloudKit: \(user.fullName), \(user.email)") } } catch { DispatchQueue.main.async { self.errorMessage = "Error saving user: \(error.localizedDescription)" print("❌ CloudKit Save Error: \(error.localizedDescription)") } } } } // ✅ Fetch User from CloudKit func fetchUser() { let userIdentifier = KeychainHelper.shared.retrieve(forKey: "userIdentifier") let savedEmail = KeychainHelper.shared.retrieve(forKey: "savedEmail") print("🔍 Debug - Retrieved from Keychain: userIdentifier=\(userIdentifier ?? "nil"), savedEmail=\(savedEmail ?? "nil")") guard let userIdentifier = userIdentifier else { print("⚠️ No stored userIdentifier in Keychain. User needs to sign in.") return } let predicate = NSPredicate(format: "userIdentifier == %@", userIdentifier) let query = CKQuery(recordType: "User", predicate: predicate) Task { [weak self] in guard let self = self else { return } do { let results = try await self.database.records(matching: query, resultsLimit: 1).matchResults if let (_, result) = results.first { switch result { case .success(let record): DispatchQueue.main.async { let fetchedUser = User(record: record) self.user = User( fullName: fetchedUser.fullName, email: savedEmail ?? fetchedUser.email, userIdentifier: userIdentifier ) self.isLoggedIn = true self.saveUserLocally(self.user!) print("✅ User loaded from CloudKit: \(fetchedUser.fullName), \(fetchedUser.email)") } case .failure(let error): DispatchQueue.main.async { print("❌ Error fetching user from CloudKit: \(error.localizedDescription)") } } } } catch { DispatchQueue.main.async { print("❌ CloudKit fetch error: \(error.localizedDescription)") } } } } // ✅ Save User Locally private func saveUserLocally(_ user: User) { if let encoded = try? JSONEncoder().encode(user) { UserDefaults.standard.set(encoded, forKey: "savedUser") UserDefaults.standard.set(user.fullName, forKey: "savedFullName") UserDefaults.standard.set(user.email, forKey: "savedEmail") print("✅ User saved locally: \(user.fullName), \(user.email)") } else { print("❌ Local Save Error: Failed to encode user data") } } // ✅ Retrieve Previously Saved Name private func retrieveSavedName() -&gt; String { return UserDefaults.standard.string(forKey: "savedFullName") ?? "Unknown" } // ✅ Retrieve Previously Saved Email private func retrieveSavedEmail() -&gt; String { return KeychainHelper.shared.retrieve(forKey: "savedEmail") ?? UserDefaults.standard.string(forKey: "savedEmail") ?? "No Email" } // ✅ Sign Out func signOut() { isLoggedIn = false user = nil UserDefaults.standard.removeObject(forKey: "savedUser") print("🚪 Signed Out") } }
0
0
241
Mar ’25
Sending emails from AWS SES to private relay service
Feedback report id: FB16605524 I'm trying to send emails to private relay service addresses using AWS SES and emails are not received. My emails are sent from dev@mydomain.fr and I've set a custom FROM domain of mail.mydomain.fr. I've added both domains and the dev@mydomain.fr adress to the "Certificates, Identifies & Profiles" section. I've set up DKIM and SPF for both. Attached a redacted version of email headers. email_headers_redacted.txt
0
0
280
Mar ’25