layer.borderWidth と layer.cornerRadius を同時に使用するとボーダーの一部に白いギザギザが出る

概要

layer.borderWidth と layer.cornerRadius を同時に使用すると、
ボーダーの一部に白いギザギザが出るCALayerのバグ? のようなものにハマりました。

UI系のライブラリのIssuesにも同じようなことを言っている方がいました。 https://github.com/IBAnimatable/IBAnimatable/issues/503

具体的には

例えば、 角丸 23pt, ボーダー 3ptのデザインを実装しようとした時にこうなります。

f:id:yokurin:20190130000626p:plain

拡大するとこんな感じ。

f:id:yokurin:20190130001117p:plain    f:id:yokurin:20190130001120p:plain


layer.allowsEdgeAntialiasing というプロパティがありますが、trueにしても関係ありませんでした。

とても細かいですけど、背景が黒系だと白いギザギザが目立つんですよね。

解決方法

結構時間かけて、英語で調べたりしたんですけど、
CALayerのバグ?ということで具体的な解決方法が見つかりませんでしたが、
私は、Border用のView を用意することで解決しました。

f:id:yokurin:20190130002604p:plain

新卒エンジニア、リクルートを退職した

はじめに

2017年4月に新卒でエンジニアとしてリクルートホールディングスに入社しまして、
2018年12月に退職します。2年弱在籍しました。

出向先
2017年度:リクルート住まいカンパニー
2018年度:リクルートテクノロジー

次は フリーランス になります。

※ 前提として新卒入社して2年弱しか経っておらず社歴が浅い。また、会社から多くのチャンスをもらい、成長できて感謝しているというのをふまえて読んでほしい。

私について

私は大学の時に田舎から上京し、大学2年くらいからプログラミングをはじめました。
在学中はインターンや業務委託としてエンジニアをしていました。

バックエンド(2年) → フロントエンド(1,2年) → iOS (2年), Android (6,7ヶ月)

www.wantedly.com


やっていたこと

新規事業開発

すでにエンジニアリング経験があったので、入社後はすぐに開発をしました。

入社後3ヶ月間は新規事業開発をしていましたが、もともと入社した理由が大規模サービス開発における、エンジニアリング組織と事業の進め方を経験したかったので、希望を出してSUUMO本体の開発チームに異動させてもらいました。

SUUMOアプリ

SUUMOアプリではiOS, Androidを担当しました。
アプリチームはエンジニアだけで 約30人います。こんなにエンジニアが多い組織はなかなかないので、貴重な経験ができました。
アプリチームでは 案件開発開発環境改善開発工程改善を行いました。

印象に残っているタスクでいうと、開発環境改善系のタスクです。
私が参画した当時、SUUMO iOS のプロジェクトファイルは相当大きく、ビルド時間が20分以上と長かったので、それを解決するためにある程度の単位ごとに Embedded Framework を順次導入しました。
Framework化することで差分ビルドで済むようになり、長いビルド時間は解消されました。 さらにFramework単位でアプリを作り、対象画面の実装やデザインをすぐに確認できるようにして、開発時間の削減もできました。


どうだったか

入社した理由、やりたかったこと

私はずっとベンチャー企業でしか働いたことがなかったので、
大企業のエンジニアリング組織 や、100→ フェーズの事業開発開発手法
を見たかったです。
他にも優秀な同期や先輩、上司に会える確率が高いというのも理由としてありました。

100→ フェーズの開発現場 (SUUMO アプリの話)

大きく分けてネイティブアプリチームとAPIチームに分かれていますが、 アプリチームは社員エンジニアと常駐の業務委託エンジニアの方で構成されていて、内製比率は約2割です。チーム全体の平均年齢は30代中盤です。APIはこれまで社員エンジニアが関わっていなかったですが、ちょうどこの10月から見始めています。

上記のような構成になっており、業務委託の方が手を動かすので、社員エンジニアにはコーディング力に加えて、チームの推進、改善を求められます。

技術的なことでいうと、大昔からの大規模アプリで大改修が厳しい中、事業側との調整を行い、テスタブルな設計を導入したり、Unit Test を入れたり、できる限りレガシーを減らし、保守・開発コストを下げるようにしています。
ただ、技術力のばらつき、採用観点で、Rx などの慣れれば飛び道具になるようなモノや、テスタブルにするためのレイヤードアーキテクチャAndroidではデファクトスタンダードになりつつある Kotlin の導入などには苦労しますが工夫をしながら進めています。
チームが大きくいろんな方がいるので講習のようなものを行い、チームのみんなが理解できている、納得できている状態にするのはまあまあ大変でコストもかかりますが、チームの成長のために協力しながら進めています。

開発手法

案件開発は、企画チームがあって、そこが考えた企画をエンジニアに流して、リリースまで行ってもらう。 リリース後に企画チームが分析し、また次の打ち手や企画を考えるという工程になっていました。 企画はGAやBigQueryを用いて定量で分析し、見つけた課題に施策を打つという王道パターンでした。
企画と開発はほぼ分業されています。

この手法でSUUMOアプリはグロースできていたので、こういう開発手法が合っているのだと思いますが、今後はお互いのスコープ拡大を目指していっています。


待遇・環境

給料は評価されればすぐに上がるし、一般的な水準より高めに設定されています。
仕事に関してもやりたいと手を上げれば誰でもやらせてもらえる、素晴らしい環境でした。
ただ、リクルートでよく言われる「お前はどうしたい?」という主体性がないと働き辛いと思います。

PCに関しても 「メモリ4GBでHDDのPCで...」のようなこと起こらず *1 、メモリ16GB、Core i5以上のMac or Windows お好みのPCが支給されます...

給料の具体的な数字は隠したいわけじゃないですが、あえて書くほどでもないので気になる方はDMなどで直接聞いてください。

よかったこと

入社前はエンジニアリングにしか興味がなかったですが、事業や社会をエンジニアリングでどうするかということへ視野を広げ、視座をあげることができました。また大企業での仕事の進め方、組織の中での進め方を間近で見て、実行できたこともよかったです。

エンジニア基本スタンス
          課題設定力 「目的からプルする」
          課題解決力 「手法論ではなく原理原則に立ち返る」
       学びの質を上げる 「失敗から学ぶ」
学びまでのリードタイムを減らす 「ムダを減らす」

エンジニアは技術だけではダメで、案件を開発するだけでなく、事業にとっての意味や価値、本当の目的を考え行動する。という基本スタンスが設定されていました。当たり前だろと思う方もいるかと思いますが、入社したての私はそこまで意識できていなかったので、これを意識することで私は変われたと思います。


やめる理由

やめる理由の一番は、時間の自由度を高くしたいからです。
1日は通勤時間を合わせると、約10時間以上は会社のために使っています。
この時間を自分で好きに使えるとなったら、今自分に必要だと感じているハードスキル、ソフトスキルを習得できる仕事や環境を作れると思います。
ちなみに現在の私のフリーランス単価を考えると、金銭的自由度も今よりけっこう上がります。

でも、本当はフリーランスになって受託開発がしたいわけではなくて、事業やサービスをやりたいという理由もあります。
また純粋にモノを作るのが好きで、さらにそれを色んな人に使ってもらって少しでも誰かの役に立っていると気付かされた時、やっていてよかったと感じます。それがユーザーに近ければ近いほど、やりがいを感じます。これは承認欲求ではないと自分では思っていますが、実際には承認欲求なのかもしれません。笑
今でもいくつかアプリ*2を出していて、こういう感じで細々開発するのもいいなーと漠然と思っています。
個人で出来ない規模や内容、スピート感であれば、手段として法人にするのもアリだと思います。
ただ今でも、本当にやりたいことはナニかという問いの答えを出せていないので、まだ考えています。。


最後に

リクルートの現場、環境、感じたこと、今後について書きました。
最初は書くか迷ったんですが、こう言語化してみると、自分の中での振り返りや、今の気持ちの整理にもなるので書いてよかったです。

長文にも関わらず、最後まで読んでくださりありがとうございました。
先輩の退職エントリーも参考になります。*3

Twitter@_yokurin

人気上昇中の私のアプリ

シフマネ:シフト管理と給料計算

シフマネ:シフト管理と給料計算

  • Tsubasa Hayashi
  • 仕事効率化
  • 無料

iOS12 AVAudioSessionPortImpl.mm:56:ValidateRequiredFields: Unknown selected data source for Port Speaker (type: Speaker) というログが出続ける

概要

iPhoneX, iOS12の実機でアプリのデバッグをしていたところ、
アプリ起動後30秒くらいの間、コンソールに以下のようなエラーログが出続けました。
ログが出続ける間、アプリも操作できず固まります。

AVAudioSessionPortImpl.mm:56:ValidateRequiredFields: Unknown selected data source for Port Speaker (type: Speaker)

forumにもスレッドが立っていました。
forums.developer.apple.com

結論

どうやらAdMobのバグのようです。
takattata.hateblo.jp

自分でもAdMobのバージョンを最新版にしたり、元に戻したりしましたが治りませんでした。
ちなみに試したバージョンは以下
7.31.0 , 7.34.0 , 7.35.1
※ 10/24時点での最新版は 7.35.1 です

ただ、僕の環境ではこの現象が起こるのはデバック環境のみでした。
7.34.0 の AdMobを利用してリリースしたアプリでテストしましたが、起動後に固まったり、カクカクすることはありませんでした。

外国人の友人から永住権の身元保証人を頼まれた話

めったに経験できそうにないことを経験したので記録として。笑

会社の同期で、友人でもある人から日本の永住権を取りたいから身元保証人になってほしいと頼まれました。
その友人は中国人で日本のこと好きで、日本にずっと住みたいという思いがあり、永住ビザを取りたいようです。そしてその永住ビザを取るためには、身元保証人という保証人が必要らしいです。

頼まれた時は、「保証人になってはダメだぞ」と小さい頃から親に言われていたので、保証人という言葉だけで少しイヤだなーって思っていました。

結論からいうと、永住権の保証人と借金をするときの連帯保証人とは違うということが理解できたので、身元保証人になることにしました。 他に頼める人がいるかもしれないけど断るのはかわいそうだし、彼を信じようという思いもありますね。

永住権の身元保証人と借金等の連帯保証人は全くの別物

ここを理解した方がいいかなと思います。 以下に身元保証人がどんなものなのかを記します。
今後、頼まれた方の参考になれば嬉しいです。

入国管理局のQ&A内容

www.immi-moj.go.jp

Q7 提出書類に身元保証書がありますが,「身元保証人」とはどのようなものでしょうか。 また,身元保証した際の責任はどうなっているのでしょうか。

 

A 入管法における身元保証人とは,外国人が我が国において安定的に,かつ,継続的に所期の入国目的を達成できるように,必要に応じて当該外国人の経済的保証及び法令の遵守等の生活指導を行う旨を法務大臣に約束する人をいいます。 身元保証書の性格について,法務大臣に約束する保証事項について身元保証人に対する法的な強制力はなく,保証事項を履行しない場合でも当局からの約束の履行を指導するにとどまりますが,その場合,身元保証人として十分な責任が果たされないとして,それ以降の入国・在留申請において身元保証人としての適格性を欠くとされるなど社会的信用を失うことから,いわば道義的責任を課すものであるといえます。

 

入管法における身元保証人とは

入管法における身元保証人は、永住ビザ申請を行う外国人が日本で安定した暮らしが出来るように指導することを法務大臣に約束する人。
保証事項について身元保証人に対する法的な強制力はないです。 万が一、ビザ申請人が法律違反等を起こしても、身元保証人が罰則を受けたり、責任を追及されることはありません。
借金等の連帯保証人とは違います。
デメリットは、もし保証人が十分な責任を果たせなかったら次回以降身元保証人としての保証力が弱いと判断され、道義的責任を負います。

道義的責任とは

法的制裁を加えるほどのことではないが、社会的・倫理的非難に値し、ルール違反として世間的に非難される場合の責任です。また道徳や人として行うべき道理などから生じる、任務を行うべきであるということ、あるいは、任務を行わなかったことによる責めなどを意味する表現。

まとめ

万が一の場合は、法的に罰せられることはないが、
国からの社会的・倫理的な信用を失うことはあるということです。

その人がどういう人か、しっかり自分で見極めて、 自分で受ける受けないを決めましょう。

   

参考リンク:

スグ分かる!永住ビザ申請の身元保証人って何? - コモンズ行政書士事務所

道義的責任とは - 日本語表現辞典 Weblio辞書

Swift UIColor Extension でよくある 16進数カラーコードを UIColor に変換する時のビット演算について

前談

import UIKit

extension UIColor {
    convenience init(red: Int, green: Int, blue: Int) {
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }

    convenience init(rgb: Int) {
        self.init(
            red: (rgb >> 16) & 0xFF,
            green: (rgb >> 8) & 0xFF,
            blue: rgb & 0xFF
        )
    }
}

16進数カラーコードを UIColor に変換する時の UIColor Extension で上記のようなコードを見かけませんか? UIColor Hex とかで検索すると上記のような UIColor の Extensionが出てきます。 こんなの

stackoverflow.com

今回は上記のコードで使用されているビット演算についてです。
普段あまりビット演算を使う場面がないので、
自分なりに何をしているか理解した範囲で話します。間違いがありましたらコメントで教えてください。
最低限、2進数、10進数、16進数の理解がないと難しいかもしれません。

例として16進数のカラーコード #3a294b を入れて説明します。
ちなみに#3a294b は 10進数 RGB で表すと Red: 58, Green: 41, Blue: 75 (0 ~ 255) となります。

UIColor.init(rgb: 0x3a294b)

Swiftの 0xプリフィックスで、16進数の定数の前には 0x を付けます。10進数の場合はプリフィックスは不要です。したがって Swiftで let a = 8 と書いた場合は10進数になります。

16進数 3a294b を2進数に変換すると以下のようになります。

00111010 / 00101001 / 01001011

※わかりやすく 8bitごとに / で区切って、桁数が揃うように先頭の00を補っています。

他にも例えば 16進数 FFFFFF を2進数に変換すると以下のようになります。

11111111 / 11111111 / 11111111

さっと2進数を確認したい場合は、以下のように 16進数から2進数に変換できます

String(0x3a294b, radix: 2) // "1110100010100101001011"

本題

こちらの方から1つずつ見て行きます。

    convenience init(rgb: Int) {
        self.init(
            red: (rgb >> 16) & 0xFF,
            green: (rgb >> 8) & 0xFF,
            blue: rgb & 0xFF
        )
    }

Red

red: (rgb >> 16) & 0xFF,

今回は rgb には 0x3a294b が入ります。

0x3a294b >> 16

>> は右ビットシフトを表すビットシフト演算子です。
したがって、式が表す意味は 16進数 3a294b16bit 分を右シフトさせる。

00111010 / 00101001 / 01001011

16進数 3a294b16bit 分を右シフトさせると

00000000 / 00000000 / 00111010

16進数 3a294b の Redの部分 16進数 3a を取り出せました。

次に

0x3a & 0xFF

& はビットANDを表すビットシフト演算子です。
したがって、式が表す意味は 16進数 0x3a0xFF とビットANDする。

これは 0x3a0xFF で ビットANDすることで最大数を16進数 FF にするためです。

00111010

11111111

の ビットANDをとると

00111010

となり、これを10進数に変換すると58 になり, Red は 58 です。合っていますね。

Green

green: (rgb >> 8) & 0xFF,

同様に見て行くと

0x3a294b >> 8

式が表す意味は 16進数 3a294b8bit 分を右シフトさせる。

00111010 / 00101001 / 01001011

16進数 3a294b8bit 分を右シフトさせると

00000000 / 00111010 / 00101001

16進数 3a294b の RedとGreenの部分 16進数 3a29 を取り出せました。

次に

0x3a29 & 0xFF

式が表す意味は 16進数 0x3a290xFF とビットANDする。

00000000 / 00111010 / 00101001

00000000 / 00000000 / 11111111

の ビットANDをとると

00101001

となり、これを10進数に変換すると41 になり, Green は 41 です。合っていますね。

Blue

次に

blue: rgb & 0xFF

同様に見て行くと

0x3a294b & 0xFF

式が表す意味は 16進数 0x3a294b0xFF とビットANDする。 Blue 特に右シフトせずに、ビットANDを取っています。 Blue は 8bit 部分なので、ビットシフトする必要がありません。

00111010 / 00101001 / 01001011

00000000 / 00000000 / 11111111

の ビットANDをとると

00000000 / 00000000 / 01001011

つまり

01001011

となり、これを10進数に変換すると75 になり, Green は 75 です。合っていますね。

よって、今回の例だと

UIColor.init(red: 58, green: 41, blue: 75)

という形で

    convenience init(red: Int, green: Int, blue: Int) {
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }

こちらのメソッドを読んでいることになります。

また

    convenience init(red: Int, green: Int, blue: Int) {
        self.init(red: CGFloat(red) / 255.0, green: CGFloat(green) / 255.0, blue: CGFloat(blue) / 255.0, alpha: 1.0)
    }

こちらの関数は、UIKitで実装されている UIColor.init に合うように
RGB のそれぞれの値が 0 ~ 1 になるように 255で 割っています。

以上です。
サンプルソースコードはこちらにあげています。

github.com

参考

業務委託先との契約を一旦、終了した

業務委託先との契約を一旦、終了しました

Smooz というブラウザアプリで有名な Astool Inc. との契約を一旦、終了しました。
2017年5月にお手伝いという形で参加して、1年ちょっとお世話になりました。

振り返り

振り返れば、色々ありました。
(みなさんに与えられる知見はほぼないので、、興味のない方はそっと閉じ、、)

新卒で会社に入ったばかりのタイミングでしたが、スタートアップをお手伝いしている先輩がいるというのを聞いて、面白そうだと思い、紹介してほしいと伝えました。
すると、その先輩は、なんで手伝いたいのか、どんなことが貢献できるか、などを文章にしてまとめてくれと僕にいい、僕が書いたその文面を持って、 Astool Inc. の代表の加藤さんに紹介してもらいました。
後日、先輩と加藤さんと、僕でランチをし、条件を話合い、Smoozアプリをお手伝いすることが決定しました。
僕は会社で働いているので、業務委託としてのお手伝いでした。

業務内容

最初はサーバーサイドエンジニアとしてJOINし、
バグ修正など、軽めのチケットをこなし、毎週土曜日にミーティングに参加していました。

3週間ほど経った時に、iOSの開発進捗がよくないので、iOSの方を手伝って欲しいと言われました。僕はiOSエンジニアとしてのJOINを希望していたので快諾しました。

iOSでもバグ修正や、いくつかの機能追加など行いました。
特に記憶に残っているのは、最初のころに担当したチケットです。
広告ブロックとID, パスワードの保存機能です。
広告ブロックはiOS11からWKWebViewでもContentRuleを設定できるようになったタイミングでしたので参考記事がなく、ドキュメントを漁りながら実装しました。
ID, パスワードの保存機能はWebサービスにログインする時に、IDとパスワードを入力すると思いますが、そのIDとパスワードをブラウザで記憶して、2回目以降は自動で入力されるもの機能です。
Firefox-iOSOSSになっていたので、それを参考にして実装しました。
汎用的に色んなサイトに対応できるように工夫したり、セキュリティ面にも考慮したり、結構大変だった。
本業の仕事から帰って来て、夜の8時〜深夜3時とかまでやったりしてましたね。 色んな実装を経験させてもらいながら、今年(2018年)の2月くらいまではiOSをやってました。

2月くらいからは、Androidを手伝うようになりました。
Androidの経験はそこまでなかったですが、バグ修正などをやりました。
Androidリファクタリング祭りもやりましたね。あまり戦力ならなかったけど。。

直近、契約を終了をしようと思ったわけ

6月に入ったくらいから、自分の中でも考えが変わって来て、、
もっと自分のサービスに注力する時間がほしいと思うようになってきました。
※4つほど個人でアプリを出しています
https://itunes.apple.com/jp/developer/tsubasa-hayashi/id1153379682

それで、ちょうど先週、代表の加藤さんにお話をしてきました。
理由はすべて本音で話しました、思っていることやりたいことなどをお話ししました。
フリーランスになるかもしれないことを伝えたら、
代表「一旦、契約はこのままにしておいて、またフリーになったら声かけてよ」
いつでもウェルカムだよと言ってもらえるのは非常に嬉しいですね。

さらに、スタートアップをやるかもしれないことを伝えたら、
たくさんのアドバイスと、またいつでも相談に乗ってくれるとも言っていただきました。。いい人すぎる。。

これから

本業の方もありますが、それ以外の時間はできるだけ自分のアプリに注力します。
さくっと終わる案件がきたらやるかもしれないけど笑
シフマネというシフトと給料管理のアプリは順調にユーザー数も増えてきて、これからという感じです。

2年以上更新をしなかったブログを再開しようと思った訳

ブログを再開します

最後に更新した記事から2年以上たっているわけですが、
ブログをまた始めようと奮起したので、こちらで再開します。
文章能力がないですが、お手柔らかに m _ _ m
※いくつか黒歴史になりそうだった記事は削除しましたw

再開する訳

いくつかの理由はありますが、私が今回再開する理由は以下の通り。

1. その当時の気持ちや考えていたこと、出来事を記録する

完全なメモ。あとで振り返れるように。あの時はこんなことがあったからこういうことを考えて行動したんだと。この出来事でこんな考えになったんだと。

2. アウトプットを増やす

社内のSlackで自分の意見をいうことがあるが、これに少し説明を付け加えるだけで世間へ向けたアウトプットできると思った。あわよくば、自分の考えや意見がどうなのか世間からのフィードバックが欲しい。もっというと、自分について知って欲しいし、世間で少しでも知ってくれている人を増やしたい。
こう考えるようになったのは、以下の出来事があったからです。

news.yahoo.co.jp

レシート換金系はほかにもあったのに、なぜこれだけバズったのか。。
このサービスがばずった理由をいろんな人と議論しました。
結論は、

  • 1枚10円になりますというわかりやすさ (他はポイント付与)
  • サービスのわかりやすさからくる拡散性
  • 即金ニーズがあるというタイミング (Cashなど時流に乗ったタイミングだった)
  • もともと注目されていた人でメディアが取り上げやすかった (&高校生)

もともと注目されていた人でメディアが取り上げやすかった (&高校生)

ここ!私も近いうちにサービスを出したいと考えているのですが、
最初から知名度がある人が出すサービスの方が普及しやすいです。
だって、芸能人が何かしたらすぐに話題になりますよね。そういうことです。 そういうヨコシマな思いもあり、再開することにしましたw

自己紹介

新卒でエンジニアとしてリクルートホールディングスに入りまして、リクルートテクノロジーズに出向しています。
業務では、SUUMO のiOS, Android の保守、運用をしています。
詳しくはこちら↓ をご覧ください。 www.wantedly.com