try! Swift行った

try! Swift

ブログを書くまでがtry! Swift

try! Swiftはずっと同じ部屋に居るので、隣の人と話したり、Twitterでフォローしてる人とこんにちはしたり弁当食べたりしやすくて楽しかった。

人に話しかけるのが得意じゃないので、Twitterでフォローしてる人に挨拶することを目標にしてて達成できたので良かった。

海外の方との英語交流は、僕の拙い英語でも(たぶん)伝わってたけど、相手が言ってることを8割以上理解できないという感じで、難しかったけど、思ってたより会話が成り立ったので良かった。

パーティーでスピーカーの方と話す機会があったんだけど、一日目の人で恥ずかしながら何を話してた人か思い出せなくて、そこらへんの話を出来なかったのが残念だった。三日間、内容の濃いトークが続くので、難しいやつはリアルタイムで理解しようとするのは諦めて後日動画を見たり、懇親会の前にトークの内容復習したりするのが良いのかなと思った。

try! Swift 2016 カテゴリーの記事一覧 - niwatakoのはてなブログ

↑これ書いた人がすごくて、トークが終わったら即文字起こし出しててすごかった。こういうもので復習したり出来る。

2週間?1週間?くらいで全トークの動画とスライドが公開されるらしいので、PokemonSwiftに興味がある人は見ましょう。

僕は2年位まともにiOS開発していなくて、Swift2出たくらいにSwift学習し始めて最近趣味の時間でiOSアプリ開発始めたくらいなので、やっていくぞという気持ちが高まった。

try! Swift良いイベントでした。ありがとうございました。

NatashaTheRobot/trySwiftApp眺めた

github.com

try! Swift行くので読んだ。

読んだ理由としては、業務でiOSアプリ作らなくなってから大分経ってて、自分でアプリ作り始めてはAuto Layout難しい……となって投げ、最近やっとAuto Layout分かってきてちまちまとアプリ作りつつある程度の状態でtry! Swift行くのもアレだなと思っていて、アプリのコードがgithubで公開されているのでせっかくだし〜ということで読んだ。

そんな感じなので役に立つこと書いてないと思う。

メモりながら読んでたので、ブログタイトル通りメモとして公開するかという感じ。

全体的に

普通のアプリを適切に作っているという感じで勉強になった。アプリ自体がシンプルなのでコード量も少なくて読みやすかった。

画面

全体的にTableViewで作ってある。

何かを一覧する画面じゃなくても、表示するコンテンツのサイズが変わるから、Cellを幾つか組み合わせてスクロール可能なUI作ってる。

表示するコンテンツのサイズが変わらなくても、多画面対応とか、途中でデザイン変更されるとかもあるから、大体の画面をTableViewで作っちゃっても良いのかなと思った。適切にView(Cell)を分けてれば他の画面でも使えるパーツ作れるし。

スケジュールみたいにPagerTabがある画面は、scrollViewを置いてPagerTabStripViewControllercontainerViewっていうoutletをつないでいた。buttonBarViewはViewControllerのコード上で設定している。

全てStoryBoardでやってるのかと思ったけどWebDisplayViewControllerはxib使ってた。 色んな文脈で使えるようなのはxibみたいな使い分けなのかもしれない

画面遷移

画面遷移にはsegue使ったり使わなかったりしてて、使い分けがよく分からなかった。

trySwiftApp/SessionsTableViewController.swift at master · NatashaTheRobot/trySwiftApp · GitHub 画面遷移にsegueを使ってない

遷移先の画面に渡す情報があるならこの方法の方がシンプルでいいのかなって思ったけどtrySwiftApp/SpeakersViewController.swift at 379ef41a331e230a2a4994a103a30cc4d978457a · NatashaTheRobot/trySwiftApp · GitHubでは同じ人が書いたコードでsegue使ってるし良く分からん。

CellReuseIdentifierなど

trySwiftApp/SessionsTableViewController.swift at 379ef41a331e230a2a4994a103a30cc4d978457a · NatashaTheRobot/trySwiftApp · GitHub

String(TableViewCell)"TableViewCell"というStringを得られるの知らなかった。

nibNameとReuseIdentifierを同じにして、Cellのクラス内にlet identifier = "TableViewCell"とかやってたんだけど、この方法良い。

ViewController

ViewControllerにoverride以外のちょっとしたメソッドを生やしたい場合はprivate extensionを使っている。デリゲートメソッドも同じで、ごちゃごちゃしなくて良い。

表示するデータ

Modelsの中のクラスに一通りベタ書きしてある。 こういうデータはDBなどを使うものっていう思い込みがあったので、見ると結構ビビる。

アプリの要件として「オフラインでも使えるようにする」みたいなのがなければ、次回以降はSwiftで書かれたAPIから情報取得するようになったりするのかな。って思ったけど開発コスト高まるから無さそう。

CIなど

テスト無いしCI回してないしふむふむ〜って感じだったけど、長期運用するようなものでも無いしテスト書くコストとアプリの要件考えると必要性低いのかなるほど〜と思った。

lintくらいはやってもいいのではーとも思った、lintの設定で揉めたりしそうだし、良識あるエンジニア数人でこの規模のアプリなら問題になることも少なそう。

次回以降のために〜とかも思ったけど、次回開催の頃にはiOSとかSwiftとか要件とか色々変わってて、1から作ったほうが良さそうという感じでCI要らんなという感じ。

絵文字

if #available(iOS 9.2, *)で表示する絵文字を分けてるんだけど、理由がよく分からなかった🤗


そんな感じでtry! Swiftの受付が朝早くて、最近11時とかに起きてるので頑張りたいと思う。

「Swiftでコマンドラインツールを作る」という文章をQiitaに投稿した

qiita.com

自分だったら後でストックしたい気がするなみたいなやつを最近Qiitaに投稿してるんだけど、そうするとブログが自炊とゴキブリを食っただけみたいになるので、Qiitaに書いたらブログで書いたというようなことを書こうという気持ちになったので書いた。

僕が考えた最強のAPIドキュメント生成

2023 追記

2023 年現在では、以下の文章では採用を見送っている OpenAPI を使えば OK という雰囲気です。

TL; DR

使ってるツールとかだいたいRuby製だけど、最終的にjsonに吐き出したりしてるから他の言語のWAFでも使える気がする。

背景

  • 以下を実施したプロジェクトの都合上、APIの実装でクライアントアプリの開発を止められない
    • プロジェクト開始からクライアントアプリ開発が本格的に始まるまでの2週間ほどで、全てのAPIエンドポイントの定義と、mockでJSONを返すようにしたかった
  • クライアントアプリ開発が始まる段階で一通りのAPIドキュメントの提供したかった
  • 過去に経験したプロジェクトで正しい情報が載っていないAPIドキュメントに苦しめられた経験があり、なるべくドキュメントと実装の整合性を保てる状態にしたかった
    • 今回はサーバーサイド開発だったが、以前はクライアントアプリ開発メインだったので、そういう問題が起こる諸々の都合を把握したり、解決したりする方法を探りたかった。
      • あとサーバーサイド開発初挑戦で、インフラとか整うまで暇を持て余していた。

他にも色々あったり記憶が歪められてる気もするけど、だいたいはこんなもんだと思う。

技術選定

ドキュメントフォーマット

以上の5つが割りと使われてそうなフォーマットに上がった。

最終的にはRAMLを使うことにしたんだけど、以下が選定理由。

autodoc

rspecからドキュメント生成するやつ。

リクエストパラメタとか諸々テストしつつ、それを元にドキュメント生成出来るので、大分良さそうという感想だったんだけど、実装よりも先にドキュメント用意したいという感じだったので見送った。

次が諸々の不都合が無いRailsプロジェクトでもautodocは使わないで、json_worldとr7kamura/rack-json_schemaでどうにかすると思う。社内の別プロジェクトでScalaやGoが使われているのもあって、特定の言語やWAFに依存しすぎるの良くないという感じ。

JSON Schema

単体のJSON定義するくらいなら出来なくもないけど、記法を覚えるコストが高くて、これで全てを書くのは無しだという感じになった。

users.jsonをuser.jsonとかreference使って書く方法がどう頑張っても分からなくて、gin0606/schaiというgemを作ったりした。 schaiはプロジェクト中盤まで現役で使ってたけど、json_worldに移行して、レスポンスのJSONJSON Schemaをjson_worldで生成するようになった。

なんで最初からjson_worldを使わなかったんだって感じだけど、当時はダメやんって思うことが何かあった気がするんだけど覚えてない。

サーバーがRubyJSON Schema使うならjson_world使おうって感じ。

API Blueprint

Markdown書いてAPIドキュメントとMockサーバー建てられるやつ。

記憶が曖昧なんだけど、JSONJSON Schemaを記載できる。

Apiary — Homeというサービスがあって、githubにドキュメント置いて、それからドキュメントとかMockサーバーとか作ってくれる。

Apiaryというサービス(会社)で使ってるし、直近でメンテされなくなる可能性とか低そうって思って、最初はAPI Blueprint導入してた。

Mockサーバー建ててくれるので、やりたいことに合致していて、ドキュメントに記載したJSON Schemaを元にnogates/vigiaとかcybertk/abaoを使ってドキュメントをJSON Schemaとの検証含めてテスト出来るかと思ったんだけど、出来なかったし、そんな書きやすくもなかったからやめた。

RAML

最終的に落ち着いたやつ。

http://raml.org/ 見れば分かるけどyaml書いてくやつ。

チャットワークAPIドキュメントで使われてる。

API Blueprintに比べて、APIのエンドポイントをyamlでツリーみたいに書いていけるので、だいぶ良かった。

説明とかが長いAPIあると、その下のエンドポイント書きづらいという問題もあるんだけど、ファイルを分けて書けたはずなので、そんな大きな問題にならないはず。

API Blueprintを止めた時点で、ドキュメントをそのまま使ってAPIとドキュメントの整合性を保とうという甘い考えを捨てて、レスポンスの整合性はrspecjson schema使って検証しようという感じになった。 ドキュメントをそのまま使ってAPIとドキュメントの整合性保てないなら、API BlueprintよりもRAMLのほうが断然書きやすいので、最終的にRAMLを使うことになった。

Swagger

なんか巨大すぎるしジャバやんみたいな雑な理由で全然調べずに止めた気がする。

雑すぎるので次API開発する機会あったらちゃんと調べたい。

ドキュメント生成

生成と言っても、RAMLなので結局手書きでAPIのドキュメントを書いてくことになる。

↓こんな感じのYAMLを書いていく。

schemas:
  - User: !include schemata/user.json

traits:
  - client_credentials:
      usage: Client Credentials Grantでアクセス可能なAPIに指定する
      headers:
        Authorization:
          description: OAuth 2.0 アクセストークン [Client Credentials Grant](http://openid-foundation-japan.github.io/rfc6749.ja.html#grant-client)
          type: string
          required: true
          example: "Bearer ACCESS_TOKEN"

  - resource_owner_password_credentials:
      usage: Resource Owner Password Credentials Grantでアクセス可能なAPIに指定する
      headers:
        Authorization:
          description: OAuth 2.0 アクセストークン [Resource Owner Password Credentials Grant](http://openid-foundation-japan.github.io/rfc6749.ja.html#grant-password)
          type: string
          required: true
          example: "Bearer ACCESS_TOKEN"

/users:
  displayName: ユーザー関連API
  post:
    is: [client_credentials]
    description: ユーザー登録
    body:
      application/x-www-form-urlencoded:
        formParameters:
          user[screen_name]:
            description: アカウント名(重複付加)
            required: true
            type: string
            example: yamada
          user[password]:
            description: パスワード
            required: true
            type: string
          user[password_confirmation]:
            description: パスワード確認
            required: true
            type: string
    responses:
      201:
        body:
          application/json:
            schema: User
            example: !include screiji/user.json
  /{user_id}:
    uriParameters:
      user_id:
        type: integer
    get:
      is: [client_credentials]
      description: ユーザー情報取得
      responses:
        200:
          body:
            application/json:
              schema: User
              example: !include screiji/user.json
    patch:
      is: [resource_owner_password_credentials]
      description: ユーザー情報更新
      body:
        application/x-www-form-urlencoded:
          formParameters:
            user[screen_name]:
              description: アカウント名(重複付加)
              required: false
              type: string
              example: yamada
      responses:
        200:
          body:
            application/json:
              schema: User
              example: !include screiji/user.json
    delete:
      is: [resource_owner_password_credentials]
      description: ユーザー削除
      responses:
        204:

schema: Userとかexample: !include screiji/user.jsonも手動で生成していて、app/resources/api/resources以下に存在するjson_worldで書いたクラスのJSON Schemaをファイルに書きだして、screijiでexampleのJSONをファイルに書き出すみたいなことをやった。

やってるrake task https://gist.github.com/gin0606/55bed5902fe820914c5b

更新忘れを防ぐためのテスト書いたりもしたけど、大分ダサい。

ドキュメント閲覧

module Api
  class DocController < ApplicationController
    def doc
      render html: raml2html, content_type: "text/html"
    end

    private
    def raml2html
      `#{Rails.root}/node_modules/raml2html/bin/raml2html -i #{Rails.root}/docs/api.raml`.html_safe
    end
  end
end

こんなようなことをしてる。

色々と手動でやっててダサいので、asset pipelineでerbなどでRAMLの元になるやつ書いて、その中でJSON Schema埋め込んで、HTML生成して描写するみたいなこと出来ればよかったんだけど、gemが無い&asset pipeline全く分からんという感じで諦めた。


そんな感じで、TL; DRに全て書いてあるから他に特に書くことに気付き、JSON Schemaで全て済ませましょうねって感じ。

社内の別プロジェクトではScalaやGoが使われているので、言語やFrameworkが変わってもそこら辺のノウハウが使えることを考えるとJSON Schemaが良いのかなと思う。

Rails以外だとJSON Schemaを上手いこと生成してくれるツールが有るのか分からないけど、無かったらjson_world使っても良いと思う。簡単なDSLJSON Schema生成出来るし、json吐き出せば各言語にValidatorあると思う。

gin0606/schaiJSON Schemaの面倒くさいの色々と省いて生成してくれる。RAML使って色々やったプロジェクトでやった限りでは使い物になるんだけど、対応してないJSON Schemaのキーワードとかも多いし、Ruby学習の一環で書いたのもあってコードの品質も糞低い。使い物になるようにするなら1から書き直したほうが良さそうという感じ。

gin0606/screijiは、JSON Schemaから雑にJSONの例示を生成してくれるやつで、これは自分で作ったけど普通に便利だと思う。このプロジェクトでもまだ使っているけど、Ruby学習の一環で書いたのもあってコードの品質が低い。

2016/02/16 14:56 追記

Qiita API v2のJSON Schemaを公開しました - Qiita Blog

最近iOSアプリ開発リハビリがてらQiitaTeam見るやつ作ってて、これさっき読んだけど、JSON Schema使う理由とかドキュメント云々とかはこれに書いてあるとおりだと思う。

r7kamuraくんが書いたJSON Schemaとか周辺の文章にも大分影響されている自覚はある。

近況

最近仕事がめちゃくちゃ暇で、色々と考えた結果考えがまとまらず将来に漠然とした不安を抱えつつある。

仕事がめちゃくちゃ暇なのは、色々な事情があり仕事しようと思えば仕事出来るんだけど如何せんやる気が無いのと、リリース済みの動いてるコードは必要が出るまで触りたくないというのと、やる気が無いので結果仕事が無いみたいな感じになってる。

所属しているのはソーシャルゲーム作りま〜っす的な会社なんだけど、前に転職未遂した時にゲーム作りたくないで〜っす的なことを言ったが慰留され、内定出たところの諸々の色々が色々で結果転職しなかったんだけど、ゲーム作る会社でゲーム作りたくないって感じなのでまぁ出来ることというか会社がやらせられることも限られて来るわけで、ここ半年くらいはRoRに初挑戦してスマホアプリのAPIを開発などしてた。

RoR凄くてRailsチュートリアル一通りやったらもう大体一通りの事は大体出来るようになるし、API開発程度なら色々と楽に実装が出来て凄いという感じだったけど、やってて全然楽しくねぇという感じがした。

たぶんサービス作るマンとか、色々と楽に実装して空いた時間で色々良くしてくみたいな感じのアレだとアレなんだろうけど、半年たってもアレをアレすることが出来ていない感じになっている。

API開発で一番興味ある部分がドキュメントの自動生成というかドキュメントと実装の乖離を無くすことで、ここ半年やってたプロジェクトでは色々と試せて良かった。

そこら辺の色々を書いてる途中で大分放置してるのを思い出したので仕事がめちゃくちゃ暇なうちに書いて公開したい。

色々と考えた結果考えがまとまらず将来に漠然とした不安を抱えつつあるんだけど、とりあえずこのままじゃいかんとは思っているが、以前まで働いていた動機が詳細端折るが死なないためという感じだったんだけど、意外と全然生きられてしまって、ゲームやアニメや未完の漫画などが増えてきて最近はなるべく長く行きたいが働きたくないという感じになりつつある。

現状だとiOS開発がやりたいが、現職でiOS開発出来る見込みは殆ど無く、以前はiOS開発しか出来ない状態だったけど今はRailsもまぁ触れるようになったし、iOS開発がしたいかって言われるとそうではないがRails使いたいかって言われると違い、僕が出来る全てやりたいという感じもありつつ働きたくないという感じになってる。というかRailsでチーム開発した結果あんま使いたくないんだけど、静的型付け言語でなんかちょうどいい感じの言語は無いんすかって思ってる。

先日また昇給して転職のタイミングを上手いことアレすることが出来ないし、転職するにしても現状の経歴だと何処にも引っかからんだろうみたいな感じがあり、打開策が見つからず将来に漠然とした不安を抱えつつある。

ゴキブリ食べた

f:id:gin0606:20160203025927j:plain

珍獣屋でゴキブリを食べた。

写真はゴキブリを食べた筆者近影で、初めてインカメラを使った自撮りをした。

f:id:gin0606:20160203025844j:plainf:id:gin0606:20160203025857j:plain

ゴキブリはこんな感じで出てくる。

ゴキブリの味は、川エビとか甘エビの唐揚げに似てて大分美味かった。

以前、行った人にクリーミーだったと聞いたので、それを期待してたんだけど、エビの唐揚げという感じでクリーミーさは感じなかった。季節によるのかもしれない。

f:id:gin0606:20160203025831j:plain

あとは蛇とか。

f:id:gin0606:20160203025909j:plain

これはなんだか忘れた。

f:id:gin0606:20160203025931j:plainf:id:gin0606:20160203025943j:plainf:id:gin0606:20160203025953j:plainf:id:gin0606:20160203030002j:plainf:id:gin0606:20160203030601j:plainf:id:gin0606:20160203030611j:plain

オオグソクムシとかあった。

グソクムシよりゴキブリのほうが美味しいので、珍獣屋に行って虫などを食べるならゴキブリは食べたほうが良いと思う。

僕がめちゃくちゃ行きたがってて、大学時代の横浜に住んでいる友人3人に付き合ってもらった。

f:id:gin0606:20160203030622j:plainf:id:gin0606:20160203030632j:plainf:id:gin0606:20160203030642j:plainf:id:gin0606:20160203030653j:plainf:id:gin0606:20160203030705j:plain

異物混入プリンというメニューがあって、これが一番反応がやばかった。

ゴキブリは僕を含めた3人が食べてて、1人は虫などに対して寛容な感じになりつつあったんだけど、これを見てから僕以外の全員がガチ目に引いてた。

異物混入プリンは僕一人でもりもり食べて、1人にあーんして一口だけ食べさせたけど精神的なダメージを大分負ってた。

異物混入プリンが来る少し前に、幼稚園時代にカタツムリを100匹くらい飼ってて、ある日突然父親に捨ててこいと言われて雨の日の公園で泣きながら一匹一匹あじさいの葉に乗せたという悲しいエピソードを話してたんだけど、そのエピソードもマイナスな印象を与えてしまった。

一緒に行った友人がまた一緒に普通の居酒屋に行ってくれることを願っている。

tabelog.com

梅酒半年経った

半年後の梅の季節にも何か漬けたい。

半年前のやつ