Swift - Realm mobile platform today extension - ios

I'm building a Notes app with today extension.
I want to link my app's data with today widget using App Group.
To do this, I have to change the default realm's fileURL to App Group URL.
Without syncConfiguration it works very well, but when I use this, the default realm's fileURL did not changed.
So my Questions is how can I change Realm.Configuration.defaultConfiguration.fileURL using realm mobile platform!!!
let file = FileManager.default
let directory: NSURL = file.containerURL(forSecurityApplicationGroupIdentifier: "group.com.myapp")! as NSURL
let realmPath = directory.appendingPathComponent("default.realm")
Realm.Configuration.defaultConfiguration = Realm.Configuration(
fileURL: realmPath,
syncConfiguration: SyncConfiguration(
user: user,
realmURL: URL(string: "realm://myserver:9080/~/myNote")!
),
objectTypes: [realmNote.self, Tag.self]
)
self.realm = try! Realm()
please help!!!...

If you set a sync configuration on the Configuration object, you cannot set a custom file URL. The sync configuration, file URL, and in-memory identifier are mutually exclusive settings. This is by design.
If you need it to work otherwise, please feel free to file a ticket at our GitHub repository, and we'll take a look.

Related

Import inital data from realm database file in Swift

I have exported realm database file (.realm) includes initial data for my app. I have use it for my Android app and I willing to use that initial database for my iOS app too. Can anyone help me how to import and use exported realm db file inside my iOS project using Swift in proper way?
Thanks.
Put your exported realm file in the Bundle Resources
let config = Realm.Configuration(
fileURL: Bundle.main.url(forResource: "filename", withExtension: "realm"),
readOnly: true)
let realm = try? Realm(configuration: config)
The realm file has to be read only.

Switching between realms (iOS / Swift 3)

I was trying to log in or register a user and connect them to an existing realm. Then, depending on the info stored in that realm, I may need them to instead connect to a different realm.
Is it not possible to try! Realm with a different configuration after it is initially configured? Is it discouraged? Does it need to be done outside of the initial DispatchQueue?
Here is the code:
SyncUser.logIn(with: usernameCredentials, server: URL(string: "http://11.22.333.0:9080")!) {
user, error in
guard let user = user else {
fatalError(String(describing: error))
}
DispatchQueue.main.async {
let configuration = Realm.Configuration(
syncConfiguration: SyncConfiguration(user: user, realmURL: URL(string: "realm://11.22.333.0:9080/ab56realmURL/NameOfRealm1")!)
)
self.realm = try! Realm(configuration: configuration)
if (someCheckOfData in realm) {
let configuration2 = Realm.Configuration(
syncConfiguration: SyncConfiguration(user: user, realmURL: URL(string: "realm://11.22.333.0:9080/ab56realmURL/NameOfRealm2")!)
)
self.realm = try! Realm(configuration: configuration2)
}
}
}
Thanks so much for any help!
No, it's not discouraged. All you're doing here is creating 2 discrete copies of Configuration, which will then subsequently be creating 2 separate Realm instances on your server.
The two will be completely separate, so there's no chance of causing an exception by incorrectly changing the configuration after it was used to create an initial Realm instance.
One thing we do recommend though is not holding onto specific Realm references like that though. They are not thread safe, and GCD isn't guaranteed to execute the same queues on the same threads, so you may be setting yourself up for a future exception.
If this is going to be your primary Realm, it's usually recommended to set that Configuration as the default Realm one. Otherwise, since Configuration is thread-safe (Assuming you don't modify it later), you can hold onto that, and use it to try! Realm(configuruation:) whenever you actually need to use Realm.

How to find Apple App Group shared directory

We are currently developing an iOS10 app, including "Messages Extension".
To share CoreDatas persistant store.sqlite inbetween App and Extension, we are using a shared "Apple App Group" directory, which is working fine.
Now we have to get our hands on the store for debug reasons and are unable to find the directory. The Apps container directories are completely empty, which makes sense. But how to download our database? Do we have to somehow copy it programmatically to a reachable place?
To sum it up:
We already use CoreData which stores model.sqlite in our shared directory.
Everything is up and running.
What we want to archive is to download the database to our computer.
Without a shared directory we can simply download the App container from the device, using Xcode->Devices. But as we do use a shared directory, the .sqlite database is not within the container.
Question:
How can we download the .sqlite database from the device to our computer?
EDIT on 2018-10-12: Updated code for Swift 4.x (Xcode 10). (Older version retained for reference.)
In Swift 4.x:
let sharedContainerURL :URL? = FileManager.default.containerURL(forSecurityApplicationGroupIdentifier: "group.etc.etc")
// replace "group.etc.etc" above with your App Group's identifier
NSLog("sharedContainerURL = \(String(describing: sharedContainerURL))")
if let sourceURL :URL = sharedContainerURL?.appendingPathComponent("store.sqlite") {
if let destinationURL :URL = FileManager().urls(for: .documentDirectory, in: .userDomainMask).first?.appendingPathComponent("copyOfStore.sqlite") {
try! FileManager().copyItem(at: sourceURL, to: destinationURL)
}
}
In older version of Swift (probably Swift 2.x):
let sharedContainerURL :NSURL? = NSFileManager.defaultManager().containerURLForSecurityApplicationGroupIdentifier("group.etc.etc") // replace "group.etc.etc" with your App Group's identifier
NSLog("sharedContainerURL = \(sharedContainerURL)")
if let sourceURL :NSURL = sharedContainerURL?.URLByAppendingPathComponent("store.sqlite")
{
if let destinationURL :NSURL = NSFileManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)[0].URLByAppendingPathComponent("copyOfStore.sqlite")
{
try! NSFileManager().copyItemAtURL(sourceURL, toURL: destinationURL)
}
}
Something like the above will get a file from the app group's shared container to the app's Documents directory. From there, you could use Xcode > Window > Devices to get it to your computer.
You could also use iTunes file sharing to retrieve the file from the app's Documents directory after setting UIFileSharingEnabled to YES in the Info.plist file, but bear in mind that this will expose the directory's contents to the user as well. Should be okay for development/debugging purposes, though.

How to access a computer file on a phone

I am using
let data = try?
NSString(contentsOfFile: "/Users/BenA**** 1/Desktop/textFile.txt",
encoding: String.Encoding.utf8.rawValue)
to access a file on my computer. When I test put the app on my phone, it obviously didn't work because it didn't have access to the file. How could I put this file on my phone and be able to access it from there? Thanks.
Include your "textFile.txt" in main bundle by drag and drop file in to xcode project, then access it by
class testViewController: UIViewController{
var data:String = ""
override func viewDidLoad() {
super.viewDidLoad()
let path = NSBundle.mainBundle().pathForResource("textFile", ofType: "txt")
data = try? NSString(contentsOfFile: path!, encoding: ENCODING)
}}
Try this way to access 'data' in rest of code.
Hope this help.
To simulate the behavior of iOS enable the sandbox on macOS.
Now you can access files only in the container of the app.
Nevertheless the predefined folders like Documents, Library etc. still exist.
To have access to that directories there a method of NSFileManager. For example one of the most important directories in iOS is the Documents directory.
let documentsFolderURL = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomain: .UserDomainMask).first!
You have to use that method each time you need to get the URL of that particular directory because for security reasons the absolute path will change.

.realm file automatically backed up by iCloud

my app was rejected because of the size of the content that it uploads to iCloud. The only file in my app's Documents folder is the default.realm database file. I think that this is the file that iCloud is uploading. How can I prevent iCloud to upload the database to iCloud?
Thanks.
According to the App Backup Best Practices section of the iOS App Programming Guide, <Application_Data>/Library/Caches or <Application_Data>/tmp will not backup to iCloud. Generally, you can use <Application_Data>/Library/Caches directory to save your data that you won't backup to iCloud.
To change the file path of Realm, you can pass the path parameter when creating Realm instance, like below:
let realmPath = NSSearchPathForDirectoriesInDomains(.CachesDirectory, .UserDomainMask, true)[0] as! String
let realm = Realm(path: realmPath.stringByAppendingPathComponent("data.realm"))
Otherwise, you can use NSURLIsExcludedFromBackupKey file system property to exclude files and directories from backups (See Technical Q&A QA1719). If you want to use the default path, there is the only way to exclude Realm file from backups.
let realm = Realm()
if let realmPathURL = NSURL(fileURLWithPath: realm.path) {
realmPathURL.setResourceValue(NSNumber(bool: true), forKey: NSURLIsExcludedFromBackupKey, error: nil)
}
Looks like the URL API has changed since the previous answer was posted. This is how you can disable the backup now:
let realm = try! Realm()
guard var url = realm.configuration.fileURL else {
return
}
var resourceValues = URLResourceValues()
resourceValues.isExcludedFromBackup = true
try? url.setResourceValues(resourceValues)

Resources