WordPress
Swift
swift4
Xcode9

【Swift】WordPressへ記事を投稿する機能を作る

はじめに

本記事ではWordPress REST APIを用いた記事の投稿機能をSwift4で実装したいと思います。
中々検索しても日本語でまとまった記事がなかったので、自分で書く事にしました。
一応解説していますが、僕への忘備録の意味合いが強いので悪しからず。
(解説としては雑かもしれません・・・)
とりあえず、Xcodeで何かプロジェクトを作っておいてください。

対象とする読者

  • swiftおよびXcodeの入門レベルの知識は一通り知っている人
  • WordPressをすでにインストール済みの人
  • REST APIおよびJSONについてある程度知っている人

開発環境

  • Mac OS High Sierra
  • Swift 4
  • Xcode 9

Alamofireのインストール

今回のHTTP通信にはAlamofireというライブラリを使います。これを使った方がコードの見た目もスマートになります。GitHubに使い方も乗っていますが、色々な人がAlamofireに関する使用例を書いていますので困った時には検索しましょう!!

https://github.com/Alamofire/Alamofire

例えば以下の記事はAlamofireを用いてAPIを叩いてみたというものです。
【Swift4】Alamofire を使ってAPIを呼び出してみた

CocoaPodsのインストール

Alamofireをインストールする方法はいくつかありますが、今回はCocoaPodsでインストールします。
CocoaPodsの詳しいインストール方法や使い方は次の記事を参考にしてください。

【Swift】CocoaPods導入手順

基本的にはターミナルを開き、

sudo gem install cocoapods

でインストールし、

pod setup

で設定完了です。

Alamofireのインストール

ここで、もしXcodeでプロジェクトを開いていたら、一旦終了させます。
そしてターミナルを開いてプロジェクトのフォルダまで移動し、以下のコマンドを実行します。

pod init

これを実行するとフォルダの中にPodfileというファイルが作成されます。
その中身をエディタで開くと、

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'あなたのアプリの名前' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for あなたのアプリの名前
end

という内容になっているかと思います。今回はAlamofireを導入したいので、

# Pods for あなたのアプリの名前

の下に

pod 'Alamofire'

という文を追加して保存します。そしてターミナル上で次のコマンドを実行します。

pod install

これでAlamofireのインストールは完了です。

注意点

この時点でプロジェクトフォルダには、.xcodeprojのアイコンを白くしたような「.xcworkspace」というものが作られています。今後はそれをXcodeで開いて作業する事になります。

importした時のエラーについて

さて、インストールしたAlamofireですが、最初にimportすると「そんなものはない」とXcodeに怒られるかと思います。
これは無視して大丈夫です。黙らせるには一回コンパイルしてください。

Application Passwordsプラグインのインストール

次はWordPressのプラグインであるApplication Passwordsのインストールです。

インストール

これはWordPressで記事を投稿する際に必要となる認証(Authentication)のためのプラグインです。
ログイン時のパスワードとは別のものです。
これについては以下のサイトを参考にしました。

WP REST APIを利用して、外部(IoTデバイス)からWordPressに投稿する

WordPressの管理画面からプラグインの新規追加へ行き、Application Passwordsを検索してインストール、有効化します。

パスワードの発行

有効化したらパスワードを発行しましょう。

管理画面のユーザーから「あなたのプロフィール」へ飛びます(ユーザーが複数ある場合はどれかひとつをクリックします。)
すると下の方にApplication Passwords の欄がありますので、そこにある入力欄に何か適当に入力します。
もちろん、自分が見て何のパスワードか分かるように入力してくださいね。

ApplicationPasswords.png

ちなみに僕はアプリの名前を入れました。
入力したらAdd Newボタンをクリックします。すると画面に認証パスワードが表示されるので、必ずどこかにコピペするなりして保存してください。
「非表示にする」ボタンを押すと二度と表示できません。

実装

ここまでで準備は完了です。ようやく実装に移ります。
今回はためしに以下のような記事を投稿してみましょう。

  • タイトル:Hello from Swift
  • 本文:これはiOSアプリから投稿された記事です。

とりあえず、テンプレートとなるソースコードをまるごとのっけちゃいます。

ViewController.swift
import UIKit
import Alamofire

class ViewController: UIViewController {

    let url = "あなたのサイトのURL"

    let password = "Application Passwordsプラグインで発行した認証パスワード"
    let user = "ユーザー名"

    let titleString = "Hello from Swift"
    let contentString = "これはiOSアプリから投稿された記事です。"

    var parameters: Parameters = [:]
    var headers: HTTPHeaders = ["Content-Type": "application/json"]

    override func viewDidLoad() {
        super.viewDidLoad()
        parameters = ["title": titleString, "content": contentString, "status": "publish"]

        if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
            headers[authorizationHeader.key] = authorizationHeader.value
        }

        Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
            .responseJSON { response in
                if let result = response.result.value as? [String: Any] {
                    print(result)
                }
            }
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

}

アプリである意味が全くないような実装ですが、とりあえずこれで投稿できるはずです。

今回はparametersという辞書には3つの要素しか書きませんでしたが、WordPress REST APIの公式ドキュメントには色々なパラメータが書いてあります。
必要に応じて加えてください。

WordPress REST API Handbook

なぜかわからない事

以下は個人的な話となりますが、今回最も躓いたポイントはAlamofireを用いた認証でした。
掲載したソースコードの中の

if let authorizationHeader = Request.authorizationHeader(user: user, password: password) {
            headers[authorizationHeader.key] = authorizationHeader.value
        }

という部分ですが、本来はこれを書かずとも簡潔に書く方法があります。それは

Alamofire.request(url, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers)
            .responseJSON { response in
                if let result = response.result.value as? [String: Any] {
                    print(result)
                }
        }.authenticate(user: user, password: password)

というようにauthenticateというメンバ関数を使うものです。
しかしこれを使うと何故か認証が通らず、結局headersに認証に関する情報を付け加えるという方法に落ち着きました。
実際Alamofireのauthenticateは多くの場合は使えるが、使えない時もあるらしいです。
WordPressで使えないのは果たして僕だけなのか、それともみんなそうなのか、是非ためしたら僕に知らせてください。

ありがとうございました。