Crashlytics Invocation Error

チームメンバーがCrashlyticsをインストールしてくれたのだが、ビルドに失敗したので、どうすればいいのか調べた。

エラーメッセージはこちら

Shell Script Invocation Error
Command /bin/sh failed with exit code 1
Crashlytics: You must install Crashlytics to continue. https://api.crashlytics.com/api/v1/******************/confirm/jp.app.appName

If this machine is a build server please remove Crashlytics.app if present and use xcodebuild so that ukissAlarm.app.dSYM is uploaded.

解決方法は単純で、Crashlyticsのビルドツールをインストールしていなかったことが原因であった。

https://crashlytics.com/downloads

Crashlyticsはなかなか良いツールだけれど、導入方法の説明ページを見つけづらくて参った。Qiita等を見てやっと解決に辿り着いた。


Crash Report解析サービスのCrashlyticsを試してみた

今回の不正解ルート
パーミッションの変更:iOS xcode 5 crashlytics error - Shell Script Invocation Error - ./Crashlytics.framework/run: Permission denied

試していないもの
Crashlytics.appを一旦削除:Crashlytics build script fails on Xcode Server CI

Scala: ファイルの内容を一行ずつ処理したい

java.nio.file.Filesで一行ごとに処理(ただしScala)

Java SE 7のjava.nio.file.Filesがとても便利な件

ファイルの内容を一行ずつ読み込んで処理したい場合に、今まではこちらのページ:(Fileの読み込み - Scala覚書)を参考に実装していましたが、nioを使えば簡単だったので、メモしておきます。

val file = Paths.get(path)
Files.readAllLines(file, Charset.defaultCharset())
     .foreach(println)

Charset.defaultCharset()が鬱陶しいですがそれに目を瞑ればシンプルです。 scala.io.Sourcejava.io.BufferedReadercommons.io.FileUtils だといずれもバッファをクローズする必要があるので、それに比べればだいぶ良いのではないでしょうか。

巨大なファイルのとき

これは、scala.io.Sourceを利用するのがよさそう。構造的部分型を利用したローンパターンを使わなければならないので、そのぶんコードが膨らみますが、そのぶん使用箇所はシンプルにまとまります。

using(Source.fromFile("file.txt")) {
     _.getLines().foreach(println)
}

def using[A <% { def close():Unit }](s: A)(f: A=>Any) {
     try f(s) finally s.close()
}

また、using内でSourceのもつメソッドを十分に活用したい場合は、構造的部分型での一般化を諦める必要があります。
参考:Scala using(ローンパターン)-Hishidama's Scala Memo-

Logbackで設定ファイルを読み込む

Logbackで設定ファイルが意図したとおりに読み込まれないという現象に遭遇したので、改めてまとめる。

読み込み順序

優先順位の高いものから順に読み込まれる。上位の条件にヒットした場合は、次の条件へは進まない。

  1. クラスパスから logback.groovy を検索する。
  2. クラスパスから logback-test.xml を検索する。
  3. クラスパスから logback.xml を検索する。
  4. JVMが ServiceLoader (JDK 6 and above) を実行している場合、ServiceLoaderは、インターフェース com.qos.logback.classic.spi.Configurator の実装のうち、最初に発見されたものを使用する。
  5. 以上がいずれも存在しなかった場合、 BasicConfigurator を使用する。

クラスパスは、起動オプション -classpath (推奨)または環境変数 ${CLASSPATH} で指定する。クラスパスで指定したディレクトリ直下のみを読み込む。

BasicConfigrator を使用する場合、ログの出力先は標準出力に向けられる。

参考: 公式

xmlファイルをjarに含めない場合

設定が変わるたびに毎度ビルドするのは面倒なので、起動オプションで指定する方法。
あらかじめjarファイルの生成時にlogback.xmlを除外したうえで、以下のオプションを指定しつつ起動すればよい。

-Dlogback.configurationFile=./logback.xml

controlling logback configuration in standalone app
Exclude logback.xml in Jar file

Scala.jsでNode.jsのモジュールを呼び出したい

Scala.jsでNode.jsのモジュールを呼び出したい

import scala.scalajs.js
import js.Dynamic.{global => g}
import js.DynamicImplicits._

val app = js.Dynamic.global.require("app")

参考1にあるように require("app") だけを指定しても、Predefのrequireしか見つからずコンパイルエラーとなったので、参考2のように明示的に指定しています。

参考1:How to invoke nodejs modules from scala.js? -stackoverflow-
参考2:scala-js/scala-js - Gitter - 2015/03/02