読者です 読者をやめる 読者になる 読者になる

酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

はてなOAuthがちょっと使いにくいなと思った話

iPhone Swift

はてなOAuthがちょっと使いにくいなと思った話。

iOSではてなフォトライフに写真をアップロードするアプリを作りたいなと考えています。

f:id:ch3cooh393:20160625175246p:plain

はてなOAuthを使うのに最適な方法を考えているのですが思い付きませんでした。実際の最適解がよくわからないのでとりあえず実現だけさせてみました。

はてなOAuthのコールバックについて

サードパーティー製Twitterクライアントなど、よくあるOAuthを使うアプリの場合にはざっと下記のような順序です。

  1. アプリからSafariを起動する(あるいはSFSafariViewControllerを起動する)
  2. サービスにログインする
  3. コールバックでカスタムURLスキーマを叩いて元のアプリに戻ってくる
  4. アプリでログイン後の機能が使えるようになる

僕もこんな感じでログイン画面を作ろうと考えていました。

はてなOAuthも当然ですがコールバックを指定することができます。

2.2. で ユーザーがアクセスを許可した場合ははてなはユーザーを 2.1. の oauth_callback で指定されたURLに oauth_verifier パラメータを付けてリダイレクトします。また URL の代わりに "oob" が指定されていた場合は oauth_verifier の値をユーザーに表示しますので、ユーザーに入力を指示して下さい。

はてなOAuthのコールバックで指定できるものは下記の2つだとわかりました。

  • URL
  • oob

このURLが少しネックでphotouploader://hogeみたいなURLのコールバックを叩いてもらおうと思うもののエラーが発生してしまいました。悶々と悩んだ結果実際に使えるのは下記の2つだとわかりました。

  • http(https) から始まるURL
  • oob

はてなOAuthを作っているひと的には

  • コールバックにoobを指定して、Safariで認証してもらってアプリに戻ってアクセスコードを入力する
  • コールバックにhttp://適当なURL/を指定して、WebView画面で認証後にURLのドメイン部分を監視してフックする

のどちらかを想定しているのかと思いました。おそらく前者かな?

App Storeに並んでいるアプリで、はてなへのログインを促しているものは後者の実装が多いようです。Safariで認証させてからアプリを起動することはできないようです。

はてなのログイン画面を作ってみた

ここでは後者の方法ではてなのログイン画面を作ってみました。かなりざっくりとですがコードを抜粋しました。認証のためにOAuthSwiftを使いました。

static func login(parentViewController: UIViewController, consumerKey: String, consumerSecret: String) -> Future<Credential, NSError> {
    let promise = Promise<Credential, NSError>()
    
    let oauthswift = OAuth1Swift(
        consumerKey:    consumerKey,
        consumerSecret: consumerSecret,
        requestTokenUrl: "https://www.hatena.com/oauth/initiate",
        authorizeUrl:    "https://www.hatena.ne.jp/touch/oauth/authorize",
        accessTokenUrl:  "https://www.hatena.com/oauth/token"
    )
    
    let viewController = UIStoryboard.init(name: "LoginWebView", bundle: nil).instantiateInitialViewController() as! LoginWebViewController
    viewController.previousViewController = parentViewController
    
    oauthswift.authorize_url_handler = viewController
    oauthswift.authorizeWithCallbackURL(
        NSURL(string: "http://photouploader.example.jp/")!,
        success: { credential, response, parameters in
            let c = Credential()
            c.oauth_token = credential.oauth_token
            c.oauth_token_secret = credential.oauth_token_secret
            
            promise.success(c)
        },
        failure: { error in
            promise.failure(HatenaError())
        }
    )
    return promise.future
}

LoginWebViewController(と名付けたWebView画面)でログインしたあとにhttp://適当なURL/に遷移するのを見張るようにしました。

class LoginWebViewController: OAuthWebViewController {
    
    @IBOutlet weak var toolbar: Toolbar!
    @IBOutlet weak var webView: UIWebView!

    var targetURL : NSURL = NSURL()
    var previousViewController: UIViewController?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // もろもろ省略
        loadAddressURL()
    }

    // MARK:-
    
    override func doHandle(url: NSURL) {
        previousViewController?.navigationController?.pushViewController(self, animated: true)
    }
    
    // MARK:-
    
    override func handle(url: NSURL) {
        targetURL = url
        super.handle(url)
        
        loadAddressURL()
    }
}
extension LoginWebViewController: UIWebViewDelegate {
    func webView(webView: UIWebView, shouldStartLoadWithRequest request: NSURLRequest, navigationType: UIWebViewNavigationType) -> Bool {
        print("\(request.URL)")
        if let url = request.URL where (url.host == "photouploader.example.jp"){
            OAuthSwift.handleOpenURL(url)
            self.dismissWebViewController()
            return false
        }
        return true
    }
}

これでログインするところまではいけると思います。

一番最初に書いた通りはてなOAuthを使ったログイン画面の最適解について悶々と考えた結果、アプリ本体に手をつける前に投げ出してしまいました。気が向いたらまた着手します。

PCエンジン版ボンバーマン 94'を駿河屋で買いました

ガジェット

先日駿河屋でぷよぷよを買いました。ぷよぷよよりもシレンで遊んでる時間の方が長いかもしれないです。

ほとんどシレンのツボ・杖分別方法を忘れていて攻略サイトを見ながら進めています。2回目のチャレンジで装備とアイテムが揃っていたので、23階で延々とレベル上げしていたところ突風に吹かれて最初の村まで戻されて絶望しました。

ゲームギア向けぷよぷよも合わせて買ってレトロフリーク用ギアコンバーターの発売待ったなしです。

ここ数ヶ月仕事が忙しくてストレス発散するように、昔持っていたけど今は捨てたかなくしてしまったものを買い戻しています。レトロゲーはプレミアムがついていて昔は100円とかで買えたものも結構良い値段になっています。

今回買ったのはPCエンジン版の「ボンバーマン 94'」です。

ボンバーマン94 【PCエンジン】

ボンバーマン94 【PCエンジン】

僕が小学生の頃に南海線春木駅の駅舎*1の裏の小道に古本屋・中古ゲーム屋があって*2、PCエンジンコアグラフィックス本体を交渉して1,300円くらいで売ってもらったんですよね。

なぜかその時はPCエンジン本体と一緒に買ったのが「ドラゴンスピリット」と「邪聖剣ネクロマンサー」の2本。しかし、小学生の僕にはどちらも難易度の高いゲームで投げ出していたのを見かねたのか、うちの母親が日本橋のソフマップで買ってきてくれたゲームが「ボンバーマン 94'」です。

今回も駿河屋で買いました。6月14日に購入して6月20日に届きました。結構早かったですね。

*1:和歌山行きの方

*2:のちにこの古本屋は泉大津警察の前に移転するのですが……

スプラトゥーンのウデマエがようやくS+になりました!

Splatoon

11月から始めてはや8ヶ月。ウデマエがS+になりました!

嫁の友達2人が嫁のために買ってくれたWii U & Splatoonでしたが、なぜか僕の方がやりこんでしまいました。嫁はまだCです。

スプラシューターコラボをメインで使って、ここに来るまでに使っていたスシコラ・オクタももうすぐカンストしてしまいそうです。

S+カンストはまず無理だろうから次は別のブキでも使えるようにしますかね。