Apollo iOSとGithub APIでContributionを表示するWidget
GithubのContributionを表示するiOSのWidgetを作った。
今日のコミット数のみ表示。
今日のコミット数を表示するWidget
Xcodeプロジェクトの作成
Xcodeで新規プロジェクト作成>SwiftUI
プロジェクト作成後、File>New>TargetからWdiget Extensionを追加
Github APIのトークン生成
https://github.com/settings/tokensでトークン生成
Apolloのインストール
公式ドキュメントに従ってセットアップ
1. ApolloのInstall
SPM with Xcode Projectでインストール
WidgetExtensionの設定のFrameworks and LibrarieでApolloを追加しないとimportでエラーとなったので追加。
2. Github APIのSchemaをダウンロード
ApolloとGraphqlをインストール
yarn add global apollo graphql
GithubAPIのSchemaをダウンロード
apollo schema:download --endpoint="https://api.github.com/graphql" --header "Authorization: Bearer {TOKEN}"
schema.jsonが作成される。
.graphql
ファイルの作成
3. 取得したいデータのクエリを作成。
この記事を参考に作成しました。
GithubのContributionを取得するクエリを.graphql
ファイルとして作成。
次のStepでこのクエリを元にコード生成するためqueryの後にクエリ名を指定する必要があります。
query ContributionCount {
user(login: "username"){
contributionsCollection {
contributionCalendar {
totalContributions
weeks {
contributionDays {
contributionCount
date
}
}
}
}
}
}
4. code generationの設定
コード生成用の設定ファイルの作成。
チュートリアル通りにProject>Install CLIでapollo-ios-cli
が生成されます。
以下のコマンドで設定ファイルapollo-codegen-config.json
を生成します。
/apollo-ios-cli init --schema-name {SCHEMA_NAME} --module-type embeddedInTarget --target-name {TARGET_NAME}
schemaSearchPaths
を変更。
"schemaSearchPaths" : [
"./schema.json"
]
3で作成したクエリからAPIアクセス用のコードを生成します。
./apollo-ios-cli generate
--schema-name
で指定した名前のディレクトリが作成されます。
このディレクトリをXcodeのTarget(WidgetExtension)に追加
Copy items if needed
とCreate groups
が選択されてることを確認。
Apollo Clientの作成
こちらの記事のApolloClientの実装をお借りしました。
データ取得
データ取得する関数とクラス作成。
func fetchGithubContribution(completion: @escaping (Int?) -> Void) {
let apollo = GraphQLClient.shared.apollo
apollo.fetch(query: GithubAPISchema.ContributionCountQuery()) { result in
guard let data = try? result.get().data else {
completion(nil)
return
}
let contributionCount = data.user?.contributionsCollection.contributionCalendar.weeks.last?.contributionDays.last?.contributionCount
completion(contributionCount)
}
}
WidgetのProviderのgetTimelineを編集
widgetの更新間隔は最低でも15分開ける必要があるとのこと。
func getTimeline(for configuration: ConfigurationIntent, in context: Context, completion: @escaping (Timeline<Entry>) -> ()) {
let currentDate = Date()
let futureDate = Calendar.current.date(byAdding: .minute, value: 15, to: currentDate)!
contribution().fetchGithubContribution { contributionCount in
var entry = SimpleEntry(date: futureDate, contribution: 0, configuration: configuration)
if let count = contributionCount {
entry = SimpleEntry(date: futureDate, contribution: count, configuration: configuration)
}
let timeline = Timeline(entries: [entry], policy: .after(futureDate))
completion(timeline)
}
}
WigetのViewを編集。
struct contributionWidgetEntryView : View {
var entry: Provider.Entry
var body: some View {
ZStack {
Color.black
VStack {
VStack(alignment: .center){
Text("Contribution")
}
.foregroundColor(Color.white)
.font(Font.system(size: 12).bold())
Text(String(entry.contribution))
.foregroundColor(Color.white)
.font(Font.system(size: 40).bold())
}
}
}
}
Widget Extentionのデバッグ
Xcodeで普通にブレークポイントを置くだけではデバッグできず。
エミュレーターで実行後、Debug->Attach to Process-> WidgetExtensionのプロセスを指定することでデバッグすることができた。
Discussion
ではなく,その前に
.
をつける必要がありますね!あと、
--schema-name
から--schema-namespace
になったようなのでになると思います!
ご参考までに!