以无线方式安装企业内部应用(new)

item-service.png

之前文章 以无线方式安装企业内部应用

将企业内部专有 App 分发到 Apple 设备

Apple 设备支持以无线方式安装企业内部专有 App,无需使用 Mac 或通过 App Store。您必须有预置描述文件才能分发此类 App。您可以使用移动设备管理 (MDM) 解决方案安装和管理预置描述文件,然后用户通过 MDM 或 App 更新进行下载并安装。预置描述文件过期之前,请参阅 Apple 开发者网站为 App 创建新描述文件。对于 iOS 或 iPadOS App,请使用新预置描述文件为首次安装该 App 的用户导出新的 App 捆绑包(.ipa 文件)。

您可以通过两种方式分发企业内部专有 App:

  • 使用 MDM

  • 使用网站

这两种方法都需要为分发准备 App,包括准备清单。

未被监督的设备所需的 App

在 iOS 15 或更高版本和 iPadOS 15 或更高版本中,MDM 管理员可于注册过程中在未被监督的设备上安装 App。用户注册 MDM 解决方案时必须同意此安装。若要启用此功能,管理员需在 MDM 描述文件的 RequiredAppIDForMDM 属性中设定该 App Store App 的 iTunesStoreID。然后管理员必须确保 App 已有设备许可或用户许可,并在进行 MDM 注册后发送 InstallApplication 命令。MDM 管理员还可添加被管理 App 的属性以确保用户无法移除该 App。如果用户已安装了该 App,会收到请求对 App 进行 MDM 管理的提醒。有关 MDM 有效负载最新更改的更多信息,请参阅 Apple 开发者网站上的 MDM 注册页面

为无线分发准备企业内部专有 App

为准备企业内部专有 App 以进行无线分发,请构建归档版本(.ipa 文件)和用于启用无线分发和 App 安装的清单文件。使用 Xcode 创建版本化的 App 归档,然后将 App 导出以用于分发到组织。Xcode 使用分发证书并包括合适的预置描述文件。清单文件是一个 XML 属性列表(.plist 文件),可供 Apple 设备用来从您的网页服务器上查找、下载和安装 App。清单文件由 Xcode 创建,使用的是您在共享用于分发到组织的归档 App 时所提供的信息。若要查看属性和关联值列表,请参阅 Apple 开发者网站上的安装应用程序命令

适用于 Mac 电脑的受管理的企业内部专有 App

虽然所有批量购买的 App 和“自定 App”都可作为受管理的 App 安装,但只有部分企业内部专有 App 可被管理。若要变为可被管理,App 软件包必须:

  • 不包含任何嵌套软件包

  • 只包含单个 App

  • 安装在“/应用程序”中

    受管理的 App 必须保留在“/应用程序”文件夹中才视为被管理。

使用 MDM 来分发 App

若要使用 MDM,请通过 InstallApplication 命令来使用清单文件。有关更多信息,请参阅针对 Apple 设备的 MDM 命令

使用网站来分发 App

若要通过无线方式安装 App,iOS 和 iPadOS App 必须满足以下要求:

  • App 的格式必须为 .ipa,并且使用企业内部预置描述文件进行构建。

  • 必须有 XML 清单文件。

  • 必须从地址以 HTTPS 开头的网站下载。

  • 必须由设备上信任的证书签名。

  • 网络配置必须允许设备访问 Apple 服务器。有关更多信息,请参阅 Apple 支持文章:在企业网络上使用 Apple 产品

为了安装软件包,用户需要使用特殊的 URL 前缀从您的网站上下载清单文件。您可以通过 iMessage 信息或邮件来分发用于下载清单文件的 URL。以下是添加了前缀的示例链接:

<a href="itms-services://?action=download-manifest&url=https://example.com/manifest.plist">Install App</a>

您负责设计和托管用于分发这些类型 App 的网站。请确保用户已通过认证,且网站可通过内网或互联网访问(取决于您的需求)。您的网站可以是链接到清单文件的单个页面。当用户轻点网站链接时,会下载清单文件,并触发下载和安装网页所描述的内容。

请确保遵循以下额外指南:

  • 请勿添加直接指向归档 App (.ipa) 的网站链接。载入清单文件时,设备会下载该 .ipa 文件。虽然 URL 的协议部分是“itms-services”,但 App Store 并不参与此过程。

  • 请确保 .ipa 文件可通过 HTTPS 访问,并且您的站点已使用 iOS 和 iPadOS 信任的证书进行了签名。如果自签名证书没有受信任的锚点并且无法由设备验证,安装会失败。

将这些项目上传到网站上可供已认证的用户访问的区域:

  • 清单文件(文件扩展名为 .plist)

  • App 文件(文件扩展名为 .ipa)

您可能需要配置网页服务器,让清单文件和 App 文件可正确传输。对于服务器,请将 MIME 类型添加到网页服务的 MIME 类型设置:

  • application/octet-stream ipa

  • text/xml plist

对于微软的互联网信息服务器 (IIS),请使用 IIS Manager 在服务器的“属性”页面中添加 MIME 类型:

  • .ipa application/octet-stream

  • .plist text/xml

【注】创建自助服务门户时,请考虑在用户的主屏幕中添加一个 Web Clip,以便用户轻松返回门户以获取以后需要的信息,如新的配置描述文件、推荐的 App Store App 以及允许用户在 MDM 解决方案中进行注册。

证书验证

用户首次打开 App 时,系统会通过联系 Apple OCSP 服务器来验证分发证书。如果证书已撤销,App 将不会启动。为了验证状态,设备必须能够访问 ocsp.apple.com。

OCSP 响应会在设备上缓存一段时间(由 OCSP 服务器指定),当前为 3 到 7 天之间。在重新启动设备和缓存的响应过期之前,将不会再次检查证书的有效性。如果当时收到撤销命令,系统将阻止 App 运行。

【警告】撤销分发证书会导致使用该证书签名的所有 App 失效。只有万不得已时才应撤销证书,比如确定专用密钥已丢失或确信证书已遭破解。

提供更新的企业内部专有 App

您自己分发的 App 不会自动更新。有新版本时,应通知用户进行更新并指导他们安装 App。请考虑让 App 检查更新,并在打开 App 时通知用户。请确保通知中提供了 itms-services 链接。您还可以使用 App 内部的 openURL 来安装更新。

如果想要用户保留他们设备上储存的 App 数据,请确保新版本与要替换的版本使用的捆绑标识符相同,并告知用户在安装新版本之前不要删除旧版本。

预置描述文件过期之前,请通过 iOS 开发者网站iPadOS 开发者网站为 App 创建新描述文件。对于首次安装 App 的用户,请使用新的预置描述文件导出新的 App 捆绑包(.ipa 文件)。

如果用户已有该 App,您不妨设定发布下一个版本的时间,并在该版本中包括新预置描述文件。这样用户在使用 App 工作时不会被打断。如果不想这样做,您可以仅分发新的 .mobileprovision 文件,这样用户便不必再次安装该 App。新的预置描述文件会覆盖 App 归档中已有的描述文件。

分发预置描述文件自签发之日起 12 个月后过期。过期后,系统会删除描述文件,App 将不会启动。

如果您的分发证书过期,App 将不会启动,而您需要使用新的分发证书来重新构建 App。分发证书自签发之日起 3 年内有效,或者在您的 Apple Developer Enterprise Program(Apple 开发者企业级计划)成员资格过期之前一直有效,以二者中更早时间为准。若要防止证书过期,请确保在成员资格过期之前先进行续订。

您可以拥有同时处于活跃状态的两个证书,并且它们彼此独立。第二个证书提供了一个重叠期,让您能够在第一个证书过期前更新 App。请求第二个分发证书时,请确保不要撤销第一个证书。

无线 App 分发故障诊断

如果无线 App 分发失败,并显示“无法下载”信息:

  • 请确定 App 已正确进行签名。测试方法是使用 Apple Configurator 将它安装到设备上,然后查看是否发生错误。

  • 请确定清单文件的链接是否正确,清单文件是否可供网络用户访问。

  • 请确保清单文件中 .ipa 文件的 URL 正确,并且网络用户可通过 HTTPS 访问该 .ipa 文件。


<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
  <!-- array of downloads. -->
  <key>items</key>
  <array>
   <dict>
    <!-- an array of assets to download -->
     <key>assets</key>
      <array>
       <!-- software-package: the ipa to install. -->
        <dict>
         <!-- required. the asset kind. -->
          <key>kind</key>
          <string>software-package</string>
          <!-- optional. md5 every n bytes. will restart a chunk if md5 fails. -->
          <key>md5-size</key>
          <integer>10485760</integer>
          <!-- optional. array of md5 hashes for each "md5-size" sized chunk. -->
          <key>md5s</key>
          <array>
            <string>41fa64bb7a7cae5a46bfb45821ac8bba</string>
            <string>51fa64bb7a7cae5a46bfb45821ac8bba</string>
          </array>
          <!-- required. the URL of the file to download. -->
          <key>url</key>
          <string>https://www.example.com/apps/foo.ipa</string>
        </dict>
        <!-- display-image: the icon to display during download.-->
        <dict>
         <key>kind</key>
         <string>display-image</string>
         <!-- optional. indicates if icon needs shine effect applied. -->
         <key>needs-shine</key>
         <true/>
         <key>url</key>
         <string>https://www.example.com/image.57x57.png</string>
        </dict>
        <!-- full-size-image: the large 512x512 icon used by iTunes. -->
        <dict>
         <key>kind</key>
         <string>full-size-image</string>
         <!-- optional. one md5 hash for the entire file. -->
         <key>md5</key>
         <string>61fa64bb7a7cae5a46bfb45821ac8bba</string>
         <key>needs-shine</key>
         <true/>
         <key>url</key><string>https://www.example.com/image.512x512.jpg</string>
        </dict>
      </array>
<key>metadata</key>
      <dict>
       <!-- required -->
       <key>bundle-identifier</key>
       <string>com.example.fooapp</string>
       <!-- optional (software only) -->
       <key>bundle-version</key>
       <string>1.0</string>
       <!-- required. the download kind. -->
       <key>kind</key>
       <string>software</string>
       <!-- optional. displayed during download; typically company name -->
       <key>subtitle</key>
       <string>Apple</string>
       <!-- required. the title to display during the download. -->
       <key>title</key>
       <string>Example Corporate App</string>
      </dict>
    </dict>
  </array>
</dict>
</plist>
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 227,022评论 6 528
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,760评论 3 412
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 174,687评论 0 373
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 62,318评论 1 307
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 71,112评论 6 405
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,645评论 1 320
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,724评论 3 435
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,885评论 0 285
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 48,387评论 1 330
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 40,368评论 3 354
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,506评论 1 365
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 38,063评论 5 355
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,759评论 3 343
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 34,150评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 35,414评论 1 281
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 51,080评论 3 386
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,494评论 2 370

推荐阅读更多精彩内容