Hello we have developed our first enterprise app recently. We are using the "In-House" option to create the distribution certificate. Client is not using the app yet. But he will be using it soon. Meanwhile i got a question. He will use the app and in future if there are any updates to the app from our side, we want the client to have it updated on his side as well . Like right now I have apps installed on my iPhone. I get update from AppStore saying the XYZ app has been updated. So i install the update. Now if our client is using the app and has saved some data on it(our app uses core data, and we built it in a way that client can store some data on the device) we want to send an update to him that would install the update, but not erase any existing client data.Is that possible? How do i do it?I am using over the air installation right now to install the app. We have a secure server, where the .ipa and .plist files are present and we have a download html page. Client clicks the link and the app gets installed. Please let me know if you need more information. Thanks.
Yes, it is possible. When you deploy an Enterprise application it requires a plist that contains metadata about the application. This metadata includes the version number that you can use to check for updates.
BOOL updateAvailable = NO;
NSDictionary *updateDictionary = [NSDictionary dictionaryWithContentsOfURL:
[NSURL URLWithString:@"http://www.example.com/pathToPlist"]];
if(updateDictionary)
{
NSArray *items = [updateDictionary objectForKey:@"items"];
NSDictionary *itemDict = [items lastObject];
NSDictionary *metaData = [itemDict objectForKey:@"metadata"];
NSString *newversion = [metaData valueForKey:@"bundle-version"];
NSString *currentversion = [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"];
updateAvailable = [newversion compare:currentversion options:NSNumericSearch] == NSOrderedDescending;
}
Once you detect the update is available navigate the user to the download URL
itms-services://?action=download-manifest&url=<url-path-to-plist>
and it will install over the existing version leaving all data in-tact and even upgrade the CoreData database if you setup auto migration and make changes.
Thanks to Joe for a fantastic response. Here is the extended version translated to swift. You can put it inside of the viewDidLoad
of your main view controller
let plistUrl = "https://example.com/example.plist"
let installationUrl = "itms-services://?action=download-manifest&url=https://example.com/example.plist"
override func viewDidLoad() {
super.viewDidLoad()
//Check for the updates
checkForUpdates()
}
func checkForUpdates() {
let qualityOfServiceClass = QOS_CLASS_BACKGROUND
let backgroundQueue = dispatch_get_global_queue(qualityOfServiceClass, 0)
dispatch_async(backgroundQueue, {
let updateDictionary = NSDictionary(contentsOfURL: NSURL(string: self.plistUrl)!)!
let items = updateDictionary["items"]
let itemDict = items?.lastObject as! NSDictionary
let metaData = itemDict["metadata"] as! NSDictionary
let serverVersion = metaData["bundle-version"] as! String
let localVersion = NSBundle.mainBundle().infoDictionary!["CFBundleVersion"] as! String
let updateAvailable = serverVersion.compare(localVersion, options: .NumericSearch) == .OrderedDescending;
if updateAvailable {
self.showUpdateDialog(serverVersion)
}
})
}
func showUpdateDialog(serverVersion: String) {
dispatch_async(dispatch_get_main_queue(), { () -> Void in
let alertController = UIAlertController(title: "New version of Example available!", message:
"Example \(serverVersion) has been released. Would you like to download it now?", preferredStyle: UIAlertControllerStyle.Alert)
alertController.addAction(UIAlertAction(title: "Not now", style: .Cancel,handler: nil))
alertController.addAction(UIAlertAction(title: "Update", style: .Default, handler: { (UIAlertAction) in
UIApplication.sharedApplication().openURL(NSURL(string: self.installationUrl)!)
}))
self.presentViewController(alertController, animated: true, completion: nil)
})
}
Just distribute the update the same way you distribute the original. The user retains the data from the earlier version.
Updated answer of @Vlad in swift 4
var plistUrl = "https://xxxxxxxxxxxxxxfgfgf/ex.plist"
var installationUrl = URL(string : "itms-services://?action=download-manifest&url=https://xxxxxxxxxxxxxxfgfgf/ex.plist")
func checkForUpdates() {
let qos = DispatchQoS(qosClass: .background, relativePriority: 0)
let backgroundQueue = DispatchQueue.global(qos: qos.qosClass)
backgroundQueue.async(execute: {
let updateDictionary = NSDictionary(contentsOf: NSURL(string: self.plistUrl)! as URL)!
let items = updateDictionary["items"]
let itemDict = (items as AnyObject).lastObject as! NSDictionary
let metaData = itemDict["metadata"] as! NSDictionary
let serverVersion = metaData["bundle-version"] as! String
print ("serverVersion=",serverVersion)
let localVersion = Bundle.main.infoDictionary!["CFBundleVersion"] as! String
print ("localVersion=",localVersion)
let updateAvailable = serverVersion.compare(localVersion, options: .numeric) == .orderedDescending
print("version is newer")
if updateAvailable {
self.showUpdateDialog(serverVersion: serverVersion)
}
})
}
func showUpdateDialog(serverVersion: String) {
DispatchQueue.main.async { () -> Void in
let alertController = UIAlertController(title: "New version of App available!", message:
"MCD \(serverVersion) has been released. Would you like to download it now?", preferredStyle: UIAlertController.Style.alert)
alertController.addAction(UIAlertAction(title: "Not now", style: .cancel,handler: nil))
alertController.addAction(UIAlertAction(title: "Update", style: .default, handler: { (UIAlertAction) in
UIApplication.shared.open(self.installationUrl!, options: [:], completionHandler: nil)
}))
self.present(alertController, animated: true, completion: nil)
}}
but this is only onetime need more modification for everytime
For app updates, the existing app data persists if the bundle ID for the app stays the same.
Apple explains Enterprise App Deployment and app updates here: http://help.apple.com/iosdeployment-apps/mac/1.1/#app43ad802c
I'd also recommend including an update checker in-app.
To do that, iVersion is a ios library by Nick Lockwood (aka Charcoal Design) that will help you to do this. It's available here: https://github.com/nicklockwood/iVersion
© 2022 - 2024 — McMap. All rights reserved.