SoftBankの信用情報誤登録でブラックリストに入ってた

無事決着がついて新規にクレジットカードを発行するこができました。
カードの増えたWalletの様子。 f:id:lvla:20170726025008p:plain
解決までに約1ヶ月ほどの時間がかかりました。
参考になるかはわかりませんが、SoftBankとどういったやり取りをしたかをその内容と共にまとめておきます。

前回の記事

lvla.hatenablog.com

tl;dr

  • SoftBankによって誤った信用情報を記録されていた。
  • メールで問い合わせ。
  • SoftBankでは信用情報を調べることが出来ないので、信用情報機関に自分で問い合わせてくれと言われた。
  • 過去の事件のときはどうやって調べたんだよ!はよせい!とつっつく(実際はもっと丁寧に言ったヨ
  • 本気出して調査してもらえることになった。
  • その間、「解約を検討してるんだけど、調査ややり取りに支障がでるか」と問い合せる。
  • NPCみたいな返事しかしてこないので解約は保留にする。
  • 修正が完了したと言われる。
  • 信用情報開示して調べるけど、自費でやるの癪に障るから補償してくれと伝える。
  • ホワイトプラン値引きするねと言われる。
  • 解約するから別の形がいいという。
  • ホワイトプラン値引きするねと言われる。
  • 諦める。
  • 修正を確認して、その旨を伝えた。

SoftBankに電話で問い合わせる。

まずはSoftBankに電話での問い合わせをしました。しかし、オペレーターには「何もわからないので店舗で聞いてほしい。」と言われました。オペレーターでは信用情報を確認することもシステムに関することもわからないでしょうからまぁしょうがない気もします。
その時点で店舗の営業時間が過ぎていたので、とりあえず問い合わせフォームから文書で問い合せることにしました。

メールで問い合わせ

問い合わせ1 2017/06/01

以下の内容で問い合わせました。

  • 平成23年5月16日に24回払いで4.6万円の端末を24回払いで契約していること。
  • 信用情報記録によると、平成25年8月21日から現在まで継続して残額1000円の支払いが遅延していることになっているということ。
  • 完済しているはずなので、誤登録じゃないか?ということ。

返答1 2017/06/01

この度は弊社からのご請求につきまして、
お客様にはご心配をおかけし誠に申し訳ございません。

お客様のご契約状況をお調べしましたところ、
以前ご契約いただきました「iPhone 4 16GB」は
2013年5月ご請求分にて完済されていることを確認ができました。

恐れ入りますが「信用情報記録」については、
弊社ではお調べすることができませんので、
ご案内がございました開示元まで、今一度ご確認をお願いいたします。

メールにてお問い合わせいただいたにもかかわらず、
このようなご返答となり恐縮ですが、
何卒、ご協力賜りますようお願い申し上げます。

問い合わせ2 2017/06/02

xxx様

ご返答ありがとうございます。

「信用情報記録」に関しては調べることができないとのことですが、2013年に「信用情報機関への入金登録情報の誤りについて」というプレスリリースをだしてらっしゃいますよね。
https://www.softbank.jp/corp/group/sbm/news/info/2013/20131001_01/
この際にはどのようにして調査を行ったのでしょうか?

まず、システムが毎月未払いの記録をCICやJICCなどの信用情報機関に申請するようになっていないかを調査し、そのようになっているのであれば停止してください。
また、現在信用情報記録に残っている誤った記録の修正を信用情報機関に申請してください。
記録の修正を申請できるのはその記録を申請した会社のみで、私の方からは信用情報記録の開示申請を行うことしかできません。

以上です、よろしくお願いいたします。

てめーで信用情報機関に問い合わせろといわれてカチンときたので、ちょっと嫌味を言った上で改めて具体的に取ってほしい対応を伝えた。

返答2 2017/06/02

この度お問い合わせいただきました件につきまして、
確認後、改めてご連絡させていただきます。

恐れ入りますが、回答まで今しばらくお待ちください。

なお、ご心配をおかけしている中、大変恐縮ではございますが、
確認にお時間頂戴することもございます。

あらかじめご了承くださいますようお願いいたします。

過去を引き合いに出したので、ちゃんと対応してもらえることになった。ここから1週間返事が途絶える。

返答2-2 2017/06/09

突然のメールにつき、失礼いたします。

お預かりしている件について、ご連絡がございます。

誠に恐れ入りますが、お問い合わせいただいた件につきまして、
確認に時間を要しております。

すでにお客様の貴重な時間を頂戴しておりますところ、
恐縮ではございますが、確認がとれ次第、改めてご連絡を
差し上げたく存じますので、回答まで、
今しばらくお待いただきますようお願い申し上げます。

調査に時間がかかっている、すまんなとメールが届く。

問い合わせ3 2017/06/14

ご連絡いただきありがとうございます、その後進捗いかがでしょうか。

この度SoftBankとの契約解除を考えているのですが、本件に関してこのメールでやり取りを引き続き行っていくことは可能でしょうか(契約が切れていると不都合があるかの確認です)

最初の問い合わせから2週間近くが経過してしまったのでつっつきを入れる。また、6月は更新月だったのでとっとと解約し、LINE Mobileに切り替えたかったので、今の状況で解約されると調査ややり取りに不都合があるかを確認したい旨を伝えた。

返答3 2017/06/14

恐れ入りますが、引き続き現在も確認を進めている状況でございます。

お時間を頂戴するばかりでご心配をおかけし、大変申し訳ございませんが、
今しばらくお待ちいただきますようお願いいたします。

「遅れてすまんな」というだけで、解約にかんしてはなにも答えてないことにイラッときた。

問い合わせ4 2017/06/14

お世話になります。

つまり、今解約されると困るということでしょうか。
解約によって過去のログが消えたりなど、調査に支障がでますか?
解約によって私と連絡を取ることが困難になるなどありますか?

できれば更新月である今のタイミングで契約を切りたいのですが。

イラッときたので具体的に尋ねる。

返答4 2017/06/15

この度は回答までにお時間を頂戴しており、お客様には重ねて
ご連絡いただくお手数をおかけし申し訳ございません。

弊社といたしましても、できる限り早急に
ご返答を差し上げられるよう努めておりますので、
今しばらくお待ちくださいますようお願い申し上げます。

またも、解約に関しては明言してもらえなかった。イライラしつつも、この人たち解約に関して物申す権限もってないんだな…と諦め返信する気が失せた。そのまま続報を待つことに。

返答4-2 2017/06/20

この度は突然のメールとなり、大変申し訳ございません。

お預かりしておりました件について、ご連絡いたします。

お客様の信用情報記録について、
信用情報機関にて情報修正が完了いたしました。

本件につきましては、お客様より多くのお時間を頂戴し、
ご迷惑をおかけいたしましたことを、深くお詫び申し上げます。

また、この度解約をご検討されているとのことですが、
よろしければ解約をお考えの理由についてお知らせいただけないでしょうか。

お客様には重ねてお手数をおかけすることなり、大変恐縮ではございますが、
何卒、ご協力賜りますようお願い申し上げます。

ついに修正が終了したと連絡がくる。

問い合わせ5 2017/06/22

ありがとうございます。

修正が完了した記録はどの信用情報機関のものでしょうか。
実際に私の方でも修正を確認したいのですが、御社のミスの為に各情報機関に手数料を払いたくないので、手数料の補償をお願いできますでしょうか。

また、毎月誤りを記録してしまっていたシステムのほうの修正も完了しましたでしょうか。

解約に関しては、MVNOへの切り替えをもともと検討していたのと、今回の件合わせてという感じです。

以上です、よろしくお願いします。

どの機関の情報を修正したのかどうか、自分でも確認したいけどSoftBankのミスのために手数料を払うのが嫌だということ、システムの方も修正したのかを尋ねる。

返答5 2017/06/24

この度お問い合わせいただきました件につきまして、
確認後、改めてご連絡させていただきます。

恐れ入りますが、回答まで今しばらくお待ちください。

なお、今回ご申告いただいております手数料とは、
具体的にどのようなお手続きに関する手数料になりますでしょうか。

手数料の金額についても併せてお知らせくださいますよう、
お願いいたします。

お客様には大変お手数をおかけすることとなり、誠に申し訳ございませんが、
何卒ご協力賜りますようお願い申し上げます。

問い合わせ6 2017/06/24

お世話になります。

JICCの情報開示手数料1000円とCICの情報開示手数料1000円です。

返答6 2017/06/24

この度は前回伺っております内容につきまして、
お忙しい中詳細をご連絡いただき、ありがとうございます。

ご記載いただいております、
各種情報機関の開示手続きに際する手数料につきましては、
弊社にてご提案できることがないか確認のうえ、
改めて連絡させていただきたく存じます。

早急に対応させていただきたいと考えておりますが、
状況によって回答にお時間を頂戴する場合もございますので、
大変恐縮ですが、あらかじめ御了承ください。

お客様には既に多大なご迷惑をおかけしている中、
重ねてお手を煩わせることとなり、心苦しい限りではございますが、
何卒ご理解ご協力のほど、お願い申し上げます。

返答6-2 2017/06/27

この度は突然のメールとなり、大変申し訳ございません。

お預かりしておりました件について、ご報告のためメールいたしました。

お問い合わせいただいておりました
「毎月誤りを記録してしまっていたシステムの修正」については完了しております。

なお、修正が完了した記録はどの信用情報機関のものであるかにつきましては、
お手数ではございますが、加盟会社について、それぞれの機関(CIC、JICC)に
お問い合わせいただきたく存じます。

また、修正をご確認いただく際に発生する手数料は、
「JICCの情報開示手数料1,000円とCICの情報開示手数料1,000円」とのことですので、
現在お客様にご利用いただいている「ホワイトプラン」の基本使用料934円(税抜)を
2か月分調整(値引き)することでご対応いたしたく存じます。

なお、本提案は実際に情報開示手数料をお支払いされました
タイミングの後に調整を行います。

そのため、お客様には本件についてご案内いたしました本日から
一ヶ月以内に手数料のお支払いをされた旨のご申告をいただいたうえで、
当窓口にて料金調整のお手続きを承りたく存じます。

以上をご確認いただき、ご不明な点がございましたら
再度お問い合わせいただきますようお願い申し上げます。

ホワイトプランの基本料2ヶ月分を値引きするよと言われる。SoftBank解約するっていったじゃん…。

問い合わせ7 2017/06/27

手数料の件ですが、解約する予定ですのでホワイトプランの値引き以外での対応をお願いしたく思います。

以上です、よろしくお願いします。

解約しちゃうから他の方法を求めた。

返答7 2017/06/27

前回のご案内をご確認いただけたとのことで、
お忙しい中ご返信いただき、誠にありがとうございます。

大変恐れ入りますが、手数料の調整につきましては、
利用料金から差し引くことになるため、
解約のお手続きをされる前までに、
ご申告いただきますようお願い申し上げます。

お客様のご意向に沿うご案内ができず、
弊社といたしましても心苦しい限りではございますが、
何卒ご容赦賜りますようお願いいたします。

どうも話が噛み合わないので諦めることに。

問い合わせ8 2017/06/29

お世話になります。

確認致しました。手数料の調整よろしくお願いします。

返答8 2017/06/30

前回のメールをご確認いただけたとのことで、
ご返信いただきありがとうございます。

ご迷惑をおかけしている中恐縮ですが、
CIC/JICCへ情報開示手数料をお支払いされましたら
1ヶ月以内にご連絡をお願いいたします。

お客様には大変お手数をおかけすることとなり恐縮ですが、
何卒ご協力賜りますよう、お願い申し上げます。

また話が噛み合ってない!!

問い合わせ9 2017/06/30

いえ、CIC JICCで情報開示を行い、確認をしましたので、手数料の調整をお願いしますということです。

返答9 2017/06/30

この度は、再度のご連絡にお手数をおかけし誠に申し訳ございません。

今回お支払いいただいたとのことですので、
JICC 情報開示手数料:1,000円(税込)
CIC 情報開示手数料:1,000円(税込)
計:2,000円(税込)を2017年7月ご利用分にて料金調整を承りました。

調整額につきましては、確定後の料金案内にて
ご確認いただきますようお願いいたします。

ホワイトプラン分を調整するっていうから2ヶ月間1000円ずつ値引きしてくれるのかとおもってたけど、1ヶ月で2000円引いてくれるらしい。よかった。

いろいろ思うこと。

以上です。
信用情報の誤記録ってのはたまにあるらしい。定期的に信用情報記録を開示してるというコメントが前回の記事についてた。たまにしておくと安全かも。

信用情報の修正を依頼しても素直に応じてもらえない事もある。信用情報機関は個人からの問い合わせでは修正を行ってくれないので、何としてでも記録を申請している会社に対応してもらおう。

サポートデスクは大変そうだ。大企業の各部署は疎結合だろうし(SoftBankぐらいの規模になると部署どころでなくて会社もちがったりするだろうし)、スタッフが持っている権限も限定的なものだろうし、そもそも彼らはシステムなど全くわからないだろうから、よくある問い合わせであれば別だが今回のような問い合わせに正確に迅速に答えること難しいのだろう。それにしても1ヶ月もかかるとは思っていなかった…。

とはいえSoftBankのサポート、5点満点でいうと2点てところでしょうかね。初動が悪かったし、話が噛み合わないことが何度かあるのはやっぱストレス。
サポートなんてこんなもんかと悟ってたんですが、最近電話したAmerican Expressのサポートの対応はとても丁寧で最高でした。精進しろ。

とりあえずみんなも気をつけてね。僕はもうSoftBankには近寄らんでおく。

AsyncLayoutInflater vs Anko, AnkoはLayoutXMLを殺すのか?

YokomakuさんがAsyncLayoutInflaterLithoのパフォーマンス比較を行っていました。 keithyokoma.hatenablog.com

ちょっと気になったので私もAsyncLayoutInflaterAnkoの比較を行ってみました。

AsyncLayoutInflater? Anko?

AsyncLayoutInflater?

LayoutXMLのInflateを非同期で行います。

Anko?

Kotlin製のView DSLです。コンセプトはいくかありますが以下のような利点が。

  • LayoutXMLのパースを行わないため高速
  • コードでViewを組むのでTypeSafe

以前軽く記事にしています。 lvla.hatenablog.com

Sample Codes

サンプルコードはYokomakuさんのものをfalkさせていただきました。 github.com

AsyncLayoutInflater

<ScrollView
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/scroll"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:layout_below="@+id/text"
    tools:context="io.github.keithyokoma.asynclayout.MainActivity">
    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="vertical">
        <!-- 10000 TextViews -->
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:text="Hello World!"/>
        ...
</LinearLayout>
</ScrollView>
class MainActivity : AppCompatActivity() {

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        val s = System.nanoTime()
        AsyncLayoutInflater(this).inflate(R.layout.activity_main, null) { view, _, _ ->
            setContentView(view)
            val e = System.nanoTime()
            Log.i("TIME", "${(e-s)} nano sec")
        }
    }
}

Anko

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    measureNanoTime {
      val text = "Hello World!"
      scrollView {
        lparams(width = matchParent, height = matchParent)
        verticalLayout {
          for (i in 0..9999) {
            textView(text)
          }
        }.lparams(width = matchParent, height = wrapContent)
      }
    }.let { Log.i("TIME", "$it nano sec") }
  }
}

Benchmark

AsyncLayoutInflater

  • 2268048923 ns
  • 2274749393 ns
  • 2299624654 ns
  • 2346767994 ns
  • 2387729873 ns

Ave. 2315384167.4 ns (2315.38 ms)

Anko

  • 1692746575 ns
  • 1719153036 ns
  • 1676609542 ns
  • 1737803819 ns
  • 1757240852 ns

Ave. 1716710764.8 ns (1716.71 ms)

AsyncLayoutInflater vs Anko

やはりXMLのパースを行わない分、Ankoのほうが速いです。
じゃぁAnkoの方がいいかというとそうでもないかなーと。もしかしたら(Ankoに比べたら)ちょっと遅いけどUI Threadを止めないAsyncLayoutInflaterのほうが良いケースもあるかもしれません。
そして、AnkoではXMLを書かないので当然Databindingを利用できません。

CA.ktでJavaに無い機能をKotlinがどう実現してるのか話してきました。

どうもどうも。

6/15にCyberAgentで開催したCA.kt #1で発表しました。

様子

How Kotlin implements features Java doesn’t have

speakerdeck.com 今回は以下の3つに関して話しました。

  • NonNull/Nullable
  • Extension Function
  • Named Argument/Default Argument

ブログ向けに改めて書き起こします。サンプルコードはKotlinとそのBytecodeをデコンパイルして生成したJavaです。

NonNull/Nullable

関数の引数を例に解説しました。この場合関数がpublicなのかprivateなのか引数がJavaでいうPrimitive型なのかClass型なのかでコンパイル後のBytecodeが行っている処理に変化が置きます。

引数がNonNull-Primitive型

fun nonNullInt(number: Int) {
  number.toString()
}
public final void nonNullInt(int number) {
   String.valueOf(number);
}

これらはもともとnullを許容しないのでそのままコンパイルされます。

  • byte
  • short
  • int
  • long
  • char
  • float
  • double
  • boolean

引数がNullable-Primitive型

fun nullableInt(number: Int?) {
  number?.toString()
}
public final void nullableInt(@Nullable Integer number) {
   if(number != null) {
      String.valueOf(number.intValue());
   }
}

nullableの場合、intのBoxTypeであるIntegerにへコンパイルされます。Integerであればnullを許容するからです。
number?.toString()といったSafe Callはif文でnullチェックを行って実行されます。

引数がNonNull-Class型

fun nonNullString(string: String) {
  string.length
}
public final void nonNullString(@NotNull String string) {
   Intrinsics.checkParameterIsNotNull(string, "string");
   string.length();
}

StringなどのClass型は本来nullを許容する型なので、関数の最初にIntrinsics#checkParameterIsNotNull(Kotlinのruntimeが持っている関数)で引数のnullチェックを行います。JavaなどのNullable/NonNullの区別がない言語からnullを渡される可能性があるからです。

引数がNullable-Class型

private fun nullableString(string: String?) {
  string?.length
}
private final void nullableString(String string) {
   if(string != null) {
      string.length();
   }
}

今度は関数先頭でのIntrinsics.checkParameterIsNotNullの呼び出しがなくなりました。引数のnullのチェックをする必要が無いからです。

Private関数

引数がNonNull-Class型の項でJavaからnullが渡される可能性を考えて、nullチェックを行っていると解説しました。
しかし、この関数をPrivateにするとまた変化が起こります。

private fun nonNullString(string: String) {
  string.length
}
private final void nonNullString(String string) {
   string.length();
}

引数に対する@NotNullアノテーションIntrinsics.checkParameterIsNotNullの呼び出しがなくなりました。Private関数であればKotlin以外の言語から呼び出されない事が保証されるからです(Reflectionは例外ですが)。

Extension Function

Package Level Extension Function

StringExtension.ktファイルの直下に以下のような拡張関数を実装してみます。

fun String.println() {
    println(this)
}
public final class StringExtensionKt {
   public static final void println(@NotNull String $receiver) {
      Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
      System.out.println($receiver);
   }
}

FileNameKtクラスのstatic methodとしてコンパイルされます。引数は拡張対象です。
そして、このExtension Functionの呼び出し元はこのstatic methodを呼ぶようにコンパイルされます。

Class Level Extension Function

class Foo {
  fun String.println() {
    println(this)
  }
}
public final class Foo {
  public final void println(@NotNull String $receiver) {
  Intrinsics.checkParameterIsNotNull($receiver, "$receiver");
  System.out.println($receiver);
  }
}

この場合はFooクラスのmethodとしてコンパイルされます。

Private Package Level Extension Function

Private Package Level Extension Functionは同ファイル内のみからアクセス可能なExtension Functionです。もちろんこちらもPackage Levelなのでstatic methodとしてコンパイルされます。しかし、そのstatic methodの公開範囲はprivateです。

以下のようなコードをFoo.ktに実装した場合について考えてみましょう。

private fun Foo.doSomething() {
}

class Foo {
  init {
    doSomething()
  }
}

Foo#doSomethingはPrivate Package Level Extension Functionなので、FooKtクラスprivate static methodとして実装されます。 FooKtのprivateなメソッドにFooからアクセスできるのはおかしいですね。
そこで、Bytecodeを見てみると以下のようになっています。

public final static synthetic access$doSomething(LFoo;)V
    @Lorg/jetbrains/annotations/NotNull;() // invisible, parameter 0
   L0
    LINENUMBER 1 L0
    ALOAD 0
    INVOKESTATIC FooKt.doSomething (LFoo;)V
    RETURN
   L1
    LOCALVARIABLE $receiver LFoo; L0 L1 0
    MAXSTACK = 1
    MAXLOCALS = 1
  ...

Fooを引数とするpublic final static synthetic access$doSomethingというsynthetic methodが生成されています。 これはコンパイラが自動生成したメソッドです。これを呼び出し元をこのメソッドを経由するようにすることでFooからFooKtのprivate static methodにアクセスします。

余談ですが、synthethic methodJavaNested Classを実装したときにも生成されます。Outer classInner class間でprivateなメソッドまたはフィールドにアクセスしようとした時です。JavaにはNested Classの仕様がありますが、Bytecode上は別々のクラスとしてコンパイルされるからです。

Named Argument

fun foo(one: String, two: String, three: String) {
}

foo(three = "tres", two = "dos", one = "uno")
String var1 = "uno";
String var2 = "dos";
String var3 = "tres";
this.foo(var1, var2, var3);

Named Argumentは一度変数に代入してから順番を揃えて関数を呼び出すようにコンパイルされます。

Default Argument

fun foo(one: String = “one",
        two: String = “two",
        three: String = "three") {
}

foo(two = "dos")
// staticなのはfoo関数をパッケージレベルに実装してコンパイルしたため。
public static void foo$default(
    String var1, String var2, String var3, int var4, Object var5) {
   if((var4 & 1) != 0) {
      var1 = "one";
   }
   if((var4 & 2) != 0) {
      var2 = "two";
   }
   if((var4 & 4) != 0) {
      var3 = "three";
   }
   foo(var1, var2, var3);
}

foo$default((String)null, "dos", (String)null, 5, (Object)null);

Default ArgumentfunctionName$defaultというメソッドが生成され、その中から関数を呼ぶようにコンパイルされます。 この例では、第1引数〜第3引数は元の関数と一致し、第4引数はDefault Argumentを適用するべき位置をこの$defaultメソッドに教えるための設定値、第5引数のObjectは用途不明です(誰か教えてくれ)。
Default Argumentを適用すべき箇所を1すべきでない箇所を0と表現します。
すると、foo$default((String)null, "dos", (String)null, 5, (Object)null)1, 0, 1となります。101を10進数に治すと5になります。これを第4引数に代入しています。 $defaultメソッドの中では101001, 010, 100論理積0と比較することでDefault Argumentを実際に適用するかどうかを決定しています。

こういった知識は必要なのか

上記はほんの一部に過ぎないが、KotlinはこのようにしてJavaが持たない機能を実現している。私達がよくある無駄なコードを書く手間をコンパイラが肩代わりしてくれています。
この知識が必要かといわれると、基本的には必要ないと思う。しかし、Javaとの相互運用を行う際にKotlinのコードがJavaからどうみえるのかといったことが分かると無駄にハマることが減ると思う。
たとえば、AndroidDataBindingBindingAdapterstatic methodを利用する。これをそのままKotlinでcompanion objectで実装しようとしてもうまくいかない。companion objectはそのクラスのinner class Companionとしてコンパイルされ、そのクラスのstatic fieldとなるからです。
そこで、Javaからどうみえるかを意識できていれば「@JvmStaticアノテーションを使おう」だとか「Extension Functionとして実装しよう」といったことが思いつきます。

SoftBankのミスで信用情報ブラック認定されてしまってるっぽい。

f:id:lvla:20170531230227p:plain

tl;dr

  • 6年前にiPhone4を分割購入してる。
  • MySoftBankを見ると完済したことになってる。
  • 信用情報記録にはiPhone4の代金として1000円が未払いということが、毎月記録されていた。
  • しょうがねーからメールで問い合わせてる。

全然クレジットカードが作れない。

やらしい話になるが同世代の平均収入よりもそこそこ多い額をもらっているはずだが、楽天カードですら落ちる
3回くらい落ちてる(ちゃんと期間を置いて申請してるよ)。
学生の頃に作った上限額の低い銀行系カードの上限額引き上げもできない。

おかしい。

信用情報記録開示を行った

しょうがないのでCICとJICCで信用情報記録をした。

すると、2011年5月11日にソフトバンクと契約した4.6万円24回払いのiPhone4(当時流行りの月月割で実質0円という奴)の残り1000円の支払いが2013年8月21日から滞っていると記録されていた。

えっ。約4年間も支払いを踏み倒しているんですか!!
そりゃぁブラック認定でクレジットカードの審査通らないわけだよ。

でもそれはおかしい。

完済してる。 f:id:lvla:20170531223013p:plain
MySoftBankで割賦契約内容を照会した。

そりゃそうだよなー。完済してなかったらその後iPhone5iPhone6の分割払いを却下されるはずだ。
督促も来てないし、そもそも未払いがあれば引き落とされるはず。

ただ、気になるのはこのページにてiPhone5iPhone6に関する記載が無いこと。

  • もしかしたら正常に支払い処理が完了している契約はここに表示されないっていう仕様で、iPhone4のみが支払いは正常に完了しているがなんかのフラグがtrueになったままのためこのページに表示されてるんじゃないか?
  • 引落しや未払いの督促、信用情報の記録を行うバッチ処理で参照するテーブルが別々なため矛盾が生じてるんじゃないか?

とかいろいろ想像できる。それは辛い。データに不整合が起きないようにデータベースを改善せねば。

プレスリリース出してた

www.softbank.jp
(2013年の情報)

分割支払金等をご入金いただいたにもかかわらず、未入金として信用情報機関※1に登録してしまうという事象が発生しておりました。
(略)
現時点において、誤登録された情報は、全て正しい信用情報へと修正されております。
影響が生じた可能性のある件数は、16,827件となります。
(略)
影響があったかもしれないお客さまへのお詫びとご連絡をさせていただきました。

連絡はもらっていないし、現在もたった1000円ぽっちを4年間踏み倒していると演出されつづけているんですが…。

メールした。

これでは一生ブラックリスト入りになってしまう。それは不便。
クレジットカードつくれないし家も車もローン組めない(両方欲しくないけど)。

経緯の説明と修正の依頼をメールした。
なんか続報あったら書くかもしれないし、書かないかも。

ついにGoogleがAndroidKotlin公式サポート👍🏻

blog.jetbrains.com

本日のGoogle I/O 2017にてGoogleAndroid開発言語としてKotlinを公式サポートすることを発表しました。 First class language、なんていい響きなんでしょう。

youtu.be

Stephanieの発表の中で突然の「One more thing…」
すると見たことのある形がパターンロックとして出現し…
f:id:lvla:20170518063159p:plain
Kotlinのロゴが!!
f:id:lvla:20170518063208p:plain
沸く会場
f:id:lvla:20170518063353p:plain
JetBrains CEOやAndrey Breslavが映し出されました。
f:id:lvla:20170518063615p:plain

その後のDeveloper向けKeynoteでもKotlinはたくさん登場しました(現在進行系で登場している)。
youtu.be

既存コードとの共存が可能であることや
f:id:lvla:20170518064153p:plain
機能の紹介
f:id:lvla:20170518064139p:plain
すでにプロダクションで利用されていることなどが話されました。
f:id:lvla:20170518064246p:plain

JetBrainsのAndrey BreslavとHadi Hariri、みんな大好きJake Wharton、PinterestのChristina LeeによるKotlinセッションの告知もされていました。
f:id:lvla:20170518064542p:plain

CyberAgentに入社しました。

2017年3月末でEurekaを退職し、4月にCyberAgentに入社しました。

誰?

前職

10ヶ月間、EurekaでPairsというデーティングサービスのAndroidアプリ開発をやってました。
ORMの移行とかアーキテクチャの刷新、新機能開発なんかをやってました。そこら辺に関しては適当にこのブログに書いてあるので興味があれば読んでみてください。

4, 5年前からあるアプリということできついコードに溢れていましたが、改善しようともがくことで色々学ぶことができました。また、大好きなKotlinの導入を受け入れてくれたチームにも感謝しています。

転職

1年も経たずにやめてしまったのでやばいことでもあったのかと聞かれます。
組織への不満は多少ありましたが、私には致命的な出来事はありませんでした。私には。

なのですぐ転職しようというよりもそのうちに転職しようくらいの温度感だったんですが、組織への不満が蓄積し始めた頃にCyberAgentから声をかけてもらい、以前から働いてみたいと思っていたので早めではありますが転職するに至りました。

前職の組織への不満はネット上に書くのは生々しいので聞きたい方はオフラインで聞いてください。

現職

f:id:lvla:20170427014831j:plain
(俺より強い奴っていうと失礼ですね、すみません。)

なぜ働いてみたかったというとこんな感じでしょうか。

  • 凄腕Androidエンジニアが多数在籍している
  • 動画を扱うプロダクトの開発をしてみたかった
  • AbemaTV, AWA, FRESH!などを見ていまの自分では作れなさそうなUIのクオリティに魅せられた
  • KotlinといえばFRESH!

そして今はFRESH!Androidアプリ開発を行っています。ちょうど今日リニューアル版がリリースされました。

今までModel層をメインに書いていたので、凝ったUIのプロダクトでViewの技術を学ぶ機会を得ることができました。また、動画を扱うプロダクトも初めてのことなのでそこら辺の技術に触れられることも楽しいです。

優秀なエンジニアが多く学ぶことが多いですし、価値に繋がるのであれば新しい技術でもガンガン導入していくスタイルなので刺激的です。

労働環境も良いです。一人あたりのワークスペース広いし、まだ行ってないけど集中部屋とかあるし、リモートワークできるので心に余裕ができました。

それではまた、どこかの勉強会で。

Mock the un-mockable Kotlin classes

f:id:lvla:20170430014523p:plain

tl;dr

  • Kotlinクラスはデフォルトfinalだからモックできない
  • Mockito2ならできるよ

Kotlinのクラス、関数はデフォルトでfinalだからモックできない。

Kotlinのクラス、関数はデフォルトfinalで継承もオーバーライドもできないのでMockitoでモックすることができません。
なので今までは以下のどれかでモック可能な状態にしていました。

  • openで継承可能、オーバーライド可能にする
  • All-open pluginでクラス/関数をすべてopenにする
  • Interfaceに切り出しておく
  • PoweMockを利用する

Mockito2.1.0でfinalでもモックできるようになった

Mockito2.1.0でMockMakerというものが導入されました。ただしMockMakerはまだ実験的段階で、デフォルトではオフになっています。
MockMakerを利用する方法は2つ用意されています。

MockMaker fileを用意する。

src/test/resources/mockito-extensionsディレクトリに以下の一行を含むorg.mockito.plugins.MockMakerファイルを置きます。

mock-maker-inline

たった一行のファイルを置くだけなのでそんなに手間ではないかな?

mockito-inlineを利用する

こちらはgradleでdependenciesを書き換えるだけです。

dependencies {
    //  testCompile "org.mockito:mockito-core:2.x.y"
    testCompile "org.mockito:mockito-inline:2.x.y"
}

どちらを利用するか

私は基本的にMockitoは直接扱っておらず、mockito-coreに依存しているKotlin向けのExtensionライブラリを利用しているのでMockMaker fileを置く方法を利用してます。