コネヒト開発者ブログ

コネヒト開発者ブログ

iOSDC Japan 2019に行ってきました!

こんにちは、iOSアプリエンジニアのあぼ(@suxisuxido)です!

2019年9月5~7日に開催されたiOSDC Japan 2019に行ってきました。今年はダークモードの横断幕とパネルが用意されていたり、お茶会やiOSDCチャレンジといった新たな試みも追加され、進化したお祭りになっていました!

f:id:aboy_perry:20190911200700j:plain
ダークモードのパネル

コネヒトはシルバースポンサーと、Tシャツスポンサーとして協賛していたので、ノベルティを受け取るやいなやTシャツを袋から取り出し写真を撮ってはしゃぎました。

f:id:aboy_perry:20190912115131j:plain
ノベルティのTシャツ

本編となる各セッションの資料と動画は、公式のタイムテーブルから辿れる各プロポーザル詳細ページにリンクが貼ってあるので、そこから見ることができます。本ブログでは感想も交えながらいくつかのセッションをご紹介したいと思います。

Advanced Segue 2019年のSegue事情

Segueを使ったことがない私にとっては、Segueの使いかたや最新のSegue事情を一気にインプットするいい機会だったので聴きに行きました。

私は、Segueは画面遷移で利用するもの、と思ってしまっていたんですがそれは間違いで、実際にはperform()メソッドをオーバーライドすればそこでできることは全てできるので、自由度が高く可能性がある機能だな〜と感じました。Storyboard上でSegueを利用する際には接続先が必要で、例として空のStoryboard Referenceを置いて繋げるというやり方がセッションで紹介されていましたが、空のStoryboard Referenceを使うことのコスト感については、セッション後にスピーカーがつぶやいている内容が興味深いです。

iOSアプリのリジェクトリスクを早期に発見するための取り組み

リジェクトによる手戻りは大きく、またタイミングによっては休日に対応する必要があるため、できるだけ早期に発見したいところです。DeNAのSWETグループではReviewガイドラインをシステムに落とし込んで運用することで早期発見を実現しているとのことでした。システム化はもちろん、開発者からSWETグループへメモを送れるようにしてコミュニケーションコストを削減している点もすごいな〜と思いました。

また、最新のReviewガイドラインのキャッチアップ方法としては、コネヒトでもすでにhttps://developer.apple.com/news/を購読してslackに流すようにしていましたが、セッション内で紹介されていた「Reviewガイドラインのdiffを取る」という取り組みが結構手軽にできて良さそうなので、試しにマネしてみることに!

f:id:aboy_perry:20190911175358p:plain
社内情報共有ツールDocbaseに作ってみたReviewガイドラインページ

実機の管理とおさらば!AWS Device FarmでiOSのテストをしよう!

タイトルの「実機の管理とおさらば!」に惹かれて聴きに行きました。なぜテストを書くのか、どうやって書けばいいのかというところに触れつつ、最終的にAWS Device Farmを使った自動テストの運用方法がイメージできる内容になっています。

現実的には全パターンのデバイスを検証機として用意できない場合のほうが多いでしょうし、特定のOS、特定のデバイスでしか再現しない不具合を事前に検知するというのはなかなか難しく、例えばユーザーからの報告で気づいてもそのデバイスが無ければデバッグできません。セッションを聴いて、AWS Device Farmのようなアプリケーションテストサービスを使うことも選択肢のひとつだな〜と思えるようになりました。ちょうどまたAppleから新たなiPhoneが発表されましたし、iOS/Androidともにデバイスは本当にたくさんありますからね・・・。

1ヶ月半でプッシュ通知許諾率を17%から40%にあげた話

こちらはLTです。タイトルの時点で色々と仮説をたてて聴いていたんですが、結論は「起動直後に承諾ダイアログを表示する」というものすごくシンプルなものでした!

会場でもドカッと笑いが起きていて、私も笑ったのですが、これすごく学びがあるな〜と思っています。問題を解決するときに、その問題を無駄に複雑に考えてしまってはないかという切り口での考察も重要なのかもな〜と考えさせられました。

セッション以外にも楽しいことがたくさん!

セッション以外にも楽しいことがたくさんあって、例えば、お茶会のときにpixivの方からいただいたリジェクトに効く御守りは、早速チームのカンバンにぶら下げています。Androidアプリでも審査が入るようになったこともありますし、iOS/Android両方に効果があるといいなーと願っています!

f:id:aboy_perry:20190910152350j:plain
リジェクト除けの御守り

スポンサーブースも楽しくて、RoomClipで利用されているデザインガイドラインの写真を撮らせていただいて、社内のデザイナーに共有できたり。Uberが公開しているクロスプラットフォームアーキテクチャRIBsと、昨年のiOSDCで話題になったMicroViewControllerを組み合わせて本番運用している話を聞けたりしました!

それから、大学時代の先輩や、前職で一緒に仕事していた人と久しぶりに会って話すことができて、これもiOSDCの魅力だな〜としみじみ感じました。

おわりに

クロージングで主催者が「We are a community. We are not a school.」と言っていたのが強く印象に残っています。今年もこの楽しいコミュニティは関わる人全員で作られました。スタッフの方々、早稲田大学、スポンサーやスピーカーの方々、そして参加者のみなさんに感謝しています!

帰ってブログ書くまでがiOSDCでおなじみのiOSDCですので、本ブログの公開をもって私のiOSDCは終了です!ありがとうございました!

potatotips #64に参加・LTしてきました

こんにちは!エンジニアの柳村です。

2019/8/27に開催されたpotatotips #64 に参加・LTしてきました。

potatotips.connpass.com

今回の会場はReproさんでした。 代々木駅から出てすぐの好立地で、おしゃれな内装でしたよ(写真を取り忘れました・・

iOS関連の発表について簡単にレポートします。

Object指向でFatViewControllerをなくす

@coffeegyunyuさん

StoryboardにObjectを配置してViewControllerの代わりにこちらで処理をさせる方法についてでした。StoryboardのObjectってなんに使うのかあまりわかってなかったのですが、ようやく使い方が判明してすっきりしました。

コントロールセンターとたたかう

@5mingame2さん

ゲームの操作中にコントロールセンターがでてきちゃうのを防ぐ方法について紹介されていました。ブースでいろんな人に試遊してもらって想定外の操作がされていないか観察するという試みはとてもいいなと思いました。

Conditional Content in SwiftUI

@yanamura_

SwiftUIで条件によってViewを出し分ける方法となぜその方法だとうまくいくのかについてお話しました。 私の個人のブログのほうでも書いてますのでよろしければご参照ください。

ちなみにママリではまだSwiftUIは使ってませんが、移行していきたい気持ちです!

iPhoneでFeliCaを読み取ってみた

@tanakasan2525さん

いろんな種類のFeliCaの読み込みを簡単にするライブラリをつくられたそうです。FeliCaの読み込み使ったアプリを作るのが楽になる便利ライブラリのようでした。

DIKitで人間がクラス間の依存関係解決するのを終わらせる

@yuuxenoさん

DIKitで依存関係の実装コードを自動生成することについて紹介されていました。人の手で実装するとどうしてもミスはしてしまいがちなので自動化できるところは自動化していくというアプローチはとてもいいなと思いました。

SwagGenのススメ

@yuta24さん

<<資料は公開されたら反映します>>

OpenAPIで書いたAPI定義からSwagGenを使ってコードの自動生成について紹介されていました。swagger-codegenと比較してtemplateが良い感じのようでした。

macOS アプリを2年ぶりにメンテしたら原型がなくなった話

@AkkeyLabさん

個人で開発していたmacOSのアプリをFluxを採用したりAnalyticsを導入したりして書き換えた際のTipsを紹介されていました。Firebase AnalyticsがMacアプリには対応してないというのは意外でした。

Flutter Pluginを作る

@konyavicさん

ReproのSDKのFlutter対応版をつくられたときのtipsを紹介されていました。Cordovaとかと比べるとFlutterのpluginはとても簡単につくれるとのことでした。

さいごに

わたしは子育てがあって最近はなかなか勉強会に参加できないのですが、久しぶりに参加してLTしたり懇親会でいろんなひととお話したりできてとても楽しかったです!また、参加できないときもpotatotipsはLT資料をアップロードしてくださる発表者が多くてとても助かっています!

ここで突然のお知らせです!

なんと、きたる2020年2月には弊社コネヒトにてpotatotips #67が開催予定です!!!

ぜひLTしにきてくださいね!お楽しみに!!!

コネヒトはiOSDC Japan 2019に協賛いたします!

こんにちは、iOSアプリエンジニアのあぼ(@suxisuxido)です!

本日は、iOSアプリ開発者の祭典iOSDC Japan 2019に協賛するお知らせです。

コネヒトはiOSDC Japan 2019に協賛いたします!

iOSDC Japan 2019に、シルバースポンサーとTシャツスポンサーとして協賛いたします。Tシャツがどんな仕上がりなのか、今から楽しみでワクワクです!

iosdc.jp

スポンサーするにあたって、コネヒトは「人の生活になくてはならないものをつくる」というミッションを掲げているので、技術コミュニティについても同様に、サポートして一緒に盛り上げていくことができたら、と思っております。*1

イベント概要

  • 開催 2019年9月5日(木)~9月7日(土)
  • 場所 早稲田大学 理工学部西早稲田キャンパス63号館
  • 対象 iOSおよび関連技術のエンジニア
  • タイムテーブル https://fortee.jp/iosdc-japan-2019/timetable
  • 主催 iOSDC Japan 2019 実行委員会 (実行委員長 長谷川智希 @tomzoh ) / WASEDA-EDGE人材育成プログラム

iOSアプリ開発者の興味がわくような発表テーマが目白押しなので、チェックしてみてください。メインの発表だけでなく、9月6日(金)と9月7日(土)は、突然思いついたネタをその場で発表できるようなアンカンファレンスが開催されます。また9月6日(金)のLT終了後、よくあるアルコール片手の懇親会ではなく「茶会」という形で参加者同士が交流できる企画もあるそうです!楽しみです!

iOSDCトークンはこちら!

#コネヒトとiOSDC

iOSDCチャレンジで使うトークンです!すごく楽しそうな企画ですので、まだの方はチェックしてみてください。

iOSDCには私とiOSアプリエンジニアのyanamuraが参加予定ですので、会場でお会いした際にはぜひお話しましょう!

Kotlin Fest 2019に参加しました!

2017年11月にAndroidエンジニアとしてjoinした関根です! 2019年8月24日に開催されたKotlin Fest 2019に参加してきました! 今回の記事では、私が聞いた公演を感想をおりまぜて紹介させて頂きます。

f:id:katsutomu0124:20190827142731p:plain

弊社はスポンサーとしての参加に加え、改めて学ぶContractsという内容で弊社富田が登壇をさせていただきました。 余談ですが、スポンサー参加や登壇への弊社の意思の一端が現れたこちらの記事を是非とも合わせてお読みください!!

tech.connehito.com

オープニングセッション

さて、肝心のKotlin Festは、長澤太郎さんの挨拶とSvetlana Isakovaさんのオープニングセッションで幕が上がりました。

Svetlana IsakovaさんはJetBrains所属のエンジニアであり、世界で1番Kotlinに詳しい一人です。 そんな彼女からKotlinの新機能について紹介をしていただきました。 スライドを読み進めていくと、Contractsも紹介がありました。Contractsという機能は、富田の講演テーマでもあり、実際に当日はこのオープニングセッションでも言及しご紹介いただきました! Svetlanaさん誠にありがとうございました!!!

Kotlin コルーチンを理解しよう 2019

最初は、弊社でも今後の利用を検討しているCoroutineを理解するべく、八木俊広さんによる講演を聴講しました。

Kotlin Coroutineの基礎をわかりやすく解説していただいたことに加えて 設計の方針とCoroutineのテストのアプローチまで幅広くお話を聞けました。 特にCoroutineのテストはブロッキング処理が絡むこともあり、実践的なアプローチの内容が聞けて非常に学び深かったです。 八木さん、貴重なお話をありがとうございました!

改めて学ぶContracts

続いて、応援の為、富田の講演を聴きに行きました。

speakerdeck.com

本人はとても緊張をしていたようですが、蓋を開けてみれば非常に好評を頂き、会場には笑いが溢れており流石の富田という講演でした。 当日の登壇のために社内2回のリハーサルをして臨んだのですが、社内メンバーからのFBも反映されており、限られた時間の中で、最後まで手を抜かずに良いものを届ける富田の人柄を再認識しました。 ちなみに余談ですが、社内のランチイベントでは、Kotlin Fest当日の講演のように彼の話でメンバーは笑わせてもらっています。 トミーさん登壇お疲れ様でした!(社内ではトミーさんと呼ばれています)

サーバーサイドKotkinでGraphQLをやってみよう

続いて、弊社でも度々話題になるGraphQLについて学ぶべく、しらじさんによる講演を聴きに行きました。

speakerdeck.com

GraphQLの基礎からKotlinでの記述方法に加え、プロダクションで必要になる認証情報の扱い方など導入に到るまでのガイドラインのようなお話でした。 個人的に、印象的だったのが、GraphQLでのテストについてクラスを綺麗に分けることが前提なのでmockすればOKという結論が印象的でした! 聴講者を巻き込みながら、会場を盛り上げるしらじさんの講演は得るものが多く楽しく学ばせて頂きました。 しらじさん、貴重なお話をありがとうございました!

フロントエンドもKotlinで書きたい! -WebページをKotlin/JSで作った軌跡-

普段フロントエンドを触る機会が少ないので興味を持ち、にしこりさぶろ〜さんの講演を聴きに行きました。

speakerdeck.com

Kotlin/JSには無知識で参加したのですが、サンプルアプリをもとに解説していただいて丁寧でわかりやすい講演でした。 すでにKotlin/JSで2つのサイトを作られていて、導入する上での注意点などにも触れて頂き、非常に説得力の高いお話でした Kotlin/JSはまだまだ情報が少ないので、みんなでアウトプットして行こうというメッセージはコミュニティを活性化する大事なメッセージだと思いました。 にしこりさぶろ〜https://blog.hatena.ne.jp/connehito/connehito.hatenablog.com/edit?entry=26006613406773967#さん、貴重なお話をありがとうございました!

Kotlin/Nativeはなぜ動くのか

最後に、Kotlin1.3の目玉の一つと言えるKotlin/Nativeの中身を理解するために荻野陽太さんの講演を聴きに行きました。

speakerdeck.com

ネイティブバイナリに変換される過程をステップごとに解説するお話で、学問的な内容に感じておりましたが、丁寧に解説していただいたおかげでよく理解できました。 今回のお話の内容の理解が深まったことで、個人的な学びに加え、Kotlin/Nativeの様なプラットフォーム非依存の技術の知識を社内に持ち込めるきっかけを頂きました! 荻野さん貴重なお話をありがとうございました!

Kotlin Festに参加して感じたこと

その他、聴講以外の感想に触れて本記事を終了したいと思います。

スタッフの運営スキルが高い

まず感じたことはKotlinFestに関わるスタッフの運営スキルが高いことでした。 誘導が非常に丁寧で、会場の移動もスムーズに行うことができました。 また富田の登壇時もアテンドも非常に真摯にご対応いただきました。 スタッフの皆様、当日お疲れ様でした!ありがとうございました!

コミュニティ運営を愛している

クロージングの際に、主催の長澤 太郎さんから案内があり、Kotlinコミュニティの主催者を壇上にあげ、1分間のアピールを募るという時間がありました。 JKUG以外のKotlinコミュニティを盛り上げていこうと言う長澤さんのメッセージと、それを暖かく迎える参加者の皆様から、Kotlinとコミュニティを盛り上げていこうと言う愛を感じられた一幕でした。 長澤さんを初めとした主催の皆様と参加された皆様。当日はありがとうございました!

最後に

改めて、主催の長澤さんを初めとした運営の皆様、登壇者の皆様、当日参加された皆様、本当にお疲れ様でした! 次回は私も登壇をできる様に精進いたします!また来年よろしくお願いします!

swift-formatで自動コード整形

こんにちは!エンジニアの柳村です。

前回SwiftFormatの導入について紹介しましたが、今回はswift-formatについて紹介します。

ここではappleのほうのswift-formatの使い方を紹介していきます。ただこちらはSwift 5.1以上に対応しているので、Swift 5.0向けにgoogleのforkのほうのswift-formatの使い方も紹介しますがこちらはあまりオススメできません。

インストール

各プロジェクト個別にswift-formatをインストールすることを前提にします。もしグローバルにインストールしたい場合はMintもしくはNSHipsterのforkをhomebrewでインストールしてください。

プロジェクトのルートディレクトリにPackage.swiftを配置します。

※ 事前にxcode-selectなどでXcode11を指定してください

// swift-tools-version:5.1
import PackageDescription

let package = Package(
    name: "Tools",
    dependencies: [
        .package(url: "https://github.com/apple/swift-format", .branch("master"))
    ]
)

設定

以下のコマンドを実行してデフォルトのフォーマットの設定を.swift-formatに書き出します。

$ swift run -c release swift-format --mode dump-configuration > .swift-format

swift-format実行時にこの.swfit-formatに書いた設定に基づいてフォーマットされます。 デフォルトはこのようになっています。

{
  "blankLineBetweenMembers" : {
    "ignoreSingleLineProperties" : true
  },
  "indentation" : {
    "spaces" : 2
  },
  "lineBreakBeforeControlFlowKeywords" : false,
  "lineBreakBeforeEachArgument" : true,
  "lineLength" : 100,
  "maximumBlankLines" : 1,
  "respectsExistingLineBreaks" : true,
  "rules" : {
    "AllPublicDeclarationsHaveDocumentation" : true,
    "AlwaysUseLowerCamelCase" : true,
    "AmbiguousTrailingClosureOverload" : true,
    "AvoidInitializersForLiterals" : true,
    "BeginDocumentationCommentWithOneLineSummary" : true,
    "BlankLineBetweenMembers" : true,
    "CaseIndentLevelEqualsSwitch" : true,
    "DoNotUseSemicolons" : true,
    "DontRepeatTypeInStaticProperties" : true,
    "FullyIndirectEnum" : true,
    "GroupNumericLiterals" : true,
    "IdentifiersMustBeASCII" : true,
    "MultiLineTrailingCommas" : true,
    "NeverForceUnwrap" : true,
    "NeverUseForceTry" : true,
    "NeverUseImplicitlyUnwrappedOptionals" : true,
    "NoAccessLevelOnExtensionDeclaration" : true,
    "NoBlockComments" : true,
    "NoCasesWithOnlyFallthrough" : true,
    "NoEmptyAssociatedValues" : true,
    "NoEmptyTrailingClosureParentheses" : true,
    "NoLabelsInCasePatterns" : true,
    "NoLeadingUnderscores" : true,
    "NoParensAroundConditions" : true,
    "NoVoidReturnOnFunctionSignature" : true,
    "OneCasePerLine" : true,
    "OneVariableDeclarationPerLine" : true,
    "OnlyOneTrailingClosureArgument" : true,
    "OrderedImports" : true,
    "ReturnVoidInsteadOfEmptyTuple" : true,
    "UseEnumForNamespacing" : true,
    "UseLetInEveryBoundCaseVariable" : true,
    "UseOnlyUTF8" : true,
    "UseShorthandTypeNames" : true,
    "UseSingleLinePropertyGetter" : true,
    "UseSpecialEscapeSequences" : true,
    "UseSynthesizedInitializer" : true,
    "UseTripleSlashForDocumentationComments" : true,
    "ValidateDocumentationComments" : true
  },
  "tabWidth" : 8,
  "version" : 1
}

設定項目についてはdocumentに説明が書いてありますがruleについては詳細にかかれていないのでルール名から察するしかありません。

実行

以下のコマンドでコードをフォーマットできます。

$ swift run -c relesase swift-format -r ソースコードのフォルダのパス -i
  • -r で指定したフォルダ内を再帰的にswiftのファイルを探します。個別のファイルを指定したい場合は-rは不要です。
  • -i を指定するとswiftのファイルをフォーマットします。(これを指定しないとコンソールにフォーマット結果が出力されるだけです)

その他のオプションについては以下をご参照ください。

OVERVIEW: Format or lint Swift source code.

USAGE: swift-format [options] <filename or path> ...

OPTIONS:
  --configuration         The path to a JSON file containing the configuration of the linter/formatter.
  --in-place, -i          Overwrite the current file when formatting ('format' mode only).
  --mode, -m              The mode to run swift-format in. Either 'format', 'lint', or 'dump-configuration'.
  --recursive, -r         Recursively run on '.swift' files in any provided directories.
  --version, -v           Prints the version and exists
  --help                  Display available options

POSITIONAL ARGUMENTS:
  filenames or paths      One or more input filenames

実行してみるとわかりますが、プロジェクト全体にかけると結構遅いです。(ママリだと1分かかりました)

また、exclude directoryとかの指定ができないので3rd Partyのソースコードなどがあった場合に特定のディレクトリのみを除外するといったことができません。

これではちょっと頻繁に実行するのはちょっと厳しいです。

そこで以下のように差分のあるswiftのファイルのみをswift-fomatに食わせるようなスクリプトをprojectのbuild phasesやgitのprecommit hookに設定するといい感じになると思います。

$ git diff --name-only | grep .*\.swift$ | xargs swift run -c release swift-format -i

まとめ

Swift 5.1以降に限定されますがswift-formatでフォーマットできました。

swift-formatは2019年8月現在まだreleaseは一つもされてないのでまだこれからといった感じはしますが、ママリのアプリではXcode11およびSwift 5.1に対応するタイミングくらいに導入しようかと考えています。

------✂------✂------✂------✂------✂------

オマケ:Swift 5.0でswift-formatを使いたい場合

Swift 5.1でやる場合との違いはインストールです。

インストール

googleのswiftのforkの特定のコミットを利用します。

$ git clone git@github.com:google/swift.git swift-format
$ cd swift-format
$ git checkout 74995aa1473b213977a14c0cb477ce89875ee27b
$ git submodule update --init
$ swift build -c release
$ cd ..

あとはSwift 5.1の手順と同じです。

実行結果

ただappleのと比べると実行結果には違いがあります。(5.0で動かすために古いコミットを指定しているのが原因なのですが)

例えばRxSwiftのインデントがこんな感じになってしまいます。。 たぶん不具合でrespectsExistingLineBreaks の指定が効いていないのではないかなと思います。

-        cameraButton.rx.tap
-            .flatMapLatest { [weak self] _ in
-                return UIImagePickerController.rx.createWithParent(self) { picker in
-                    picker.sourceType = .camera
-                    picker.allowsEditing = false
-                }
-                .flatMap { $0.rx.didFinishPickingMediaWithInfo }
-                .take(1)
-            }
-            .map { info in
-                return info[.originalImage] as? UIImage
-            }
-            .bind(to: imageView.rx.image)
-            .disposed(by: disposeBag)
+        cameraButton.rx.tap.flatMapLatest { [weak self] _ in
+            return UIImagePickerController.rx.createWithParent(self) { picker in
+                picker.sourceType = .camera
+                picker.allowsEditing = false
+            }.flatMap { $0.rx.didFinishPickingMediaWithInfo }.take(1)
+        }.map { info in
+            return info[.originalImage] as? UIImage
+        }.bind(to: imageView.rx.image).disposed(by: disposeBag)

あと@unknown default@unknowndefault になってしまうバグがあってコンパイルに通らなくなってしまったりするのでお気をつけください。

コネヒトは技術コミュニティになくてはならない開発組織を目指すために「スマイル制度」をはじめました!

(2020/11/27 追記)「ス・マイル制度」は「スマイル制度」に改名しました。

こんにちは!CTOの@itoshoです。いきなりですが、今日はコネヒトで新たに発足した「ス・マイル制度」のお披露目をしたいと思います!

tl:dr

  • ス・マイル制度という新しい取り組みをはじめました!
  • 目的は…
    • 技術コミュニティに貢献したい
    • そのためにコネヒトらしい手法でアウトプットの支援を実現したい
  • コネヒトらしい手法とは…
    • アウトプットに対して、マイルという報酬を個人ではなくチームに発生させる
    • マイルはチームの共有資産として誰でも自由に使うことが出来る
    • マイルをどう活用すれば、チームが成長するかを全員で議論する

ス・マイル制度のロゴ

ス・マイル制度とは?

一言で言うと、アウトプット支援的な制度なのですが、従来のアウトプット支援制度と違うのはアウトプットに対して、直接インセンティブを払うのではなく、一度「マイル」という形で開発部*1に貯金される点です。そして、ス・マイル制度ではその貯めたマイルを誰でも自己研鑽のために自由に使うことが出来ます。

例えば、あるエンジニアがOSSにコントリビュートをすると一定のマイルが貯まります。そうすると別のエンジニアはそのマイルを利用して、海外のカンファレンスのチケットを買うことが出来るようになります。

f:id:itosho525:20190821230230p:plain

ス・マイル制度で実現したいこと

このス・マイル制度は、僕がCTOに就任する少し前*2から構想を練り始めた制度です。コネヒトは以前からアウトプットを推奨しており、KotlinやCakePHPのコントリビューターが在籍しています。しかし、推奨はしていたものの、特に会社として目に見える形で支援していたわけではありませんでした。ですので、CTOになったタイミングで会社としてちゃんとアウトプットを支援・評価したいと思ったのが、ス・マイル制度を立ち上げたきっかけです。

また、これまでコネヒトは多くのOSSの恩恵を受けたり、他社の事例を参考にしたりすることで、サービスを成長させてこれたと言っても過言ではありません。ですので、技術コミュニティや他社に「恩返し」したいと強く思いました。そして、コネヒトが得たものを技術コミュニティに還元出来れば、それをもとに技術コミュニティが発展し、技術コミュニティが発展すれば、それにより更にコネヒトも成長するという、Win-Winのループをつくることが出来るのではないか?と考えました。

コネヒトは「人の生活になくてはならないものをつくる」というミッションを掲げています。その中で、開発組織としても技術コミュニティや他社になくてはならない開発組織をつくることがス・マイル制度のゴールになります。

f:id:itosho525:20190821230121p:plain

制度設計時に気をつけたこと

順番が逆

ス・マイル制度で意識したことはコネヒトらしさです。そのために制度は一人で考えず、メンバー全員の意見を聞くようにしました。*3その中で、当初ス・マイル制度は、アウトプットに対して直接金銭的なインセンティブを払うというシンプルなものを考えていました。しかし、何人かのメンバーから「アウトプットを支援すること自体は良いがインセンティブの順番が逆ではないか?」という意見をもらいました。

これはどういうことかと言うと、技術コミュニティに貢献するためには、何らかのアウトプットが必要になります。そして、アウトプットをするためには、学習=インプットが必要になります。しかし、(ものにもよりますが)インプットには一定お金がかかる場合があります。ですので、アウトプット後にお金があるのではなく、アウトプットする前(=インプットをしたい時)にお金があるべきではないかというわけです。

お金のモチベーションは長続きしない

また、ほとんどのメンバーから金銭的なインセンティブは大きなモチベーションにはならないという意見も貰い、確かにダニエル・ピンクのモチベーション3.0ではないですが、お金のモチベーションは長続きしないと考え、最終的に「マイル」という形で、マイルをみんなの共有資産とすることで、お互いを支え合いながら、必要な時に必要な支援が受けられるように設計しました。

更にアウトプットの価値や、組織として何に投資するべきかを全員で議論するために、アウトプットは申請制にし、そもそもアウトプットとして認められるか?認められる場合、どれぐらいの価値があるか?というのをメンバーが承認する形にしています。*4

インプットについては、他薦を認めつつ、こちらもメンバーの申請制にしており、申請すれば自由に使える純粋な福利厚生ではなく、そのインプットによって、期待される成果やアウトプットなどを約束するようにし、その使途を議論出来るようにしました。

こうして、最終的にとてもコネヒトらしい制度が出来たと自負していますが、このような制度をつくる時は、他社の制度やHowをそのまま輸入するのではなく、自分たちのカルチャーにアジャストした形にしないと上手くワークしないということを改めて学びました。

早速盛り上がっているよ!

ス・マイル制度運用を開始してから、1ヶ月弱が立ちましたが早速多くのアウトプットが申請〜承認されています。ちなみに、管理ツールは内製しているのですが、この管理ツールは先日ブログでも紹介した「社内ツールをCakePHP4でつくりました」ツールになります。

ス・マイル制度は制度をつくることがゴールではなく、運用を開始してからが本番だと思います。ですので、運用ルール自体も今後継続的に改善していく必要があると考えています。そのため、運用に関しても僕一人ではなく、コアとなる運用メンバーを中心に開発部全体で行っています。ス・マイル制度の本当の評価や価値は今後生まれてくるものだと思いますので、また時々進捗などをお知らせ出来ればと考えています。

f:id:itosho525:20190821230523p:plain

最後に

現代のソフトウェア開発がOSSや技術コミュニティと切っても切り離せない関係にある中で、企業が金銭的な見返りや打算抜きに技術コミュニティと手を取り合っていくことの重要性はこれからますます高まっていくと僕は考えています。というわけで、ス・マイル制度が、企業と技術コミュニティをお互い持続可能な形で支え合う取り組みに出来るようこれから大切に育てていきたいと思います。そして、コネヒトを技術コミュニティになくてはならない笑顔があふれる*5開発組織にしていくぞ!

*1:開発部はコネヒトでエンジニアとデザイナーが所属する組織です。

*2:CTOに就任したのは2019年の6月。

*3:多数決で決めれば良いものではないので、最終的な意思決定はCTOの僕が行っています。

*4:もちろん、最初は判断基準がないと困ると考えたので、例えば、広報立ち会いの登壇は50000マイルというようなベースとなる基準表を用意しています。

*5:ちなみに、ス・マイルのスにはスペイン語で「あなたの」という意味も込めています。

SwiftFormatで自動コード整形

こんにちは!エンジニアの柳村です。主にママリのiOSアプリの開発を担当しています。

今回はSwiftFormatの導入についてお話します

背景

コネヒトではSwiftはraywenderlichのswift style guideをコーディングのスタイルガイドとしてコードを書いています。

ですが、各開発者が全てのスタイルガイドを覚えているわけではなく、ときどきスタイルガイドからはずれていたりインデントや改行が他のコードと不一致だったりしてコードレビューで指摘したりするといったことがありました。

レビューではコーディングスタイルを気にするよりももっと他のことに注意を払ってレビューすることに力を注ぎたいのでコードフォーマッターを導入してみることにしました。

フォーマッターの選定

Swiftのコードフォーマッターはいくつか存在しています。

まずは試しにcocoapodsに対応していて導入が楽なSwiftFormatにしてみました。

なぜcocoapodsがよかったかというと、フォーマッターのインストールはhomebrewなどを使って各自の環境にインストールするという手段もありますが、複数人で開発を行う場合に各自のインストールしているバージョンに違いが発生する恐れがあります。cocoapodsにしておけばインストールされるバージョンが固定されるので意図しないバージョンが使われてしまうといった恐れがなくなるメリットがあるからです。

設定

cocoapodsでインストールして、Debug Configurationでビルドした際に自動でフォーマットするように設定していきます。

Podfile

   pod 'SwiftFormat/CLI', :configurations => ['Debug']

Project

XcodeのTarget->Build Phasesに以下を追加します

if [ $CONFIGURATION = "Debug" ]; then
"${PODS_ROOT}/SwiftFormat/CommandLineTool/swiftformat" .
fi

.swift

.swift-versionがなければ作成しSwiftのバージョンを記載します。

5.0

.swiftformat

.swiftformatにルールを記載することでデフォルトのルールを変更することができます。

デフォルトのルールのままだとdiffがすごいことになったので以下の一部のデフォルトのルールをdisableにしました。

--disable trailingCommas, strongOutlets, unusedArguments, hoistPatternLet, blankLinesAroundMark

おわりに

このように導入はさっくりとできてしまうので、気軽に試せるのでおすすめです!

次回はswift-formatの使い方について紹介したいと思います、お楽しみに!