How to hide SQLite db files so they are not seen in iTunes file sharing - swift

I have file sharing enabled on my app and so, when you view the documents folder in iTunes, there are the Core Data sqlite files siting there just waiting to be fiddled with by the user.
I have found a few discussions on this but, surprisingly, no one seems to address the concerns I have.
Some say to 'move' them to the library folder - in a custom sub-directory, and another says just rename the files prefixing each with a period.
Both options sound lovely, but these are essential OS files!
So my first question is, if you do either of these things (with NSFileManager.defaultManager() - I presume), will the app just automatically find them afterwards? ...or is there a specific 'way' in which you do (either of) them ...so that the app finds them afterward?
Any responses, if you could demonstrate using Swift rather than Objective C, that would be appreciated! Thanks, :)

Figured it out:
To anyone wondering the same thing (which I have seen many doing),
In my app delegate > in the 'persistentStoreCoordinator' lazy variable,
I changed the following line of code:
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("MyAppName.sqlite")
to the following two lines of code:
let library = NSFileManager.defaultManager().URLsForDirectory(.LibraryDirectory, inDomains: .UserDomainMask)[0] as NSURL
let url = libary.URLByAppendingPathComponent("MyAppName.sqlite")

This would be the syntax for Swift 3 / 4:
let library = FileManager.default.urls(for: .libraryDirectory, in: .userDomainMask)[0] as NSURL
let url = library.appendingPathComponent("MyAppName.sqlite")

Related

Swift - Grab all the files from a specific folder/remote URL on a server

I am trying to access a specific folder in a remote URL e.g.http://dev.servertest.com/sessions/id/video
from there, I want to grab all the videos from the folder and download them to the device.
I know how to download the videos from a remote URL to the directory but I can't work out to grab all the videos from the specific video folder.
Also, the server may change depending on the user using their own server but the rest of the structure should be the same "/sessions/id/video"
Below is the code I use to upload from a specific folder "ImportVideos" from my app directory if that helps.
func loadVideos(){
let fm = FileManager.default
let dirPaths = fm.urls(for: .documentDirectory, in: .userDomainMask)
let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0];
do {
let videoList = try fm.contentsOfDirectory(atPath: "\(documentsPath + "/ImportVideo")")
for filename in videoList {
videoSubtitles.append(filename) //this is used to populate my tableview
}
} catch let error {
print("error: \(error.localizedDescription)")
}
}
If someone could point me in the right direction that would be great. Thanks.
The HTTP protocol does not provide any means of getting a list of files in a directory. What you're trying to do is not generally possible without a manifest — a list of files that you want to download.
The easiest way to do that is to run a script on the server, e.g.
#!/bin/sh
FILES_DIR=/path/to/directory/on/server
cd "$FILES_DIR"
ls > allfiles.txt
Then have your app fetch the file http://example.com/path/to/allfiles.txt, then split it by newline, and fetch each file. This approach also provides the advantage of letting you later replace that text file with a script handler that serves different file lists to different clients, if desired, e.g. for supporting different versions of your app.
Alternatively, if your server supports WebDAV, then it is possible to configure the directory with WebDAV enabled and use a WebDAV library to find out what files are in the directory. However, this is probably not a good idea, because WebDAV is relatively complex and easy to misconfigure.
Finally, some web servers provide a way to enable "directory listings" — a web page that has links to all of the files in the directory. (Many people will tell you that this is a bad idea from a security perspective, though that is debatable.) It is possible, though inherently fragile, to parse such a page and extract the links. This approach is strongly discouraged, however, because it could break completely when you update to a new version of the web server software.

Date still in Core Data app after I delete the .sqlite files

I have (finally) managed to get prototype app using Core Data to persist to an sqlite file. Quitting and restarting I see the same data. So all seems well.
I want to now start from scratch again so I went to delete the sqlite persisted data. I set up it's location as :
open lazy var applicationDocumentsDirectory: NSURL = {
// The directory the application uses to store the Core Data store file.
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
return urls[urls.count-1] as NSURL
}()
let url = self.applicationDocumentsDirectory.appendingPathComponent("TrainingDiary.sqlite")
which places the .sqlite files in ~/Library/Containers/uk.me.stevenlord.Core-Data-Binding/Data/Documents
There are four files in there: iChats, TrainingDiary.sqlite, TrainingDiary.sqlite-shm and TrainingDiary.sqlite-wal
I close my app. Delete all there files. When I reopen my app the full Core Data model is still there and when I look back in this directory the files are back.
What am I missing ?
EDIT:
I've figured out whats happening though I still don't quite understand why this is how it works. The above code specifies where the Core Data should be saved:
which places the .sqlite files in
~/Library/Containers/uk.me.stevenlord.Core-Data-Binding/Data/Documents/TrainingDiary.sqlite
This it does however I've now found that the app also saves the following
~/Library/Containers/uk.me.stevenlord.Core-Data-Binding/Data/Library/Application Support/Core Data Binding/Core_Data_Binding.sqlite
My XCode9 project is called "Core Data Binding". If I delete this file and start up my app I get an app with no data as expected.
So the persistent store is not going to where I specified. So still confused.
I'm missing something still. But something different

How to find the path of sqlite.sql file and print it?

I know this question already answered before but when I tried to print the path for the sqlite file of my application as below I got the path but could not go to it in finder.
I used below code to get the path
let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true).last! as String
print(paths)
The path I got is as below:
/var/mobile/Containers/Data/Application/5412CDDE-8D40-46B2-A61D-65065796F7CE/Documents
when I try to copy and paste it in GOTO it can not find it
please advise me
In case you are using NSPersistantContainer, you get the URL(s):
persistentContainer.persistentStoreCoordinator.persistentStores.first!.url!
when I try to copy and paste it in GOTO it can not find it
that path is on the Simulator and not on the local Finder.
Duplicate of: Access files in /var/mobile/Containers/Data/Application without jailbreaking iPhone
or
Duplicate of: How to view the data in sqlite file running in iphone application?
How to find the path of sqlite.sql file and print it?
accessing your sqlite database is described here:
Copy Sqlite DataBase in Swift does not work properly
Use this in your swift class to get the location of sqlite database for your application running in iOS simulator.
let urls = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
print(urls[urls.count-1] as URL)
You will need SQLite database browser to look after the database. We can only locate sqlite database file only for application running in simulator but not in the iPhone directly.

How to handle "open in" retrieved file with swift 2

I'm trying to build a quite simple app which uploads files to our server using standard http requests.
I'd like the app to be some sort of hub being able to open an email attachement for example.
That worked out, I added the info to the info.plist.
Now that file is sent to my app successfully (eg a pdf file)...
How can I retrieve that file url to display it for example in a webview ? I googled for hours, seems to fo through the appDelegate but I have no idea how that continues...
Just found this code, now I'm stucked (and don't even know if that actually works !)
func application(application: UIApplication, openURL url: NSURL, sourceApplication: String?, annotation: AnyObject?) -> Bool {
let dictionary = NSDictionary(contentsOfURL: url)
return true
}
Any help to point me in the right direction is highly appreciated ! I started using swift 5 days ago, please be gentle ;)
I have not tested this, but it appears that what you want to do is this:
Go to your project settings
Go to the "info" tab
Under "Document Types" add the document types you want to support
To get the added file, you need to look in the Documents/Inbox folder for your app, as shown below:
let filemgr = NSFileManager.defaultManager()
let documentsDirectory = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true)[0] as NSString
let inboxPath = documentsDirectory.stringByAppendingPathComponent("Inbox")
do {
let dirFiles = try filemgr.contentsOfDirectoryAtPath(inboxPath)
} catch {
//Handle error
}
I am not certain what exactly gets passed to application:openURL:sourceApplication:annotation:, but it might help in checking which file was opened.
Additionally, straight from Apple:
Use this directory to access files that your app was asked to open by outside entities. Specifically, the Mail program places email attachments associated with your app in this directory. Document interaction controllers may also place files in it.
Your app can read and delete files in this directory but cannot create new files or write to existing files. If the user tries to edit a file in this directory, your app must silently move it out of the directory before making any changes.
This answer adapted from this tutorial (part 2 & part 3)

Changing application CFBundleURLScheme plist entry dynamically (after compilation)

I'm trying to create an iPhone application that will handle a variety of URL Schemes that I will determine dynamically by querying a server.
Is it possible to register for a custom url scheme programmatically? In other words, can you update the CFBundleURLScheme plist entry after the application has been compiled / deployed?
I haven't been able to find any examples of this being done elsewhere, but nor can I find any definitive reasons why this isn't possible.
Many thanks.
I'm sorry, there is no way. You cannot register custom url schemes programmatically. You also cannot edit your Info.plist, application bundles are read-only on the iPhone.
Here is how I solved it for Swift:
var plistPath = NSBundle.mainBundle().pathForResource("Info", ofType: "plist")
var urlStuff = NSMutableDictionary(contentsOfFile: plistPath!)
var urlType = NSDictionary(objectsAndKeys: "com.appprefix.AppName", "CFBundleURLName", NSArray(object: "idofobject"), "CFBundleURLSchemes")
urlStuff?.setObject(NSArray(object: urlType), forKey: "CFBundleURLTypes")
urlStuff?.writeToFile(plistPath!, atomically: true)
NEW ANSWER AS OF 2021
It is now possible to edit your Info.plist before compiling your app using some scripts.
You can refer to this post: Add/Replace URL Scheme in Info.plist using bash script