Xamarin.Forms でア
プリをリリースした
素人の話+α
2015/10/3
JXUGC #6 東京
エクセルソフト株式会社
ソフトウェア事業部
Business Development Manager
田淵 義人
宣伝 • ユーザーグループに是非ご参加ください
• http://jxug.org
• https://www.facebook.com/groups/xm.jxug
• Xamarin 日本語情報
• http://ytabuchi.hatenablog.com
• ペゾルドさんの Xamarin.Forms 本 (PDF)
• http://bit.ly/xmfbook
• Xamarin 本
• http://www.amazon.co.jp/dp/4822298345 (書
籍)
• http://www.amazon.co.jp/gp/product/B00MN5
P6PY (Kindle)
宣伝その2 • 今日は登壇いただけませんでしたが、ライ
フベアさんが Xamarin 使いを募集していま
す。 事例を頂けるのを待ってますw
• フェンリルさんも(ry
少しエモーショナルです
技術ネタは他の方がやってくださったので、主にリ
リースまでの体験談などを。
自己紹介 • 田淵義人
• 目指せ!Xamarin エバンジェリスト
• 目指せ!開発もチョットデキル営業
• 目指せ!Xamarin でググれ の自己紹介
• Twitter を Xamarin でエゴサしてる
• Androider, Google 信者
• Twitter: @ytabuchi
• facebook: ytabuchi.xlsoft
• Blog: http://ytabuchi.hatenablog.com/
自己紹介 • 田淵義人
• 目指せ!Xamarin エバンジェリスト
• 目指せ!開発もチョットデキル営業
• アプリリリースしました!今日はその話
• 目指せ!Xamarin でググれ の自己紹介
• Twitter を Xamarin でエゴサしてる
• Androider, Google 信者 → MS も良いな
• Twitter: @ytabuchi
• facebook: ytabuchi.xlsoft
• Blog: http://ytabuchi.hatenablog.com/
アプリ開発
の経緯
• おでコン (Windows Phone アプリコンテス
ト) にアプリを出したい!
IT勉強会検索 • 残念ながら受賞は出来ませんでしたが、と
ても良い経験になりました
• 使ってみて感想頂けると嬉しいです^^
• Windows Phone 版
• Xamarin.Forms の Windows Phone アプリを
Windows ストアにリリースしてみた
• Android 版
• Xamarin.Forms の Android アプリを Google
Play にリリースしてみた
• iOS 版
• 個人で Developer Program に加入しました。
これから申請。
開発もチョット
デキル営業へ
の道
• 大事なもの
• モチベーション
• 素人にもやさしく教えてくれる同僚
• 営業時間内に営業がコード書いても 20-80
の法則で許容してくれる環境
• 偉大な先人の方々の情報
• ビルドしてアプリが動いた時の感動
リリースっ
て大変
• 画像ファイル結構沢山用意しないといけな
い
• ベクターで作った方が楽なので アイコン作成
ツールに期待
• Gimp は辛いw
• 説明文が 1,000 文字とか必要
• タイトル、キャッチ、説明文などでかなりダウ
ンロード数とかが変わるらしい
• A/B テストなど、マーケティングの要素もあっ
て面白い
• ダウンロード数が伸びない問題
こんなの作りました
IT勉強会検索 (XF 勉強用アプリ)
各 OS の Date Picker コントロール
ざっくり中身説明
httpclient / Json.NET 楽ちん
try
{
using (var client = new HttpClient())
{
var response = await client.GetAsync(uri);
response.EnsureSuccessStatusCode(); // StatusCode が 200 以外なら Exception
using (var stream = await response.Content.ReadAsStreamAsync())
{
using (var streamReader = new StreamReader(stream))
{
var json = await streamReader.ReadToEndAsync();
var res = JsonConvert.DeserializeObject<ConnpassJson>(json);
return res;
}
}
}
}
catch (Exception e) {}
LINQ 難しい (メソッドで書きたい…)
from evnt in connpassResult.events
join city in cities on SpecifyCity.GetCity(evnt.address) equals city
where evnt.started_at <= DateTime.Now.AddMonths(5)
where evnt.started_at > DateTime.Now
where ngWordsList.All(word => !evnt.title.Contains(word))
select new AllEventsInfo
{
Site = "site_connpass.png",
Title = evnt.title,
Event_uri = evnt.event_url,
Start_at = evnt.started_at,
End_at = evnt.ended_at,
Description = evnt.description,
Overview = HtmlToString.GetString(evnt.description, 50),
Address = evnt.address,
City = SpecifyCity.GetCity(evnt.address),
Accepted = evnt.accepted,
Limit = evnt.limit,
Organizer = evnt.series == null ? evnt.owner_display_name : evnt.series.title,
};
XF の DataBinding 楽ちん (XAML)
<TableView Intent="Settings">
<TableRoot>
<TableSection Title="東京・大阪">
<SwitchCell Text="東京" On="{Binding TokyoValue, Mode=TwoWay}" />
<SwitchCell Text="大阪" On="{Binding OsakaValue, Mode=TwoWay}" />
</TableSection>
<TableSection Title="北海道地方">
<SwitchCell Text="北海道" On="{Binding HokkaidoValue, Mode=TwoWay}" />
</TableSection>
<TableSection Title="東北地方">
<SwitchCell Text="東北地方一括設定" OnChanged="ToggleAreaTohokuValues" />
<SwitchCell Text="青森県" On="{Binding AomoriValue, Mode=TwoWay}" />
<SwitchCell Text="岩手県" On="{Binding IwateValue, Mode=TwoWay}" />
<SwitchCell Text="宮城県" On="{Binding MiyagiValue, Mode=TwoWay}" />
<SwitchCell Text="秋田県" On="{Binding AkitaValue, Mode=TwoWay}" />
<SwitchCell Text="山形県" On="{Binding YamagataValue, Mode=TwoWay}" />
<SwitchCell Text="福島県" On="{Binding FukushimaValue, Mode=TwoWay}" />
</TableSection>
</TableRoot>
</TableView>
XF の DataBinding 楽ちん (C#)
// コード側
var dateLabel = new Label
{
Style = Application.Current.Resources[“SubColoredLabel”] as Style, // Styles 指定
};
dateLabel.SetBinding(Label.TextProperty,
new Binding("Start_at", stringFormat: "日時: {0:yyyy/M/d HH:mm} ~")); // stringFormat
var contentLabel = new Label { };
contentLabel.SetBinding(Label.TextProperty,
new Binding("Description", converter: new HtmlToPlainConverter())); // IValueConverter
// IValueConverter 実装
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
// HtmlAgilityPack を使用してタグ付きの string からタグを除去します。
var hap = new HtmlAgilityPack.HtmlDocument();
hap.LoadHtml(value.ToString());
var doc = hap.DocumentNode.InnerText;
// logic
}
Dependency Service (頑張りたくないw)
// Interface を PCL に用意
public interface ISaveAndLoad
{
void SaveData(string filename, string text);
string LoadData(string filename);
}
// Android 実装の例
public void SaveData(string filename, string text)
{
var documentsPath =
System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var filePath = Path.Combine(documentsPath, filename);
// File.WriteAllText ですべて上書きします。AppendAllText だと追加するようです。
System.IO.File.WriteAllText(filePath, text);
}
営業でもXamarin.Formsで
アプリが作れるよ!
ご清聴ありがとうございます

Xamarin.Formsでアプリをリリースした素人の話

  • 1.
    Xamarin.Forms でア プリをリリースした 素人の話+α 2015/10/3 JXUGC #6東京 エクセルソフト株式会社 ソフトウェア事業部 Business Development Manager 田淵 義人
  • 2.
    宣伝 • ユーザーグループに是非ご参加ください •http://jxug.org • https://www.facebook.com/groups/xm.jxug • Xamarin 日本語情報 • http://ytabuchi.hatenablog.com • ペゾルドさんの Xamarin.Forms 本 (PDF) • http://bit.ly/xmfbook • Xamarin 本 • http://www.amazon.co.jp/dp/4822298345 (書 籍) • http://www.amazon.co.jp/gp/product/B00MN5 P6PY (Kindle)
  • 3.
    宣伝その2 • 今日は登壇いただけませんでしたが、ライ フベアさんがXamarin 使いを募集していま す。 事例を頂けるのを待ってますw • フェンリルさんも(ry
  • 4.
  • 5.
    自己紹介 • 田淵義人 •目指せ!Xamarin エバンジェリスト • 目指せ!開発もチョットデキル営業 • 目指せ!Xamarin でググれ の自己紹介 • Twitter を Xamarin でエゴサしてる • Androider, Google 信者 • Twitter: @ytabuchi • facebook: ytabuchi.xlsoft • Blog: http://ytabuchi.hatenablog.com/
  • 6.
    自己紹介 • 田淵義人 •目指せ!Xamarin エバンジェリスト • 目指せ!開発もチョットデキル営業 • アプリリリースしました!今日はその話 • 目指せ!Xamarin でググれ の自己紹介 • Twitter を Xamarin でエゴサしてる • Androider, Google 信者 → MS も良いな • Twitter: @ytabuchi • facebook: ytabuchi.xlsoft • Blog: http://ytabuchi.hatenablog.com/
  • 7.
    アプリ開発 の経緯 • おでコン (WindowsPhone アプリコンテス ト) にアプリを出したい!
  • 8.
    IT勉強会検索 • 残念ながら受賞は出来ませんでしたが、と ても良い経験になりました •使ってみて感想頂けると嬉しいです^^ • Windows Phone 版 • Xamarin.Forms の Windows Phone アプリを Windows ストアにリリースしてみた • Android 版 • Xamarin.Forms の Android アプリを Google Play にリリースしてみた • iOS 版 • 個人で Developer Program に加入しました。 これから申請。
  • 9.
    開発もチョット デキル営業へ の道 • 大事なもの • モチベーション •素人にもやさしく教えてくれる同僚 • 営業時間内に営業がコード書いても 20-80 の法則で許容してくれる環境 • 偉大な先人の方々の情報 • ビルドしてアプリが動いた時の感動
  • 10.
    リリースっ て大変 • 画像ファイル結構沢山用意しないといけな い • ベクターで作った方が楽なのでアイコン作成 ツールに期待 • Gimp は辛いw • 説明文が 1,000 文字とか必要 • タイトル、キャッチ、説明文などでかなりダウ ンロード数とかが変わるらしい • A/B テストなど、マーケティングの要素もあっ て面白い • ダウンロード数が伸びない問題
  • 11.
  • 12.
  • 13.
    各 OS のDate Picker コントロール
  • 14.
  • 15.
    httpclient / Json.NET楽ちん try { using (var client = new HttpClient()) { var response = await client.GetAsync(uri); response.EnsureSuccessStatusCode(); // StatusCode が 200 以外なら Exception using (var stream = await response.Content.ReadAsStreamAsync()) { using (var streamReader = new StreamReader(stream)) { var json = await streamReader.ReadToEndAsync(); var res = JsonConvert.DeserializeObject<ConnpassJson>(json); return res; } } } } catch (Exception e) {}
  • 16.
    LINQ 難しい (メソッドで書きたい…) fromevnt in connpassResult.events join city in cities on SpecifyCity.GetCity(evnt.address) equals city where evnt.started_at <= DateTime.Now.AddMonths(5) where evnt.started_at > DateTime.Now where ngWordsList.All(word => !evnt.title.Contains(word)) select new AllEventsInfo { Site = "site_connpass.png", Title = evnt.title, Event_uri = evnt.event_url, Start_at = evnt.started_at, End_at = evnt.ended_at, Description = evnt.description, Overview = HtmlToString.GetString(evnt.description, 50), Address = evnt.address, City = SpecifyCity.GetCity(evnt.address), Accepted = evnt.accepted, Limit = evnt.limit, Organizer = evnt.series == null ? evnt.owner_display_name : evnt.series.title, };
  • 17.
    XF の DataBinding楽ちん (XAML) <TableView Intent="Settings"> <TableRoot> <TableSection Title="東京・大阪"> <SwitchCell Text="東京" On="{Binding TokyoValue, Mode=TwoWay}" /> <SwitchCell Text="大阪" On="{Binding OsakaValue, Mode=TwoWay}" /> </TableSection> <TableSection Title="北海道地方"> <SwitchCell Text="北海道" On="{Binding HokkaidoValue, Mode=TwoWay}" /> </TableSection> <TableSection Title="東北地方"> <SwitchCell Text="東北地方一括設定" OnChanged="ToggleAreaTohokuValues" /> <SwitchCell Text="青森県" On="{Binding AomoriValue, Mode=TwoWay}" /> <SwitchCell Text="岩手県" On="{Binding IwateValue, Mode=TwoWay}" /> <SwitchCell Text="宮城県" On="{Binding MiyagiValue, Mode=TwoWay}" /> <SwitchCell Text="秋田県" On="{Binding AkitaValue, Mode=TwoWay}" /> <SwitchCell Text="山形県" On="{Binding YamagataValue, Mode=TwoWay}" /> <SwitchCell Text="福島県" On="{Binding FukushimaValue, Mode=TwoWay}" /> </TableSection> </TableRoot> </TableView>
  • 18.
    XF の DataBinding楽ちん (C#) // コード側 var dateLabel = new Label { Style = Application.Current.Resources[“SubColoredLabel”] as Style, // Styles 指定 }; dateLabel.SetBinding(Label.TextProperty, new Binding("Start_at", stringFormat: "日時: {0:yyyy/M/d HH:mm} ~")); // stringFormat var contentLabel = new Label { }; contentLabel.SetBinding(Label.TextProperty, new Binding("Description", converter: new HtmlToPlainConverter())); // IValueConverter // IValueConverter 実装 public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { // HtmlAgilityPack を使用してタグ付きの string からタグを除去します。 var hap = new HtmlAgilityPack.HtmlDocument(); hap.LoadHtml(value.ToString()); var doc = hap.DocumentNode.InnerText; // logic }
  • 19.
    Dependency Service (頑張りたくないw) //Interface を PCL に用意 public interface ISaveAndLoad { void SaveData(string filename, string text); string LoadData(string filename); } // Android 実装の例 public void SaveData(string filename, string text) { var documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal); var filePath = Path.Combine(documentsPath, filename); // File.WriteAllText ですべて上書きします。AppendAllText だと追加するようです。 System.IO.File.WriteAllText(filePath, text); }
  • 20.
  • 21.