iOS企业OTA分发无法下载应用程序

32

我创建了一个iOS应用程序,并希望通过空中分发进行分发。我遵循了这个指南:

http://help.apple.com/iosdeployment-apps/mac/1.1/?lang=en-us#app43ad77ea

该应用程序使用企业证书签名,并包含分发配置文件。

当我尝试下载该应用程序到iPad上(使用此指南中描述的技术)时,屏幕上会出现一个带有我的下载图标的正方形图标,名称为“等待...”,然后一秒钟后名称更改为我的实际应用程序名称,接着又一秒钟后我收到以下错误消息:

无法下载应用程序。

此时无法下载“你的应用程序”。

在指南中,提供了三个故障排除提示:

如果无线应用程序分发失败并显示“无法下载”消息,请检查以下内容:

确保应用程序已正确签名。通过使用iPhone配置实用程序或Apple Configurator将其安装到设备上进行测试,并查看是否出现任何错误。

确保清单文件的链接正确,并且Web用户可以访问清单文件。

确保.manifest文件中的.ipa文件的URL正确,并且Web用户可以访问.ipa文件。

我检查了这三个方面,它们都没有问题。

还有什么原因会导致我的下载问题?


6
尝试为.ipa文件设置正确的MIME类型:"AddType application/octet-stream .ipa"(适用于Apache服务器)。请查看https://dev59.com/EG865IYBdhLWcg3wnP6a。 - llullulluis
我不得不重新构建 - 似乎存档(ipa)缺少一半的文件。整个过程中 Xcode 没有出现任何错误消息。 - pstanton
12个回答

33
alexey 所提到的,太多原因可能导致这个消息。苹果将其用作"捕获所有错误"的方式。
您可以通过控制台进行诊断。将设备连接到桌面电脑,并从XCode的组织者(仅适用于Mac)或iPhone配置实用程序(Mac和Windows)访问它。但是...
事情并不那么简单! :-( 控制台可能远远不够。有时那里没有相关的信息。

那么,最后的办法是按照清单再次进行。从零开始做起。有很多外部资源 可以使用...但是,以下是我目前的通用和非详细化的Over The Air分发清单



  1. Have a Distribution build - This is the most complicated part, done always on the web, and Apple changes the steps all the time. In general, you need a certificate, an identifier and the provisioning profile. Listing devices is almost always required. My current choice is "Distribution -> In House".

    Apple Developer -> Member Center -> Certificates, Identifiers & Profiles -> Provisioning Profiles -> Add (+)

    P.S.: If you do want to list the devices, make sure the UDIDs are correct. Many issues reported here.

  2. Set the profile under Project -> Build Settings - Since XCode 5, things changed. Instead of code signing with an identity you can clear all that up and set it under *Code Signing -> *Provisioning Profile. The Identity should automatically change to "Automatic". There's also no more need to manually download files from step 1 and install them. XCode manages that now.

    XCode 5 -> Project Navigator -> Project -> Build Settings

  3. Archive - In Xcode 5, there's no need any more to "Build for Archive". Just archive it. It should show up next on Organizer, and it will take some time if it's a big project. Many errors can come up on this step, but they're almost always related to code compilation and not to OTA.

  4. Deploy - Now in Organizer -> Archives, select the proper archive (should be already selected as the most recent one) click on "Distribute", then Save for Enterprise or Ad Hoc Deployment. May be big wait now. When saving the file, there is an option to "Save for Enterprise Distribution". That is a completely misleading name. What it really does is create the plist file. If you have one already, it's fine. You can even manually edit it, which is generally better. The plist be needed for step (5). Here's a good one:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>items</key>
        <array>
            <dict>
                <key>assets</key>
                <array>
                    <dict>
                        <key>kind</key>
                        <string>software-package</string>
                        <key>url</key>
                        <string>http://example.com/app.ipa</string>
                    </dict>
                    <dict>
                        <key>kind</key>
                        <string>full-size-image</string>
                        <key>needs-shine</key>
                        <false/>
                        <key>url</key>
                        <string>http://example.com/FullSizeImage.png</string>
                    </dict>
                    <dict>
                        <key>kind</key>
                        <string>display-image</string>
                        <key>needs-shine</key>
                        <false/>
                        <key>url</key>
                        <string>http://example.com/Icon.png</string>
                    </dict>
                </array>
                <key>metadata</key>
                <dict>
                    <key>bundle-identifier</key>
                    <string>com.example.app</string>
                    <key>kind</key>
                    <string>software</string>
                    <key>subtitle</key>
                    <string>for iOS</string>
                    <key>title</key>
                    <string>My App</string>
                </dict>
            </dict>
        </array>
    </dict>
    </plist>
    
  5. Distribute - Skip this step if you want to install it using XCode or iPhone Configuration Utility. You're done. This is putting on the file on a web site. "Simply" add a HTML page with a href link such as this:

     itms-services://?action=download-manifest&url=http://example.com/app.plist
    

    Unfortunately dealing with web servers is never simple. So also check the server mime-type! I've made a couple PHP files to deal with them, if your server supports php. Just keep your files as they are (the plist, html and ipa) and link to app.plist.php instead:

    app.plist.php

    $file = fopen("app.plist", "r");
    while(!feof($file)){
        $line = fgets($file);
        print str_replace(".ipa", ".ipa.php", $line);
    }
    fclose($file);
    ?>
    

    app.ipa.php

    <?php
    header('Content-type: application/octet-stream');
    
    $file = fopen("app.ipa", "r");
    while(!feof($file)){
        $line = fgets($file);
        print $line;
    }
    fclose($file);
    ?>
    

  6. Verify - Ensure that all files listed in the assets array are available to download. If any of these files return 404 or such (including the icons) the entire install will fail. You must either (A) make those files available or (B) delete those missing entries from the plist. The icon entries are not required for the download to work.

    Here is an example plist with no icons:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
        <key>items</key>
        <array>
            <dict>
                <key>assets</key>
                <array>
                    <dict>
                        <key>kind</key>
                        <string>software-package</string>
                        <key>url</key>
                        <string>http://example.com/app.ipa</string>
                    </dict>
                </array>
                <key>metadata</key>
                <dict>
                    <key>bundle-identifier</key>
                    <string>com.example.app</string>
                    <key>kind</key>
                    <string>software</string>
                    <key>subtitle</key>
                    <string>for iOS</string>
                    <key>title</key>
                    <string>My App</string>
                </dict>
            </dict>
        </array>
    </dict>
    </plist>
    

文件示例是清单的非常重要的一部分。它们必须完全正确。

仔细检查plist和html文件!

P.S.:我写这个答案是因为,在我的情况下,这只是一个“简单”的问题,是.plist文件链接错误导致的。而且,这种错误很难诊断。只有通过执行此清单,我才能找到错误!它指向的是“another-app.ipa”而不是“app.ipa”!


1
这行代码帮助我解决了问题。<string>http://example.com/app.ipa</string>,请确保software-package指向实际的IPA文件。 - Tony
1
控制台提示+1。它准确地描述了应用程序无法安装的原因,而不是设备上显示的通用“无法安装”消息。 - n00neimp0rtant
如果是这个原因的话,请给alexey there点个赞吧,@n00neimp0rtant。他想出了这个方法!;-) - cregox
1
关于#6令人烦恼的部分是控制台上没有任何关于安装失败原因的信息。希望这能帮助某个人避免像我一样花费时间进行调试! - Saltymule
@Saltymule,很抱歉版主拒绝了您的编辑建议。我自己无法验证它,也无法验证它,但它看起来非常有用和准确。您是正确的,通常安装错误提供的调试信息太少或根本没有。 - cregox
1
我想再次强调@cregox提到的最后一点。我刚刚在错误的路径上浪费了几个小时,最终找到了.ipa文件...大家务必三思而后行;) - Guillaume Munsch

12

导致这个消息出现的原因有很多。

诊断它的最好方法是将设备连接到Mac,并在组织者(Organizer)中查找设备的控制台(Console)

例如,在我的情况下,它是:

verify_bundle_metadata:此应用程序没有构建来支持此设备系列


几乎完美!欲了解更多信息,请阅读我的回答 - cregox
2
Xcode 6及以上版本的更新答案。设备已从组织者中分离出来。在Xcode 6或7中,进入窗口>设备,选择设备,然后在左下角有一个带箭头的框。单击它,它将展开先前最小化的控制台。我通过这种方式找到了我的问题,顺便说一句,它是错误的捆绑标识符!我们更改了我们的捆绑名称,但正在重用以前版本的plist文件,并忘记在那里更新它。 - RobDigital
在控制台中找到相关的位置可能很困难,因为它会不断记录日志,可以搜索字符串“下载完成安装”或“应用程序安装失败”等。 - shim

7

回答自己的问题:

问题出在manifest.plist文件中一个缩略图的路径设置不正确,因此不仅ipa文件需要正确的路径,临时下载的图标也需要,否则安装将会失败并显示上述错误信息。


1
嗯,同样的问题,但这对我没有解决。 - d2burke
1
@d2burke 设置服务器MIME类型您可能需要配置您的Web服务器,以便正确传输清单文件和应用程序文件。对于Mac OS X Server,请使用Server Admin将以下MIME类型添加到MIME类型设置中:application/octet-stream ipatext/xml plist对于IIS,请使用IIS Manager在服务器的属性页面中添加MIME类型:.ipa application/octet-stream.plist text/xml - Karthik
这个链接会对您有所帮助,并解决您的问题@d2burke http://ios-programming.blogspot.in/2012/04/share-ipa-on-private-server-using-save.html - Karthik
1
这也发生在我身上。按照被接受的答案中的所有步骤,但结果发现我的其中一个缩略图是404。 - Samuel Clay

6
另一个可能的问题是.plist和.ipa文件都需要使用HTTPS进行托管,而不仅仅是普通的HTTP。软件包字符串应如下所示:
<key>kind</key>
<string>software-package</string>
<key>url</key>
<string>https://example.com/app.ipa</string>

这是一个很小的失误,但却困扰了我一段时间。


3

当我们尝试将一个iOS 5+应用安装到一个iOS4.3.5的手机上时,我们也遇到了同样的错误提示。您是否也检查了部署/构建目标和目标架构,以匹配显示该问题的设备?


当我将我的代码签名身份切换到目标的分发时,我遇到了这个问题。当我将项目切换到分发时,问题得到了解决。我不知道为什么它们之间没有关联。 - mbm29414

1
确保所有文件中的大小写匹配。它们往往是不区分大小写的。

1
在我的情况下,问题出在我的设备上安装了同一应用程序的旧版本,具有相同的捆绑标识符(从应用商店下载)。因此,当我尝试通过企业分发下载其新版本时,什么都没有发生,根本没有错误。从设备中删除现有版本解决了我的问题。

1

我在控制台中发现了以下信息:

installcoordinationd(MobileInstallation)[99] : ****bundleID****:5:11:1:1:正在更新 ****bundleID**** 的占位符元数据,失败原因是 1 _LSInstallType 1,底层错误为 (Error Domain=MIInstallerErrorDomain Code=13 "Failed to verify code signature of /private/var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.IoCSM9/extracted/Payload/App.app : 0xe8008016 (The executable was signed with invalid entitlements.)" UserInfo={LibMISErrorNumber=-402620394, LegacyErrorString=ApplicationVerificationFailed, SourceFileLine=147, FunctionName=+[MICodeSigningVerifier _validateSignatureAndCopyInfoForURL:withOptions:error:], NSLocalizedDescription=Failed to verify code signature of /private/var/installd/Library/Caches/com.apple.mobile.installd.staging/temp.IoCSM9/extracted/Payload/App.app : 0xe8008016 (The executable was signed with invalid entitlements.)}), 来源 17>

在这里我们应该注意到:
无法验证 App.app 的代码签名
可执行文件的权限无效。

在我的情况下,是因为我从亚马逊下载了企业版构建。但是,它所构建的配置文件已经过期了(在开发人员控制台中找到)。

另一个带有不同目的的:

"此应用程序无法安装。" UserInfo={NSLocalizedDescription=此应用程序无法安装, NSUnderlyingError=0x100cbd3c0 {Error Domain=MIInstallerErrorDomain Code=64 "升级的 application-identifier 权限字符串 (BBBUUUU.com.bundle.www) 与已安装应用程序的 application-identifier 字符串 (CCCEEEE.com.bundle.www) 不匹配;拒绝升级。" UserInfo={LegacyErrorString=MismatchedApplicationIdentifierEntitlement, FunctionName=-[MIInstallableBundle _validateApplicationIdentifierForNewBundleSigningInfo:error:],SourceFileLine=878,NSLocalizedDescription=升级的 application-identifier 权限字符串 (BBBUUUU.com.bundle.www) 与已安装应用程序的 application-identifier 字符串 (CCCEEEE.com.bundle.www) 不匹配;被拒绝

这里我刚刚删除了应用程序的先前版本。错误是因为我更改了捆绑标识的团队,并且使用先前的捆绑标识安装了该应用程序。


使用以下方法打开控制台:

  • Xcode > 窗口 > 设备
  • 选择设备
  • 在左下角展开一个带有箭头的框来打开控制台。

0

请检查您的XCode.plist文件中的bundle identifier


0
在我的情况下,我采取了以下措施来解决提供ipa共享链接后消除“无法连接到dl.dropboxusercontent”消息的问题: 1. 从属性列表中删除md5部分 2. 将512 * 512和57 * 57图像上传到Dropbox,并在属性列表中的fill_size_image和display_image中提供共享链接。

哎呀?这跟Dropbox有什么关系? - Todd Sewell
该捆绑包已发布在Dropbox上。 - Lakhwinder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接