I need to save records to the production environment instead of the development environment in CloudKit. What I have tried to do in order to manage that is what many have recommended me. Submit a build of the app, and download it using TestFlight. That way, the records will be saved to the production environment, they said.
This is my code for saving records
func uploadRecordsToProduction() {
let cloudContainer = CKContainer(identifier: "MyContainserString")
let publicDatabase = cloudContainer.publicCloudDatabase
publicDatabase.saveRecord(record, completionHandler: {_,_ in
})
}
If I run the app in Xcode simulator the record gets saved in the development environment. If I run the app using Testflight, no record is being saved it seems. What is happening?
Related
I have a watchOS only app (not my first) and using UserDefaults.standard.set() to store some data. In my other project it is working fine but in this project it do not store anything. Values to store are present (Array). Even after triggering UserDefaults.standard.synchronize() which is not needed on my other app it do not work. Any suggestions on which factors it can be possible to not work?
After rebuilding / running the app from XCode the data is gone.
Just saving like that
UserDefaults.standard.set(self.data, forKey: "fetchData")
UserDefaults.standard.synchronize()
Where self.data is an Array with items of type Dictionary<String,Any> (Int and Date get stored)
I've been using Realm for more than a year on a specific app & it has been in the AppStore for just as long. Everything has been fine until a few days ago when a newly approved & released build into the AppStore now crashes for ALL users after updating & attempting to open the app.
Users are saying the only way to fix this is by deleting the app from the device & doing a fresh install. That's a catastrophe. Luckily we save user data/progress on a server.
This started happening immediately after Realm was updated by using the pod update command in terminal.
By installing a previous build from TestFlight, opening it at least once & then building & running the app on the device with the old TestFlight build from Xcode produces a very specific crash error in the log when initializing an instance of Realm:
"Opening Realm files of format version 20 is not supported by this
version of Realm"
Note, I did NOT touch or alter the code in any way after pods were updated.
Here's how the Realm configuration currently looks like (& has looked like for the past 6 months):
let config = Realm.Configuration(schemaVersion: 30, migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 30 {
migration.deleteData(forType: CategoryRealmModel.className())
migration.deleteData(forType: CourseRealmModel.className())
}
})
Realm.Configuration.defaultConfiguration = config
Would really appreciate any ideas on what can be done. I need to release a new build that will not crash when updated on top of any older versions.
Eureka, I found the answer. To be able to overlay a new build on top of an older one without having Realm crash, requires the alteration of the Realm configuration as such:
let config = Realm.Configuration(schemaVersion: 30, migrationBlock: { migration, oldSchemaVersion in
if oldSchemaVersion < 30 {
migration.deleteData(forType: CategoryRealmModel.className())
migration.deleteData(forType: CourseRealmModel.className())
}
}, deleteRealmIfMigrationNeeded: true)
Realm.Configuration.defaultConfiguration = config
It's not enough to merely use the function migration.deleteData(forType: SomeRealmModel.className()) on every existing RealmModel within the app. One needs to set deleteRealmIfMigrationNeeded to true during configuration.
Apparently it triggers a better inner process - full deletion of the existing Realm database if it deems migration necessary. Which it will if an older version of the app exists.
We ran into strange behavior.
Install the app from test flight
App creates a local sqlite database in the NSDocumentDirectory
User deletes the app
User reinstalls the app again from test flight (newer version)
App sees old database in the app
This has happened several times. And my understanding was that apps are supposed to delete everything with it once they are deleted. Yet intermittently this happens.
Anyone seen this issue before?
I assume this is caused by iCloud backup and restore functionality. If you don't set the exclude back-up key explicitly, the iOS will automatically back-up your files in the document directory. In your case, the previous database was backed-up in the iCloud and when you re-installed the app, the iCloud restored the database file. That's the reason why you are seeing the old data. If you don't need to back up your app's database file use the following code:
Swift 4:
do
{
var resourceValues = URLResourceValues()
resourceValues.isExcludedFromBackup = true
try databaseURL.setResourceValues(resourceValues)
}
catch
{
print(error.localizedDescription)
}
Old Version Code
do
{
// Database URL
try databaseURL.setResourceValue(true, forKey:NSURLIsExcludedFromBackupKey)
}
catch let error as NSError
{
print("Error excluding \(URL.lastPathComponent) from backup \(error)");
}
Reference: How do I prevent files from being backed up to iCloud and iTunes?
I am trying to enable the data protection for my core data file. Here is what I did.
Project settings enabled the data protection in capabilities.
Modified persistent store coordinator getter
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite")
var failureReason = "There was an error creating or loading the application's saved data."
do {
try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: [NSSQLitePragmasOption : ["journal_mode" : "DELETE"], NSPersistentStoreFileProtectionKey : NSFileProtectionComplete])
}
Ran the code and installed the app on the device.
Downloaded the app container and opened package content, and could see the .sqlite file
Now locked the device
Kept it for 10 sec, and then downloaded the app container again for the same app.
7.Opened the package content, I can still see the package content and sqlite file :(
I am using free provisioning profile if that helps in anyway.
What mistake am I doing here?? Why is this .sqlite file is not encrypted?
Please help. Thanks in advance.
Because the computer your device is connected to is a Trusted Computer, it can read your app's container even if the device is locked. I know of two options to test if the sqlite file is encrypted:
1) Jailbreak your device. Then SSH into your device, and try to read the sqlite file (ie. 'cat sqlite_file') when the device is locked. If the file is encrypted, you won't be able to read it.
2) You can inspect the attributes on the sqlite file and make sure the NSFileProtectionKey attribute is appropriately set:
let attributes = try? FileManager.default.attributesOfItem(atPath: sqlite_path)
print(attributes)
I have developed application in Swift. Application is enterprise application so it will never go live on App Store.
I need to update the application within app if update is available for the application.
Right now I have done with backend and iOS side code. I have created .plist file which contains my uploaded .ipa file url and other things. ref
I have successfully implemented code of how can I download and update the app within app itself.
But the issue is when app start to download it stops at 60% and when I try to retry download it's shows error Unable to Downlaod App.
Is there any way I can implement the same idea ?
Swift code
func getTheData() {
let appversion = NSBundle.mainBundle().infoDictionary!["CFBundleShortVersionString"] as! String
var query = PFQuery(className:"AppVersion")
query.getObjectInBackgroundWithId("Parse unique key") {
(version: PFObject?, error: NSError?) -> Void in
if error == nil && version != nil {
let oldVersion = version?.valueForKey("version") as! String
println(version?.valueForKey("version"))
if appversion == oldVersion {
println("Same Version")
}
else {
println(version)
println("Different version")
let url = version?.valueForKey("ipaURL") as! String
UIApplication.sharedApplication().openURL(NSURL(string:url)!)
}
} else {
println(error)
}
}
}
ANSWER:
I have found the issue.The issue is with iOS 9.0 and above only. From XCode 7 and above, you have to generate(Not manually) manifest.plist file with organizer only. When you are creating ipa file using export option in organizer you will get two options 1)Bitcode 2)generate manifest for OTA update. You have to crete Manifest.plist file with XCode's organizer only.
Seeing as the app is open, I would recommend showing the user a message to update. The AlertView button action should take the user to the webpage to download the new version.
This is not ideal from what you are trying to achieve, but is a way I have done it in the past and works fine.
The issue is the provision profile when you create Archive that time you need to correct device which is listed into provision profile.
Before few days same issue I face and connected same device along with provision profile UDID container.
So I created R&D over that and solve the same problem.