概要
- Xamarin.Macでアプリを作るにあたって、アプリアップデート用のライブラリ(Sparkle)を使いたい!
- Xamarin.Macからネイティブのライブラリを使用するためにはObjective Sharpieを使ってXamarin.Macに向けてライブラリのAPIを公開する必要がある
- その手順を踏んで公開されてるライブラリ、SparkleSharpがあったのでそれを使ってアップデータを実装してみる
- .pkg で配布する前提で準備する際にファイルの準備等でハマったのでその辺も共有したい
Sparkle is なに?
これ(sparkle-project/Sparkle)です。
アプリをApp Store外で配布するにあたっては効率的にアップデートを確認し、アップデートがあればインストール!みたいな仕組みが欲しいですよね?
それで調べてみると大体これが出てきます。
ざっくりとした仕組みは、
- アップデート内容を書いたxmlファイル(appcast.xml)を自分でホスト
- Sparkleのメソッドを呼び出してそれを見に行って、更新があるか確認
- 更新があればSparkleがそのxmlの内容を拾って表示
- appcast.xmlで指定したURLにアプリ本体を探しに行ってくれる
というものです。
Sparkleが出してくるUIはこんな感じで、
準備するxmlはこんな感じです。
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Sparkle Sharp Sample App Changelog</title>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version 2.1</title>
<description>
<![CDATA[
<ul>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
<li>Suspendisse sed felis ac ante ultrices rhoncus. Etiam quis elit vel nibh placerat facilisis in id leo.</li>
<li>Vestibulum nec tortor odio, nec malesuada libero. Cras vel convallis nunc.</li>
<li>Suspendisse tristique massa eget velit consequat tincidunt. Praesent sodales hendrerit pretium.</li>
</ul>
]]>
</description>
<pubDate>2017-07-24T17:32:53+0900</pubDate>
<enclosure url="https://github.com/toshi0607/SparkleSharpSample/releases/download/1.2/SparkleSharpSample.zip" sparkle:version="2.0" length="5075016" type="application/octet-stream" sparkle:dsaSignature="MCwCFEVkEFdF43INMskJjylMGxO9odWnAhRPtY0QEgIaOqjXnlHnWZXKYJWwcg==" />
</item>
</channel>
</rss>
- appcast.xmlにはhttpsで接続しないといけない
- 配布する.pkg(.zipとか.dmgとかでもよい)に秘密鍵で署名し、アプリの中には公開鍵を含めておく
のような感じで、セキュリティ面の配慮もありいい感じですね。
Xamarin.MacプロジェクトでSparkleを使う
基本こんな手順です。
MacApp用アップデート管理システムSparkleの使い方(Xamarin.Mac編)
Objective Sharpieを使ってバインディング情報を生成し、使用したいXamarin.Macに突っ込んで参照するみたいな感じです。
記事に書いてある通り、 めげない気持ち
が必要です。
ただ、探してみるとおそらくこの手順を踏んで公開してくれてるであろう SparkleSharpというのがあったので今回はそれで実装してみます。
Xmarin.MacプロジェクトにSparkleSharpを取り込む
対象プロジェクトで下記実行します。
git submodule add https://github.com/rainycape/SparkleSharp.git
Sparkle.csproj
をプロジェクトに追加します。
この状態でビルドしたらSparkleがメインのプロジェクトから使用できます。
Sparkleで必要な設定の準備を行う
秘密鍵・公開鍵
インストールするアプリの妥当性をチェックするための秘密鍵・公開鍵を準備します。
Sparkle(本家)には秘密鍵・公開鍵を生成するやつが入ってるのでクリックして生成します。
SparkleSharpSample/SparkleSharp/Sparkle/3rdparty/Sparkle/bin/generate_keys
↓
- dsa_priv.pem
- dsa_pub.pem
appcast.xml
更新情報を確認するためのファイルです。
- enclosure: アプリ(インストーラ)本体を配布するURL
- dsaSignature: アプリ(インストーラ)を秘密鍵で署名するときに生成される文字列
- length: アプリ(インストーラ)のファイルサイズ
<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" xmlns:dc="http://purl.org/dc/elements/1.1/">
<channel>
<title>Sparkle Sharp Sample App Changelog</title>
<description>Most recent changes with links to updates.</description>
<language>en</language>
<item>
<title>Version 2.1</title>
<description>
<![CDATA[
<ul>
<li>Lorem ipsum dolor sit amet, consectetur adipiscing elit.</li>
<li>Suspendisse sed felis ac ante ultrices rhoncus. Etiam quis elit vel nibh placerat facilisis in id leo.</li>
<li>Vestibulum nec tortor odio, nec malesuada libero. Cras vel convallis nunc.</li>
<li>Suspendisse tristique massa eget velit consequat tincidunt. Praesent sodales hendrerit pretium.</li>
</ul>
]]>
</description>
<pubDate>2017-07-24T17:32:53+0900</pubDate>
<enclosure url="https://github.com/toshi0607/SparkleSharpSample/releases/download/1.2/SparkleSharpSample.zip" sparkle:version="2.0" length="5075016" type="application/octet-stream" sparkle:dsaSignature="MCwCFEVkEFdF43INMskJjylMGxO9odWnAhRPtY0QEgIaOqjXnlHnWZXKYJWwcg==" />
</item>
</channel>
</rss>
とりあえずgithubに置いたものを参照するようにしてます。
Sparkleで必要な設定
info.plist
のソーなんとか(いじっても切れててわからない…)に SUFeedURL
と SUPublicDSAKeyFile
を追加します。
おもむろに Main.Storyboard
をダブルクリックして Storyboard を立ち上げて先ほど生成した dsa_pub.pem
を D&D します。
本家は Xcode に D&D してねって書いてあったのですが、VS for Mac だとできないので…
VS for Macから見ると追加されていて、ビルド時にBundleに含むことになってるのでこれでよさそうです。
UIの追加
何でもいいのですが、とりあえずアプリを立ち上げたときにアップデートチェックするボタンを追加します。
Storyboard からボタンを追加し、C#コードにボタンをクリックしたときに呼ぶメソッド( Action
)を公開するために ViewController.h
にリンクします。
これで Storyboard を閉じると VS for Mac 上の ViewController.designer.cs
にActionが同期され、 ViewController.cs
でC#でメソッドが書けます。
とても手前味噌なのですが、この辺は僕が土曜日に翻訳した記事で丁寧に説明されてますw
Xamarin.Macを初めて触る人に贈る、Xamarin公式 Hello, Mac の日本語訳記事
Sparkle
を using
して、ボタンをクリックしたときに呼び出すメソッドを追加します。
using System;
using Sparkle;
using AppKit;
using Foundation;
namespace SparkleSharpSample
{
public partial class ViewController : NSViewController
{
SUUpdater updater;
public ViewController(IntPtr handle) : base(handle)
{
}
public override void ViewDidLoad()
{
base.ViewDidLoad();
// Do any additional setup after loading the view.
}
public override NSObject RepresentedObject
{
get
{
return base.RepresentedObject;
}
set
{
base.RepresentedObject = value;
// Update the view, if already loaded.
}
}
public override void AwakeFromNib()
{
base.AwakeFromNib();
updater = new SUUpdater();
updater.AutomaticallyChecksForUpdates = false;
}
partial void CheckUpdates(NSObject sender)
{
updater.CheckForUpdates(new NSObject());
}
}
}
インストーラの準備と配置
インストーラ作成
ビルドのオプション(インストーラーパッケージを作成する)にチェックを入れれば.pkgを作ってくれます。
インストーラを署名する
プロジェクトを右クリック、オプションをクリックして「インストーラーパッケージを署名する」にチェックを入れます。
これについてはXmairn.Macの公式ページでも詳細に説明されています。Developer IDの登録、Developer ID証明書(インストーラ)の発行が必要です。
インストーラをzip化する
- ビルドで生成した
SparkleSharpSample-x.0.pkg
を使用します。
.pkg名は 必ず最終的にできるアプリと同じに してください。
デフォルトではSparkleSharpSample-1.2.pkg
のような形で生成されますが、最終的にアプリ名は SparkleSharpSample.app
となるのでバージョンのサフィックスは削除します。
ditto -c -k --sequesterRsrc --keepParent ~/Desktop/SparkleSharpSample.pkg ~/Desktop/SparkleSharpSample.zip
zip化したインストーラを署名する
SparkleSharpSample/SparkleSharp/Sparkle/3rdparty/Sparkle/bin/sign_update
- 先ほど生成した
dsa_priv.pem
- Developer ID証明書での署名が済んだ
SparkleSharpSample.zip
を使用します。
/Users/sugita-toshinori/codes/xamarin/SparkleSharpSample/SparkleSharp/Sparkle/3rdparty/Sparkle/bin/sign_update ~/Desktop/SparkleSharpSample.zip ~/Desktop/dsa_priv.pem
// => MCwCFEVkEFdF43INMskJjylMGxO9odWnAhRPtY0QEgIaOqjXnlHnWZXKYJWwcg==
※パス通しましょう
appcast.xmlに使用する length
もここでようやくわかります。
wc -c < ~/Desktop/SparkleSharpSample.zip
// => 5075016
# 動作確認
アプリを起動して、「CheckUpdates」をクリックするとアップデートが確認できます。
そして「Install Update」をクリックすると、5.1Mのファイルをダウンロードできました。
引き続きpkgでのアップデートを走らせることができます。
最後に
- MacApp用アップデート管理システムSparkleの使い方の @econa77 さん、MacApp用アップデート管理システムSparkleの使い方(Xamarin.Mac編の @ailen0ada さんに助けていただきましたありがとうございました…!
- ライブラリの準備/設定に必要なことは元のネイティヴライブラリのドキュメントがやはり最強なので、困ったら熟読するのが良さげです。