Unable to load database with FMDB in swift - ios

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())")
}

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

FileManager.createDirectory fails with NSCocoaErrorDomain Code: 518

I'm doing
let tempDirectory = URL(string: "\(NSTemporaryDirectory())video/")!
do {
try FileManager.default.createDirectory(
at: tempDirectory,
withIntermediateDirectories: true)
} catch { report(error) }
and that's often throwing an NSCocoaErrorDomain Code: 518.
Any idea of the reason? I thought that could because there's already something there, so I added
var isDir: ObjCBool = false
if FileManager.default.fileExists(
atPath: tempDirectory.absoluteString,
isDirectory: &isDir
) {
if isDir.boolValue {
print("Temp directory exists on launch")
}
else {
print("Temp directory exists on launch and is a file")
}
return
}
but that doesn't seem to catch anything
Your building of tempDirectory isn't correct. You want:
let tempDirectory = URL(fileURLWithPath: NSTemporaryDirectory()). appendingPathComponent("video")
The issue with your code is that you were not passing a value URL string to URL(string:). Since you have a file path you need to use URL(fileURLWithPath:). And build paths/URLs using the provided methods to ensure slashes and other parts are added correctly.
Print your value of tempDirectory from your original code and then print the new value from the code in my answer. Note the key difference.
Your URL will be something like:
/var/...
and it may be missing the slash before "video".
The correct file URL will be something like:
file:///var/...

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 .

Uploading a file from AVCapture using AFNetworking

I have a video that is captured with AVCapture, and I'm trying to upload with AFNetworking with Swift.
Code:
let manager = AFHTTPRequestOperationManager()
let url = "http://localhost/test/upload.php"
var fileURL = NSURL.fileURLWithPath(string: ViewControllerVideoPath)
var params = [
"familyId":locationd,
"contentBody" : "Some body content for the test application",
"name" : "the name/title",
"typeOfContent":"photo"
]
manager.POST( url, parameters: params,
constructingBodyWithBlock: { (data: AFMultipartFormData!) in
println("")
var res = data.appendPartWithFileURL(fileURL, name: "fileToUpload", error: nil)
println("was file added properly to the body? \(res)")
},
success: { (operation: AFHTTPRequestOperation!, responseObject: AnyObject!) in
println("Yes thies was a success")
},
failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
println("We got an error here.. \(error.localizedDescription)")
})
The code above fails, I keep getting
was file added properly to the body? false"
note that ViewControllerVideoPath is a string containing the location of the video which is:
"/private/var/mobile/Containers/Data/Application/1110EE7A-7572-4092-8045-6EEE1B62949/tmp/movie.mov"
using println().... The code above works when I'm uploading a file included in the directory and using:
var fileURL = NSURL.fileURLWithPath(NSBundle.mainBundle().pathForResource("test_1", ofType: "mov")!)
So definitely my PHP code is fine, and the problem lies with uploading that file saved on the device, what am I doing wrong here?
Comments don't allow a full explanation so here is more info;
NSBundle.mainBundle() refers to a path in the bundle file The path in the simulator differs from that of the application ... this is not what you want. There are a number of "folders" you can access based on your needs (private or sharable/files that can get backed up to the cloud). NSPathUtils.h gives a breakdown of the paths available. In keeping with conventions used by most, you should probably create a private path under your application path by doing something like;
- (NSURL *) applicationPrivateDocumentsDirectory{
NSURL *pathURL = [[self applicationLibraryDirecory]URLByAppendingPathComponent:#"MyApplicationName"];
return pathURL;
}
- (NSURL *) applicationLibraryDirecory{
return [[[NSFileManager defaultManager] URLsForDirectory:NSLibraryDirectory inDomains:NSUserDomainMask] lastObject];
}
You can test if it exists, if not, create it ... then store your video files in this path, and pass this to your AVCapture as the location to store the file.
Here are the code that can do following functionality in swift.
1 : Check weather directory exist or not. if not exist then create directory(Directory has given application name) in document directory folder.
2 : Now we have application directory. so all file that from application will write/read in/from this directory.
let file = "file.txt"
let directoryName = “XYZ” // Here “XYZ” is project name.
var error : NSError?
let filemgr = NSFileManager.defaultManager()
let dirPaths = NSSearchPathForDirectoriesInDomains(.DocumentDirectory,
.UserDomainMask, true)
let documentsDirectory = dirPaths[0] as! String
var dataPath = documentsDirectory.stringByAppendingPathComponent(directoryName)
if !NSFileManager.defaultManager().fileExistsAtPath(dataPath) {
NSFileManager.defaultManager().createDirectoryAtPath(dataPath, withIntermediateDirectories: false, attributes: nil, error: &error)
} else {
println("not creted or exist")
}
Now we have Directory so only need to write/read data from directory.
how to write file in document directory in swift
let filePath = dataPath.stringByAppendingPathComponent(file);
let text = "some text"
//writing
text.writeToFile(filePath, atomically: false, encoding: NSUTF8StringEncoding, error: nil);
How to read file from document directory.
let filePath = dataPath.stringByAppendingPathComponent(file);
// Read file
let text2 = String(contentsOfFile: filePath, encoding: NSUTF8StringEncoding, error: nil)
Output :
Hope this will help you.

SQLLite Error - Failed to open DB

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
}

Resources