Новый App Store Connect API, который был анонсирован на WWDC 2018, наконец позволил писать приложения для App Store Connect. Вы можете использовать этот API для получения метаданных приложений, TestFlight-сборок, загрузки отчетов о продажах и многого другого. Apple добавляла новые конечные точки на протяжении всех этих лет, и недавний релиз версии 2.0 не стал исключением, добавив конечные точки для отзывов клиентов и многого другого.
App Store Connect API соответствует спецификациям OpenAPI и поставляется с обширной документацией, которую предоставляет сама Apple. Спецификации OpenAPI, которые внедрила Apple, дала мне возможность реализовать работу с API в рамках App Store Connect Swift SDK во время написании Swift-приложений. Давайте же разберемся, как мы можем создавать свои инструменты разработчика с помощью этого API в Swift.
С чего следует начать
Прежде чем углубляться в примеры кода и идеи, лежащие в основе API, вам не мешало бы посмотреть соответствующие сегменты WWDC.
Доклад Automating App Store Connect с WWDC 2018 — отличная отправная точка. Если еще добавить официальную документацию Apple, то этого будет достаточно, чтобы начать работу с API.
Новые конечные точки API обычно анонсируют во время обсуждения “Что нового в App Store Connect?” в рамках WWDC, поэтому, если вас интересуют другие доклады по этой теме, вы можете посмотреть выступления с WWDC 2022, WWDC 2020, WWDC 2019 и WWDC 2018. Особое внимание следует уделить докладу Automating App Store Connect, подробно разбирающему само API.
Аутентификация в App Store Connect API
Авторизация в API происходит через веб-токены JSON (JWT) и требует персонального API-ключа из учетной записи App Store Connect вашей организации для создания токенов на предъявителя (bearer tokens).
Запрос API-ключа App Store Connect
Прежде чем вы сможете начать использовать API, вам нужно сгенерировать ключ внутри App Store Connect. Вы можете создать ключ на вкладке “Users and Access”:
Генерация ключей для аутентификации в App Store Connect API
JWT-токен требует от вас ряда параметров:
Issuer ID
Идентифицирует издателя, создавшего токен аутентификации, и является одинаковым для всех ключей в рамка одной организации.
Key ID
Идентификатор ключа является необязательным для веб-токенов JSON. Он может понадобиться, когда у вас есть несколько ключей для подписи токенов, и вам нужно найти правильный, чтобы проверить подпись.
Private Key
Приватный ключ связан с идентификатором ключа и используется для аутентификации вас в App Store Connect API.
Подробнее об аутентифицированных запросах можно прочитать в официальной документации, но лично я считаю, что вам не нужно писать эту логику самостоятельно. Вместо этого вы можете использовать мой App Store Connect Swift SDK.
Использование App Store Connect API в Swift
Вы можете работать с App Store Connect API в Swift с помощью опенсорсного пакета App Store Connect Swift SDK. Этот SDK реализует спецификации OpenAPI и уже содержит последние конечные точки, анонсированные в рамках WWDC 2022.
Вы можете интегрировать этот пакет с помощью пакетного менеджера Swift:
dependencies: [
.package(url: "https://github.com/AvdLee/appstoreconnect-swift-sdk.git", .upToNextMajor(from: "2.0.0"))
]
Или же вы можете использовать тот же URL при добавлении пакета в Xcode.
Конечных точек API, с которыми вы можете работать, достаточно много, но в этом примере мы будем формировать простой список приложений и их Bundle Identifier:
Пример SwiftUI-приложения, использующего App Store Connect API для формирования списка приложений.
Вы также можете найти этот пример в моем репозитории, если вам не терпится самим разобраться в коде.
Начнем мы с создания новой view model, которая возьмет на себя создание провайдера API и выполнение запросов API:
final class AppsListViewModel: ObservableObject {
@Published var apps: [AppStoreConnect_Swift_SDK.App] = []
/// Перейдите на https://appstoreconnect.apple.com/access/api и создайте собственный ключ. Это также страница для поиска идентификатора приватного ключа и идентификатора издателя (issuer ID)
/// Загрузите приватный ключ и откройте его в текстовом редакторе. Удалите знаки табуляции (enters) и скопируйте содержимое в параметр приватного ключа.
func loadApps() {
Task.detached {
let request = APIEndpoint
.v1
.apps
.get(parameters: .init(
sort: [.bundleID],
fieldsApps: [.appInfos, .name, .bundleID],
limit: 5
))
do {
let apps = try await self.provider.request(request).data
await self.updateApps(to: apps)
} catch {
print("Something went wrong fetching the apps: \(error)")
}
}
}
@MainActor
private func updateApps(to apps: [AppStoreConnect_Swift_SDK.App]) {
self.apps = apps
}
}
SDK использует async/await и @MainActor-атрибуты, доступные в Concurrency Framework. Чтобы этот код работал должным образом, вам нужно будет добавить ваши ключи в инициализатор APIConfiguration.
Прежде чем создавать view, давайте углубимся в определенный APIEndpoint для получения списка приложений:
let request = APIEndpoint
.v1
.apps
.get(parameters: .init(
sort: [.bundleID],
fieldsApps: [.appInfos, .name, .bundleID],
limit: 5
))
Вы можете создать APIEndpoint, следуя официальной документации. Пространство имен v1 требуется для определения версии API, которую вы хотите использовать, поскольку некоторые конечные точки стали доступны, начиная с версии 2.0.
Каждая конечная точка определяет набор методов, которые вы можете выполнять на основе поддерживаемых REST-методов. Сущности и пути будут сгенерированны опенсорсным фреймворком CreateAPI.
У вас есть возможность определять свойства, сортировку и ограничения, которые вы хотите применить для каждой конкретной конечной точки, что дает вам возможность возвращать только те данные, которые вам нужны.
Подключение данных к SwiftUI View
Теперь, когда у нас есть список приложений, который мы можем отобразить, пора приступать к созданию пользовательского интерфейса. Для того, чтобы отобразить имя приложения и соответствующий ему Bundle Identifier, мы создадим простой список и проитерируем по набору наших приложений:
struct AppsListView: View {
@ObservedObject var viewModel = AppsListViewModel()
var body: some View {
NavigationView {
ZStack {
List(viewModel.apps, id: \.id) { app in
VStack(alignment: .leading) {
Text(app.attributes?.name ?? "Unknown name")
.font(.headline)
Text(app.attributes?.bundleID ?? "Unknown bundle ID")
.font(.subheadline)
}
}
ProgressView()
.opacity(viewModel.apps.isEmpty ? 1.0 : 0.0)
}.navigationTitle("List of Apps")
}.onAppear {
viewModel.loadApps()
}
}
}
Что я могу сделать с помощью этого API?
App Store Connect API содержит множество конечных точек, с которыми вы можете работать, так что ваши возможности практически безграничны! Чтобы простимулировать вашу фантазию, ниже я приведу список инструментов разработчика, которые вы можете создать:
Приложение для просмотра отзывов клиентов и ответа на них.
Управление пользователями TestFlight.
Создание инструмента для быстрой загрузки отчетов о продажах.
Взаимодействие с рабочими процессами и сборками Xcode Cloud.
У вас могут быть свои идеи по разработке приложений с использованием этого API. Дайте мне знать, если вы разместили свое решение в открытом доступе — я буду рад разместить его здесь.
Могу ли я отправить приложение в App Store с помощью этого API?
Да, еще как! Однако вам придется позволить пользователям создавать свои ключи для своих организаций. Невозможно разрешить пользователям входить в систему и генерировать ключи автоматически. Тем не менее, это не должно останавливать вас от создания инструмента разработчика, от которого мы все можем получить пользу!
Заключение
App Store Connect API — это большой набор конечных точек API, позволяющих получить доступ к данными App Store Connect. Вы можете создать инструменты разработчика для своих команд внутри компании или развернуть приложение в App Store, которым сможет пользоваться любой желающий. Используя App Store Connect Swift SDK, вы можете включиться в работу всего за несколько минут!
Если вы хотите углубить свои познания в Swift, посетите страницу, посвященную Swift. Не стесняйтесь обращаться ко мне или писать мне в Твиттере, если у вас есть какие-либо советы или отзывы.
Спасибо за внимание!
Всех желающих приглашаем на открытое занятие «Flux в SwiftUI, самая эффективная архитектура на 2022 год?», на котором обсудим:
1. Очевидные проблемы MVVM при создании iOS приложений на SwiftUI;
2. Возможные расширения MVVM с помощью SOA и Coordinator паттернов;
3. Почему большинство приложений на SwiftUI пишется на архитектурной концепции Flux.
Регистрируйтесь по ссылке.