科技微讯

再次分析 Apple OTA 检测

我写的微信小程序“通知中心”支持订阅 iOS、macOS、watchOS 等苹果系统的更新通知,但有时候可能有三十分钟左右的延迟,被用户吐槽通知的太慢了吧...

于是再次认真分析了 iOS 的 OTA 检测,但最后的结论依然是:算了,还是保持现在的检测方法吧...

以下是我的调查笔记。

获取设备列表

要想获得苹果产品列表、设备型号、ProductName 等信息,可以用 ipsw.me 的这个 API,返回的结果包含了 iPhone、iPad、watch、mac、tv。

async function app() {
  const url = "https://api.ipsw.me/v4/devices";
  const json = await got({
    url: url,
    responseType: "json",
  }).then((res) => res.body);
  const list = json
    .map((item) => {
      return {
        name: item.name,
        identifier: item.identifier,
        kind: item.name
          .replace(/^([^\s]+)\s{1}.+$/gi, "$1")
          .replace(/^([^\d]+)\d{1}.+$/gi, "$1"),
      };
    })
    .sort((a, b) => {
      if (a.name > b.name) return 1;
      else return -1;
    });
  const group = list.reduce((acu, item) => {
    acu[item.kind] = acu[item.kind] ? acu[item.kind] : [];
    acu[item.kind].push(item);
    return acu;
  }, {});
  const kinds = Object.keys(group);
  fs.writeFileSync("./devices.json", JSON.stringify(group));
}

app();

Github 也有人收集了这些信息,但只是一个 md 文件,用的话需要自己改成 json。

正式版检测

com_apple_MobileAsset_SoftwareUpdate.xml

从这个很出名的 xml 文件获取的信息,ipsw.me 的数据应该主要就是从这里同步的吧。

为什么不用这个数据?

async function app() {
  const url =
    "https://mesu.apple.com/assets/com_apple_MobileAsset_SoftwareUpdate/com_apple_MobileAsset_SoftwareUpdate.xml";
  const xml = await got(url).then((res) => res.body);
  const json = plist.parse(xml);
  const list = json.Assets.map((item) => {
    const SUDocumentationID = item.SUDocumentationID;
    const osVersion = item.OSVersion.startsWith("9.9.")
      ? item.OSVersion.replace("9.9.", "")
      : item.OSVersion;
    const isBeta = item.ReleaseType
      ? true
      : item.SUDocumentationID === "preRelease"
      ? true
      : false;
    const buildnum = item.Build;
    return {
      version: osVersion,
      isBeta: isBeta,
      build: buildnum,
      SUDocumentationID: SUDocumentationID,
    };
  });
  fs.writeFileSync("./ios_clean.json", JSON.stringify(list));
}

app();

ipsw.me 的 API

这个 API 按照日期列出了苹果正式版的发布记录,没有测试版,等同于 ipsw 的这个 RSS

为什么不用这个?因为基本没有 watchOS,主要是 iOS 和 macOS。

gdmf.apple.com/v2/pmv

这个地址可以拿到目前在 sign 的最新的正式版,但是没有 build number。通过这个链接,我才发现苹果官网的 rss 内容不全,12.5.6 和 16.0、15.7 同一天发布,但是 rss 没有,watchOS 6.3、macOS 11.7 也是,它们都是面向旧机型发布的系统。

可以考虑以后都通过这个链接检测正式版更新,但需要找到一种获取 build number 的方法,可以通过 ipsw.me 的 api 获取?另外需要观察它的更新速度,比 rss 快还是慢?

2022-09-23 更新:发现这种方法也有问题,iOS 16.0.2 发布了,但这个链接没有第一时间显示,同一天发布的 watchOS 9.0.1 倒是显示了,PostingDate 不知道为什么也会自动更新,watchOS 9.0 的 PostingDate 今天更新为 09-22。

async function app() {
  const url = "https://gdmf.apple.com/v2/pmv";
  const json = await got({
    url: url,
    responseType: "json",
    https: {
      //这个选项不能省
      rejectUnauthorized: false,
    },
  }).then((res) => res.body);

  const list = [...json.PublicAssetSets.iOS, ...json.PublicAssetSets.macOS].map(
    (item) => {
      let osType = "";
      if (item.SupportedDevices.find((item) => /mac/i.test(item))) {
        osType = "macOS";
      }
      if (item.SupportedDevices.find((item) => /iphone/i.test(item))) {
        osType = "iOS";
      }
      if (item.SupportedDevices.find((item) => /ipad/i.test(item))) {
        osType = "iPadOS";
      }
      if (item.SupportedDevices.find((item) => /tv/i.test(item))) {
        osType = "tvOS";
      }
      if (item.SupportedDevices.find((item) => /watch/i.test(item))) {
        osType = "watchOS";
      }
      return {
        version: `${osType} ${item.ProductVersion}`,
        pubDate: item.PostingDate,
        SupportedDevices: item.SupportedDevices,
      };
    }
  );
  fs.writeFileSync("./pmv_clean.json", JSON.stringify(list));
}

app();

测试版检测

ipswbeta.dev/ios/16.x/

这里的测试版,仅指 developer beta,不是 public beta。这个网站可以拿到测试版的 ipsw 链接,但是不知道它是怎样拿到的,这个网站也没有公开的 api。

appledb.dev

这个网站也有测试版的下载链接,但是也没有公开的 api。

检测 Release Note

正式版的 release note 可以直接爬取官网:

苹果的 xml 也提供正式版的 release note,但是需要自己下载,解压,然后选出中文。

ipsw.me 的 api 也提供文档数据(详情),但是没有中文。

所以 release note 最好的做法还是直接爬苹果官网吧。

thumbsup0
thumbsdown0
暂无评论