I'm trying to migrate a existing core data db into an app group so that it can be accessed by an apple watch.So far i have triedfunc migrateStore() {
persistentContainer = NSPersistentContainer(name: "Diamond_Painting_Logbook")
persistentContainer.loadPersistentStores { (description, error) in
if let error = error {
fatalError("Could not create CoreData store: \(error)")
}
var nURL = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.Desbrina.dpl.Diamond-Painting-Logbook.shared")
nURL = nURL?.appendingPathComponent("Diamond_Painting_Logbook.sqlite")
if let newURL = nURL {
do {
let psc = self.persistentContainer.persistentStoreCoordinator
let store = psc.persistentStores[0]
NSLog("7 *****************")
try psc.migratePersistentStore(store, to: newURL, options: nil, withType: NSSQLiteStoreType)
NSLog("8 *****************")
} catch {
}
}
}
}Its throwing an error on the line.try psc.migratePersistentStore(store, to: newURL, options: nil, withType: NSSQLiteStoreType)I'm asuming its because the destination file doesn't exist.2019-11-23 19:55:45.132081+0000 Diamond Painting Logbook[6707:1813609] 7 *****************2019-11-23 19:55:45.132863+0000 Diamond Painting Logbook[6707:1813609] [logging-persist] cannot open file at line 43353 of [378230ae7f]2019-11-23 19:55:45.132901+0000 Diamond Painting Logbook[6707:1813609] [logging-persist] os_unix.c:43353: (0) open(/private/var/mobile/Containers/Shared/AppGroup/BF375BFE-4AF0-4F78-BDEE-C4A4A12493B3/Diamond_Painting_Logbook.sqlite) - Undefined error: 02019-11-23 19:55:45.132917+0000 Diamond Painting Logbook[6707:1813609] [logging] API call with unopened database connection pointer2019-11-23 19:55:45.132929+0000 Diamond Painting Logbook[6707:1813609] [logging] misuse at line 162611 of [378230ae7f]2019-11-23 19:55:45.133370+0000 Diamond Painting Logbook[6707:1813609] [error] error: -addPersistentStoreWithType:SQLite configuration:PF_DEFAULT_CONFIGURATION_NAME URL:file:///private/var/mobile/Containers/Shared/AppGroup/BF375BFE-4AF0-4F78-BDEE-C4A4A12493B3/Diamond_Painting_Logbook.sqlite/ options:{ NSPersistentStoreRemoveUbiquitousMetadataOption = 1;} ... returned error NSCocoaErrorDomain(256) with userInfo dictionary { NSFilePath = "/private/var/mobile/Containers/Shared/AppGroup/BF375BFE-4AF0-4F78-BDEE-C4A4A12493B3/Diamond_Painting_Logbook.sqlite"; NSSQLiteErrorDomain = 14;}CoreData: error: -addPersistentStoreWithType:SQLite configuration:PF_DEFAULT_CONFIGURATION_NAME URL:file:///private/var/mobile/Containers/Shared/AppGroup/BF375BFE-4AF0-4F78-BDEE-C4A4A12493B3/Diamond_Painting_Logbook.sqlite/ options:{ NSPersistentStoreRemoveUbiquitousMetadataOption = 1;} ... returned error NSCocoaErrorDomain(256) with userInfo dictionary { NSFilePath = "/private/var/mobile/Containers/Shared/AppGroup/BF375BFE-4AF0-4F78-BDEE-C4A4A12493B3/Diamond_Painting_Logbook.sqlite"; NSSQLiteErrorDomain = 14;}
Post
Replies
Boosts
Views
Activity
I'm trying to move from NSUserDefaults so that the values sync across devices. The value I'm trying to sync is a single bool, to identify if an initial data import has been done.I'm using the following codevar keyValStore = NSUbiquitousKeyValueStore()
keyValStore.synchronize()
let firstRun: Bool = keyValStore.bool(forKey: "firstRun")
NSLog("First Run: \(firstRun)")
if(!firstRun) {
keyValStore.set(true, forKey: "firstRun")
keyValStore.synchronize()
}If I run the app on my iPhone, it works as expected, the import only works once. If I then run the app on my iPad, it does that import again when it shouldn't, the log showsFirst Run: false
I'm currently sharing data between devices using core data and cloud kit.Currently I have a "Picture" entity which stores the filename, the date it was added and a relation to another entity.The details in core data successfully syncs, how would I go about syncing the image file. The file is saved in the documents folder and I can get its file path usinglet imagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent(imageName)Research seems to show I need to use CKAsset to upload/download the file but how do I go about doing this?
I'm using the following code to convert images to data to store them in core data, however its causing the app to crash due to running out of memory.let imagePath = (NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as NSString).appendingPathComponent(mainPicName)
if fileManager.fileExists(atPath: imagePath) {
DispatchQueue.main.async {
if let image : UIImage = UIImage(contentsOfFile: imagePath) {
let imageData = image.pngData()
}
}
}If I comment out the let imageData = image.pngData() line then I don't get the issueWith the line commented out, the memory usage once the app has loaded is less than 100MB, if its not commented it can get to 2GB before crashing
Is there an easier way in Xcode to create mapping models.
Currently I'm on model 15 and having to create individual models from 1 to 15 is time consuming.
I've tried copying an older model and changing the destination but am unable to see any of the new fields added
I have a app that I'm trying to migrate over to using CloudKit to store the core data so it can be synced across devices.
The syncing is working fine, the issue I'm having is that the app adds some initial data to the database, this is causing it to be duplicated when its installed on another device. Currently I'm using user defaults to store a bool locally if the first run has been performed, which obviously only works per device
Is there any way to see if data already exists in the cloud and prevent the addition of the initial data.
Apple's documentation would suggest its possible if an object already exists but on first launch there's no objects in the local store.
I don't want to query any particular record, just if records exist
https://developer.apple.com/documentation/coredata/mirroring_a_core_data_store_with_cloudkit/reading_cloudkit_records_for_core_data
I'm trying to add a shortcut item to my app. I have the item appearing, and it's responding but can't work out how to get the segue to work. I have it going to the right tab but need to go to the root view and perform a segue from there.
The segue is already setup on the ProjectList view controller and its called "addProject"
My view storyboard is setup as so: UITabViewController -> UINavigationController-> UITableViewController (ProjectList) -> Other additional views
func applicationDidBecomeActive(_ application: UIApplication) {
		if let shortcutItem = shortcutItemToProcess {
				if shortcutItem.type == "addProject" {
						if let window = self.window, let tabBar : UITabBarController = window.rootViewController as? UITabBarController {
								tabBar.selectedIndex = 0
								
						}
				}
				shortcutItemToProcess = nil
		}
}
I have the below code for my view's body
Currently when I go to the ItemDetailView View and then press back to return to this view, the filtered list is no longer there, it's back the full view. How to I get it to keep the filtered list when I go back? The text is still in the search bar
NavigationLink(destination: ItemAddView(series: series), isActive: $noItemsShowing) { EmptyView() }
List {
ForEach(items) { item in
NavigationLink(destination: ItemDetailView(item: item)) {
Text(fullItemName(item: item))
}
}
}
.searchable(text: $searchText)
.onSubmit(of: .search) {
items.nsPredicate = NSPredicate(format: "series = %@", series)
if(!searchText.isEmpty) {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount > 0 AND name CONTAINS[cd] %@", series, searchText)
}
}
.onChange(of: searchText) { _ in
items.nsPredicate = NSPredicate(format: "series = %@", series)
if(!searchText.isEmpty) {
items.nsPredicate = NSPredicate(format: "series = %@ AND amount > 0 AND name CONTAINS[cd] %@", series, searchText)
}
}
.navigationBarTitle("\(series.name ?? "Error") Items", displayMode: .inline)
}
I'm trying to change the background colour of a row in a list based on a value
I have an Int16 value stored in card.owned and I want to change the background if this value is above 0, otherwise use the normal background.
Previously with a table view I could change it with the cellForRowAtIndexPath method, but not sure how to do it with SwiftUI without changing every row
Currently I have
ForEach(cards) { section in
let header: String = nameForSectionHeader(sectionID: section.id)
Section(header: Text(header)) {
ForEach(section) { card in
NavigationLink(destination: CardView(card: card)) {
VStack(alignment: .leading) {
if let name = card.name, let id = card.cardID {
Text("\(id) - \(name)")
}
if let set = card.set, let setName = set.name {
Text("Set: \(setName)")
}
if card.owned > 0 {
Text("Owned: \(card.owned)")
}
}
}
}
}
}
.listRowBackground(lightGreen)
}
I have a list with sections headers on two views. One view has the section headers as collapsible, the other doesn't.
Both use pretty much the same code, what defines if a section header is collapsible?
Code for the one that doesn't collapse
ForEach(cards) { section in
let header: String = nameForSectionHeader(sectionID: section.id)
Section(header: Text(header)) {
ForEach(section) { card in
NavigationLink(destination: CardView(card: card)) {
HStack {
Image(card.imageName ?? "")
.renderingMode(.original)
.resizable()
.scaledToFit()
.frame(width: 50.0)
VStack(alignment: .leading) {
if let name = card.name, let id = card.cardID {
Text("\(id) - \(name)")
}
Text("Owned: \(card.owned)")
}
}
}
}
}
}
}
and the code for the one that does
ForEach(cards) { section in
let header: String = nameForSectionHeader(sectionID: section.id)
Section(header: Text(header)) {
ForEach(section) { card in
NavigationLink(destination: CardView(card: card)) {
VStack(alignment: .leading) {
if let name = card.name, let id = card.cardID {
Text("\(id) - \(name)")
}
if let set = card.set, let setName = set.name {
Text("Set: \(setName)")
}
if card.owned > 0 {
Text("Owned: \(card.owned)")
}
}
}
}
}
}
.listRowBackground(lightGreen)
}
I have the below fetch request which I want to be able to dynamically change the setup of.
The request is setup initially as
sectionIdentifier: \.level,
sortDescriptors: [NSSortDescriptor(keyPath: \Card.level, ascending: true),
NSSortDescriptor(keyPath: \Card.setID, ascending: true),
NSSortDescriptor(keyPath: \Card.cardID, ascending: true),
NSSortDescriptor(keyPath: \Card.name, ascending: true)],
animation: .default)
private var cards: SectionedFetchResults<Int16, Card>
I've got the predicate change working fine, but get errors with the sort descriptors and the section identifier
On setting the sort descriptors I get the error
Cannot convert value of type 'NSSortDescriptor' to expected element type 'Array<SortDescriptor>.ArrayLiteralElement' (aka 'SortDescriptor')
And setting the section identifier I get
Cannot assign value of type 'SectionedFetchResults<String, Card>.Type' to type 'KeyPath<Card, Int16>'
The code I have is below.
if groupBy == 2 {
cards.nsPredicate = nil
let sortSetID = NSSortDescriptor(keyPath: \Card.setID, ascending: true)
let sortName = NSSortDescriptor(keyPath: \Card.name, ascending: true)
cards.sortDescriptors = [sortSetID, sortName] // This errors
cards.sectionIdentifier = SectionedFetchResults<String, Card> // This errors
}
My App does some importing when its first setup. I have it set to store core data in cloud kit.
My issue is if you run it on one device, everything imports fine. Run it on a second, and it will import for a second time, duplicating the records.
I'm trying to see if there's a way of checking if there is anything in cloud kit before running the import, but I'm always getting back false, even if I know there are records.
The code I'm using to check is
NSLog("Existance Check")
checkIfExistsInCloudKit() { (result) in
print(result)
if result == false {
NSLog("Does Not Exist")
//let ImportData : ImportData = ImportData(viewContext: viewContext)
//ImportData.importAll()
} else {
NSLog("Does Exist")
}
}
NSLog("Existance Check Complete")
and the function is
func checkIfExistsInCloudKit(_ completion: @escaping (Bool) -> ()) {
var result = false
let container = CKContainer(identifier: "******")
let privateDB = container.privateCloudDatabase
let predicate = NSPredicate(format: "CD_brand = %@", "DMC")
let query = CKQuery(recordType: "CD_Colour", predicate: predicate)
privateDB.perform(query, inZoneWith: nil) { records, error in
//guard let records = records else { return }
result = true
}
completion(result)
}
2023-04-15 14:07:28.092262+0100 Stitchers Companion[4553:113693] Existance Check
false
2023-04-15 14:07:28.092897+0100 Stitchers Companion[4553:113693] Does Not Exist
2023-04-15 14:07:28.092962+0100 Stitchers Companion[4553:113693] Existance Check Complete
I'm currently using a navigationview and am now getting an warning
'init(destination:tag:selection:label:)' was deprecated in iOS 16.0: use NavigationLink(value:label:) inside a List within a NavigationStack or NavigationSplitView
I'm trying to move to another view from a button (there will be several hence using tags) but I can't seem to get my head around how to do it.
The code I currently have
var body: some View {
List {
NavigationLink(destination: ProjectColourAddView(project: project), tag: 1, selection: $action) {
EmptyView()
}
Group {
Button(action: { self.showImageMenu = true }) {
Text("New Title Image")
}
.confirmationDialog("Select Image Source", isPresented: $showImageMenu, titleVisibility: .visible) {
Button("Take Photo") {
self.isShowCamera = true
}
Button("Choose from Albums") {
self.isShowPhotoLibrary = true
}
}
Button(action: {
self.action = 3
NSLog("More Images")
}) {
Text("More Images (x)")
}
Button(action: {
self.action = 2
NSLog("Add Image")
}) {
Text("Add Image")
}
Button(action: {
self.action = 1
NSLog("Colour List")
}) {
Text("Colour List")
}
}
}
}
I'm looking to see if its possible to change the background colour of a cell, but fill it based on a percentage
I'm creating the cell in a List {}
let gradient = LinearGradient(colors: [.green, .white], startPoint: .leading, endPoint: .trailing)
List {
Section(header: Text("Total")) {
Text("Total Obtained: \(totalObtained) - \(totalComplete)%")
.listRowBackground(gradient)
}
}
totalComplete has the percentage variable
Xcode keeps complaining about changes when I try and commit, I get the error "The local repository is out of date."
When I try and pul changes from the remote, I get the message "Your local repository has uncommitted changes that need to be stashed before you can continue. "
When I try and commit, every time it shows a UserInterfaceState.xcuserstate file. if I try and commit it I get the local repository error.