14

您好,我们最近开发了我们的第一个企业应用程序。我们正在使用“内部”选项来创建分发证书。客户尚未使用该应用程序。但他很快就会使用它。同时我有一个问题。他将使用该应用程序,并且将来如果我们这边对应用程序有任何更新,我们希望客户也可以在他这边进行更新。就像现在我的 iPhone 上安装了应用程序。我从 AppStore 收到更新,说 XYZ 应用程序已更新。所以我安装更新。现在,如果我们的客户正在使用该应用程序并在其上保存了一些数据(我们的应用程序使用核心数据,并且我们以客户端可以在设备上存储一些数据的方式构建它)我们想向他发送将安装的更新更新,但不会删除任何现有的客户端数据。那可能吗?我该怎么做?我现在正在使用无线安装来安装应用程序。我们有一个安全的服务器,其中存在 .ipa 和 .plist 文件,并且我们有一个下载 html 页面。客户单击链接并安装应用程序。如果您需要更多信息,请告诉我。谢谢。

4

5 回答 5

27

是的,有可能。当您部署企业应用程序时,它需要一个包含有关应用程序元数据的 plist。此元数据包括可用于检查更新的版本号。

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;
}

检测到更新可用后,将用户导航到下载 URL

itms-services://?action=download-manifest&url=<url-path-to-plist>

如果您设置自动迁移并进行更改,它将安装在现有版本上,使所有数据保持不变,甚至升级 CoreData 数据库。

于 2012-12-04T20:20:32.367 回答
6

感谢乔的精彩回应。这是翻译成 swift 的扩展版本。你可以把它放在viewDidLoad你的主视图控制器里面

let plistUrl = "https://example.com/example.plist"
let installationUrl = "itms-services://?action=download-manifest&amp;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)
    })
}
于 2016-04-01T23:37:14.730 回答
1

只需以与分发原始版本相同的方式分发更新。用户保留早期版本的数据。

于 2012-12-04T20:17:58.967 回答
1

swift 4 中@Vlad 的更新答案

 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)
    }}

但这只是一次,每次都需要更多修改

于 2020-04-28T07:57:55.913 回答
0

对于应用程序更新,如果应用程序的捆绑包 ID 保持不变,则现有应用程序数据将保持不变。

Apple 在此处解释企业应用程序部署和应用程序更新:http: //help.apple.com/iosdeployment-apps/mac/1.1/#app43ad802c

我还建议在应用程序中包含一个更新检查器。

要做到这一点,iVersion 是 Nick Lockwood(又名 Charcoal Design)的一个 ios 库,它将帮助您做到这一点。它在这里可用: https ://github.com/nicklockwood/iVersion

于 2014-01-22T17:56:39.273 回答