LoginSignup
2
1

More than 5 years have passed since last update.

Xamarin.MacからアップデートライブラリSparkleのC♯バインディングのSparkleSharpを使用する

Last updated at Posted at 2017-08-02

概要

  • 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はこんな感じで、

スクリーンショット 2017-07-25 11.27.49.png

準備するxmlはこんな感じです。

appcast.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 をプロジェクトに追加します。

スクリーンショット 2017-07-25 11.47.42.png

スクリーンショット 2017-07-25 11.48.09.png

参照を追加します。
スクリーンショット 2017-07-25 11.50.06.png

この状態でビルドしたらSparkleがメインのプロジェクトから使用できます。

Sparkleで必要な設定の準備を行う

秘密鍵・公開鍵

インストールするアプリの妥当性をチェックするための秘密鍵・公開鍵を準備します。

Sparkle(本家)には秘密鍵・公開鍵を生成するやつが入ってるのでクリックして生成します。

SparkleSharpSample/SparkleSharp/Sparkle/3rdparty/Sparkle/bin/generate_keys

  • dsa_priv.pem
  • dsa_pub.pem

appcast.xml

更新情報を確認するためのファイルです。

  • enclosure: アプリ(インストーラ)本体を配布するURL
  • dsaSignature: アプリ(インストーラ)を秘密鍵で署名するときに生成される文字列
  • length: アプリ(インストーラ)のファイルサイズ
appcast.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>

とりあえずgithubに置いたものを参照するようにしてます。

Sparkleで必要な設定

info.plistのソーなんとか(いじっても切れててわからない…)に SUFeedURLSUPublicDSAKeyFile を追加します。
スクリーンショット 2017-08-02 23.37.35.png

おもむろに Main.Storyboard をダブルクリックして Storyboard を立ち上げて先ほど生成した dsa_pub.pem を D&D します。

スクリーンショット 2017-07-25 15.01.49.png

本家は Xcode に D&D してねって書いてあったのですが、VS for Mac だとできないので…

VS for Macから見ると追加されていて、ビルド時にBundleに含むことになってるのでこれでよさそうです。

UIの追加

何でもいいのですが、とりあえずアプリを立ち上げたときにアップデートチェックするボタンを追加します。

Storyboard からボタンを追加し、C#コードにボタンをクリックしたときに呼ぶメソッド( Action )を公開するために ViewController.h にリンクします。

スクリーンショット 2017-07-25 12.31.48.png

これで Storyboard を閉じると VS for Mac 上の ViewController.designer.cs にActionが同期され、 ViewController.cs でC#でメソッドが書けます。

とても手前味噌なのですが、この辺は僕が土曜日に翻訳した記事で丁寧に説明されてますw

Xamarin.Macを初めて触る人に贈る、Xamarin公式 Hello, Mac の日本語訳記事

Sparkle を using して、ボタンをクリックしたときに呼び出すメソッドを追加します。

ViewController.cs
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を作ってくれます。

スクリーンショット 2017-07-25 12.46.39.png

インストーラを署名する

プロジェクトを右クリック、オプションをクリックして「インストーラーパッケージを署名する」にチェックを入れます。

スクリーンショット 2017-08-02 23.01.55.png

これについては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」をクリックするとアップデートが確認できます。
スクリーンショット 2017-07-25 13.01.11.png

そして「Install Update」をクリックすると、5.1Mのファイルをダウンロードできました。

スクリーンショット 2017-08-02 22.33.20.png

スクリーンショット 2017-08-02 22.33.29.png

引き続きpkgでのアップデートを走らせることができます。

スクリーンショット 2017-08-02 22.33.43.png

最後に

2
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1