Post

Replies

Boosts

Views

Activity

UIDocumentBrowserViewController - adjust order and color of navigation bar items
I'm using UIDocumentBrowserViewController. This view controller automatically creates a TabView with navigation titles and up to two trailing navigation bar items. To visualize this, open the Files app by Apple on an iPhone. I want to do the following: Add a third button and place it farthest on the trailing side. Keep all three buttons blue (the default color), but adjust the color of the navigation title to use the primary text color (it is also currently blue, by default) Button Order If my button is represented by C, then the order from left-to-right or leading-to-trailing should be A B C. I tried to add it by using additionaltrailingnavigationbarbuttonitems: class DocumentBrowserViewController: UIDocumentBrowserViewController, UIDocumentBrowserViewControllerDelegate { override func viewDidLoad() { super.viewDidLoad() let button = UIBarButtonItem(...) additionalTrailingNavigationBarButtonItems.append(button) } } This always adds it as the leftmost trailing item. The order when the view loads is C A B, where C represents my button. Here are some things I've tried: Add it in viewWillAppear - same results. Add it in viewDidAppear - same results. Add it using rightBarButtonItems - does not show up at all. insert it at: 0 instead of appending it - same results. Add it with a delay using DispatchQueue.main.async - same results. After some experimentation, I realized that the arrays referenced by additionalTrailingNavigationBarButtons and rightBarButtonItems seem to be empty, other than my own button. This is the case even if the DispatchQueue delay is so long that the view has already rendered and the two default buttons are clearly visible. So I'm not sure how to place my button relative to these, since I can't figure out where they actually are in the view controller's properties. How do I put my button farther to the trailing/right side of these two default buttons? Title Color The navigation titles created by UIDocumentBrowserViewController are blue when not in their inline format. I want them to use the primary text color instead. In viewDidLoad, I could do something like this: UINavigationBar.appearance().tintColor = UIColor.label This will change the title color to white or black, but it will also change the color of the buttons. I've tried various approaches like titleTextAttributes, and none of them seem to work with this view controller. How do I change just the color of the navigation title, and not the color of the navigation bar items?
0
0
211
Jan ’25
Transaction.environment is undefined/nil in TestFlight
I'm using Transaction.environment to determine server behavior. https://developer.apple.com/documentation/storekit/apptransaction/environment https://developer.apple.com/documentation/storekit/appstore/environment I gather this information on the app using StoreKit and then send it to the server: originalTransactionId = transaction.originalID originalTransactionEnvironment = transaction.environment When testing within Xcode, on a simulator, the value sent to the server for originalTransactionEnvironment is Xcode - as expected. When testing on a device using a TestFlight build, the value sent to the server for originalTransactionEnvironment is undefined/nil. I expected it to be Sandbox - and later in production it should be Production. Most importantly, the value sent to the server for originalTransactionId in the TestFlight version is not undefined/nil - it is the value I expected it would be. The transaction was originally for a subscription purchase, if that makes a difference. So the transaction is available, and information like originalID is also available. Why is transaction.environment not available? What is the behavior in production?
0
0
231
Dec ’24
App Store Server Notifications and API Client - Toggling Sandbox vs Production Environment
The documentation mentions the following: Verify your receipt first with the production URL; then verify with the sandbox URL if you receive a 21007 status code. This approach ensures you don’t have to switch between URLs while your app is in testing, in review by App Review, or live in the App Store. This way, you can use one server environment to handle both Sandbox and Production environments. It is necessary to pass App Review. However, I'm not manually hitting these URLs - I'm using Apple's libraries. Specifically, the environment is used in SignedDataVerifier and AppStoreServerAPIClient. (I can't link to these because, for some reason, the domain apple.github.io is not allowed. The documentation for these is only found there. You can find it quickly by searching these terms and the domain.) Here is how SignedDataVerifier is being used: const verifier = new SignedDataVerifier( appleRootCertificates, APPLE_ENABLE_ONLINE_CHECKS, APPLE_ENVIRONMENT, APPLE_BUNDLE_ID, APPLE_APP_ID ) const verifiedNotification: ResponseBodyV2DecodedPayload = await verifier.verifyAndDecodeNotification(signedPayload) if (!verifiedNotification) { // Failure return } Here is how AppStoreServerAPIClient is being used: const appStoreServerAPIClient = new AppStoreServerAPIClient( SIGNING_KEY, APPLE_IAP_KEY_ID, APPLE_IAP_ISSUER_ID, APPLE_BUNDLE_ID, APPLE_ENVIRONMENT ) const statusResponse: StatusResponse = await appStoreServerAPIClient.getAllSubscriptionStatuses(originalTransactionId, [Status.ACTIVE]) In the source code for SignedDataVerifier.verifyAndDecodeNotification, I can see that it throws a VerificationException(VerificationStatus.INVALID_ENVIRONMENT) error . So for SignedDataVerifier is it as simple as wrapping my code in a try/catch and checking that the error's status code is 21007? I'm unsure about this because if you scroll to the bottom of the linked source code file, you can see the enumeration VerificationStatus, but it's unclear if this member has a value of 21007. The source code for AppStoreServerAPIClient only says that it throws an APIException if a response could not be processed, so I'm not too sure about how to handle this one.
1
1
527
Dec ’24
SwiftData - delete all instances of model causes "Type cannot conform to PersistentModel" error
Background I have a SwiftData Model specified like this, within a SwiftUI app: @Model class MyModel { // Model information. } It's been working as expected. I can add it to my app's model container as follows: WindowGroup { ContentView() } .modelContainer(for: [MyModel.self]) And have been able to create, persist, and fetch data as expected. Problem I created a function to delete the persisted data: func deleteData(modelContext: ModelContext) { modelContext.delete(MyModel.self) } But the compiler is throwing this error: Type 'MyModel.Type' cannot conform to 'PersistentModel'. I'm attempting to do this based of the documentation which specifies that only a model may be provided to delete all instances: Warning If you don’t provide a predicate, the context will remove all models of the specified type from the persistent storage. Other Information Is this a bug in Xcode or the Swift compiler? It makes no sense at all, for the following reasons. MyModel is explicitly PersistentModel I can adjust my model to the following without any errors: @Model class MyModel: PersistentModel { // Model information. } So clearly MyModel does conform to PersistentModel, but it doesn't clear the error. (Note: There are no compiler errors that pop up, but there actually will be a Preview error that says Redundant conformance of 'MyModel' to protocol 'PersistentModel', which is helpful as more confirmation that it conforms either way.) .modelContainer(for:) accepts PersistentModel I'm calling .modelContainer(for: [MyModel.self]) without any issues, and the documentation for this function confirms that it accepts a PersistentModel for parameter. The documentation for ModelContainer has these initializers: init(for: Schema, migrationPlan: (any SchemaMigrationPlan.Type)?, configurations: [ModelConfiguration]) throws convenience init(for: any PersistentModel.Type..., migrationPlan: (any SchemaMigrationPlan.Type)?, configurations: ModelConfiguration...) throws convenience init(for: Schema, migrationPlan: (any SchemaMigrationPlan.Type)?, configurations: ModelConfiguration...) throws One of them explicitly accepts any PersistentModel.Type, and the other two accept Schema, whose documentation shows the initializer that I seem to be using, which also accepts any PersistentModel.Type: init([any PersistentModel.Type], version: Schema.Version) Conclusion Overall, it seems like this might be a bug since the class can be explicitly labeled as PersistentModel without errors, and it's already being used with functions that require a PersistentModel parameter. What can I do about this? I found this answer from about a year ago, but none of the solutions seem applicable. One of them mentions a bug that was supposedly fixed. I'm on Xcode 15.4.
1
0
788
Aug ’24