Post

Replies

Boosts

Views

Activity

trailingSwipeActionsConfigurationProvider causes shadow effect on UICollectionViewListCell gone
Currently, I have achieve shadow and corner effect for UICollectionViewListCell, using the following code. UICollectionViewListCell class NoteCell: UICollectionViewListCell { override func awakeFromNib() { super.awakeFromNib() initShadow() initCorner() } private func updateShadowColor() { // Determine the shadow color based on the current interface style let shadowUIColor = UIColor.label self.layer.shadowColor = shadowUIColor.cgColor } private func initShadow() { // https://www.hackingwithswift.com/example-code/uikit/how-to-add-a-shadow-to-a-uiview self.layer.shadowOpacity = 0.3 self.layer.shadowOffset = CGSize(width: 0.5, height: 0.5) self.layer.shadowRadius = 2 self.layer.masksToBounds = false self.updateShadowColor() // Remove the following two lines if you experience any issues with shadow rendering: self.layer.shouldRasterize = true self.layer.rasterizationScale = UIScreen.main.scale } private func initCorner() { var backgroundConfig = UIBackgroundConfiguration.listPlainCell() backgroundConfig.backgroundColor = .systemBackground backgroundConfig.cornerRadius = 16 self.backgroundConfiguration = backgroundConfig } layout private func layoutConfig() -> UICollectionViewCompositionalLayout { let layout = UICollectionViewCompositionalLayout { section, layoutEnvironment in var config = UICollectionLayoutListConfiguration(appearance: .plain) config.headerMode = .none config.footerMode = .none config.showsSeparators = false config.headerTopPadding = 0 config.backgroundColor = nil config.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath in guard let self = self else { return nil } // Knowing what we are tapping at. var snapshot = dataSource.snapshot() let sectionIdentifier = snapshot.sectionIdentifiers[indexPath.section] let itemIdentifiers = snapshot.itemIdentifiers(inSection: sectionIdentifier) let itemIdentifier: NoteWrapper = itemIdentifiers[indexPath.item] let deleteHandler: UIContextualAction.Handler = { action, view, completion in completion(true) // TODO: //snapshot.reloadItems([itemIdentifier]) } let deleteAction = UIContextualAction(style: .normal, title: "Trash", handler: deleteHandler) var swipeActionsConfiguration = UISwipeActionsConfiguration(actions: [ deleteAction, ]) deleteAction.image = UIImage(systemName: "trash") deleteAction.backgroundColor = UIColor.systemRed swipeActionsConfiguration.performsFirstActionWithFullSwipe = false return swipeActionsConfiguration } // https://developer.apple.com/forums/thread/759987 let layoutSection = NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment) layoutSection.interGroupSpacing = 16 // Distance between item. layoutSection.contentInsets = NSDirectionalEdgeInsets( top: 16, // Distance between 1st item and its own header. leading: 16, bottom: 16, // Distance of last item and other header/ bottom edge. trailing: 16 ) return layoutSection } return layout } This is the outcome. However, when I perform swipe action, the shadow effect is gone. Do you have any idea how I can resolve such? Thanks.
0
0
456
Oct ’24
Official document for CONSUMPTION_REQUEST - What kind of data we are receiving?
This documentation describes what kind of data we should be sending to Apple server, once we are receiving CONSUMPTION_REQUEST https://developer.apple.com/documentation/appstoreserverapi/consumptionrequest But, it doesn't describe what kind of data we are receiving, when we are receiving CONSUMPTION_REQUEST? May I know, is such a document available? Thank you.
0
0
558
Dec ’24
Issue with Empty Reporting in Apple Search Ads (Basic)
Hi, I am using Apple Search Ads (Basic), and I’ve noticed that my bank account has been debited weekly. However, when I recently tried to access the reports, they appear empty. Please see the attached screenshots for reference. Is there a customer support representative from Apple Search Ads who can assist me with this issue? Thank you.
0
0
432
Jan ’25
Managing Legacy Subscriptions on the App Store
I have several subscription plans in the App Store that I no longer wish to offer to new users. In my app, these old subscriptions are hidden, but they remain active so existing subscribers can continue their plans and be charged as usual. However, some new users are still able to switch to these old subscription plans through the App Store. What is the best solution for this situation? I want to continue serving existing subscribers while preventing new users from subscribing to these legacy plans. Thank you.
2
0
269
Sep ’25
UIToolbar buttons losing spacing in Xcode 26.1.1 Legacy Mode (UIDesignRequiresCompatibility)
We're using XCode 26.1.1 We do not have resource to adopt Liquid Glass design. Hence, we are using the following workaround <key>UIDesignRequiresCompatibility</key> <true/> This is our Storyboard. Pre XCode 26 Before XCode 26.1.1, the bottom toolbar looks great. In XCode 26 However, in XCode 26.1.1, the bottom toolbar buttons seems to "Squish together". Do anyone have any idea, how I can make UIToolbar works by enabling UIDesignRequiresCompatibility? Thanks.
Topic: UI Frameworks SubTopic: UIKit Tags:
0
0
160
Dec ’25
Is Xcode Intelligence Ready for Production? My Experience and a Quest for Better Tools
I am looking to optimize my AI-assisted workflow within Xcode. Previously, my process was inefficient: Manually selecting and copying code snippets from Xcode into Gemini. Asking a specific question (e.g., "Modify this to show an alertError message box"). Copying the result back into Xcode. I attempted to switch to the new native Intelligence feature in Xcode to streamline this, but I found significant shortcomings: Latency: The response time is noticeably slow. Much slower than asking directly on Gemini 3 Pro. Lack of Context: The AI often fails to grasp the full project context. For example, it frequently claims it cannot see the code for ScannerView even though it is part of the project. I often have to prompt it multiple times before it finally "finds" the file. Is Xcode's Intelligence feature actually production-ready yet? If not, what tools do you recommend that integrate well with iOS development? To be clear, I am not looking for "vibe coding." I have a clear grasp of the problem and the high-level solution. My goal is to delegate the low-level implementation to the AI. I need a tool that has full project context from the start, eliminating the need to manually copy-paste snippets into a chat window.
1
0
94
Mar ’26
The following simple function will cause Xcode 12E262 to have "Abort: trap 6"
The following simple function will cause Xcode 12E262 to have "Abort: trap 6" during compilation. import UIKit import CoreData class ViewController: UIViewController {     func xyz() {         let container = NSPersistentContainer(name: "xyz")         let batchUpdateRequest = NSBatchUpdateRequest(entityName: "xyz")         let batchUpdateResult = try! container.viewContext.execute(batchUpdateRequest) as? NSBatchUpdateResult         guard let batchUpdateResult = batchUpdateResult else { return }     }     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.     } } We will not observe "Abort: trap 6", if under Build Settings, we are using "Optimize for Speed" in Debug, instead of "No Optimization" We can also avoid "Abort: trap 6", if we change the following code guard let batchUpdateResult = batchUpdateResult else { return } to guard let batchUpdateResult2 = batchUpdateResult else { return } May I know, why is it so? A simpler code example to reproduce problem, without CoreData would be import UIKit class ViewController: UIViewController {     func getAny() throws -> Any? {         return nil     }     func xyz() {         let name = try! getAny() as? UIViewController         guard let name = name else { return }     }     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.     } }
2
0
985
Jun ’21
Why an invisible same cell is being updated when update is performing using NSFetchedResultsController and Diffable Data Source?
Introduction I expect when I perform "update" on 1 of the CoreData entity content, corresponding UICollectionViewCell should updated seamlessly. But, the thing doesn't work as expected. After debugging, I notice that instead of updating visible UICollectionViewCell on screen, an invisible offscreen UICollectionViewCell has been created and all update operations are performed on the invisible UICollectionViewCell?! Simple hookup between NSFetchedResultsController and Diffable Data Source The hookup is pretty straightforward extension ViewController: NSFetchedResultsControllerDelegate { func controller(_ fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshotReference: NSDiffableDataSourceSnapshotReference) { guard let dataSource = self.dataSource else { return } let snapshot = snapshotReference as NSDiffableDataSourceSnapshot<Int, NSManagedObjectID> print("dataSource.apply") dataSource.apply(snapshot, animatingDifferences: true) { } } } Simple data structure import Foundation import CoreData extension NSTabInfo { @nonobjc public class func fetchRequest() -> NSFetchRequest<NSTabInfo> { return NSFetchRequest<NSTabInfo>(entityName: "NSTabInfo") } @NSManaged public var name: String? @NSManaged public var order: Int64 } extension NSTabInfo : Identifiable { } Simple data source to update cell private func initDataSource() { let dataSource = DataSource( collectionView: collectionView, cellProvider: { [weak self] (collectionView, indexPath, objectID) -> UICollectionViewCell? in guard let self = self else { return nil } guard let cell = collectionView.dequeueReusableCell( withReuseIdentifier: "cell", for: indexPath) as? CollectionViewCell else { return nil } guard let nsTabInfo = self.getNSTabInfo(indexPath) else { return nil } cell.label.text = nsTabInfo.name print("Memory for cell \(Unmanaged.passUnretained(cell).toOpaque())") print("Content for cell \(cell.label.text)\n") return cell } ) self.dataSource = dataSource } Updating code doesn't work We perform update on the 1st cell using the following code @IBAction func updateClicked(_ sender: Any) { let backgroundContext = self.backgroundContext backgroundContext.perform { let fetchRequest = NSFetchRequest<NSTabInfo>(entityName: "NSTabInfo") fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "order", ascending: true) ] do { let nsTabInfos = try fetchRequest.execute() if !nsTabInfos.isEmpty { // Perform update on the first cell nsTabInfos[0].name = "\(Int(nsTabInfos[0].name!)! + 1)" if backgroundContext.hasChanges { try backgroundContext.save() } } } catch { print("\(error)") } } } Nothing is changed on the screen. However, if we look at the print output. We can see the initial content ("0") of the 1st cell is updated to "1". But, all of these are being done in an invisible same instance cell. dataSource.apply Memory for cell 0x0000000138705cd0 Content for cell Optional("1") Memory for cell 0x0000000138705cd0 Content for cell Optional("1") Memory for cell 0x0000000138705cd0 Content for cell Optional("2") Memory for cell 0x0000000138705cd0 Content for cell Optional("3") Ordering work without issue Changing the ordering of the cell works as expected. The following is the code for charging ordering. @IBAction func moveClicked(_ sender: Any) { let backgroundContext = self.backgroundContext backgroundContext.perform { let fetchRequest = NSFetchRequest<NSTabInfo>(entityName: "NSTabInfo") fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "order", ascending: true) ] do { let nsTabInfos = try fetchRequest.execute() for (index, element) in nsTabInfos.reversed().enumerated() { element.order = Int64(index) } if backgroundContext.hasChanges { try backgroundContext.save() } } catch { print("\(error)") } } } Do you have idea why such problem occur? I prefer not to have collectionView.reloadData as workaround, as it will create more issue (like resetting scroll position, cell press state, ...) I posted a complete demo at https://github.com/yccheok/problem-update-frc-diffable Thank you
1
0
1.3k
Jul ’21
Should I use weak to avoid from interferencing with CoreData memory management?
Currently, I have the following core data backed collection view, which enable users to perform add/ delete/ modify/ reordering. It will be much more convenient to achieve what I, if I let UICollectionViewCell, to hold its corresponding NSManagedObject. So that I can each perform add/ delete/ modify/ reordering. I was wondering, should I mark the NSManagedObject as weak, to avoid from interferencing with how CoreData manage its memory? Using weak class TabInfoSettingsCell: UICollectionViewCell { // NSManagedObject. Use weak, as we do not want to inteference with how CoreData manage its memory. private weak var nsTabInfo : NSTabInfo? Use strong Or, such concern is invalid. We can simply use strong class TabInfoSettingsCell: UICollectionViewCell { // NSManagedObject. private var nsTabInfo : NSTabInfo? Use struct Or, such concern is valid and using weak is unsafe (as it can become nil in some edge case?). We can use a struct, which contains everything including objectID, but excluding NSManagedObjectContext. class TabInfoSettingsCell: UICollectionViewCell { // struct. Contains everything including objectID, but excluding NSManagedObjectContext. private var tabInfo : TabInfo? This come with the cost of having to create a struct out from NSManagedObject each time, in cellForItemAt. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { ... tabInfoSettingsCell.update(nsTabInfo.toTabInfo()) ... } May I know, which is the correct design, as far as safe memory management is concerned?
1
0
709
Jun ’21
Is NSAsynchronousFetchRequest suitable for production app?
NSAsynchronousFetchRequest seems like an answer to read large amount of data from CoreData, without blocking main thread. But, it is lacking some key features, provided by NSFetchedResultsController. The key features are :- In NSFetchedResultsControllerDelegate didChange and controllerDidChangeContent, we automatically receive a complete change information of persistence store. This enables us to implement the animation of add/delete/move/modify in collection view. Always listen to DB changes. Whenever there is changes being written into the persistence store, NSFetchedResultsControllerDelegate didChange and controllerDidChangeContent will be triggered automatically. This enables us to ensure our UI is in sync with DB. But, NSAsynchronousFetchRequest doesn't come with NSAsynchronousFetchedResultsController :( I was wondering, if you were using NSAsynchronousFetchRequest, how do you implement Animation changes on collection view? Always listen to DB change? My initial thought for animation changes on collection view, it seems we can utilise UICollectionViewDiffableDataSource. But, I notice it might be highly memory inefficient to do so. We need to keep ALL NSManagedObject in memory, fire all faults during comparison. It looks like we will run out of memory, if there are many rows. May I know, how do you achieve the following features, if you ever apply NSAsynchronousFetchRequest in production app? Animation changes on collection view? Always listen to DB change? Thanks.
1
0
811
Jul ’21
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
trailingSwipeActionsConfigurationProvider causes shadow effect on UICollectionViewListCell gone
Currently, I have achieve shadow and corner effect for UICollectionViewListCell, using the following code. UICollectionViewListCell class NoteCell: UICollectionViewListCell { override func awakeFromNib() { super.awakeFromNib() initShadow() initCorner() } private func updateShadowColor() { // Determine the shadow color based on the current interface style let shadowUIColor = UIColor.label self.layer.shadowColor = shadowUIColor.cgColor } private func initShadow() { // https://www.hackingwithswift.com/example-code/uikit/how-to-add-a-shadow-to-a-uiview self.layer.shadowOpacity = 0.3 self.layer.shadowOffset = CGSize(width: 0.5, height: 0.5) self.layer.shadowRadius = 2 self.layer.masksToBounds = false self.updateShadowColor() // Remove the following two lines if you experience any issues with shadow rendering: self.layer.shouldRasterize = true self.layer.rasterizationScale = UIScreen.main.scale } private func initCorner() { var backgroundConfig = UIBackgroundConfiguration.listPlainCell() backgroundConfig.backgroundColor = .systemBackground backgroundConfig.cornerRadius = 16 self.backgroundConfiguration = backgroundConfig } layout private func layoutConfig() -> UICollectionViewCompositionalLayout { let layout = UICollectionViewCompositionalLayout { section, layoutEnvironment in var config = UICollectionLayoutListConfiguration(appearance: .plain) config.headerMode = .none config.footerMode = .none config.showsSeparators = false config.headerTopPadding = 0 config.backgroundColor = nil config.trailingSwipeActionsConfigurationProvider = { [weak self] indexPath in guard let self = self else { return nil } // Knowing what we are tapping at. var snapshot = dataSource.snapshot() let sectionIdentifier = snapshot.sectionIdentifiers[indexPath.section] let itemIdentifiers = snapshot.itemIdentifiers(inSection: sectionIdentifier) let itemIdentifier: NoteWrapper = itemIdentifiers[indexPath.item] let deleteHandler: UIContextualAction.Handler = { action, view, completion in completion(true) // TODO: //snapshot.reloadItems([itemIdentifier]) } let deleteAction = UIContextualAction(style: .normal, title: "Trash", handler: deleteHandler) var swipeActionsConfiguration = UISwipeActionsConfiguration(actions: [ deleteAction, ]) deleteAction.image = UIImage(systemName: "trash") deleteAction.backgroundColor = UIColor.systemRed swipeActionsConfiguration.performsFirstActionWithFullSwipe = false return swipeActionsConfiguration } // https://developer.apple.com/forums/thread/759987 let layoutSection = NSCollectionLayoutSection.list(using: config, layoutEnvironment: layoutEnvironment) layoutSection.interGroupSpacing = 16 // Distance between item. layoutSection.contentInsets = NSDirectionalEdgeInsets( top: 16, // Distance between 1st item and its own header. leading: 16, bottom: 16, // Distance of last item and other header/ bottom edge. trailing: 16 ) return layoutSection } return layout } This is the outcome. However, when I perform swipe action, the shadow effect is gone. Do you have any idea how I can resolve such? Thanks.
Replies
0
Boosts
0
Views
456
Activity
Oct ’24
Unable to edit the poster frame of app preview
After waiting for few hours, I am still not able to edit the poster frame of app preview. Can anyone from App Store Connect assist me on this? Thank you.
Replies
0
Boosts
0
Views
351
Activity
Dec ’24
Official document for CONSUMPTION_REQUEST - What kind of data we are receiving?
This documentation describes what kind of data we should be sending to Apple server, once we are receiving CONSUMPTION_REQUEST https://developer.apple.com/documentation/appstoreserverapi/consumptionrequest But, it doesn't describe what kind of data we are receiving, when we are receiving CONSUMPTION_REQUEST? May I know, is such a document available? Thank you.
Replies
0
Boosts
0
Views
558
Activity
Dec ’24
Issue with Empty Reporting in Apple Search Ads (Basic)
Hi, I am using Apple Search Ads (Basic), and I’ve noticed that my bank account has been debited weekly. However, when I recently tried to access the reports, they appear empty. Please see the attached screenshots for reference. Is there a customer support representative from Apple Search Ads who can assist me with this issue? Thank you.
Replies
0
Boosts
0
Views
432
Activity
Jan ’25
Managing Legacy Subscriptions on the App Store
I have several subscription plans in the App Store that I no longer wish to offer to new users. In my app, these old subscriptions are hidden, but they remain active so existing subscribers can continue their plans and be charged as usual. However, some new users are still able to switch to these old subscription plans through the App Store. What is the best solution for this situation? I want to continue serving existing subscribers while preventing new users from subscribing to these legacy plans. Thank you.
Replies
2
Boosts
0
Views
269
Activity
Sep ’25
Request for Faster In-App Purchase Review
I requested an expedited review, and the app was approved within a few hours. However, the in-app purchase subscription plan is still under review. Is there anything I can do to speed up the approval process for the in-app purchase, or do I just have to wait? Thanks.
Replies
0
Boosts
0
Views
205
Activity
Oct ’25
UIToolbar buttons losing spacing in Xcode 26.1.1 Legacy Mode (UIDesignRequiresCompatibility)
We're using XCode 26.1.1 We do not have resource to adopt Liquid Glass design. Hence, we are using the following workaround <key>UIDesignRequiresCompatibility</key> <true/> This is our Storyboard. Pre XCode 26 Before XCode 26.1.1, the bottom toolbar looks great. In XCode 26 However, in XCode 26.1.1, the bottom toolbar buttons seems to "Squish together". Do anyone have any idea, how I can make UIToolbar works by enabling UIDesignRequiresCompatibility? Thanks.
Topic: UI Frameworks SubTopic: UIKit Tags:
Replies
0
Boosts
0
Views
160
Activity
Dec ’25
Is Xcode Intelligence Ready for Production? My Experience and a Quest for Better Tools
I am looking to optimize my AI-assisted workflow within Xcode. Previously, my process was inefficient: Manually selecting and copying code snippets from Xcode into Gemini. Asking a specific question (e.g., "Modify this to show an alertError message box"). Copying the result back into Xcode. I attempted to switch to the new native Intelligence feature in Xcode to streamline this, but I found significant shortcomings: Latency: The response time is noticeably slow. Much slower than asking directly on Gemini 3 Pro. Lack of Context: The AI often fails to grasp the full project context. For example, it frequently claims it cannot see the code for ScannerView even though it is part of the project. I often have to prompt it multiple times before it finally "finds" the file. Is Xcode's Intelligence feature actually production-ready yet? If not, what tools do you recommend that integrate well with iOS development? To be clear, I am not looking for "vibe coding." I have a clear grasp of the problem and the high-level solution. My goal is to delegate the low-level implementation to the AI. I need a tool that has full project context from the start, eliminating the need to manually copy-paste snippets into a chat window.
Replies
1
Boosts
0
Views
94
Activity
Mar ’26
Is Product Page Optimization in App Store Connect broken?
This issue has persisted for a week. Whenever I tap on "View Analytics" in Product Page Optimization, I always get the error: "The page you're looking for can't be found." Is anyone else encountering this issue? Thanks.
Replies
0
Boosts
0
Views
91
Activity
2w
The following simple function will cause Xcode 12E262 to have "Abort: trap 6"
The following simple function will cause Xcode 12E262 to have "Abort: trap 6" during compilation. import UIKit import CoreData class ViewController: UIViewController {     func xyz() {         let container = NSPersistentContainer(name: "xyz")         let batchUpdateRequest = NSBatchUpdateRequest(entityName: "xyz")         let batchUpdateResult = try! container.viewContext.execute(batchUpdateRequest) as? NSBatchUpdateResult         guard let batchUpdateResult = batchUpdateResult else { return }     }     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.     } } We will not observe "Abort: trap 6", if under Build Settings, we are using "Optimize for Speed" in Debug, instead of "No Optimization" We can also avoid "Abort: trap 6", if we change the following code guard let batchUpdateResult = batchUpdateResult else { return } to guard let batchUpdateResult2 = batchUpdateResult else { return } May I know, why is it so? A simpler code example to reproduce problem, without CoreData would be import UIKit class ViewController: UIViewController {     func getAny() throws -> Any? {         return nil     }     func xyz() {         let name = try! getAny() as? UIViewController         guard let name = name else { return }     }     override func viewDidLoad() {         super.viewDidLoad()         // Do any additional setup after loading the view.     } }
Replies
2
Boosts
0
Views
985
Activity
Jun ’21
Why an invisible same cell is being updated when update is performing using NSFetchedResultsController and Diffable Data Source?
Introduction I expect when I perform "update" on 1 of the CoreData entity content, corresponding UICollectionViewCell should updated seamlessly. But, the thing doesn't work as expected. After debugging, I notice that instead of updating visible UICollectionViewCell on screen, an invisible offscreen UICollectionViewCell has been created and all update operations are performed on the invisible UICollectionViewCell?! Simple hookup between NSFetchedResultsController and Diffable Data Source The hookup is pretty straightforward extension ViewController: NSFetchedResultsControllerDelegate { func controller(_ fetchedResultsController: NSFetchedResultsController<NSFetchRequestResult>, didChangeContentWith snapshotReference: NSDiffableDataSourceSnapshotReference) { guard let dataSource = self.dataSource else { return } let snapshot = snapshotReference as NSDiffableDataSourceSnapshot<Int, NSManagedObjectID> print("dataSource.apply") dataSource.apply(snapshot, animatingDifferences: true) { } } } Simple data structure import Foundation import CoreData extension NSTabInfo { @nonobjc public class func fetchRequest() -> NSFetchRequest<NSTabInfo> { return NSFetchRequest<NSTabInfo>(entityName: "NSTabInfo") } @NSManaged public var name: String? @NSManaged public var order: Int64 } extension NSTabInfo : Identifiable { } Simple data source to update cell private func initDataSource() { let dataSource = DataSource( collectionView: collectionView, cellProvider: { [weak self] (collectionView, indexPath, objectID) -> UICollectionViewCell? in guard let self = self else { return nil } guard let cell = collectionView.dequeueReusableCell( withReuseIdentifier: "cell", for: indexPath) as? CollectionViewCell else { return nil } guard let nsTabInfo = self.getNSTabInfo(indexPath) else { return nil } cell.label.text = nsTabInfo.name print("Memory for cell \(Unmanaged.passUnretained(cell).toOpaque())") print("Content for cell \(cell.label.text)\n") return cell } ) self.dataSource = dataSource } Updating code doesn't work We perform update on the 1st cell using the following code @IBAction func updateClicked(_ sender: Any) { let backgroundContext = self.backgroundContext backgroundContext.perform { let fetchRequest = NSFetchRequest<NSTabInfo>(entityName: "NSTabInfo") fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "order", ascending: true) ] do { let nsTabInfos = try fetchRequest.execute() if !nsTabInfos.isEmpty { // Perform update on the first cell nsTabInfos[0].name = "\(Int(nsTabInfos[0].name!)! + 1)" if backgroundContext.hasChanges { try backgroundContext.save() } } } catch { print("\(error)") } } } Nothing is changed on the screen. However, if we look at the print output. We can see the initial content ("0") of the 1st cell is updated to "1". But, all of these are being done in an invisible same instance cell. dataSource.apply Memory for cell 0x0000000138705cd0 Content for cell Optional("1") Memory for cell 0x0000000138705cd0 Content for cell Optional("1") Memory for cell 0x0000000138705cd0 Content for cell Optional("2") Memory for cell 0x0000000138705cd0 Content for cell Optional("3") Ordering work without issue Changing the ordering of the cell works as expected. The following is the code for charging ordering. @IBAction func moveClicked(_ sender: Any) { let backgroundContext = self.backgroundContext backgroundContext.perform { let fetchRequest = NSFetchRequest<NSTabInfo>(entityName: "NSTabInfo") fetchRequest.sortDescriptors = [ NSSortDescriptor(key: "order", ascending: true) ] do { let nsTabInfos = try fetchRequest.execute() for (index, element) in nsTabInfos.reversed().enumerated() { element.order = Int64(index) } if backgroundContext.hasChanges { try backgroundContext.save() } } catch { print("\(error)") } } } Do you have idea why such problem occur? I prefer not to have collectionView.reloadData as workaround, as it will create more issue (like resetting scroll position, cell press state, ...) I posted a complete demo at https://github.com/yccheok/problem-update-frc-diffable Thank you
Replies
1
Boosts
0
Views
1.3k
Activity
Jul ’21
Should I use weak to avoid from interferencing with CoreData memory management?
Currently, I have the following core data backed collection view, which enable users to perform add/ delete/ modify/ reordering. It will be much more convenient to achieve what I, if I let UICollectionViewCell, to hold its corresponding NSManagedObject. So that I can each perform add/ delete/ modify/ reordering. I was wondering, should I mark the NSManagedObject as weak, to avoid from interferencing with how CoreData manage its memory? Using weak class TabInfoSettingsCell: UICollectionViewCell { // NSManagedObject. Use weak, as we do not want to inteference with how CoreData manage its memory. private weak var nsTabInfo : NSTabInfo? Use strong Or, such concern is invalid. We can simply use strong class TabInfoSettingsCell: UICollectionViewCell { // NSManagedObject. private var nsTabInfo : NSTabInfo? Use struct Or, such concern is valid and using weak is unsafe (as it can become nil in some edge case?). We can use a struct, which contains everything including objectID, but excluding NSManagedObjectContext. class TabInfoSettingsCell: UICollectionViewCell { // struct. Contains everything including objectID, but excluding NSManagedObjectContext. private var tabInfo : TabInfo? This come with the cost of having to create a struct out from NSManagedObject each time, in cellForItemAt. func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { ... tabInfoSettingsCell.update(nsTabInfo.toTabInfo()) ... } May I know, which is the correct design, as far as safe memory management is concerned?
Replies
1
Boosts
0
Views
709
Activity
Jun ’21
Is NSAsynchronousFetchRequest suitable for production app?
NSAsynchronousFetchRequest seems like an answer to read large amount of data from CoreData, without blocking main thread. But, it is lacking some key features, provided by NSFetchedResultsController. The key features are :- In NSFetchedResultsControllerDelegate didChange and controllerDidChangeContent, we automatically receive a complete change information of persistence store. This enables us to implement the animation of add/delete/move/modify in collection view. Always listen to DB changes. Whenever there is changes being written into the persistence store, NSFetchedResultsControllerDelegate didChange and controllerDidChangeContent will be triggered automatically. This enables us to ensure our UI is in sync with DB. But, NSAsynchronousFetchRequest doesn't come with NSAsynchronousFetchedResultsController :( I was wondering, if you were using NSAsynchronousFetchRequest, how do you implement Animation changes on collection view? Always listen to DB change? My initial thought for animation changes on collection view, it seems we can utilise UICollectionViewDiffableDataSource. But, I notice it might be highly memory inefficient to do so. We need to keep ALL NSManagedObject in memory, fire all faults during comparison. It looks like we will run out of memory, if there are many rows. May I know, how do you achieve the following features, if you ever apply NSAsynchronousFetchRequest in production app? Animation changes on collection view? Always listen to DB change? Thanks.
Replies
1
Boosts
0
Views
811
Activity
Jul ’21
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
Replies
1
Boosts
0
Views
1.5k
Activity
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?
Replies
1
Boosts
0
Views
1.4k
Activity
May ’22