Opening a SQLite from bundle using Swift - swift

I have a .sqlite file in my app bundle. I seem to open the file, but I can not access the tables in the file.
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("test.sqlite")
//opening the database
if sqlite3_open(fileURL.path, &db) == SQLITE_OK {
print("opening database")
}
let queryString = "SELECT * FROM Table1"
var stmt:OpaquePointer?
//preparing the query
if sqlite3_prepare(db, queryString, -1, &stmt, nil) != SQLITE_OK{
let errmsg = String(cString: sqlite3_errmsg(db)!)
print("error preparing insert: \(errmsg)")
return
}
This gives following error message: "error preparing insert: no such table: Table1"
As I see it, the databse is found and opened, but cannot be accessed. As I see it from other posts at Stackoverflow, this should work
EDIT: I now see that if I misspell the databse name from test.sqlite to ttestt.sqlite, I still get the same error. Meaning the database is not found. What is wrong with this line?
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false).appendingPathComponent("test.sqlite")

The solution was to copy the database from the bundle to the documnents directory:
let bundleURL = Bundle.main.url(forResource: "test", withExtension: "sqlite")!
try manager.copyItem(at: bundleURL, to: documentsURL)
rc = sqlite3_open_v2(documentsURL.path, &db, SQLITE_OPEN_READWRITE, nil)

Related

Swift Filemanager fails to create temporary directory

This Code:
let csvString = self.generateCSV()
let tmpURL = try FileManager.default.url(for: .itemReplacementDirectory,
in: .userDomainMask,
appropriateFor: nil,
create: true)
let tempFileUrl = tmpURL.appendingPathComponent("App-DigiAufklaerung-\(self.formatDateToPrecision(Date())).csv")
let data = csvString.data(using: .utf8)
try data?.write(to: tempFileUrl,
options: .atomic)
self.csvFile = tempFileUrl
(I thought) should create a tmp file, from which i can then share the cdv through AirDrop, but the creation of the tmpDir fails, what am i doing wrong here?
This error message was printed several times:
CFURLSetTemporaryResourcePropertyForKey failed because it was passed an URL which has no scheme

Creating a directory at /Users/Shared/ - using Swift

I am using the following code to create a directory in /Users/Shared/ to share data of my application between all users. When i run the code gotthe below output.
2019-03-08 19:41:41.751418+0530 MyApp[7224:488397] Couldn't create document directory
2019-03-08 19:41:41.754026+0530 MyApp[7224:488397] Document directory is file:///Users/Appname
let fileManager = FileManager.default
if let tDocumentDirectory = fileManager.urls(for: .userDirectory, in: .localDomainMask).first {
let filePath = tDocumentDirectory.appendingPathComponent("Appname")
if !fileManager.fileExists(atPath: filePath.path) {
do {
try fileManager.createDirectory(atPath: filePath.path, withIntermediateDirectories: true, attributes: nil)
} catch {
NSLog("Couldn't create document directory")
}
}
NSLog("Document directory is \(filePath)")
}
I don't why this error occured. How this can be done?
Please read the log messages carefully.
You are trying to create the folder file:///Users/Appname which is not in /Users/Shared. You have to append "Shared/Appname".
And you are encouraged to use the URL related API of FileManager (and less confusing variable names šŸ˜‰)
let fileManager = FileManager.default
let userDirectory = try! fileManager.url (for: .userDirectory, in: .localDomainMask, appropriateFor: nil, create: false)
let folderURL = userDirectory.appendingPathComponent("Shared/Appname")
if !fileManager.fileExists(atPath: folderURL.path) {
do {
try fileManager.createDirectory(at: folderURL, withIntermediateDirectories: true, attributes: nil)
} catch {
print("Couldn't create document directory", error)
}
}
print("Document directory is \(folderURL)")

create plist and copy it to folder MacOS Swift

I have been racking my brain on how to create and write a plist to a certain Folder Directory in MacOS. In my case to the LaunchDaemons folder in /Library. I know how to create the plist but its the writing to the LaunchDaemons folder that I am having issues with. This code below from my understanding is for the sandbox but how do I do it outside of the sandbox? Cheers
let fileManager = FileManager.default
let documentDirectory = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0] as String
let path = documentDirectory.appending("test.plist")
I have added the code with the help I have received and have no errors but it is not writing anything to the folder. Here is the code:
let libraryDirectory = try! FileManager.default.url(for: .libraryDirectory, in: .localDomainMask, appropriateFor: nil, create: false)
let launchDaemonsFolder = libraryDirectory.appendingPathComponent("LaunchDaemons/test.plist")
if FileManager.default.fileExists(atPath: launchDaemonsFolder.path) {
print(launchDaemonsFolder)
let plistDictionary : [String: Any] = [
"ExitTimeOut": 600,
"Label": "BOOT.SHUTDOWN.SERVICE",
"ProgramArguments": ["/test.sh"] as Array,
"RunAtLoad": false,
"WorkingDirectory": "/"
]
let dictionaryResult = NSDictionary(dictionary: plistDictionary)
let fileWritten = dictionaryResult.write(to: launchDaemonsFolder, atomically: true)
print("is the file created: \(fileWritten)")
} else {
print("File Exists")
}
First of all NSSearchPathForDirectoriesInDomains is outdated, it's highly recommended to use the URL related API anyway.
This code creates an URL pointing to /Library/LaunchDaemons
let libraryDirectory = try! FileManager.default.url(for: .libraryDirectory, in: .localDomainMask, appropriateFor: nil, create: false)
let launchDaemonsFolder = libraryDirectory.appendingPathComponent("LaunchDaemons")

Sqlite error in while appending file

I am ne to iOS developer i want to one thing that when i connect Sqlite with Xcode then after appending the code in nsobject class the error comes second line that instance member documents cannot be used type of class name
Here is code-
let documents = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
let fileURL = documents.URLByAppendingPathComponent("test.sqlite")
var db: COpaquePointer = nil
if sqlite3_open(fileURL, &db) == SQLITE_OK {
print("Successfully opened connection to database at \(fileURL)")
return db
} else {
print("Unable to open database. Verify that you created the directory described " +
"in the Getting Started section.")
}
Please resolve my problem
It would appear that you're trying to declare fileURL outside of a method. If this is a property, you can't reference documents like that. So, either make this a local variable of your method, or collapse these two declarations into a single statement:
In Swift 3:
let fileURL = try! FileManager.default.url(for: .documentDirectory, in: .userDomainMask, appropriateFor: nil, create: false)
.appendingPathComponent("test.sqlite")!
In Swift 2:
let fileURL = try! NSFileManager.defaultManager().URLForDirectory(.DocumentDirectory, inDomain: .UserDomainMask, appropriateForURL: nil, create: false)
.URLByAppendingPathComponent("test.sqlite")!
That avoids referencing documents at all.
As an aside, you can't pass fileURL to the sqlite3_open function. You should use fileURL.path (or, in Swift 2, fileURL.path!).

iOS9 Swift File Creating NSFileManager.createDirectoryAtPath with NSURL

Before iOS9, we had created a directory like so
let documentsPath = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as! String
let logsPath = documentsPath.stringByAppendingPathComponent("logs")
let errorPointer = NSErrorPointer()
NSFileManager.defaultManager().createDirectoryAtPath(logsPath, withIntermediateDirectories: true, attributes: nil, error: errorPointer)
But with iOS9 they removed String.stringByAppendingPathComponent. The auto convert tool replaced our use of String with NSURL. createDirectoryAtPath() takes a string so I need to convert the NSURL to a string. We used absolutePath like so: (update for iOS9)
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let logsPath = documentsPath.URLByAppendingPathComponent("logs")
do {
try NSFileManager.defaultManager().createDirectoryAtPath(logsPath.absoluteString, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}
But I am getting the following error:
Unable to create directory Error Domain=NSCocoaErrorDomain Code=513
"You donā€™t have permission to save the file ā€œlogsā€ in the folder
ā€œDocumentsā€."
UserInfo={NSFilePath=file:///var/mobile/Containers/Data/Application/F2EF2D4F-94AF-4BF2-AF9E-D0ECBC8637E7/Documents/logs/,
NSUnderlyingError=0x15664d070 {Error Domain=NSPOSIXErrorDomain Code=1
"Operation not permitted"}}
I figured this one out. createDirectoryAtPath() is unable to process a path with the "file://" prefix. To get a path without the prefix you must use path() or relativePath().
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0])
let logsPath = documentsPath.URLByAppendingPathComponent("logs")
do {
try NSFileManager.defaultManager().createDirectoryAtPath(logsPath.path!, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}
Incorrect path (notice file://):
file:///var/mobile/Containers/Data/Application/F2EF2D4F-94AF-4BF2-AF9E-D0ECBC8637E7/Documents/logs/
Correct path:
/var/mobile/Containers/Data/Application/F2EF2D4F-94AF-4BF2-AF9E-D0ECBC8637E7/Documents/logs/
Swift 3
let documentsPath = NSURL(fileURLWithPath: NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0])
let logsPath = documentsPath.appendingPathComponent("logs")
do {
try FileManager.default.createDirectory(at: logsPath!, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}
Swift 4
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
let logsPath = paths[0].appendingPathComponent("logs")
do {
try FileManager.default.createDirectory(at: logsPath, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
NSLog("Unable to create directory \(error.debugDescription)")
}