调用App Store Connect Api
对iOS的证书、描述文件、账号、设备等管理,之前都去苹果开发者中心操作,官网上操作也比较繁杂,想搞一些自动化之类的,更是麻烦,有时候官网都打不开……
其实苹果还提供里一套API接口,创建证书、创建账号、增加devices等等,这些都可以调用命令操作,可以按需来完成自动化操作或批量操作。
API接口地址:https://api.appstoreconnect.apple.com
文档地址:https://developer.apple.com/documentation/appstoreconnectapi
有人可能看完文档还是不知道怎么下手,简述一下步骤:
1. 生成token
(1)key 和iss以及.p8文件生成就不累述
(2) 构造header
algorithm = 'ES256'
base_api_url = "https://api.appstoreconnect.apple.com"
header = {
"alg": algorithm,
"kid": key,
"typ": "JWT"
}
(3)构造payload
#
payload = {
"iss": iss,
"exp": int(time.mktime((datetime.now() + timedelta(minutes=20)).timetuple())),
"aud": "appstoreconnect-v1"
}
(4)生成token
token = jwt.encode(payload=payload, key=private_key, algorithm=algorithm, headers=header).decode('ascii')
return token
(5)封装请求处理
def base_call(url, token, method="get", data=None):
"""
:param url:
:param token:
:param method:
:param data:
:return:
""" re_header = {"Authorization": "Bearer %s" % token}
r = {}
url = base_api_url + url requests.adapters.DEFAULT_RETRIES = 1
req = requests.session()
req.keep_alive = False if method.lower() == "get":
r = req.get(url, params=data, headers=re_header) elif method.lower() == "post":
re_header["Content-Type"] = "application/json"
r = req.post(url=url, headers=re_header, data=json.dumps(data)) elif method.lower() == "patch":
re_header["Content-Type"] = "application/json"
r = req.patch(url=url, headers=re_header, data=json.dumps(data))
return r
比如我们以增加设备id为例:

def set_devices(api_token, data):
"""
增加devices信息
:param api_token:
:param data:
:return:
"""
set_device_url = '/v1/devices'
res = base_call(set_device_url, api_token, 'post', data)
return res
post_data = {
"data": {
"attributes": {
"name": i.split(',')[0],
"platform": "IOS",
"udid": i.split(',')[1]
},
"type": "devices"
}
}
res = api.set_devices(api_token, post_data)
if res.status_code != 201:
print(res.json()['errors'][0]['detail'])
else:
print("add time:", res.json()['data']['attributes']['addedDate'])
这里的参数组装需要注意,需要参考文档一层层组装参数,data包含自子参数,子参数再包含子参数
完整的代码示例:
# -*- coding:utf-8 -*-
# Author: drew
# create time: 2020-07030
# update time:
# app store connect api import jwt
import time
import json
import requests
from datetime import datetime, timedelta algorithm = 'ES256'
base_api_url = "https://api.appstoreconnect.apple.com" def get_token(key, iss, key_file):
"""
:param key:
:param iss:
:param key_file:
:return:
"""
# 读取私钥
private_key = open(key_file, 'r').read()
# 构造header
header = {
"alg": algorithm,
"kid": key,
"typ": "JWT"
}
# 构造payload
payload = {
"iss": iss,
"exp": int(time.mktime((datetime.now() + timedelta(minutes=20)).timetuple())),
"aud": "appstoreconnect-v1"
} token = jwt.encode(payload=payload, key=private_key, algorithm=algorithm, headers=header).decode('ascii')
return token def base_call(url, token, method="get", data=None):
"""
:param url:
:param token:
:param method:
:param data:
:return:
""" re_header = {"Authorization": "Bearer %s" % token}
r = {}
url = base_api_url + url requests.adapters.DEFAULT_RETRIES = 1
req = requests.session()
req.keep_alive = False if method.lower() == "get":
r = req.get(url, params=data, headers=re_header) elif method.lower() == "post":
re_header["Content-Type"] = "application/json"
r = req.post(url=url, headers=re_header, data=json.dumps(data)) elif method.lower() == "patch":
re_header["Content-Type"] = "application/json"
r = req.patch(url=url, headers=re_header, data=json.dumps(data))
return r # ------------------ 获取具体接口的方法 ------------------ def get_devices(api_token, data=None):
"""
获取devices信息
:param api_token:
:param data:
:return:
"""
get_devices_url = '/v1/devices'
if data is None:
data = {
"filter[platform]": "IOS",
# "filter[status]": "ENABLED",
"limit": 100
}
res = base_call(get_devices_url, api_token, 'get', data)
return res def set_devices(api_token, data):
"""
增加devices信息
:param api_token:
:param data:
:return:
"""
set_device_url = '/v1/devices'
res = base_call(set_device_url, api_token, 'post', data)
return res def update_devices(api_token, id, data,):
"""
增加devices信息
:param id:
:param api_token:
:param data:
:return:
"""
set_device_url = '/v1/devices/{%s}' % id
res = base_call(set_device_url, api_token, 'patch', data)
return res """
if __name__ == "__main__": ios_api_key = 'T8****8AD8'
ios_api_issuer = '69a**9-b79b-4**3-e053-5b**1a4d1'
file_key = "/Users/drew/.private_keys/AuthKey_T85LR***8.p8"
token_api = get_token(ios_api_key, ios_api_issuer, file_key)
# get_udid()
post_data = {
"data": {
"attributes": {
"name": "zb",
"platform": "IOS",
"udid": "80b677c2c****e476caf61ba0d34274000"
},
"type": "devices"
}
} res = set_udid(token_api, post_data)
print(res)
"""
调用App Store Connect Api的更多相关文章
- [App Store Connect帮助]二、 添加、编辑和删除用户(6)生成 API 密钥
如果已批准您访问 App Store Connect API,您可以生成 API 密钥,以便使用该密钥配置.认证和使用 App Store Connect 服务. 有关管理和保护您密钥的更多信息,请参 ...
- [App Store Connect帮助]九、衡量 App 表现(1)分析和报告概述
App Store Connect 提供如下分析和报告,以衡量您 App 的表现并查看向您支付的最终付款. App 分析 通过 App Store 展示次数.产品页面查看次数.销售额.App 使用次数 ...
- [App Store Connect帮助]一、 App Store Connect 使用入门(1)App Store Connect 工作流程
您使用 App Store Connect 提交并管理您在 App Store 中销售的 App,使用 TestFlight 分发您 App 的 Beta 版本,接受法律协议,输入您的税务和银行业务信 ...
- [App Store Connect帮助]三、管理 App 和版本(2.4)输入 App 信息:提供加密出口合规证明文稿
上传至 App Store Connect 的 App 被上传至位于美国的 Apple 服务器.如果您提交 App 的目的是为了在 App Store 上分发您的 App 或通过美国或加拿大的境外 T ...
- [App Store Connect帮助]二、 添加、编辑和删除用户(1)用户帐户和职能概述
您可以在 App Store Connect 的“用户和访问”部分管理用户.添加沙盒测试员以及管理 API 密钥. 用户职能决定了用户对 App Store Connect 和 Apple Devel ...
- [App Store Connect帮助]八、维护您的 App(4.3)回复顾客评论(iOS、macOS 或 watchOS)
您可以公开回复顾客评论,但在您的 App Store 产品页上每条评论仅会显示一条回复.您可以回复评论.编辑回复,以及删除回复. 在回复和编辑显示在 App Store 上之前(可能需要至多 24 小 ...
- [App Store Connect帮助]八、维护您的 App(4.1)监控顾客评论:评分与评论概述
App Store 上的评分与评论 顾客可以按照 1 星至 5 星的级别对您的 App 进行评分.顾客还可为您的 iOS 和 macOS App 撰写评论,但无法为 Apple TVOS App 撰写 ...
- [App Store Connect帮助]七、在 App Store 上发行(4)分阶段发布某个版本更新(iOS 和 watchOS)
当您发布您 App 的一个版本更新时,您可以选择分阶段发布您的 iOS App.如果您正在提交一个 iOS 版本更新,且您的 App 处于以下 App 状态之一,则此选项可用. 准备提交 正在等待审核 ...
- [App Store Connect帮助]七、在 App Store 上发行(2.5)设定价格与销售范围:向企业或教育机构分发您的 App
您可以向您添加至 App Store Connect 以及参与“Apple 商务”或“校园教务管理”的用户.企业或教育机构单独分发您的非公开 App.此选项仅在您的 App 尚未获得批准时可用. 有关 ...
- [App Store Connect帮助]七、在 App Store 上发行(2.2)设定价格与销售范围:将您的 App 以预订形式发布
在首次将您的 App 发布至 App Store 前,您可以选择以预订形式提供该 App.在您的 App 发布以供下载之前,顾客可以查看您的产品页并订购您的 App.您的 App 一旦发布,顾客将会收 ...
随机推荐
- vue3自定义Hooks
比较简单的小demo,直接上代码吧 ts使用defineComponent,setup()里面使用 Composition API 写法,逻辑块清晰,不用前后文查找,拒绝 spaghetti code ...
- setting.json 20210825 更新
vue代码格式化思路 { "pasteImage.path": "${currentFileNameWithoutExt}_Images/", "up ...
- canvas-screenshot 视频截屏功能,选择视频的一个区域,进行截图
预览地址:http://pengchenggang.gitee.io/canvas-screenshot/ 参考资料:https://www.canvasapi.cn/ <!DOCTYPE ht ...
- pyecharts + Django你不知道这个架构有多美
pyecharts + Django你不知道这个架构有多美 何为echarts? pyecharts 是一个用于生成 Echarts 图表的类库.Echarts 是百度开源的一个数据可视化 JS ...
- Spring Boot自动运行之 CommandLineRunner、ApplicationRunner和@PostConstruct
在使用Spring Boot开发的工作中,我们经常会需要遇到一种功能需求,比如在服务启动时候,去加载一些配置,去请求一下其他服务的接口.Spring Boot给我们提供了三种常用的实现方法: 第一种是 ...
- python面向对象编程(封装、隐藏)
一 封装 1.封装介绍封装是面向对象三大特性最核心的一个特性封装<----->整合2.将封装的属性进行隐藏操作1).如何隐藏:在属性名前加__前缀,就会实现一个对外隐藏属性效果该隐藏需要注 ...
- 说说Vue 3.0中Treeshaking特性?举例说明一下?
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 一.是什么 Tree shaking 是一种通过清除多余代码方式来优化项目打包体积的技术,专业术语叫 Dead code eliminat ...
- 神经网络——基于sklearn的参数介绍及应用
一.MLPClassifier&MLPRegressor参数和方法 参数说明(分类和回归参数一致): hidden_layer_sizes :例如hidden_layer_sizes=(50, ...
- CYarp:力压frp的C#高性能http内网反代中间件
我以前开发过HttpMouse的http内网反代中间件,但由于当时的知识点与设计水平受限,所以把它下马了.随着自身又遇到http内网反代的需求,在frp不能满足我需求情况下,我又启动了一个叫CYarp ...
- KingbaseESV8R6普通用户无权限执行vacuum
背景 数据库日志有如下提示: WARNING: skipping "pivot_t1" --- only table or database owner can vacuum it ...