SQLLite Error - Failed to open DB - ios

I have the following sqllite code:
func createAndCheckDatabase()-> Bool
{
var success: Bool = true
var db:COpaquePointer = nil // Get path to DB in Documents directory
let docDir:AnyObject = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0]
let path = docDir.stringByAppendingPathComponent("MyDatabase.db")
// Check if copy of DB is there in Documents directory
let fm = NSFileManager.defaultManager()
if !(fm.fileExistsAtPath(path)) {
// The database does not exist, so copy to Documents directory
let from = NSBundle.mainBundle().resourcePath!.stringByAppendingPathComponent(databaseName)
var error:NSError?
if !fm.copyItemAtPath(from, toPath: path, error: &error) {
//ALWAYS ERRORS HERE THE FIRST TIME
println("SQLiteDB - #1 failed to open DB.")
println("Error - \(error!.localizedDescription)")
}
}
databasePath = path
// Open the DB
let cpath = (path as NSString).UTF8String
let error = sqlite3_open(cpath, &db)
if error != SQLITE_OK {
// Open failed, close DB and fail
println("SQLiteDB - another error - couldn't open DB")
sqlite3_close(db)
}
return success
}
I call this function within my app delegate with the thought that it would successfully create my database once (and only once). Whenever I clear settings and run it, it always hits the area I've marked (error) once. After running it again I never get this error anymore.
Is there some logic flaw in this code (I mostly copied this code) or am I perhaps reporting an error that is actually not? I suspect that it might just be happening the first time it creates, but i'm actually OK and can start interacting with the database just fine.
Also does anyone sees something concerning in the code?
Thanks!

Well, after not really figuring out why the above code cobbled together from online tutorials did as I described, I found a very helpful article here:
http://metrozines.com
This ended up solving my problem (by following how they did things and introducing the code from the tutorial). Now when I clear settings, it doesn't crash and starting it up again works correctly without throwing an error.
The code that works now is this:
func createAndCheckDatabase() -> Bool {
let DATABASE_RESOURCE_NAME = "abc"
let DATABASE_RESOURCE_TYPE = "sqlite"
let DATABASE_FILE_NAME = "abc.sqlite"
let documentFolderPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as String
let dbfile = "/" + DATABASE_FILE_NAME;
self.dbFilePath = documentFolderPath.stringByAppendingString(dbfile)
let filemanager = NSFileManager.defaultManager()
if (!filemanager.fileExistsAtPath(dbFilePath) ) {
let backupDbPath = NSBundle.mainBundle().pathForResource(DATABASE_RESOURCE_NAME, ofType: DATABASE_RESOURCE_TYPE)
if (backupDbPath == nil) {
return false
} else {
var error: NSError?
let copySuccessful = filemanager.copyItemAtPath(backupDbPath!, toPath:dbFilePath, error: &error)
if !copySuccessful {
println("copy failed: \(error?.localizedDescription)")
return false
}
}
}
return true
}

Related

MLUpdateContext is empty when updating CoreML model

My problem is the following - In the method below the variable finalContext seem to not contain anything. I get error message : Error: The operation couldn’t be completed. (Foundation._GenericObjCError error 0.) when calling the function. I need help how to debug this issue or what could be the possible cause for this. EDIT - finalContext does not contain the model that I am trying to access.
func updateModel(){
//Configuration for when update is performed
let modelConfig = MLModelConfiguration()
modelConfig.computeUnits = .cpuAndGPU
let fileManager = FileManager.default
//Image batch for updating the model
//Might need to change from a batch to a single image
let updateImages: [UIImage] = [theImage!]
let imageBatch = createTrainingData(imageArray: updateImages, outputLabel: "dog") // temp outputLabel
do {
let updateTask = try MLUpdateTask(forModelAt: globalCompiledModel!, trainingData: imageBatch, configuration: modelConfig,
progressHandlers: MLUpdateProgressHandlers(forEvents: [.trainingBegin,.epochEnd],
progressHandler: { (contextProgress) in
print(contextProgress.event)
// you can check the progress here, after each epoch
}) { (finalContext) in
do {
// Save the updated model to temporary filename.
let documentDirectory = try fileManager.url(for: .documentDirectory, in: .userDomainMask, appropriateFor:nil, create:true)
let fileURL = documentDirectory.appendingPathComponent("CatDog.mlmodelc")
print("Updated temp model URL: \(fileURL)")
try finalContext.model.write(to: fileURL)
} catch(let error) {
print("Error: \(error.localizedDescription)")
}
})
updateTask.resume()
} catch {
print("Error while updating: \(error.localizedDescription)")
}
}
I found the issue here. MLArrayBatchProvider was not properly configured by me so the updateTask was not properly completed.
Es domaj, ka vajag panemt iepist al un paprovet velreiz
For me the issue was resolved by abandoning using a UpdatableTrainingInput class that conformed to id<MLFeatureProvider>, but instead creating a MLDictionaryFeatureProvider as shown here: https://developer.apple.com/documentation/coreml/model_personalization/personalizing_a_model_with_on-device_updates?language=objc

SQlite Cipher IOS

This here i have shared to show that i have Sqlite file present in copy bundle resources : I am using Sqlitecipher in my iOS app when run my app in Simulator (offline) it shows all of the data successfully and every query works fine like (update,delete,insert) but when testing my app on device it doesn't shows up anything. Following way i tried it :
Saved Sqlite file in bundle
Copied Sqlite file from bundle to Document Directory
Delete app from Simulator and reset my Simulator but i am still facing the same issue. Kindly suggest solution ( its a Salesforce native App )
This is the code to get file from bundle to Document Directory in Appdelegate:`
func copyFile()
{
var documents: NSString
documents = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let bundlePath = NSBundle.mainBundle().pathForResource("LeadWork1", ofType: "sqlite")
print(bundlePath, "\n") //prints the correct path
let destPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first!
let fileManager = NSFileManager.defaultManager()
let fullDestPath = NSURL(fileURLWithPath: destPath).URLByAppendingPathComponent("LeadWork1.sqlite")
let fullDestPathString = fullDestPath.path
print(fullDestPathString)
print(fileManager.fileExistsAtPath(bundlePath!)) // prints true
if fileManager.fileExistsAtPath(bundlePath!) == true
{
print("File Exist")
}
else
{
do{
try fileManager.copyItemAtPath(bundlePath!, toPath: [enter image description here][1]fullDestPathString!)
}catch{
print("\n")
print(error)
}
}
let error = sqlite3_open(fullDestPathString!, &database)
if error != SQLITE_OK
{
print("Error while opening");
}
else
{
// print(fileForCopy)
print(destPath)
print("already open");
}
}`
Help will be appreciated!
Just Enable following :
Select Project -> Build Setting -> Architecture Tab - > Build Release to YES
Make sure to enable Both Debug and Release to YES.
It will solve your issue .

Cannot find file in app extension's shared container

I want to write log file at my extension, and read it at my app.
For this purpose, I'm using shared groups (so both the app and the extension would be able to read from the same file)
I wrote the following code:
Extension:
let fileManager = NSFileManager.defaultManager()
let containerUrl = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.MyCompany.MyProj")
let extensionLogDirectory = containerUrl?.path?.stringByAppendingString("AppExtensionLogs")
let logFileManager = DDLogFileManagerDefault(logsDirectory: extensionLogDirectory)
PacketTunnelProvider.fileLogger = DDFileLogger(logFileManager: logFileManager)
PacketTunnelProvider.fileLogger!.rollingFrequency = 60*60*12
PacketTunnelProvider.fileLogger!.logFileManager.maximumNumberOfLogFiles = 1
DDLog.addLogger(PacketTunnelProvider.fileLogger)
App (just to read the log file):
let fileManager = NSFileManager.defaultManager()
let containerUrl = fileManager.containerURLForSecurityApplicationGroupIdentifier("group.MyCompany.MyProj")
if let extensionLogDirectory = containerUrl?.path?.stringByAppendingString("AppExtensionLogs") {
do {
let directoryContents = try fileManager.contentsOfDirectoryAtPath(extensionLogDirectory)//always fails
for file in directoryContents {
let path = extensionLogDirectory.stringByAppendingString(file)
do {
let fileContents = try NSString(contentsOfFile: path, encoding: NSUTF8StringEncoding)
NSLog("file: \(fileContents)")
}
catch {/* error handling here */
}
}
}
catch {/* error handling here */
NSLog("nope!")
}
But, something now right - it's seems like contentsOfDirectoryAtPath always fails with "no such file" error
What's wrong in this code?
The problem is unrelated to app extensions or CocoaLumberjack.
stringByAppendingString just concatenates strings, so that the path
separator "/" is missing in the generated directory name.
There was a dedicated method stringByAppendingPathComponent, which however
has been deprecated in Objective-C and is no longer available in Swift.
You should operate on the URL by using URLByAppendingPathComponent
instead:
let extensionLogDirectory = containerUrl?.URLByAppendingPathComponent("AppExtensionLogs").path

Unable to load database with FMDB in swift

I'm trying to create an app with login/signup. I'm using sqlite to save the user information and password. But it's not working since the database isn't being loaded into the code.
let filemgr = NSFileManager.defaultManager()
let dirPaths =
NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
.UserDomainMask, true)
var docsDir = dirPaths[0] as! String
print(docsDir)
var databasePath = docsDir + "/contacts.sqlite"
if filemgr.fileExistsAtPath(databasePath as String) {
let contactDB = FMDatabase(path: databasePath as String)
if contactDB == nil {
print("Error: \(contactDB.lastErrorMessage())")
}
//Remaining code
}
I inserted print (contactDB) right below it's declaration to see what it contains.
2016-02-24 13:27:59.445 Login[12850:1625864] The FMDatabase <FMDatabase: 0x7fd76b804750> is not open.
nil
This is what I got in the console. "Login" is the class name where this code is from. I'm unable to make progress since I'm unable to load the database. Any help is much appreciated. Thanks in advance!
EDIT: The problem was resolved after I added contactDB.open(). I'm still having problem with it.
<FMDatabase: 0x7fbb41f5fa70>
Optional(false)
2016-02-24 14:18:51.272 Login[13064:1649879] Error calling sqlite3_step (21: out of memory) rs
I'm getting this in the console when I try to print the error.
It says it's not open. Try contactDB.open().
or
if contactDB.open() {
// Do your DB work here.
contactDB.close()
} else {
println("Error: \(contactDB.lastErrorMessage())")
}

Can't load image with UIImage or NSData

I am programming a Swift application, and I can't load image saved in the application by using UIImage(contentsOfFile: imgPath) or NSData(contentsOfFile: imgPath)
private func loadData() {
println("load DATA DANGEROUS")
let (dangerous, err) = SD.executeQuery("SELECT * FROM Dangerous")
if err == nil && !dangerous.isEmpty {
var tabPhoto : [DangerousImage] = []
for d in dangerous {
let desc = d["description"]!.asString()!
let idDangerous = d["id"]!.asInt()!
println("iddangerous : \(idDangerous)")
let (photos, error) = SD.executeQuery("SELECT * FROM Photo WHERE idDangerous = ?", withArgs: [idDangerous])
if error == nil {
for photo in photos {
let imgPath = photo["photoPath"]!.asString()!
println(imgPath)
let uimage = UIImage(contentsOfFile: imgPath) // fatal error: unexpectedly found nil while unwrapping an Optional value
tabPhoto.append(DangerousImage(img: uimage!, path: imgPath))
}
}
println("add ENTRY")
self.tabEntry.append(Entry(descript: desc, tab: tabPhoto))
}
}
println("TAB ENTRY : \(tabEntry)")
}
My picture exists with this path : /var/mobile/Containers/Data/Application/...ID-APP.../Documents/images/JPEG_201506162_101128_IOS_99804574.jpg
Thank for your help.
Ysee
From I can see in your code, you are storing the full path to the image in your database, eg. "/var/mobile/Containers/Data/Application/...ID-APP.../Documents/images/JPEG_201506162_101128_IOS_99804574.jpg". Since iOS8, the folder structure has changed - the UDID in the path is changing every time the app is updated or a new build is installed during development. That's why should store a relative path to your image, eg. "/images/JPEG_201506162_101128_IOS_99804574.jpg" and then get the Documents directory with NSSearchPathForDirectoriesInDomains method.

Resources