Post

Replies

Boosts

Views

Activity

Is restore button still required if we were using StoreKit2 Transaction.currentEntitlements
Since StoreKit2 Transaction.currentEntitlements will able to return us user current owned purchased, during app startup. If that is the case, is it still necessary for developer to provide a restore button? If we still need to provide a restore button, what should the restore button do and what API should it call? Thanks
1
0
1.5k
Apr ’22
AVFAudio - Is it safe to perform file copy immediately after AVAudioRecorder.stop()
We start a voice recording via self.avAudioRecorder = try AVAudioRecorder( url: self.recordingFileUrl, settings: settings ) self.avAudioRecorder.record() At certain point, we will stop the recording via self.avAudioRecorder.stop() I was wondering, is it safe to perform file copy on self.recordingFileUrl immediately, after self.avAudioRecorder.stop()? Is all recording data has been flushed to self.recordingFileUrl and self.recordingFileUrl file is closed properly?
1
0
1.4k
May ’22
What are some reliable mechanism to prevent data duplication in CoreData CloudKit?
Every of our data row, contains an unique uuid column. Previously, before adopting CloudKit, the uuid column has a unique constraint. This enables us to prevent data duplication. Now, we start to integrate CloudKit, into our existing CoreData. Such unique constraint is removed. The following user flow, will cause data duplication. Steps to cause data duplication when using CloudKit Launch the app for the first time. Since there is empty data, a pre-defined data with pre-defined uuid is generated. The pre-defined data is sync to iCloud. The app is uninstalled. The app is re-installed. Launch the app for the first time. Since there is empty data, a pre-defined data with pre-defined uuid is generated. Previous old pre-defined data from step 3, is sync to the device. We are now having 2 pre-defined data with same uuid! :( I was wondering, is there a way for us to prevent such duplication? In step 8, we wish we have a way to execute such logic before written into CoreData Check whether such uuid exists in CoreData. If not, write to CoreData. If not, we will pick the one with latest update date, then overwrite the existing data. I once try to insert the above logic into https://developer.apple.com/documentation/coredata/nsmanagedobject/1506209-willsave . To prevent save, I am using self.managedObjectContext?.rollback(). But it just crash. Do you have any idea, what are some reliable mechanism I can use, to prevent data duplication in CoreData CloudKit? Additional info: Before adopting CloudKit We are using using the following CoreData stack class CoreDataStack { static let INSTANCE = CoreDataStack() private init() { } private(set) lazy var persistentContainer: NSPersistentContainer = { precondition(Thread.isMainThread) let container = NSPersistentContainer(name: "xxx", managedObjectModel: NSManagedObjectModel.wenote) container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { // This is a serious fatal error. We will just simply terminate the app, rather than using error_log. fatalError("Unresolved error \(error), \(error.userInfo)") } }) // So that when backgroundContext write to persistent store, container.viewContext will retrieve update from // persistent store. container.viewContext.automaticallyMergesChangesFromParent = true // TODO: Not sure these are required... // //container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy //container.viewContext.undoManager = nil //container.viewContext.shouldDeleteInaccessibleFaults = true return container }() Our CoreData data schema has Unique constraint. Deny deletion rule for relationship. Not having default value for non-null field. After adopting CloudKit class CoreDataStack { static let INSTANCE = CoreDataStack() private init() { } private(set) lazy var persistentContainer: NSPersistentContainer = { precondition(Thread.isMainThread) let container = NSPersistentCloudKitContainer(name: "xxx", managedObjectModel: NSManagedObjectModel.wenote) container.loadPersistentStores(completionHandler: { (storeDescription, error) in if let error = error as NSError? { // This is a serious fatal error. We will just simply terminate the app, rather than using error_log. fatalError("Unresolved error \(error), \(error.userInfo)") } }) // So that when backgroundContext write to persistent store, container.viewContext will retrieve update from // persistent store. container.viewContext.automaticallyMergesChangesFromParent = true // TODO: Not sure these are required... // //container.viewContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy //container.viewContext.undoManager = nil //container.viewContext.shouldDeleteInaccessibleFaults = true return container }() We change the CoreData data schema to Not having unique constraint. Nullify deletion rule for relationship. Having default value for non-null field. Based on a feedback of a Developer Technical Support engineer from https://developer.apple.com/forums/thread/699634?login=true , hen mentioned we can Detecting Relevant Changes by Consuming Store Persistent History Removing Duplicate Data But, it isn't entirely clear on how it should be implemented, as the github link provided in broken.
1
1
1.3k
Jun ’22
Is there any special handling required in StoreKit2, to handle promo code redemption?
My users will redeem promo code via app store (outside my app) Currently, I am using StoreKit2 to Query Transaction.currentEntitlements during app startup Keep listening to Transaction.updates I was wondering, is that is so, is there any special code required, to handle Promo code redeem from user? I guess by keep listening to Transaction.updates, will able to handle such case? But, I am not able to test that, without rolling out my app to production. Thanks.
1
0
773
Sep ’22
Stability of XCode 14
My XCode 13+ was used at MacBook Pro (13-inch, M1, 2020, 16G RAM) without issue Even since updated XCode to 14 week ago, I experience slowness while typing in XCode, and other editing operation. and, this crash happens few times a day Does anyone experience the same thing as I do? Thanks.
1
0
663
Sep ’22
Is there any static analysis tool which can help us detect memory leak cause by missing [weak self]?
I was wondering, is there any tool, which can help to detect memory leak caused by missing [weak self]. For instance, the following code contains memory leak issue caused by lack of [weak self] class ImagePageViewController: UIPageViewController { lazy var memoryLeak = UIAction( title: "memory_leak", image: nil ) { _ in print(">>>> \(self)") } } Is there any tool which can help us to prevent such issue? I have tried  https://github.com/realm/SwiftLint but it is not able to detect such.
1
0
697
Sep ’22
How to avoid CoreData corruption when developing Share extension to CoreData in AppGroup?
We plan to develop a Share extension. The CoreData is storing its SQLite file in AppGroup folder. The share extension will run in a different process than main app's. Since share extension and main app are running in different process, both will have their own instance of CoreData. However, even there are multiple instances of CoreData in different processes, their underlying are pointing to a single same SQLite file. Under https://developer.apple.com/library/archive/documentation/General/Conceptual/ExtensibilityPG/ExtensionScenarios.html#//apple_ref/doc/uid/TP40014214-CH21-SW1 It mentions When you set up a shared container, the containing app—and each contained app extension that you allow to participate in data sharing—have read and write access to the shared container. To avoid data corruption, you must synchronize data accesses. Use Core Data, SQLite, or Posix locks to help coordinate data access in a shared container. But it isn't clear, what are detailed steps required to How can we synchronize access to CoreData among 2 processes? Who should responsible to consume relevant store change, and update the single token file? (https://developer.apple.com/documentation/coredata/consuming_relevant_store_changes) Should it be main app, share extension or both? Thank you.
1
0
894
Nov ’22
Is there a way to override the theme of WidgetKit, so that we can retrieve correct named color in WidgetKit?
In main app, I can override dark/ light theme based on user preference, so that I can retrieve correct color information based on named color. if (user preference) { overrideUserInterfaceStyle = .light } else { overrideUserInterfaceStyle = .dark } // Dark theme/ light theme automatic aware color. SwiftUI.Color("purpleColor") However, how can I override the theme of a WidgetKit, so that my WidgetKit can interpret named color correctly? I know in WidgetKit, I can read what is current system wide theme settings using  @Environment(\.colorScheme) But, that is not what I want. I want the ability to override theme of a WidgetKit based on user preference, then able to retrieve correct named color. Thanks.
1
0
995
Aug ’24
Does anyone know how I can reset/ cancel my in-app purchase status from TestFlight account?
I install and test my own app, in real device, from TestFlight. I want to able to keep testing on the in-app purchase/ subscription feature. I notice once I have purchase an item success (I was prompted to enter password during purchase), it will forever be marked as purchased. In simulator, if I uninstall then re-install again the app, the in-app purchase status will all be reset. However, for TestFlight in real device, I do not find a way to reset my purchase. (So that I can keep testing on the purchase process) Does anyone know, how I can reset/ cancel my in-app purchase status from TestFlight account?
1
1
961
Mar ’23
UISheetPresentationController: Remove Dim Background but Keep Touch-to-Dismiss?
I'm using the UISheetPresentationController to present a view, as shown in the following code: @IBAction func click(_ sender: Any) { let whiteViewController = WhiteViewController.instanceFromMainStoryBoard() if let sheet = whiteViewController.sheetPresentationController { sheet.detents = [.medium()] sheet.prefersScrollingExpandsWhenScrolledToEdge = false sheet.prefersGrabberVisible = false // Remove dim effect. ////sheet.largestUndimmedDetentIdentifier = .medium } self.present(whiteViewController, animated: true) } The outcome is as follow This code results in a presentation with: A dimmed background. A 'Touch anywhere to dismiss' behavior. However, I want to remove the dim background while keeping the 'Touch anywhere to dismiss' functionality. When I add the line: sheet.largestUndimmedDetentIdentifier = .medium The dim background is indeed removed, but the touch-to-dismiss behavior is gone too, as illustrated: Is there a way to achieve both – removing the dim background and retaining the touch-to-dismiss functionality? Thank you.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
2k
Oct ’23
Troubleshooting Core Data Lightweight Migration: A Real-World Challenge
In my recent endeavor, I aimed to introduce new Fetch Index Elements to the Core Data model of my iOS application. To achieve this, I followed a process of lightweight migration, detailed as follows: Navigate to Editor > Add Model Version to create a new version of the data model. Name the new version with a sequential identifier (e.g., MyAppModelV3.xcdatamodel) based on the naming convention of previous models. Select the newly created version, MyAppModelV3.xcdatamodel, as the active model. Mark this new version as the "Current" model in the Xcode properties panel on the right. In the new version of the model, MyAppModelV3.xcdatamodel, and add the new Fetch Index Elements there. Also, insert "v3" in the Versioning Hash Modifier field of affected entity, to indicate this modification. Upon reflection, I realized that creating a new version of the xcdatamodel might not have been necessary for this particular case. However, it appears to have caused no adverse effects on the application's functionality. During testing, I executed the application in a simulated environment, initially running an older version of the app to inspect the database content with SQLite DB Browser. I then upgraded to the latest app version to verify that the migration was successfully completed without causing any crashes. Throughout this testing phase, I employed the -com.apple.CoreData.MigrationDebug 1 flag to monitor all SQL operations, ensuring that indexes were appropriately dropped and recreated for the affected entity. Following thorough testing, I deployed the update to production. The majority of users were able to upgrade to the new app version seamlessly. However, a small fraction reported crashes at startup, indicated by the following error message: Fatal error: Unresolved error Error Domain=NSCocoaErrorDomain Code=134110 "An error occurred during persistent store migration." UserInfo={NSUnderlyingError=0x2820ad3e0 {Error Domain=NSCocoaErrorDomain Code=134100 "The managed object model version used to open the persistent store is incompatible with the one that was used to create the persistent store." UserInfo={metadata={ NSPersistenceFrameworkVersion = 1338; NSStoreModelVersionChecksumKey = "qcPf6+DfpsPrDQ3j1EVXcBIrFe1O0R6IKd30sJf4IrI="; NSStoreModelVersionHashes = { NSAttachment = {length = 32, ... Strangely, the only way I could replicate this issue in the simulator was by running the latest version of the app followed by reverting to an older version, a scenario unlikely to occur in a real-world setting. This raises the question: How could this situation arise with actual users, considering they would typically move from an old to a new version rather than the reverse? I am reaching out to the community for insights or advice on this matter. Has anyone else encountered a similar problem during the Core Data migration process? How did you resolve it?
1
1
945
Sep ’24
What are some other actionable items I can do, so that I can get through "Guideline 4.3(a) - Design - Spam" app update rejection?
I have an app which is in the app store since 2022. It is an app with combined features of note taking, todo list and calendar. My most recent app update is rejected with the following message. Guideline 4.3(a) - Design - Spam We noticed your app shares a similar binary, metadata, and/or concept as apps submitted to the App Store by other developers, with only minor differences. Submitting similar or repackaged apps is a form of spam that creates clutter and makes it difficult for users to discover new apps. Next Steps Since we do not accept spam apps on the App Store, we encourage you to review your app concept and submit a unique app with distinct content and functionality. Resources Some factors that contribute to a spam rejection may include: Submitting an app with the same source code or assets as other apps already submitted to the App Store Creating and submitting multiple similar apps using a repackaged app template Purchasing an app template with problematic code from a third party Submitting several similar apps across multiple accounts Learn more about our requirements to prevent spam in App Review Guideline 4.3(a). Support Reply to this message in your preferred language if you need assistance. If you need additional support, use the Contact Us module. Consult with fellow developers and Apple engineers on the Apple Developer Forums. Help improve the review process or identify a need for clarity in our policies by suggesting guideline changes. I reply the reviewer with the following message. Hi, I am writing to appeal the rejection of my app, XXX. I would like to emphasize the unique aspects of XXX that distinguish it from other apps in the market: Integrated Functionality: Unlike most apps that are standalone note-taking, to-do, or calendar apps, XXX uniquely combines all three functions into a single app. Extensive Calendar Features: XXX includes a comprehensive calendar feature covering holidays in 250 countries and 3,680 states and provinces, a rare and valuable feature. Chinese Lunar Calendar: Our app includes a Chinese Lunar Calendar, which is highly appreciated in the Taiwanese market, adding a culturally specific feature not commonly found in other apps. Organizational Tools: XXX allows unlimited tabs and colors for organizing notes, surpassing many competitors who offer limited color options. Flexible Viewing and Sorting Modes: Users can choose from four viewing modes (Grid, Compact Grid, List, Compact List) and five sorting modes (Modified Time, Created Time, Alphabet, Color, Check, Reminder), enhancing the user experience by providing flexibility and customization. No Character Limit: Our design supports notes of any length without character limitations, unlike many apps that impose restrictions. Organized To-Do Lists: Completed to-do items are automatically moved to the bottom, keeping the list clean and organized, a feature that sets us apart from other apps. Rich Attachments: XXX supports unlimited picture attachments, drawing attachments, and voice recordings for notes, offering more versatility than many other apps. Advanced Security: XXX offers 3 different kinds of password lock mechanisms to protect note privacy, ensuring users have multiple options for securing their information. Powerful Reminders: Our app includes highly customizable reminders that can repeat daily, weekly, monthly, or yearly, making it easy for users to stay on top of their tasks and appointments. Due to the character limits of this form, I cannot list all the unique features of XXX. Please refer to our product description for a comprehensive overview. We are proud of our 5k user reviews with an average rating of 4.8, reflecting user satisfaction with XXX's unique features. Here's are some of the recent reviews. (United states only. Please kindly contact me to obtain full list of the reviews) by ??? – Jun 14, 2024 omg i cannot explain how much i love XXX like unlike the boring notes app this one is actually fun to use and rlly easy and i rlly like the fonts, color, to do list, calandar that can remind you like every day, week, month, and year like omg?!?!? i love XXX and this app is going in like my "I 💖U" folder like tysm for making XXX idk what i would do without it like omg tysm i cant explain in words how much i love it💖💖💖💖💖💖💖💖💖💖💖💖💖💖 by ??? – May 12, 2024 I love it sooo much I give it a 5 because there is a password so no one can look by ??? – Apr 30, 2024 Perfect app. All in one by ??? – Mar 26, 2024 I just downloaded this app a few days ago and I love it!! 😃 Up til recently I ALWAYS used paper sticky notes that I would have on my desk - and the reason why is because I could see everything all at once at all times; it’s very convenient - but it also produces clutter and anxiety because every subject is all in one place. XXX fixed that!! 😀 With tabs and the list or grid view mode, I can have more organization of subjects and still see almost everything all at once! I love it! 🤩 suggestion I would really love to have more format options for the text! 🙂 Like a button to indent, and be able to have sub notes with points, dashes, or numbers. It makes everything look more tidy and neat. Thank you for this wonderful app! 😆 I am available at 123-456-789 to discuss further and provide additional detail. Thank you. Till to date, I haven't received reply from the reviewer. May I know, what are some other actionable items I can do, so that I can get through "Guideline 4.3(a) - Design - Spam" app update rejection? Thank you so much!
1
0
1.2k
Aug ’24
Specifying Item Spacing in UICollectionLayoutListConfiguration
Currently, I am using UICollectionViewCompositionalLayout to achieve the following list layout with spacing: We were thinking of trying out UICollectionLayoutListConfiguration due to its ability to support swipe actions. We would like to specify the spacing between each item. However, I do not find a way to specify item spacing in UICollectionLayoutListConfiguration. Does UICollectionLayoutListConfiguration not support item spacing, or have I missed something? Thanks.
Topic: UI Frameworks SubTopic: UIKit Tags:
1
0
870
Jul ’24
Optimizing Sorting and Order Management in CoreData
Sorting is an important feature in my app. I am using integers to represent the ordering sequence. Items: A, B, D, E, H Order number: 0, 1, 2, 3, 4 When I insert a new item "C", here's the outcome: Items: A, B, C, D, E, H Order number: 0, 1, 2, 3, 4, 5 Here's the write operation required on existing order numbers: D: 2 -> 3 E: 3 -> 4 H: 4 -> 5 I wish to reduce the number of write operations because CoreData is pretty slow at writing. The problem becomes more significant when my users start to have a few thousand items in CoreData. Here's my current workaround: leaving gaps between each order number. For instance: Items: A, B, D, E, H Order number: 0, 10, 20, 30, 40 When I insert a new item "C", here's the outcome: Items: A, B, C, D, E, H Order number: 0, 10, 11, 20, 30, 40 No write operations are required on existing order numbers. Every 1 or 2 weeks, when my users close the app, I run background tasks to re-arrange the gaps between order numbers so that when users insert new items, fewer existing order numbers will be affected. Items: A, B, C, D, E, H Order number: 0, 10, 20, 30, 40, 50 Since sorting is pretty common, I was thinking some of you might have a better idea on how to reduce write operations on existing order numbers. If you have a better idea, do you mind to share it with us? Thanks.
1
0
516
Jul ’24