Swift - Populate core data from premade sqlite file - swift

Not the same question as here.
I have a premade sqlite file that has three columns: chapter, verseNumber and verseText. My core data entity has the same name for its attributes. How do I populate the core data database from my sqlite file?

Core Data can not read arbitrary SQLite files. You would have to convert the file into a Core Data database manually. The format that Core Data uses to read from / write to SQLite is proprietary.
You have to use SQLite directly to read the data. I'd suggest using something like FMDB for reading the data. To put the data into a Core Data store, you should follow the guidelines of Efficiently Importing Data.

Here is what I ended up doing:
#IBAction func getSQLDB (sender: NSButton) {
let documentsFolder = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let path = documentsFolder.stringByAppendingPathComponent("kjv.db")
println(documentsFolder)
let database = FMDatabase(path: path)
if !database.open() {
println("Unable to open database")
return
}
//if let rs = database.executeQuery("SELECT * FROM bible WHERE (book = 'Gen') AND (chapter = '1')", withArgumentsInArray: nil) {
if let rs = database.executeQuery("SELECT * FROM bible WHERE (book = 'Genesis') OR (book = 'Exodus')", withArgumentsInArray: nil) {
while rs.next() {
let content = rs.stringForColumn("content")
let verseNumber: Int! = rs.stringForColumn("verse").toInt()
let chapter: Int! = rs.stringForColumn("chapter").toInt()
let name = rs.stringForColumn("book")
// Loops through all the information from the query and creates a book
makeBook(name, content: content, chapter: chapter, verseNumber: verseNumber)
}
} else {
println("select failed: \(database.lastErrorMessage())")
}
database.close()
}

Related

What's the syntax for updating existing attributes in core data compared to saving a new object in core data?

How is the syntax for adding new data to core data different from updating existing data in core data. For instance, if I have a core data entity of Person and attributes name: String, gender: String, and last_occupation: [Int : String](where Int corresponds to their age when they quit), I am confused which of the two syntax I already know I should use.
let appDelegate = UIApplication.shared.delegate as? AppDelegate
let context = appDelegate.persistentContainer.viewContext
let container = NSEntityDescription.insertNewObject(forEntityName: "Person", into: context) as! Person
//And then assigning attributes
container.name = some_string
container.gender = some_string
container.last_occupation = custom_object_that_conformsTo_codable_protocol
VS
let fetchRequest = NSFetchRequest(entityName: "Person")
let results = try context.fetch(fetchRequest)
if let container = results.first {
container.name.value = some_string
container.gender.value = some_string
container.last_occupation = custom_object
try context.save()
context.refresh(transformableContainer, mergeChanges: false)
}
When should I use one method over another, and if I know that I will be replacing existing attributes in core data with newly updated ones instead of just changing their values, is it okay to use the first method?
The first syntax inserts a new record – you have to save the context afterwards.
The second syntax fetches existing data and updates a record.
However to update a specific record you have to add a predicate and most likely you don't want to update the name and the gender attributes
let name = "John Doe"
let fetchRequest : NSFetchRequest<Person> = Person.fetchRequest()
fetchRequest.predicate = NSPredicate(format: "name == %#", name)
let results = try context.fetch(fetchRequest)
if let container = results.first {
// container.name = some_string
// container.gender = some_string
container.last_occupation = custom_object
try context.save()
context.refresh(transformableContainer, mergeChanges: false)
}

Set up Bar Code Scanner Database Through Parse Server: Swift

I have a general question.
I have built in Xcode a unique QrCode that is generated based off of a user's objectID found in Parse Server.
Ultimately, I am trying to figure out how to scan that item using a scanner such as (another iphone, other mobile scanners) and once scanned, send that objectID and other information to that same parse database.
If that is not possible, I was wondering if it would be easier to scan it directly to Microsoft Excel and then manually input that data into parse (although this could take some time).
Here is my code:
import SwiftUI
import CoreImage.CIFilterBuiltins
let filter = CIFilter.qrCodeGenerator()
let context = CIContext()
var username = String()
var objectId = String()
//ViewDidLoad:
username = "Michael"
objectId = "Abc3432f5"
//qrCode Formatting
let image = generateQRCodeImage(string: objectId)
qrCodeImage.image = image
qrCodeImage.layer.magnificationFilter = CALayerContentsFilter(rawValue: kCISamplerFilterNearest)
//Functions
func generateQRCodeImage (string: String) -> UIImage {
let data = Data(string.utf8)
filter.setValue(data, forKey: "inputMessage")
if let qrCodeImage = filter.outputImage {
if let qrCodeCGImage = context.createCGImage(qrCodeImage, from: qrCodeImage.extent) {
return UIImage(cgImage: qrCodeCGImage)
}
}
return UIImage(systemName: "xmark") ?? UIImage()
}
And if so, is there a way to check if the data has already been uploaded to the excel spreadsheet?

Swift: Saving Multiple Images to Core Data

I have a Recipe entity with a one-to-many relationship to RecipeImage. The problem I'm having is how to properly save multiple images. What I'm trying to do is once I selected the images, I store them in a tempImageArray. Once I select "Done" I try to convert images within tempImageArray into an array of data since Core Data only accept images as Binary Data. I then set my recipe.images as that array of data.
Currently, I'm only able to save 1 photo instead multiple.
I think im close to the solution but just needs some guidance. Any help you be much appreciated!
class ListDetailViewController: UITableViewController {
var recipeToEdit: Recipe?
var recipeImages = [RecipeImage]()
//image collection
var tempImageArray = [UIImage]()
private func createRecipe() {
let context = CoreDataManager.shared.persistentContainer.viewContext
let recipe = NSEntityDescription.insertNewObject(forEntityName: "Recipe", into: context) as! Recipe
recipe.setValue(textField.text, forKey: "name")
let image = NSEntityDescription.insertNewObject(forEntityName: "RecipeImage", into: context) as! RecipeImage
for i in tempImageArray {
image.imageData = i.jpegData(compressionQuality: 0.8)
recipeImages.append(image)
}
recipe.images?.setValue(recipeImages, forKey: "images")
image.recipe = recipe
do {
try context.save()
//Perform save
navigationController?.popViewController(animated: true)
self.delegate?.didAddRecipe(recipe: recipe)
} catch let saveErr {
print("Failed to save recipe", saveErr)
}
}

how to store [UIImage] into Core Data and retrieve to [UIImage] from binary date

my code is like these:
//save to core data
func addPaper(){
let paper = Paper(context: self.context)
paper.id = UUID()
paper.subject = self.subject
paper.score = Float(self.score) ?? 0
paper.title = self.title
let imgs = try? NSKeyedArchiver.archivedData(withRootObject: self.images, requiringSecureCoding: true)
paper.images = imgs
try? self.context.save()
}
//retrieve to [UIImage]
let imgs = NSKeyedUnarchiver.unarchivedObject(ofClass: [UIImage], from: paper.images!)
there is an error tip:Static method 'unarchivedObject(ofClass:from:)' requires that '[UIImage]' conform to 'NSCoding'
I don't know what to do next, can anyone give me some help?
You should not store image in CoreData. Maybe store in base64 format, and you can encode/decode whenever you want.
Base64 To image:
func base64ToImage(data: String) -> Data{
let encodedImageData = data
let imageData = Data(base64Encoded: encodedImageData)
return imageData!
}
imageView.image = UIImage(data: dataDecoded)
Image to base64
func imageToBase64(image: UIImage) -> String {
return image.pngData()!
.base64EncodedString()
}
maybe you need this, any object can be saved to core data.
:https://stackoverflow.com/questions/56453857/how-to-save-existing-objects-to-core-data
I copied the following steps from others, hope it helps
1.making your custom types (Exercise) subclass of NSObject
2.setting the attribute's type in the core data model to Transformable
3.setting the CustomClass to [Exercise]

Swift core data FetchRequest NSData to UIIMage

Good morning all, I am using Swift "new for me" and core data I am trying to fetch my stored UIIMage from core data the following way. FYI it is saved as Binary Data in core. And I can see the data if I NSLog it. My Fetch Request looks like this. I have NO ERRORS but my image is not showing.
When I save to Core Data the NSLog looks like this..
Did I get to Save Image
2015-10-12 09:05:43.307 Car-Doc-Safe-Plus[13972:3524049] The NewImage has this in it (entity: Documents; id: 0x7fd4c0432060 ; data: {
autoClub = nil;
driverLicense = <89504e47 0d0a1a0a 0000000d 49484452 00000215 00000155 08020000 00d7368a d8000000 01735247 4200aece 1ce90000 001c>;
insuranceID = nil;
noteText = nil;
plate = nil;
registration = nil;
})
But when i Fetch it looks like this..
The Request has this in it (entity: Documents; predicate: ((null)); sortDescriptors: ((null)); type: NSManagedObjectResultType; )
**override func viewDidLoad() {
super.viewDidLoad()
let appDel:AppDelegate = (UIApplication.sharedApplication().delegate as! AppDelegate)
let context:NSManagedObjectContext = appDel.managedObjectContext!
let request = NSFetchRequest(entityName: "Documents")
request.returnsObjectsAsFaults = false;
let results : NSArray
try! results = context.executeFetchRequest(request)
if results.count > 0 {
let res = results[0] as! NSManagedObject
carImageView.image = res.valueForKey("driverLicense")as? UIImage
}
}**
I know I am missing something but I cannot figure it out. Any help is greatly appreciated.
JZ
The "binary data" type in Core Data is intended for reading and writing NSData objects. Since you want to read/write UIImage, you need to use the "transformable" type. With transformable, Core Data will attempt to use NSCoding to encode/decode the data, converting it to/from NSData as needed (Swift as? will not do this). Since UIImage conforms to NSCoding, you don't need to do any extra work except to tell Core Data to convert the data.