Post

Replies

Boosts

Views

Activity

Reply to Do we still need to comply with SB2420 on Jan 1st for distributing apps in Texas ?
Apple gave the answer: https://developer.apple.com/news/?id=8jzbigf4 A recent injunction issued by a district court suspended enforcement of Texas state law SB2420, which introduced age assurance requirements for app marketplaces and developers. In light of this ruling, Apple will pause previously announced implementation plans and monitor the ongoing legal process. So, everything on pause, no requirement on Jan 1st. Until further instructions.
Dec ’25
Reply to iOS App rejected
Do you ever use lob mobile ? __ in swift mean that it's a private API or internal var https://github.com/touchlab/SKIE/discussions/93 So here, some of your code (maybe a third party library) is calling this private func. Please give more context: do you use third party framework ? do you use objC ?
Dec ’25
Reply to DeclaredAgeRange.requestAgeRange returns .notAvailable despite Family‑Sharing child account (iOS 26.2, Xcode 26.2)
Please post exact code. The present code would not compile. Impossible to comment on incomplete code. And please edit your comment with linefeeds. The present text is very hard to read. You should also edit your code with code formatter Closer to this, but some instructions still missing if #available(iOS 26.2, *) { #if canImport(DeclaredAgeRange) do { let response = try await AgeRangeService.shared.requestAgeRange(ageGates: 18, in: self) switch response { case let .sharing(range): break // handle range case .declinedSharing: break // handle declined @unknown default: break // handle unknown } } } catch let err as AgeRangeService.Error { if case .notAvailable = err { print("AgeRange notAvailable") } else { print("AgeRange other error: \(err)") } } } catch { print("AgeRange generic error: \(error)") } #endif // canImport(DeclaredAgeRange) }
Topic: UI Frameworks SubTopic: UIKit
Dec ’25
Reply to Inconsistent App Review Decisions Are Hurting Time-Critical iOS Releases
For sure, that causes some stress at each submission a new version. Even though we must admit that review is a filtering process that may catch new issue each time. This is what I do in some cases: write comments for reviewer. In your case, like: "Since previous approval, changes are only minor bug fixes in ". Or that "app was once rejected but after explanation with review team it was accepted without change." That will help reviewer get the context.
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
Yes, a message before termination is needed. But end of the game, once user clicks OK (UIKit) will be app termination, with all our apologies for the inconvenience. So here is what the code could look like in UIKit. Any comment welcomed. import UIKit import DeclaredAgeRange import StoreKit // In case need to check appStoreAgeRating class ViewController: UIViewController { @IBOutlet weak var welcomeLabel: UILabel! @IBOutlet weak var stopButton: UIButton! var task: Task<Void, Never>? // To allow to cancel Task if needed override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // test for age to be done here instead of button action ? } @available(iOS 26.2, *) // Called only on iOS 26.2+ in any case func testAgeRange() async -> Bool { do { print("Calling isEligibleForAgeFeatures") var isEligible = false print("iOS 26.2 or later") isEligible = try await AgeRangeService.shared.isEligibleForAgeFeatures // try Task.checkCancellation() // How to allow user to cancel the check to avoid being blocked ? print("isEligible", isEligible) // Does not work on simulator if !isEligible { print("Not in Texas") return true // Not in Texas, so we can proceed } } catch { // AgeRangeService.Error.notAvailable { // No age range provided. return true // should we accept if no ageRange provided, in order not to cause problem out of Texas ? } do { let response = try await AgeRangeService.shared.requestAgeRange(ageGates: /*13, 15,*/ 18, in: self) // To be safe, test for 18 in Texas var lowerBound = 18 switch response { case .declinedSharing: print("User declined to share age.") return false case .sharing(let range): lowerBound = range.lowerBound ?? 18 print("User age range: \(range.lowerBound ?? 0)-\(range.upperBound ?? 99)") @unknown default: print( "fatalError()") return false } var ok = false if lowerBound >= 18 { // Allow access to 18+ features. We test only for Texas ok = true } else { // Require parental consent ? // Show age-appropriate content ok = false // Allow access only to 18+ in Texas } return ok // Authorized for all 18+ in Texas } catch { // AgeRangeService.Error.notAvailable { // No age range provided. return false } } func executeStart() { welcomeLabel.isHidden = false } // In case too long wait @IBAction func stopTask(_ sender: UIButton) { print("ask to stop task", task?.isCancelled) task?.cancel() print("cancelled?", task?.isCancelled) stopButton.isHidden = true } @IBAction func start(_ sender: UIButton) { stopButton.isHidden = false task = Task { // @MainActor in print("Start") if #available(iOS 26.2, *) { let appStoreAgeRating = await AppStore.ageRatingCode ?? 18 // Not used yet if await self.testAgeRange() { // self needed if detached Task // Need to test for parental control here ? if self.task?.isCancelled != nil { print("Task has been cancelled") } } else { print("No testAgeRange") // Alert and exit the app when user acks alerts, with the following message // "Access to this app is age-restricted due to local laws in your state or territory.") // "Please verify your age with Apple and allow this app to access your age information.") // "For further information, please refer to the following Apple support article: https://support.apple.com/en-us/122770") } } else { print("Not 26.2") // do nothing ? We can run the app. } self.executeStart() } print("We have completed the task") } }
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
Many thanks.   Having thought about all this for another day, my new plan is to drop the App Store age rating check (for now), and use age 18 for the age gate parameter. That may be the safe and simplest way. It will hurt some Texas users, but not the rest of the world, which is very important.   If requestAgeRange throws, I will assume the user is a child and restrict access. That raises another question. If the whole app is OK for 4+, what should be blocked ? Should we terminate the app ?
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
@jwcarr thanks for this detailed analysis. That's the type of advice we would have expected from Apple… I think they have ways to avoid the legal issues. A few more points: There should likely be a step (0) (0) check if iOS is 26+. Otherwise, proceed without any test (because we cannot do them) (1) get the App Store age rating with let appStoreAgeRating = await AppStore.ageRatingCode ?? 18, (2) request the user's age with let ageRangeResponse = try await AgeRangeService.shared.requestAgeRange(ageGates: appStoreAgeRating), (3) check that the user has agreed to share their age, (4) check that lowerBound >= appStoreAgeRating, and (5) check that the verification method is not one of the self-declared methods. If this procedure fails, I should block access to the app and provide a link to Apple's support page A few more questions: in (1), which import to use AppStore.ageRatingCode ? in (2), if UIKit and not SwiftUI, need the in parameter let ageRangeResponse = try await AgeRangeService.shared.requestAgeRange(ageGates: appStoreAgeRating, in: self) where should parental control be tested ? In step (5) ? where to deal with change in user's age or repudiation (as required by law if I read properly) what happens if the requests in await do not respond ? Is there some type of timeout, to avoid user being locked in waiting ? It is a serious issue not be able to test on simulator. We may be forced to publish an app without thoroughly testing it works OK for so in Texas.
Dec ’25
Reply to Where to find sample code for SB2420 compliance and questions
isEligibleForAgeFeatures issue solved with forum help. func testAgeRange() async -> Bool { do { let isEligible = try await AgeRangeService.shared.isEligibleForAgeFeatures if !isEligible { return true // Not in Texas } } catch { // AgeRangeService.Error.notAvailable { // No age range provided. return false } But cannot be tested on simulator, that's a major issue.
Topic: UI Frameworks SubTopic: UIKit Tags:
Dec ’25
Reply to Texas's SB 2420: obligations depending on app rating ?
All on pause. And may be all we'll have to do is check age declared by user.
Replies
Boosts
Views
Activity
Dec ’25
Reply to Do we still need to comply with SB2420 on Jan 1st for distributing apps in Texas ?
Apple gave the answer: https://developer.apple.com/news/?id=8jzbigf4 A recent injunction issued by a district court suspended enforcement of Texas state law SB2420, which introduced age assurance requirements for app marketplaces and developers. In light of this ruling, Apple will pause previously announced implementation plans and monitor the ongoing legal process. So, everything on pause, no requirement on Jan 1st. Until further instructions.
Replies
Boosts
Views
Activity
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
Law is on pause in Texas. I understand we have nothing to do in the short term. Except to prepare for Utah and Louisiana laws planned to come into force in May and July.
Replies
Boosts
Views
Activity
Dec ’25
Reply to App rejected for using non-public API __SwiftValue in Runner – Swift runtime false positive?
Others have reported similar issue: https://developer.apple.com/forums/thread/811203
Replies
Boosts
Views
Activity
Dec ’25
Reply to iOS App rejected
Others had the same issue, with Flutter: https://developer.apple.com/forums/thread/811110
Replies
Boosts
Views
Activity
Dec ’25
Reply to iOS App rejected
yes we use objective c So, it is probably an issue of compatibility between Swift and objC as explained in another case in the referenced thread. You should file a bug report and appeal to the Review Board explaining the context.review
Replies
Boosts
Views
Activity
Dec ’25
Reply to iOS App rejected
Do you ever use lob mobile ? __ in swift mean that it's a private API or internal var https://github.com/touchlab/SKIE/discussions/93 So here, some of your code (maybe a third party library) is calling this private func. Please give more context: do you use third party framework ? do you use objC ?
Replies
Boosts
Views
Activity
Dec ’25
Reply to DeclaredAgeRange.requestAgeRange returns .notAvailable despite Family‑Sharing child account (iOS 26.2, Xcode 26.2)
Please post exact code. The present code would not compile. Impossible to comment on incomplete code. And please edit your comment with linefeeds. The present text is very hard to read. You should also edit your code with code formatter Closer to this, but some instructions still missing if #available(iOS 26.2, *) { #if canImport(DeclaredAgeRange) do { let response = try await AgeRangeService.shared.requestAgeRange(ageGates: 18, in: self) switch response { case let .sharing(range): break // handle range case .declinedSharing: break // handle declined @unknown default: break // handle unknown } } } catch let err as AgeRangeService.Error { if case .notAvailable = err { print("AgeRange notAvailable") } else { print("AgeRange other error: \(err)") } } } catch { print("AgeRange generic error: \(error)") } #endif // canImport(DeclaredAgeRange) }
Topic: UI Frameworks SubTopic: UIKit
Replies
Boosts
Views
Activity
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
@jarrodlombardo-eventbase NEVER terminate your app. Thanks, I'll follow your advice. I will disable all buttons from the welcome page. Where did you implement the ageVerification code ? In viewDidLoad ?
Replies
Boosts
Views
Activity
Dec ’25
Reply to Inconsistent App Review Decisions Are Hurting Time-Critical iOS Releases
For sure, that causes some stress at each submission a new version. Even though we must admit that review is a filtering process that may catch new issue each time. This is what I do in some cases: write comments for reviewer. In your case, like: "Since previous approval, changes are only minor bug fixes in ". Or that "app was once rejected but after explanation with review team it was accepted without change." That will help reviewer get the context.
Replies
Boosts
Views
Activity
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
Yes, a message before termination is needed. But end of the game, once user clicks OK (UIKit) will be app termination, with all our apologies for the inconvenience. So here is what the code could look like in UIKit. Any comment welcomed. import UIKit import DeclaredAgeRange import StoreKit // In case need to check appStoreAgeRating class ViewController: UIViewController { @IBOutlet weak var welcomeLabel: UILabel! @IBOutlet weak var stopButton: UIButton! var task: Task<Void, Never>? // To allow to cancel Task if needed override func viewDidLoad() { super.viewDidLoad() // Do any additional setup after loading the view. // test for age to be done here instead of button action ? } @available(iOS 26.2, *) // Called only on iOS 26.2+ in any case func testAgeRange() async -> Bool { do { print("Calling isEligibleForAgeFeatures") var isEligible = false print("iOS 26.2 or later") isEligible = try await AgeRangeService.shared.isEligibleForAgeFeatures // try Task.checkCancellation() // How to allow user to cancel the check to avoid being blocked ? print("isEligible", isEligible) // Does not work on simulator if !isEligible { print("Not in Texas") return true // Not in Texas, so we can proceed } } catch { // AgeRangeService.Error.notAvailable { // No age range provided. return true // should we accept if no ageRange provided, in order not to cause problem out of Texas ? } do { let response = try await AgeRangeService.shared.requestAgeRange(ageGates: /*13, 15,*/ 18, in: self) // To be safe, test for 18 in Texas var lowerBound = 18 switch response { case .declinedSharing: print("User declined to share age.") return false case .sharing(let range): lowerBound = range.lowerBound ?? 18 print("User age range: \(range.lowerBound ?? 0)-\(range.upperBound ?? 99)") @unknown default: print( "fatalError()") return false } var ok = false if lowerBound >= 18 { // Allow access to 18+ features. We test only for Texas ok = true } else { // Require parental consent ? // Show age-appropriate content ok = false // Allow access only to 18+ in Texas } return ok // Authorized for all 18+ in Texas } catch { // AgeRangeService.Error.notAvailable { // No age range provided. return false } } func executeStart() { welcomeLabel.isHidden = false } // In case too long wait @IBAction func stopTask(_ sender: UIButton) { print("ask to stop task", task?.isCancelled) task?.cancel() print("cancelled?", task?.isCancelled) stopButton.isHidden = true } @IBAction func start(_ sender: UIButton) { stopButton.isHidden = false task = Task { // @MainActor in print("Start") if #available(iOS 26.2, *) { let appStoreAgeRating = await AppStore.ageRatingCode ?? 18 // Not used yet if await self.testAgeRange() { // self needed if detached Task // Need to test for parental control here ? if self.task?.isCancelled != nil { print("Task has been cancelled") } } else { print("No testAgeRange") // Alert and exit the app when user acks alerts, with the following message // "Access to this app is age-restricted due to local laws in your state or territory.") // "Please verify your age with Apple and allow this app to access your age information.") // "For further information, please refer to the following Apple support article: https://support.apple.com/en-us/122770") } } else { print("Not 26.2") // do nothing ? We can run the app. } self.executeStart() } print("We have completed the task") } }
Replies
Boosts
Views
Activity
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
Many thanks.   Having thought about all this for another day, my new plan is to drop the App Store age rating check (for now), and use age 18 for the age gate parameter. That may be the safe and simplest way. It will hurt some Texas users, but not the rest of the world, which is very important.   If requestAgeRange throws, I will assume the user is a child and restrict access. That raises another question. If the whole app is OK for 4+, what should be blocked ? Should we terminate the app ?
Replies
Boosts
Views
Activity
Dec ’25
Reply to Cannot close my own threads
@Forums Product Manager thanks for replying. I tested today, seems to work now. So, no bug report. Was probably an issue on the server. I'll try on this post. It works.
Replies
Boosts
Views
Activity
Dec ’25
Reply to Guidance on implementing Declared Age Range API in response to Texas SB2420
@jwcarr thanks for this detailed analysis. That's the type of advice we would have expected from Apple… I think they have ways to avoid the legal issues. A few more points: There should likely be a step (0) (0) check if iOS is 26+. Otherwise, proceed without any test (because we cannot do them) (1) get the App Store age rating with let appStoreAgeRating = await AppStore.ageRatingCode ?? 18, (2) request the user's age with let ageRangeResponse = try await AgeRangeService.shared.requestAgeRange(ageGates: appStoreAgeRating), (3) check that the user has agreed to share their age, (4) check that lowerBound >= appStoreAgeRating, and (5) check that the verification method is not one of the self-declared methods. If this procedure fails, I should block access to the app and provide a link to Apple's support page A few more questions: in (1), which import to use AppStore.ageRatingCode ? in (2), if UIKit and not SwiftUI, need the in parameter let ageRangeResponse = try await AgeRangeService.shared.requestAgeRange(ageGates: appStoreAgeRating, in: self) where should parental control be tested ? In step (5) ? where to deal with change in user's age or repudiation (as required by law if I read properly) what happens if the requests in await do not respond ? Is there some type of timeout, to avoid user being locked in waiting ? It is a serious issue not be able to test on simulator. We may be forced to publish an app without thoroughly testing it works OK for so in Texas.
Replies
Boosts
Views
Activity
Dec ’25
Reply to Where to find sample code for SB2420 compliance and questions
isEligibleForAgeFeatures issue solved with forum help. func testAgeRange() async -> Bool { do { let isEligible = try await AgeRangeService.shared.isEligibleForAgeFeatures if !isEligible { return true // Not in Texas } } catch { // AgeRangeService.Error.notAvailable { // No age range provided. return false } But cannot be tested on simulator, that's a major issue.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
Boosts
Views
Activity
Dec ’25