📑

iOSアプリからQiitaに投稿してみる

2022/12/29に公開約4,300字

はじめに

HTTP通信のGETに関しては、よく使用するのですが、POSTはあまり触ったことがなかったので、QitiaAPIで練習してみました。

(UIの実装は省略します。)

実装する

アクセストークンの発行

ヘッダーのアイコン > 設定

アプリケーションを選択

新しいトークンを発行するをクリック

スコープを設定して、発行するをクリック
(今回は書き込みしか行わないので、write_qiitaにだけチェックを入れます。)

コーディング

structの用意

公式ドキュメント
POSTするJSONに合わせて、リクエスト用の構造体を作成します。

struct PostArticleJSON: Encodable {
    var body: String
    var `private`: Bool
    var tags: [Tag]
    var title: String
    var tweet: Bool

    struct Tag: Encodable {
        var name: String
        var versions: [String]
    }
}

enum QiitaAPIError: Error, LocalizedError {
    case urlError
    case someError

    var errorDescription: String {
        switch self {
        case .urlError:
            return "URLが無効"
        case .someError:
            return "エラーが発生"
        }
    }
}

coediting, group_url_nameはQiita Teamでのみ有効のようなので、今回は省略しました。

リクエストの作成

class QiitaAPI {
    private let baseURL = "https://qiita.com/api/v2"

    static func postArticle() async throws {
        guard let url = URL(string: baseURL + "/items") else {
            throw QiitaAPIError.urlError
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer {最初に作成したトークンをセット}", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let article = PostArticleJSON(
            body: "# テスト",
            private: true,
            tags: [
                .init(name: "swift", versions: ["0.0.1"]),
            ],
            title: "タイトル",
            tweet: false
        )
        let httpBody = try! JSONEncoder().encode(article)
        request.httpBody = httpBody
    }
}

リクエスト生成は、下記を参考にしました。

通信処理の追加

class QiitaAPI {
    static let baseURL = "https://qiita.com/api/v2"

    static func postArticle() async throws {
        guard let url = URL(string: baseURL + "/items") else {
            throw QiitaAPIError.urlError
        }

        var request = URLRequest(url: url)
        request.httpMethod = "POST"
        request.setValue("Bearer {最初に作成したトークンをセット}", forHTTPHeaderField: "Authorization")
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")

        let article = PostArticleJSON(
            body: "# テスト",
            private: true, // ← 限定公開にしておく
            tags: [
                .init(name: "swift", versions: ["0.0.1"]),
            ],
            title: "タイトル",
            tweet: false
        )
        let httpBody = try! JSONEncoder().encode(article)
        request.httpBody = httpBody

        // 追加↓↓
        do {
            let (_, response) = try await URLSession.shared.data(for: request)
            guard let httpResponse = response as? HTTPURLResponse else {
                throw QiitaAPIError.someError
            }
            let statusCode = httpResponse.statusCode

            if statusCode != 201 {
                throw QiitaAPIError.someError
            }
        } catch {
            throw QiitaAPIError.someError
        }
    }
}

エラーレスポンスをデコードしたい場合は下記のstructが使用できます。

struct QiitaAPIErrorJSON: Decodable {
    var type: String
    var message: String
}

実行!

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        Task {
            do {
                try await QiitaAPI.postArticle()
            } catch {
                print("エラー")
            }
        }
    }
}

結果

無事に限定公開で投稿することができました🎉

GitHubで編集を提案

Discussion

ログインするとコメントできます