読者です 読者をやめる 読者になる 読者になる

酢ろぐ!

カレーが嫌いなスマートフォンアプリプログラマのブログ。

バージョン0.2 PreviewになったWindows Bridge for iOSを使ってみた

唐突にWindows Bridge for iOSのことを思い出しました。

Windows Bridge for iOSは、Objective-Cで書かれたiOSアプリをWindowsで使えるようにするプロジェクトの名称です。

Build 2015で発表された当時、Project Islandwoodと呼ばれていました。2015年8月にWinObjCの名称でプレビュー版がでました。2016年7月に現在の名称であるWindows Bridge for iOSの名称でローンチされました。*1

iOS APIをWindows APIにラッピングすることで、iOSで書いたコードを再利用してWindowsで使うことができるようにするという試みです。たしか2015年時点にはSwiftの破壊的仕様変更が諸々発生していたころで、まだObjective-CからSwiftへの移行は時期尚早ではないかと話していたような気がします。

2017年現在、多くのiOSアプリプロダクトはSwiftに移行したか、そうでないプロダクトに関してはXamarinやRuby Motion、React Nativeへの移行を済ませてしまっているかもしれませんね。

現在のWindows Bridge for iOSについて調べる

以前にも同じように調査していました。2015年8月時点、バージョンは(たしか)付けられておらずdevelopブランチからgit cloneしてきたもので確認していました。

2016年7月時点。バージョンは「0.1 Preview (July 15, 2016)」でした。

現在のWindows Bridge for iOSのバージョンは「0.2 170228 (Feb 28, 2017)」です。マイナーバージョン番号が繰り上がっています。

Windows Bridge for iOSプロジェクトの良いところは、「iOS APIでやっていたことをWindowsで実現したい」と考えた時に実装をみることで理解を深めることができるかもしれません。反面、まだAPIの互換性は完全ではないので一部実装に関してはスタブになっている部分もあります。

f:id:ch3cooh393:20170312161101p:plain

どれだけ互換性が上がっているのか調査する

以前、作成したUITableViewにカスタムセルを表示させるサンプルプロジェクトが残っていたのでそのまま流用してみました。

0.2になってもUITableView#registerNibを使ってnibを登録してセルを利用しているのはうまくWindowsでは再現できていませんでした。

f:id:ch3cooh393:20170312215713p:plain

xibの解釈が上手くいっていないのかもしれないですね。

デフォルトのセルであれば、下記のようにセルに画像を設定したのもきちんと表示されていました。これは0.1 Preview (July 15, 2016)から変わらずできるようです。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
    UIImage *image = [UIImage imageNamed:@"chiich4_1"];
    
    NSDate *object = self.objects[indexPath.row];
    cell.textLabel.text = [object description];
    cell.imageView.image = image;
    
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"InkoCell" forIndexPath:indexPath];

    return cell;
}

f:id:ch3cooh393:20170312220346p:plain

トラブルシューティング

しばらく触っていなかったのもあり、今回Windows Bridge for iOSを使うにあたってハマってしまいました。

サポートされていない16ビットアプリケーション!と警告がでてしまう

Releaseの.zipではなくSource Codeの方の.zipファイルをダウンロードしてしまっていたようです。

最初原因がわからず右往左往してしまいました。変換プログラムのvsimporter.exeで実行時にエラーが発生してしまいます。

>cd C:\works\tableviewsample2
>C:\works\WinObjC-0.2.170228\bin\vsimporter.exe

本来この時点で.xcprojからVisual Studio向けの.slnが生成されるのですが、エラーダイアログが表示されてしまいます。

f:id:ch3cooh393:20170312164135p:plain

Visual Studio 2015 Update 3をインストールする(本質的な解決にはなりませんでした)

Windows Bridge for iOSを利用するのに必要なのはVisual Studio 2015 Update 3でした。

  • Windows 10, build 10586 or higher.
  • Visual Studio 2015 Update 3

VSのバージョンを調べてみるとVisual Studio 2015 Update 2のままだったようです。

f:id:ch3cooh393:20170312164622p:plain

Update 3へのアップデートに時間がかかっていたので放置して出かけました。Visual Studio 2015 Update 3で同様にダメだったので調べてみたところFAQに同じ問題について書かれていました。

FAQ · Microsoft/WinObjC Wiki · GitHub

Releaseからダウンロードするファイルを間違えていたようでした。Source Codeをダウンロードした場合はSDKをビルドするか、ビルド済みの.zipの方をダウンロードして使うかしましょう。

関連記事

このエントリでは、Windows Bridge for iOS (旧名: WinObjC)についてを紹介させていただきました。Windows Bridge for iOSは、Windows 10で使用できるようにブリッジさせて、Objective-CのコードやiOS APIを使ったコードを再利用するためのプロジェクトです。

この他にもWindows Bridge for iOSのネタを紹介しております。Tipsをまとめておりますのでこちらのページをご参照ください。

*1:Microsoftのプロダクトは名前がコロコロ変わるなぁ……

ポケモンガチャに挑戦する(11) ポケットモンスタールビー

全国図鑑をそろえたい!のでポケモンガチャに挑戦するシリーズの第11回目です。前回の記事は「ポケモンガチャに挑戦する(10) ポケットモンスターアルファサファイア」でした。

休みですしポケモンガチャに挑戦してみましょう。

旧作ポケモンを中古で購入してセーブデータを確認する試みです。ポケモンガチャについてはこちらの記事をごらんください。

さて、今回はポケットモンスタールビーを買ってきました。

ポケットモンスタールビー

ポケモンセットとして出品されていたうちの1本です。

ポケットモンスター ルビー

ポケットモンスター ルビー

経験上ポケモンのシナリオをクリアーするのにだいたい20時間くらいなので、11時間でバッジを8個持っているということは前オーナーはかなりポケモンに詳しい方なのかもしれません。

トレーナーカード

起動してみました。ポケモン図鑑が32匹と最小限のバトルでクリアしているようでした。

手持ちのポケモン

次に手持ちのポケモンのチェックをしてみましょう。そのあたりで捕まえられるポケモンしか残っていませんでした。

ボックス

最後にボックスをみていきます。

残念ながらこのカセットは何も入ってなかったようです。

関連記事

この他にもポケモンについて書いています。まとめておりますのでこちらのページをご参照ください。よろしくお願いします。

NSTextAttachmentが含まれているNSAttributedStringでは行間をあけることができない

UILabelで「画像+複数行のテキスト」を実装したいが、行間の調整をすることができず頭を抱えていました。ミニマムコードで現象が再現するのか、このエントリを書きながら調査ました。

結論を先に書くと、NSTextAttachmentにもlineSpacingを設定する必要があるでした。

問題の現象

下図は、NSTextAttachmentを含んだNSAttributedStringを表示させています。

f:id:ch3cooh393:20170310134424p:plain

コードは下記のようになっている。

func setMultipleText() {        
    let str = NSMutableAttributedString()
    
    //プロ生ちゃんアイコンを追加する
    let number = NSTextAttachment()
    if let image = UIImage(named: "sd06") {
        number.image = image
        number.bounds = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
    }
    str.append(NSAttributedString(attachment: number))
    
    //長いテキストを追加する
    let longText = "プロ生ちゃん「ああああ(...省略...)あああ」"
    
    let style = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
    let font = UIFont.boldSystemFont(ofSize: 19)
    style.minimumLineHeight = font.lineHeight + 30
    style.maximumLineHeight = font.lineHeight + 30
    
    let attr: [String : Any] = [
        NSFontAttributeName: font,
        NSParagraphStyleAttributeName: style
    ]
    let longTextString = NSAttributedString(string: longText, attributes: attr)
    str.append(longTextString)
    
    //ラベルにNSAttributedStringを設定する
    label.attributedText = str
}

プロ生ちゃんアイコンを追加する処理をコメントアウトにして実行ます。

//        //プロ生ちゃんアイコンを追加する
//        let number = NSTextAttachment()
//        if let image = UIImage(named: "sd06") {
//            number.image = image
//            number.bounds = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
//        }
//        str.append(NSAttributedString(attachment: number))

画像だけにした場合はきちんと行間が開きます。

f:id:ch3cooh393:20170310134920p:plain

ここまで調査して、NSTextAttachmentが含まれているNSAttributedStringでは行間をあけることができないのではないか?と考えました。同じようなケースでハマっている人も見かけませんでした。

解決した

NSTextAttachment分まで含めて属性を設定することで、NSTextAttachmentが含まれているNSAttributedStringでも行間を開けることができました。

func setMultipleText() {        
    let str = NSMutableAttributedString()
    
    //プロ生ちゃんアイコンを追加する
    let number = NSTextAttachment()
    if let image = UIImage(named: "sd06") {
        number.image = image
        number.bounds = CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height)
    }
    str.append(NSAttributedString(attachment: number))
    
    //長いテキストを追加する
    let longText = "プロ生ちゃん「ああああ(...省略...)あああ」"
    str.append(NSAttributedString(string: longText))
    
    //属性を設定する
    let style = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
    let font = UIFont.boldSystemFont(ofSize: 19)
    style.minimumLineHeight = font.lineHeight + 30
    style.maximumLineHeight = font.lineHeight + 30
    
    let attr: [String : Any] = [
        NSFontAttributeName: font,
        NSParagraphStyleAttributeName: style
    ]
    
    //属性を付与する
    str.addAttributes(attr, range: NSRange(location: 0, length: str.length))
    
    //ラベルにNSAttributedStringを設定する
    label.attributedText = str
}

上記のコードを実行すると、下図のようになります。

f:id:ch3cooh393:20170310135936p:plain

lineSpacingを使う

持ってくるコードが悪くてここまでminimumLineHeight、maximumLineHeightを使って1行あたりのサイズを調整していました。スクリーンショットを撮り直すのが面倒なのでこのエントリではそのままにしておきます。

行間をあけるのであれば、lineSpacingの方が適切ですね。

 //属性を設定する
    let style = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
    let font = UIFont.boldSystemFont(ofSize: 19)
//        style.minimumLineHeight = font.lineHeight + 30
//        style.maximumLineHeight = font.lineHeight + 30
    style.lineSpacing = 30

上記のコードを実行すると、下図のようになります。

f:id:ch3cooh393:20170310140133p:plain

関連記事