SDD(Sleep-Driven Development)

睡眠の重要性!!睡眠の重要性!!

Rider Build 11でソリューションが読み込めない

追記

10/22のBuild 12にて日本語でも問題なくソリューションを開けることを確認致しました。

追記ここまで

現在(2016/9/27)Riderの最新のバージョンであるビルド11でソリューションが開けなくなるバグがあります。

具体的に書くとソリューションを開こうとするとエラーっぽいのが表示されてその後もう一度開こうとすると永遠にソリューションの読み込みをします。初期の頃を思い出す・・・

このバグに対する対処が下記に載っています。

https://youtrack.jetbrains.com/issue/RIDER-2431

対処法はなんと・・・

_人人人人人人人人人人人人人人人人人_
> システム言語を英語にする!!! <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

私は英語苦手マンなのでOSの言語はもちろん日本語なのですがこれが原因でした・・・。
あと中国語もアウトっぽいですね。

この手のバグはいつになったら駆逐されるのでしょうか・・・。

Public EAP!?

そして上記のyoutrackを見て気づきました。

なんとラベルに Public EAPが!!!!!!!!!!

EAP 12の横にPublic EAPのタグがあります!

他のやつ見てみるとついていたりついてなかったりまちまちで判断に困るのですがもうすぐPublic EAPがくると思うと感慨深いですね。。

とりあえずBug FixされたBuild 12の公開はよ

macOS SierraでKarabinerが使えないときの応急処置

9/21にmacOS Sierraが正式リリースされました。

私も勇んでアップデートしたのですがやはりいろいろ問題があったり(ログインパスワード勝手に変えられたりGoogle Chromeがバグっぽい挙動したり)

その中でも特に困ったのが Karabinerが使えない

macOSのUSキーボードユーザーにとっては致命的です。

これの回避方法は他のアプリを使うなりすればいいのですがKarabinerの公式サイトを見たら単純なキーの変更を行えるKarabiner-Elementsというものを開発中らしい。

今回はそのKarabiner-Elementsを使ってとりあえずかなを使えるようにしてみました。

インストール

まずはインストール。

https://github.com/tekezo/Karabiner-Elements

のページにある

https://pqrs.org/latest/karabiner-elements-latest.dmg

からイメージファイルを落としてきます。

インストール自体は他と変わらなくハイハイ押せばいいのですが、最後に外付けキーボード使ってないのにキーボードが見つかりません的なウィンドウが出たら何も押さず閉じちゃって大丈夫です。

設定ファイル

インストールが終了したら設定ファイルを書きます。

設定ファイルの置き場所は~/.karabiner.d/configurationです。なかったらたぶんKarabiner-Elementを起動すれば作られるはず。

最初はconfigurationの中身は空っぽなので適当にターミナルから

vi ~/.karabiner.d/configuration/karabiner.json

で設定ファイルを作成します。そして試しに

{
    "profiles": [
        {
            "name": "Default profile",
            "selected": true,
            "simple_modifications": {
                "caps_lock": "japanese_kana",
                "right_shift":"japanese_eisuu"
            }
        }
    ]
}

と編集して保存してみてください。

そうするとcaps_lockで日本語入力が、右Shiftキーで英字入力ができると思います。

現在はまだ開発途中で単純なキーの入れ替えしかできないようなのでKarabinerのようにCommandキー1回押すと日本語入力みたいな器用な真似はできません(たぶん)。

なので個人的に使わないキーであるcaps_lockと右Shiftキーに英語日本語キーを割り当てました。

他のキーに割り当てたい場合は

https://github.com/tekezo/Karabiner-Elements/blob/master/src/share/types.hpp

にキーの割当一覧が乗っているので適宜変更してください。

MacでC#ユーザーのRider入門〜便利機能〜

今回はRiderの便利機能の紹介

getonlyから変更通知プロパティへの変換

Xamarin.Formsをやっていると変更通知プロパティが結構出てくるのですが、もしもともとあるプロパティを変更通知可能にしようとする場合バッキングフィールド書いて〜プロパティのsettergetter書いて〜は結構手間だと思います。

Riderならそんな面倒な変換も一瞬でやってくれます! 例としてgetonlyプロパティをregion付きの変更通知プロパティに変えてみました。

f:id:crocus7724:20160918141140g:plain

Autoプロパティからバッキングフィールドのプロパティへの変換がAlt+Enterで簡単にできます!しかもバッキングフィールドの名前はプロパティの名前のアンダーバー+ロワーキャメルケースへ自動的に変換。めっちゃ便利。

Currentメソッド作成

また、よくあるかわからないけどシングルトンパターンを作るときに初回はインスタンス作成して次回以降はそれを使いまわすみたいな感じになると思いますがこれもRiderならスラスラ書けます。
Sample Current{get;}=new Sample();でいいだろという声は聞こえません

f:id:crocus7724:20160918141236g:plain

なんとnullチェックで冗長だった場合短い構文に書き換えてくれます!!素晴らしい。

Linqサポート

冗長だったやつを短いのに変えるのはnullチェックだけではありません。もしforeachで長い文を書いていた場合Linqに変換してくれます。

f:id:crocus7724:20160918141350g:plain

個人的に+=じゃなくて=が嬉しいですがまあ問題ないんでしょう。

リネーム

リネームのためだけにRiderを開いてもいいほど強力です。どのくらい強力かというと条件があうと別プロジェクトのコメントアウトした部分もリネームするか聞いてきます。

例としてバッキングフィールド付きプロパティをリネームしたとき

f:id:crocus7724:20160918141407g:plain

ちゃんとバッキングフィールドも一緒にリネームするか聞いてきます。地味に凄いですね。

Search Everywhere

これはIntelliJを使っている人ならよく知っていると思いますがShiftキーを2回押すことでいろんなものを検索します。

なんとこれクラスやシンボルだけでなく設定まで検索できます。

f:id:crocus7724:20160918142328g:plain

これでいちいちあの設定はどこだっけと悩む必要はなくなりますね!

ほかにもいろいろ便利な機能がありますがこの辺で。

とりあえずAlt+EnterとSearch Everywhereが便利すぎです。

MacでC#ユーザーのRider入門〜インストール〜

RiderとはJetBrainsが開発中のCross-platform C# IDEです。 詳しくはこちらを御覧ください。

Project Rider – 新しい C# IDE #jetbrainsrider | JetBrains ブログ

ReSharpermacOSで使えます。

ReSharpermacOS で使えます!!

(あとIntelliJなどのプラグインも使えます)

これは使うしかありません。さっそくインストールしましょう!!

注意

まずRiderは2016/9/17現在Private EAPです。上のリンクにはリリースは8月を予定と書いてある通り、当初の予定では2月にPrivate EAP、6月ごろにPublic EAP、8月か9月ころに正式リリースだった記憶があるのですが、Private EAPもギリギリまで遅れ(日本時間で2/29の24時頃だったのでギリギリセーフ(?))それから未だにPrivate EAPです。なので

  • Xamarinのプロジェクトは作れません。Xamarin Studioをお使いください。
  • Xamarinのプロジェクトを実行できません。Xamarin Studioをお使いください。
  • プロジェクト操作がかなり怪しいです(ファイル削除してもファイルが残る)。Xamarin Studioでも怪しいです。

ただし、現在のPrivate EAP10ではだいぶ使い勝手もよくC#でコーディングする分にはほぼ問題ありません。むしろReSharperが素敵すぎます。

インストール手順

まずはPrivate EAPのサブスクライバーに登録します。

以下のページの下の方で申し込みが出来ます。

www.jetbrains.com

入力が終わったらSubscribeを押します。すると2-3分以内にメールがくるのでそのメールにあるOS Xのダウンロードリンクを押します。

するとdmgファイルが落っこちてくるのでインストールします。

f:id:crocus7724:20160917200425p:plain

インストールが終了したら早速起動してみましょう。

最初にこんな画面が出てきました。

f:id:crocus7724:20160917200505p:plain

以前のバージョンなんて無いので下を選択します。

次にどちらのUIを使うかの選択肢が出てきました。

f:id:crocus7724:20160917200535p:plain

LightかDarkですね。私は断然Dark派です。

次にどのエディターカラーを使うかを選択します。左がReSharper(違和感あるけど)、真ん中がVisualStudio(違和感あるけど)、右がDarcula(というかIntelliJ)ですね。

f:id:crocus7724:20160917200555p:plain

私は初期のRiderがReSharper一択で慣れてしまったのでReSharperです。

お次はKeymapです。

f:id:crocus7724:20160917201014p:plain

Visual StudioライクかReSharperライクかIntelliJIDEAライクかが選択できます。個人的にはあとで設定から変えられるReSharper(macOS)が好きですが初期設定でも結構キーが衝突しているのでmacOSユーザーならIntelliJのキーマップがいいのかな?

お次はターミナルからRiderを起動できるようにするかです。

f:id:crocus7724:20160917201123p:plain

私は結構ターミナルを使うことがあるのでとりあえずチェックを付けときました。

最後はチュートリアルやバグ報告する場所などのリンクです。

f:id:crocus7724:20160917201141p:plain

では早速Start using Riderを押しましょう!

f:id:crocus7724:20160917201230p:plain

IntelliJプラットフォームユーザーなら見慣れた画面が出てきました。

これで準備は完了です。お疲れ様でした!!

SynchronizationContext.Currentでnullが返ってくる

躓きかけたのでメモ

C#で以下のようなメソッドを書いたとします。

//Task.Run(()=>Hoge())などで呼び出す
public void Hoge()
{
    //ネイティブUI操作
}

これを非同期(バッググラウンドスレッド)で触ろうとすると死にます。いわゆるUIスレッド以外でUI要素に触ってはいけない問題です。これを回避するにはUIスレッドで実行してやればいいだけです。

PCLの場合、呼び出し側が自分で制御できる場合は例えばTaskSchedulerクラスのFromCurrentSynchronizationContextを使えば問題ないわけですが

//var sheduler=TaskScheduler.FromCurrentSynchronizationContext();
//Task.Factory.StartNew(()=> { Hoge(); },CancellationToken.None,TaskCreationOptions.None, sheduler)で呼び出す
public void Hoge()
{
    //ネイティブUI操作
}

ライブラリ等で呼び出し側を自分で制御できない場合SynchronizationContext.Current.Postメソッドを使えばいいです。

しかしこれにも少し問題があって例えば以下のようなコードを書くと死にます。

//Task.Run(()=>Hoge())などで呼び出す
public void Hoge()
{
    SynchronizationContext.Current.Post((_=>
    {
        //ネイティブUI操作
    },null));
}

何故かと言うとSynchronizationContext.CurrentはUIスレッド以外で呼び出すとnullが返ってきてヌルポるからです。

これを回避するには必ずメインスレッド中で変数などに確保しておくのが手っ取り早いです。もしHoge()のクラスがバックグラウンドスレッド以外で初期化されるならフィールドに確保しておくのが一番簡単でしょう。

SynchronizationContext context=SynchronizationContext.Current;

//Task.Run(()=>Hoge())などで呼び出す
public void Hoge()
{
    context.Post((_=>
    {
        //ネイティブUI操作
    },null));
}

しかしクラスの初期化自体がバックグラウンドスレッドの場合はフィールドで初期化でもヌルポるかもしれません。

これを回避するには絶対にUIスレッドで実行されるところで初期化してstaticにもたせてあげればよさそうなのですが少し面倒ですね・・・

Xamarin.Forms macOSをとりあえず実行してみた

9/7、GithubのXamarin.FormsにmacOSブランチが生えました。

これでXamarin.Formsを使えばWindows(UWP)、AndroidiOSmacOSとほぼ全ての主要なプラットフォームを1ソースで書けるようになりました。やったねXamarin.Formsちゃん!対応するプラットフォームが増えたよ!!

さっそく動かしてみました。

git colne

最初にGithubからXamarin.FormsのmacOSブランチをクローンします。

Kazuki:Projects Yamamoto$ git clone -b macOS https://github.com/xamarin/Xamarin.Forms.git
Cloning into 'Xamarin.Forms'...
remote: Counting objects: 9996, done.
remote: Compressing objects: 100% (89/89), done.
remote: Total 9996 (delta 34), reused 0 (delta 0), pack-reused 9907
Receiving objects: 100% (9996/9996), 14.51 MiB | 1.73 MiB/s, done.
Resolving deltas: 100% (6314/6314), done.
Checking connectivity... done.

Xamarin Studioで実行

そしたらXamarin.Forms.slnをXamarin Studioで開きます。最初は各プロジェクトだけ開いて実行してましたがたまに起動できなくなったりして面倒くさくなったのでまとめて開くことにしました。

開いたらソリューションオプションを開き、スタートアッププロジェクトをXamarin.Forms.ContorlGallery.MacOSに変更します。

f:id:crocus7724:20160911051823p:plain

あとは実行ボタンを押せば起動できます!

f:id:crocus7724:20160911051848p:plain

うーんボタンに歴史を感じますね。あと適当にリストを選択するとクラッシュして死にます。

Demoページ

実行出来たのはいいですがデモはTwitter風でした。これはXamarin.Forms.Controls.MacTwitterDemoになります。なのでXamarin.Forms.Controls.App.csのMainPageを差し替えてあげます。

MainPage = new MacTwitterDemo();

そしてもう一度実行します。

f:id:crocus7724:20160911051934p:plain

ちゃんとデモみたいにTwitter風のページが表示されました。こっちはいい感じ。なおボタンとかは全部押せません。

ちなみにXamarin.FormsなのでiOSでもデモページを表示できます。

もう一度ソリューションオプションを開きスタートアッププロジェクトをXamarin.Forms.ControlGarally.iOSに変更して実行します。

f:id:crocus7724:20160911051952p:plain

画像が表示されてません。しかしそれ以外は表示できてるので問題無いですねハイ。

現在ブランチが生えただけですがそのうち正式にサポートされるでしょう。今は楽しみにやm・・・やりがいが増えるのを待ってます。

MacでNuGetパッケージを作成するときの注意

MacでNugetパッケージ作ってたときハマったのでメモ

nugetのバージョンは3.4.4.1321

Macでもnugetコマンドを使えばNugetパッケージを作れるのですが若干罠めいたものがあります。

結論から先に言うと.nuspecは.slnと同じ階層でパスは相対パス



では実際に問題のあるやり方をしていきましょう。

とりあえず例としてXamarin StudioでXamarin.Formsライブラリプロジェクトを作成してSampleと名づけました。

これをNugetパッケージにするときプロジェクトの真下にいろいろ広げてもいいのですが、たとえば複数プロジェクトを対象とするときは.slnと同じ階層にディレクトリを作ってそこに.nuspecなどを置く人もいると思います。

今回はtoolsというディレクトリを作り、そこでnuget specで.nuspecファイルを作成し以下のように編集しました。

<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
  <metadata>
    <id>Sample</id>
    <version>1.0.0</version>
    <authors>Yamamoto</authors>
    <licenseUrl>http://LICENSE_URL_HERE_OR_DELETE_THIS_LINE</licenseUrl>
    <projectUrl>http://PROJECT_URL_HERE_OR_DELETE_THIS_LINE</projectUrl>
    <iconUrl>http://ICON_URL_HERE_OR_DELETE_THIS_LINE</iconUrl>
    <requireLicenseAcceptance>false</requireLicenseAcceptance>
    <description>Sample NuGet Package</description>
    <copyright>Copyright 2016</copyright>
    <tags>Sample</tags>
    <dependencies>
      <dependency id="Xamarin.Forms" version="2.3.1.114" />
    </dependencies>
  </metadata>
  <files>
    <file src="../Sample/bin/Debug/Sample.dll" target="lib"/>
  </files>
</package>

今回特にどこかで公開するようなパッケージではないのでlicenseUrlとかはデフォルトそのまま。

あとはnuget packしてあげればパッケージが作られます。

Kazuki:tools Yamamoto$ nuget pack Sample.nuspec -OutputDirectory ~/Nuget
'Sample.nuspec' からパッケージをビルドしています。
パッケージ '/Users/Yamamoto/Nuget/Sample.1.0.0.nupkg' が正常に作成されました。

私は~/Nugetに私物のNugetを置きXamarin Studioなどで参照させているので-OutputDirectoryオプションをつけています。

今回は特に問題なくパッケージが作成されました。

そして別プロジェクトでNugetパッケージを追加して早速使おうとするのですが・・・

f:id:crocus7724:20160910190400p:plain

表示されません。(本当なら名前空間にSampleがあるはず)

どういうことでしょうか?

とりあえずNugetパッケージはできているのに名前空間が出てこないということは.dllが参照されていない可能性があります。

相対パスがいけないのかということでsrcを絶対パスに。

<file src="/Users/Yamamoto/Projects/Sample/Sample/bin/Debug/Sample.dll" target="lib"/>

そしてまたnuget pack

Kazuki:tools Yamamoto$ nuget pack Sample.nuspec -OutputDirectory ~/Nuget
'Sample.nuspec' からパッケージをビルドしています。
Directory '/Users/Yamamoto/Projects/Sample/tools/Users/Yamamoto/Projects/Sample/Sample/bin/Debug' not found.

な に こ れ

なんと絶対パスで書いても相対パス扱いされてる。うーん意味がわからない。

なおNuspec Referenceのsrcの説明には

The location of the file or files to include. The path is relative to the NuSpec file unless an absolute path is specified.

とあります。私は英語苦手だけどGoogle先生の力を借りて読むと絶対パスを指定しない限り相対パスになるよとのこと。なら問題なく絶対パスが使えるはずなんだけど使えない辛い

なお解決方法は簡単です。諦めて.slnと同じ階層に.nuspecを置き

 <file src="Sample/bin/Debug/Sample.dll" target="lib"/>

にします。あとはnuget packしてあげてパッケージを新しいのにしてあげれば・・・

f:id:crocus7724:20160910190330p:plain

はい、無事に追加出来ました。

結論

MacでNugetパッケージを作るときは絶対パスも../も使わない

以上、Macでnuget怪奇現象でした。