SlideShare a Scribd company logo
1 of 50
Download to read offline
iOS の動画アプリ開発に 
Xamarin を使ってみた 
@irgaly 
Japan Xamarin User Group 
JXUG Conference (East) #2 
2014/11/22 
@日本マイクロソフト 品川本社 セミナールームA
目次 
• 自己紹介 
• 実績 
• アプリ説明/設計 
• Xamarin.iOSのメリット/デメリット 
• メモリ管理の罠 
• 原因と対策 
• メディアの扱い 
• 画面回転 
• Background Fetch 
• Jenkinsビルド 
• まとめ
自己紹介 
• 北川大智 / @irgaly 
• フェンリル株式会社 
• 共同開発部 
• Android / iOS エンジニア 
• Android Lollipop, Material Design に興味あり 
• いずれ Dart の時代が来ると思っている 
• vim / arch linux 
とりあえず新しいものに食い付いておくタイプ
実績
過去の実績 
• NHK 紅白歌合戦アプリ(2013) 
ViewModel 実装の担当 
• Xamarin/C# エンジニアを名乗れ 
るようになった 
• Objective-C からの解脱 
NHK紅白アプリ
業務に使ってみて
今回のアプリ 
• マルチメディア系 iPhone アプリ 
• iOS 7.0 以上 
• Android は開発対象外 
• Android 版は先行開発済み 
• Android 版の移植開発 
• 機能 
• ソーシャルログイン 
• Twitter, Facebook 
• 動画撮影 
• ショートムービー、連続撮影、Landscape, Portrait 
• 動画ダウンロード・再生 
• 動画の連続再生
設計 
• MVVMCross で MVVM 
• いつでもクロスプラットフォーム展開できるように 
• Xamarin を選ぶ理由 
• Model, API などは Service で制御。それ以外は ViewModel + View 
• Service または MVVMCross Plugin 
• Facobook iOS SDK (Xamarin Components) 
• Xamarin.Social (Twitter ログイン) (Xamarin Components) 
• 効果測定ネイティブ SDK バイディング 
• 録画機能もプラグイン化 (クロスプラットフォーム対応に向けて) 
• その他 
• Mac/Xamarin Studio 
• Xib/AutoLayout/AssetCatalog...
Xamarin.iOS を使って・メリット 
• モバイルアプリ開発に MVVM を導入できる 
• C# の恩恵 
• LINQ の威力 
• Objective-C の闇にはまらない 
• Attribute, Reflection... 
• 必要な機能はひととおり NuGet/Xamarin Component で調 
達 できる 
• OS のすべての機能にアクセスでき、ネイティブ Binding 
も作れる 
• 業務利用にも耐えられる 
• C# ノウハウでの知識集約 
• クロスプラットフォーム展開 
• OS やプロジェクトを越えてのプラグイン利用 
• MVVMCross の強力な武器を使える 
• Service (DI), Messenger, Plugin... 
※ iOS/Objective-C 開発と比較した場合
Xamarin.iOS を使って・デメリット 
• MVVM のオーバーヘッド 
• クラス数/インスタンス数が多く、画面生成のパフォーマン 
スに難儀 
• iOSはもともとMVVM設計ではない → 内部的にリフレク 
ションを多用することのオーバーヘッド 
• iOS でのメモリリーク問題 
• どう頑張ってもメモリリークを駆逐できない 
• GC の問題 
• 基本的な対策はとりつつ、今後のXamarin社の対応に期 
待 
• エンジニアの問題 
• チームメンバーが多いと、どうしてもメモリリーク対応 
漏れが発生する 
※ iOS/Objective-C 開発と比較した場合
現実 
• 開発スピードが上がったり、コストが削減されるようなも 
のではない。 
• MVVMの採用で品質は向上する 
• もちろんクロスプラットフォーム対象に開発すれば総合で 
見た場合のスピード・コスト・品質に変化あり 
• エンジニアとしてはモダンな開発環境で揃えられるので心 
安らぐ 
• 構成切り替え、Jenkins ビルド、Reveal、Crashlytics など 
に対応しており、不便になることはない 
• Xamarin Profilerなど、今後もツールは充実する方向にあ 
る 
• C#を書けるスマホアプリエンジニアの確保が難しい 
※ iOS/Objective-C 開発と比較した場合
メモリ管理の罠
メモリリークに気付く 
ある日 
(絶望) 
※当時はXcode Instrumentsでした
調べる 
• c# - Xamarin iOS memory leaks everywhere - Stack Overflow 
• http://stackoverflow.com/questions/25532870/xamarin-ios-memory-leaks-everywhere 
• Best way to recursively dispose UIViews in Xamarin iOS 
• http://education-eco.blogspot.jp/2014/08/best-way-to-recursively-dispose-uiviews. 
html 
• Memory and Performance Best Practices | Xamarin 
• http://developer.xamarin.com/guides/cross-platform/ 
deployment,_testing,_and_metrics/memory_perf_best_practices/ 
• Advanced Memory Management on iOS and Android - Mark Probst 
and Rodri… 
• http://www.slideshare.net/Xamarin/advanced-memory-management-on-ios-and-android- 
mark-probst-and-rodrigo-kumpera 
• Memory Management Pitfalls in Xamarin iOS - Introduction 
• http://bluetubeinc.com/blog/2013/6/memory-management-pitfalls-in-xamarin-ios-introduction 
奥が深そう
原因は? 
• 二つのGCが同時に機能している 
• Xamarin.iOS の GC と iOS の GC の相性が悪い 
• 参照カウンタ方式の闇 
• UIView でだいたいリークする
原因と発生パターン 
• ネイティブオブジェクト間での循環参照 
• サブクラス化と EventHandler 
• アンマネージリソースを Dispose していない
UIView の循環参照 
• NSObject を継承したクラスを作ると発生
対策 
1 public class MyView : UIView { 
2 WeakReference<UIViewController> _parent; 
3 public MyView (UIViewController parent) { 
4 _parent = new WeakReference<UIViewController>(parent); 
5 } 
6 } 
• WeakReference を使う 
• Objective-C ではおなじみの習慣 
• C#で書いていると忘れがちになるが、同じように対応す 
る
サブクラス化とEventHandler 
1 public class CustomButton : UIButton {} 
2 
3 public class MyViewController : UIViewController { 
4 public override void ViewDidLoad () { 
5 var button = new CustomButton(); 
6 View.Add(button); 
7 button.TouchUpInside += (s, e) => { 
8 ButtonClick(); 
9 }; 
10 } 
11 } 
• EventHandler で循環参照発生
対策 
1 public override void ViewWillAppear(bool animated) 
2 
3 { 
4 UIButton.TouchUpInside += ButtonClick; 
5 } 
6 
7 public override void ViewWillDisappear(bool animated) 
8 { 
9 UIButton.TouchUpInside -= ButtonClick; 
10 } 
• EventHandler の削除
アンマネージリソースの Dispose 漏れ 
1 public override void ViewDidLoad () { 
2 var imageView = ...; 
3 var image = UIImage.FromBundle ("hoge.png"); 
4 imageView.Image = image; 
5 
6 _otherButton.TouchUpInside += (s, e) => { 
7 imageView.RemoveFromSuperview();// UIImageを解放できていない 
8 } 
9 }
対策 
1 public override void ViewDidLoad () { 
2 var imageView = ...; 
3 var image = UIImage.FromBundle ("hoge.png"); 
4 imageView.Image = image; 
5 
6 _otherButton.TouchUpInside += (s, e) => { 
7 imageView.RemoveFromSuperview(); 
8 imageView.Dispose(); 
9 image.Dispose(); // すぐに解放する 
10 } 
11 }
対策まとめ 
• 親の参照には WeakReference を使う 
• 不要になったら EventHandler の削除 
• 怪しかったら Dispose する 
• → むしろ Touch プロジェクト(Xamarin.iOS) 側のコードビ 
ハインドをできる限り減らす 
• Core プロジェクト(PCL) プロジェクトのコードはこれら 
の危険が少ない
メディアの扱い
メディアの扱い 
• 動画撮影 
• プラグインを独自実装 
• PlatformService 
• プラットフォーム固有の機能について 
• 機能紹介 
DIを使うことで、Core プロジェクトから 
プラットフォームの機能を扱えるようにする。
独自のMVVMCross Plugin 
• PCLとプラットフォームとでプロジェクトを分ける
IMvxVideoCapture 
1 public interface IMvxVideoCapture 
2 { 
3 Task<bool> SetupCaptureSessionAsync(); 
4 bool StartRecording(string filePath); 
5 Task<bool> StopRecording(); 
6 bool SwitchCamera(); 
7 bool UpdateOrientation(VideoOrientation orientation); 
8 } 
9 
10 public interface IMvxVideoCapture<TPreviewView> : IMvxVideoCapture 
11 { 
12 bool StartPreview(IMvxVideoDisplay<TPreviewView> display); 
13 bool StopPreview(); 
14 } 
• プラットフォームに依存しないインタフェースを定義する
MvxVideoCapture 
初期化からプレビュー開始まで(part1) 
1 var session = new AVCaptureSession 
2 { 
3 SessionPreset = AVCaptureSession.PresetHigh 
4 }; 
5 var camera = 
AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video); 
6 var mic = 
AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio); 
7 var cameraInput = AVCaptureDeviceInput.FromDevice(camera); 
8 session.AddInput(cameraInput); 
9 var micInput = AVCaptureDeviceInput.FromDevice(mic); 
10 session.AddInput(micInput); 
• Touch プロジェクト側で実装を書く 
• iOS AVFoundation クラスを C# からそのまま扱える
MvxVideoCapture 
初期化からプレビュー開始まで(part2) 
11 var queue = new DispatchQueue("CaptureBuffer"); 
12 var videoOutput = new AVCaptureVideoDataOutput(); 
13 session.AddOutput(videoOutput); 
14 videoOutput.SetSampleBufferDelegate(this, queue); 
15 var connection = 
videoOutput.ConnectionFromMediaType(AVMediaType.Video); 
16 connection.VideoOrientation = 
GetCaptureOrientation(_currentOrientation); 
17 var audioOutput = new AVCaptureAudioDataOutput(); 
18 session.AddOutput(audioOutput); 
19 audioOutput.SetSampleBufferDelegateQueue(this, queue); 
20 var previewLayer = new AVCaptureVideoPreviewLayer(session); 
21 session.StartRunning(); 
• Touch プロジェクト側で実装を書く 
• iOS AVFoundation クラスを C# からそのまま扱える
MvxVideoCapture 
コーデックの設定から撮影開始部分(part1) 
1 var videoSettings = new NSMutableDictionary(); 
2 videoSettings.Add(AVVideo.CodecKey, AVVideo.CodecH264); 
3 videoSettings.Add(AVVideo.WidthKey, new NSNumber(640)); 
4 videoSettings.Add(AVVideo.HeightKey, new NSNumber(480)); 
5 var compressionSettings = new NSMutableDictionary(); 
6 compressionSettings.Add(AVVideo.AverageBitRateKey, new 
NSNumber(2413000)); 
7 videoSettings.Add(AVVideo.CompressionPropertiesKey, 
compressionSettings); 
8 videoSettings.Add(AVVideo.ScalingModeKey, AVVideoScalingModeKey. 
9 ResizeAspectFill); 
10 
11 var videoInput = new AVAssetWriterInput(AVMediaType.Video, new 
12 AVVideoSettingsCompressed(videoSettings)); 
13 videoInput.ExpectsMediaDataInRealTime = true; 
14 writer.AddInput(videoInput); 
• AVAssetWriterInput の引数を作成するために、 
NSMutableDictionary を C# から扱っています。
MvxVideoCapture 
コーデックの設定から撮影開始部分(part2) 
15 
16 var audioSettings = new NSMutableDictionary(); 
17 audioSettings.Add(AVAudioSettings.AVFormatIDKey, NSNumber.FromInt32((int) 
18 AudioFormatType.MPEG4AAC)); 
19 audioSettings.Add(AVAudioSettings.AVNumberOfChannelsKey, NSNumber.FromInt16(2)) 
20 ; 
21 audioSettings.Add(AVAudioSettings.AVSampleRateKey, NSNumber.FromFloat(44100.0f) 
22 ); 
23 var audioInput = new AVAssetWriterInput(AVMediaType.Audio, new AudioSettings( 
24 audioSettings)); 
25 writer.AddInput(audioInput); 
• AVAssetWriterInput の引数を作成するために、 
NSMutableDictionary を C# から扱っています。
Core プロジェクトから MvxVideoCapture を使う 
1 ... 
2 var videoCapture = Mvx.Resolve<IMvxVideoCapture>(); 
3 videoCapture.StartRecording(filePath); 
4 
5 ... 
6 
7 await videoCapture.StopRecording(); 
• MVVMCross プラグインとしてインタフェースとプラットフォーム固有の実 
装を分けたため、ViewModel 側の PCL プロジェクトへこれを記述できる
PlatformService 
1 public class TouchPlatformService : IPlatformService 
2 { 
3 public IMediaFile GetMediaFile(string path) 
4 { 
5 return new TouchMediaFile(path); 
6 } 
7 
8 public async Task Share(string shareText) 
9 { 
10 var items = new NSObject[] { 
11 new NSString(shareText) 
12 }; 
13 var activity = new UIActivityViewController(items, null); 
14 var vc = ...; 
15 ... 
16 await vc.PresentViewControllerAsync(activity, true); 
17 } 
18 
19 public string VersionName() 
20 { 
21 return NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion"). 
22 ToString(); 
23 } 
24 
25 ... 
• プラットフォーム固有の機能を呼び出すユーティリティサービ 
ス
画面回転
画面回転 
• 現在の iPhone の傾きや、傾きの変化を取得する 
• 動画撮影の縦、横切り替えに使用 
• BeginGeneratingDeviceOrientationNotifications で判定する 
• 画面ロック時には回転通知は発生しない
画面回転 
1 public override void ViewWillAppear(bool animated) 
2 { 
3 base.ViewWillAppear(animated); 
4 
5 UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications(); 
6 var notificationAvailable = false; 
7 _orientationObserverToken = NSNotificationCenter.DefaultCenter.AddObserver( 
8 UIDevice.OrientationDidChangeNotification, notification => 
9 { 
10 notificationAvailable = true; // 傾き取得成功 
11 ... // 傾きに応じた処理 
12 }); 
13 
14 Task.Run(async () => 
15 { 
16 await Task.Delay(500); 
17 if(!notificationAvailable) { 
18 … // 傾きロックされている可能性がある。Portraitであるとみなして処理 
19 } 
20 }).Forget(); 
21 }
画面回転 
1 public override void ViewWillDisappear(bool animated) 
2 
3 { 
4 base.ViewWillDisappear(animated); 
5 UIDevice.CurrentDevice.EndGeneratingDeviceOrientationNotifications(); 
6 if (_orientationObserverToken != null) 
7 { 
8 NSNotificationCenter.DefaultCenter.RemoveObserver(_orientationObserverT 
9 oken); 
10 _orientationObserverToken = null; 
11 } 
12 }
Background Fetch
Background Fetch 
• iOS7 以上で、バックグラウンドのアプリが一定期間ごとに起動し、な 
んらかの処理を実行できる機能 
• 起動の間隔はOSが決定するため、指定することはできない 
• 30秒間のみ処理可能であり、できることは限られてくる 
• 主にAPIとの通信で、データ更新をチェックするための機能 
• 30秒を過ぎるとプロセスが殺される
プロジェクトの設定 
• iOSのプロジェクト設定から、Background fetchオプショ 
ンを設定する
Background Fetch 
1 public override bool FinishedLaunching(UIApplication app, NSDictionary 
options) 
2 
3 { 
4 ... 
5 
6 // BackgrondFetchの呼び出し間隔指定 
7 UIApplication.SharedApplication 
8 .SetMinimumBackgroundFetchInterval( 
9 UIApplication.BackgroundFetchIntervalMinimum); 
10 
11 return true; 
12 } 
• AppDelegateで、起動時に Background Fetch の間隔を設定
PerformFetchの実装 1 public override async void PerformFetch(UIApplication application, Action< 
2 UIBackgroundFetchResult> 
3 completionHandler) 
4 
5 { 
6 var cancelToken = new CancellationTokenSource(); 
7 try 
8 { 
9 // 25秒で強制中断 
10 cancelToken.CancelAfter(25000); 
11 
12 // API通信などを実行 
13 … 
completionHandler(UIBackgroundFetchResult.NewData); 
14 } 
15 catch (OperationCanceledException) 
16 { 
17 completionHandler(UIBackgroundFetchResult.Failed); 
18 } 
19 } 
• 保険として25秒制限をしているが、安全に対応するならBackground Transfer 
(NSURLSession Background mode)で対応する 
• Xamarin はアップデートが早いため、OSの最新機能もすぐ使えるようになる 
• マイナーな機能は SDK にバグがあることもある
Jenkins ビルド
Jenkins ビルド 
• 弊社ではすべてのプロダクトは Jenkins でビルドしています 
• 納品時のトラブルを防ぐ 
• エンジニア不在の時でも最新のアプリの動作確認を行える 
• Xamarin.iOS x Jenkins は公式ガイドあり 
• http://developer.xamarin.com/guides/cross-platform/ci/jenkins_walkthrough/ 
• Jenkins は Mac 上で実行されている 
• Jenkins ビルドでの構成(定数)切り替えビルド対応
プロジェクト側の準備 
• mdtool コマンドは定数切り替えに対応していない 
• 定数切り替え対応のため、Touchプロジェクトにシンボル 
を定義しておく
Jenkins 環境の準備 
Jenkins 環境で作業します 
• Xamarin Studio をインストールする 
• ライセンス認証する 
• Stable の最新バージョンにアップデートしておく 
• 開発チームとJenkinsで、「常にXamarin StudioのStable最新 
環境で作業する」という取り決めをしておく 
• Xcode も一度は起動して使える状態にしておく(念のため) 
• プロビジョニングプロファイルと署名をインポートしておく
ビルド構成を作成 
• フリースタイルビルド構成 
• ビルド環境 > ビルドプロセスに環境変数をインジェクト 
(Environment Injector Plugin)
ビルド構成を作成 
• ビルド > シェルの実行 > シェルスクリプト 
1 sed -i '' -Ee "s/__JENKINS__;/${Options};/g" MyProject.*/MyProject.*.csproj 
2 
4 /Applications/Xamarin Studio.app/Contents/MacOS/mdtool -v build -t:Build -c:$ 
(BuildConfiguration}|iPhone -p:MyProject.Touch MyProject/MyProject.sln 
5 
6 find MyProject/MyProject.Touch/bin/${BuildConfiguration} -name '*.ipa' -exec 
7 mv {} MyProject/MyProject.Touch/bin/${ 
8 BuildConfiguration}/MyProject-${ 
9 BuildConfiguration}-${BUILD_ID}.ipa ;
まとめ
まとめ 
• iOS寄りの各機能の紹介をコードレベルで紹介しました 
• PCLとプラットフォームのプロジェクトを分けて実装する 
• パッケージマネージャなどの機能は揃っており、Xamarin 
は開発プラットフォームとしては強力 
• プラットフォーム固有の機能へのアクセスもできるため、 
業務に耐えうる 
• プラットフォームごとの対応の手間はかかる、罠も多い

More Related Content

What's hot

Xamarin 101 ~環境構築からビルド・テストまで~
Xamarin 101 ~環境構築からビルド・テストまで~Xamarin 101 ~環境構築からビルド・テストまで~
Xamarin 101 ~環境構築からビルド・テストまで~Masaki Takeda
 
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~ShinichiAoyagi
 
Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~
Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~
Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~Tatsuji Kuroyanagi
 
Visual Studio 2015 + Xamarin
Visual Studio 2015 + XamarinVisual Studio 2015 + Xamarin
Visual Studio 2015 + XamarinShinichiAoyagi
 
Xamarin によるクロスプラットフォームモバイルアプリ開発
Xamarin によるクロスプラットフォームモバイルアプリ開発Xamarin によるクロスプラットフォームモバイルアプリ開発
Xamarin によるクロスプラットフォームモバイルアプリ開発Hironov OKUYAMA
 
Windows アプリケーション開発 はじめに ~ Windows アプリケーション開発初学者の方向け Visual Studio を使ったアプリケーショ...
Windows アプリケーション開発はじめに ~ Windows アプリケーション開発初学者の方向けVisual Studio を使ったアプリケーショ...Windows アプリケーション開発はじめに ~ Windows アプリケーション開発初学者の方向けVisual Studio を使ったアプリケーショ...
Windows アプリケーション開発 はじめに ~ Windows アプリケーション開発初学者の方向け Visual Studio を使ったアプリケーショ...Fujio Kojima
 
いまさら学ぶMVVMパターン
いまさら学ぶMVVMパターンいまさら学ぶMVVMパターン
いまさら学ぶMVVMパターンYuta Matsumura
 
Prism + ReactiveProperty入門
Prism + ReactiveProperty入門Prism + ReactiveProperty入門
Prism + ReactiveProperty入門一希 大田
 
Xamarin 概要 2015年5月版
Xamarin 概要 2015年5月版Xamarin 概要 2015年5月版
Xamarin 概要 2015年5月版Yoshito Tabuchi
 
C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介
C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介
C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介Yoshito Tabuchi
 
モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点
モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点
モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点Yoshito Tabuchi
 
20171202 Xamarinの歩き方
20171202 Xamarinの歩き方20171202 Xamarinの歩き方
20171202 Xamarinの歩き方Yoshito Tabuchi
 
塹壕よりLivetとMVVM
塹壕よりLivetとMVVM塹壕よりLivetとMVVM
塹壕よりLivetとMVVMHiroshi Maekawa
 
C++からC#まで Visual Studio 縛り (で死ぬ実験)
C++からC#まで Visual Studio 縛り (で死ぬ実験)C++からC#まで Visual Studio 縛り (で死ぬ実験)
C++からC#まで Visual Studio 縛り (で死ぬ実験)Takashi Kawasaki
 
Xamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しよう
Xamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しようXamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しよう
Xamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しようAkira Onishi
 
ゆるふわ Xamarin Tips
ゆるふわ Xamarin Tipsゆるふわ Xamarin Tips
ゆるふわ Xamarin TipsDaiki Kawanuma
 
Xamarin概要+最新情報
Xamarin概要+最新情報Xamarin概要+最新情報
Xamarin概要+最新情報Yoshito Tabuchi
 
かけ算で使いこなす Xamarin
かけ算で使いこなす Xamarinかけ算で使いこなす Xamarin
かけ算で使いこなす XamarinTatsuji Kuroyanagi
 
Visual studio 2013 Overview
Visual studio 2013 OverviewVisual studio 2013 Overview
Visual studio 2013 Overview一希 大田
 

What's hot (20)

Xamarin 101 ~環境構築からビルド・テストまで~
Xamarin 101 ~環境構築からビルド・テストまで~Xamarin 101 ~環境構築からビルド・テストまで~
Xamarin 101 ~環境構築からビルド・テストまで~
 
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
“なめらか”なメトロスタイルアプリを作るために ~WinRT の非同期性を活用したアプリ開発~
 
Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~
Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~
Xamarin で Prism を使いたい! ~「正式対応」 まで待てない人のための Prism 利用 Tips~
 
Visual Studio 2015 + Xamarin
Visual Studio 2015 + XamarinVisual Studio 2015 + Xamarin
Visual Studio 2015 + Xamarin
 
Xamarin によるクロスプラットフォームモバイルアプリ開発
Xamarin によるクロスプラットフォームモバイルアプリ開発Xamarin によるクロスプラットフォームモバイルアプリ開発
Xamarin によるクロスプラットフォームモバイルアプリ開発
 
Windows アプリケーション開発 はじめに ~ Windows アプリケーション開発初学者の方向け Visual Studio を使ったアプリケーショ...
Windows アプリケーション開発はじめに ~ Windows アプリケーション開発初学者の方向けVisual Studio を使ったアプリケーショ...Windows アプリケーション開発はじめに ~ Windows アプリケーション開発初学者の方向けVisual Studio を使ったアプリケーショ...
Windows アプリケーション開発 はじめに ~ Windows アプリケーション開発初学者の方向け Visual Studio を使ったアプリケーショ...
 
いまさら学ぶMVVMパターン
いまさら学ぶMVVMパターンいまさら学ぶMVVMパターン
いまさら学ぶMVVMパターン
 
Prism + ReactiveProperty入門
Prism + ReactiveProperty入門Prism + ReactiveProperty入門
Prism + ReactiveProperty入門
 
Xamarin 概要 2015年5月版
Xamarin 概要 2015年5月版Xamarin 概要 2015年5月版
Xamarin 概要 2015年5月版
 
C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介
C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介
C#でのクロスプラットフォーム モバイル開発環境 Xamarin のご紹介
 
モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点
モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点
モバイル向けクロスプラットフォーム開発ツール Xamarin の概要とその利点
 
20171202 Xamarinの歩き方
20171202 Xamarinの歩き方20171202 Xamarinの歩き方
20171202 Xamarinの歩き方
 
塹壕よりLivetとMVVM
塹壕よりLivetとMVVM塹壕よりLivetとMVVM
塹壕よりLivetとMVVM
 
C++からC#まで Visual Studio 縛り (で死ぬ実験)
C++からC#まで Visual Studio 縛り (で死ぬ実験)C++からC#まで Visual Studio 縛り (で死ぬ実験)
C++からC#まで Visual Studio 縛り (で死ぬ実験)
 
Xamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しよう
Xamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しようXamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しよう
Xamarin + Visual Studio によるマルチプラットフォーム対応アプリ開発 - iOS, Android, Windows に対応しよう
 
ゆるふわ Xamarin Tips
ゆるふわ Xamarin Tipsゆるふわ Xamarin Tips
ゆるふわ Xamarin Tips
 
Xamarin概要+最新情報
Xamarin概要+最新情報Xamarin概要+最新情報
Xamarin概要+最新情報
 
かけ算で使いこなす Xamarin
かけ算で使いこなす Xamarinかけ算で使いこなす Xamarin
かけ算で使いこなす Xamarin
 
MVVM入門
MVVM入門MVVM入門
MVVM入門
 
Visual studio 2013 Overview
Visual studio 2013 OverviewVisual studio 2013 Overview
Visual studio 2013 Overview
 

Viewers also liked

AVFoundationを使った無音カメラアプリの作り方
AVFoundationを使った無音カメラアプリの作り方AVFoundationを使った無音カメラアプリの作り方
AVFoundationを使った無音カメラアプリの作り方Takashi Ohtsuka
 
Xamarin バッドノウハウ大全
Xamarin バッドノウハウ大全Xamarin バッドノウハウ大全
Xamarin バッドノウハウ大全Yoshito Tabuchi
 
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2Yoshito Tabuchi
 
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
この辺でXamarin導入による 効果と限界をしっかり把握してみよう  MVP Community Camp 2015 この辺でXamarin導入による 効果と限界をしっかり把握してみよう  MVP Community Camp 2015
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015 Shinichi Hirauchi
 
iPhoneカメラアプリ開発入門(第1回)
iPhoneカメラアプリ開発入門(第1回)iPhoneカメラアプリ開発入門(第1回)
iPhoneカメラアプリ開発入門(第1回)Takashi Ohtsuka
 
Sansan における Android アプリ自動テスト導入事例
Sansan における Android アプリ自動テスト導入事例Sansan における Android アプリ自動テスト導入事例
Sansan における Android アプリ自動テスト導入事例健一 辰濱
 
iOSアプリ開発のCI環境 - Jenkins編 -
iOSアプリ開発のCI環境 - Jenkins編 -iOSアプリ開発のCI環境 - Jenkins編 -
iOSアプリ開発のCI環境 - Jenkins編 -Toshiyuki Hirata
 
Xamarin & Google Maps SDKでクロスプラットフォーム地図アプリ
Xamarin & Google Maps SDKでクロスプラットフォーム地図アプリXamarin & Google Maps SDKでクロスプラットフォーム地図アプリ
Xamarin & Google Maps SDKでクロスプラットフォーム地図アプリKohei Otsuka
 
Xamarin で ReactiveUI を使ってみた
Xamarin で ReactiveUI を使ってみたXamarin で ReactiveUI を使ってみた
Xamarin で ReactiveUI を使ってみたHironov OKUYAMA
 
続Xamarinはじめました
続Xamarinはじめました続Xamarinはじめました
続XamarinはじめましたYuya Yamaki
 
Jxugc#22 lt古川
Jxugc#22 lt古川Jxugc#22 lt古川
Jxugc#22 lt古川F. Syam
 
Xamarinは辛いよ
Xamarinは辛いよXamarinは辛いよ
Xamarinは辛いよTakkiiii
 
Xamarin.Formsで鉄道模型を制御してみた
Xamarin.Formsで鉄道模型を制御してみたXamarin.Formsで鉄道模型を制御してみた
Xamarin.Formsで鉄道模型を制御してみたayasehiro
 
Enterpriseから見たXamarinの可能性
Enterpriseから見たXamarinの可能性Enterpriseから見たXamarinの可能性
Enterpriseから見たXamarinの可能性Atsushi Nakamura
 
カメラアプリ開発入門3
カメラアプリ開発入門3カメラアプリ開発入門3
カメラアプリ開発入門3Takashi Ohtsuka
 
JXUGC 13 東京 はじめに
JXUGC 13 東京 はじめにJXUGC 13 東京 はじめに
JXUGC 13 東京 はじめにYoshito Tabuchi
 
Xamarin開発環境の選択
Xamarin開発環境の選択Xamarin開発環境の選択
Xamarin開発環境の選択Miho Kurosawa
 
Xamarinはじめました
XamarinはじめましたXamarinはじめました
XamarinはじめましたYuya Yamaki
 

Viewers also liked (20)

AVFoundationを使った無音カメラアプリの作り方
AVFoundationを使った無音カメラアプリの作り方AVFoundationを使った無音カメラアプリの作り方
AVFoundationを使った無音カメラアプリの作り方
 
Xamarin バッドノウハウ大全
Xamarin バッドノウハウ大全Xamarin バッドノウハウ大全
Xamarin バッドノウハウ大全
 
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
Xamarin 概要 @ 「Xamarin」って何? Wエバンジェリストによる特濃「Xamarin」勉強会 Rev2
 
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
この辺でXamarin導入による 効果と限界をしっかり把握してみよう  MVP Community Camp 2015 この辺でXamarin導入による 効果と限界をしっかり把握してみよう  MVP Community Camp 2015
この辺でXamarin導入による 効果と限界をしっかり把握してみよう MVP Community Camp 2015
 
Xamarin 基礎講座
Xamarin 基礎講座Xamarin 基礎講座
Xamarin 基礎講座
 
iPhoneカメラアプリ開発入門(第1回)
iPhoneカメラアプリ開発入門(第1回)iPhoneカメラアプリ開発入門(第1回)
iPhoneカメラアプリ開発入門(第1回)
 
Sansan における Android アプリ自動テスト導入事例
Sansan における Android アプリ自動テスト導入事例Sansan における Android アプリ自動テスト導入事例
Sansan における Android アプリ自動テスト導入事例
 
iOSアプリ開発のCI環境 - Jenkins編 -
iOSアプリ開発のCI環境 - Jenkins編 -iOSアプリ開発のCI環境 - Jenkins編 -
iOSアプリ開発のCI環境 - Jenkins編 -
 
Xamarin & Google Maps SDKでクロスプラットフォーム地図アプリ
Xamarin & Google Maps SDKでクロスプラットフォーム地図アプリXamarin & Google Maps SDKでクロスプラットフォーム地図アプリ
Xamarin & Google Maps SDKでクロスプラットフォーム地図アプリ
 
Xamarin で ReactiveUI を使ってみた
Xamarin で ReactiveUI を使ってみたXamarin で ReactiveUI を使ってみた
Xamarin で ReactiveUI を使ってみた
 
続Xamarinはじめました
続Xamarinはじめました続Xamarinはじめました
続Xamarinはじめました
 
Jxugc#22 lt古川
Jxugc#22 lt古川Jxugc#22 lt古川
Jxugc#22 lt古川
 
Xamarinは辛いよ
Xamarinは辛いよXamarinは辛いよ
Xamarinは辛いよ
 
Xamarin.Forms概要
Xamarin.Forms概要Xamarin.Forms概要
Xamarin.Forms概要
 
Xamarin.Formsで鉄道模型を制御してみた
Xamarin.Formsで鉄道模型を制御してみたXamarin.Formsで鉄道模型を制御してみた
Xamarin.Formsで鉄道模型を制御してみた
 
Enterpriseから見たXamarinの可能性
Enterpriseから見たXamarinの可能性Enterpriseから見たXamarinの可能性
Enterpriseから見たXamarinの可能性
 
カメラアプリ開発入門3
カメラアプリ開発入門3カメラアプリ開発入門3
カメラアプリ開発入門3
 
JXUGC 13 東京 はじめに
JXUGC 13 東京 はじめにJXUGC 13 東京 はじめに
JXUGC 13 東京 はじめに
 
Xamarin開発環境の選択
Xamarin開発環境の選択Xamarin開発環境の選択
Xamarin開発環境の選択
 
Xamarinはじめました
XamarinはじめましたXamarinはじめました
Xamarinはじめました
 

Similar to iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East

MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」U-dai Yokoyama
 
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~normalian
 
Windowsストアアプリ開発 オープンセミナー広島
Windowsストアアプリ開発 オープンセミナー広島Windowsストアアプリ開発 オープンセミナー広島
Windowsストアアプリ開発 オープンセミナー広島Akira Onishi
 
Building Silverlight Large Scale Application Using MVVM
Building Silverlight Large Scale Application Using MVVMBuilding Silverlight Large Scale Application Using MVVM
Building Silverlight Large Scale Application Using MVVMShotaro Suzuki
 
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」Yoshito Tabuchi
 
2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料OCHI Shuji
 
【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -
【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -
【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -ShinichiAoyagi
 
Application Insight Introduction
Application Insight IntroductionApplication Insight Introduction
Application Insight IntroductionKazushi Kamegawa
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionYoshitaka Seo
 
2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発
2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発
2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発Fujio Kojima
 
Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)
Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)
Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)shigeya
 
スマートフォンアプリケーション開発の最新動向
スマートフォンアプリケーション開発の最新動向スマートフォンアプリケーション開発の最新動向
スマートフォンアプリケーション開発の最新動向Tsutomu Ogasawara
 
20110212 Silverlight から Bing Maps に触れる
20110212 Silverlight から Bing Maps に触れる20110212 Silverlight から Bing Maps に触れる
20110212 Silverlight から Bing Maps に触れるKenji Wada
 
Visual Studio を使わず .NET する
Visual Studio を使わず .NET するVisual Studio を使わず .NET する
Visual Studio を使わず .NET するm ishizaki
 
CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~
CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~
CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~SEGADevTech
 
NET MAUI for .NET 7 for iOS, Android app development
 NET MAUI for .NET 7 for iOS, Android app development  NET MAUI for .NET 7 for iOS, Android app development
NET MAUI for .NET 7 for iOS, Android app development Shotaro Suzuki
 
Windows10の展開手法
Windows10の展開手法Windows10の展開手法
Windows10の展開手法NAOKI ABE
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejsTakayoshi Tanaka
 
ABC2012Spring 20120324
ABC2012Spring 20120324ABC2012Spring 20120324
ABC2012Spring 20120324Tak Inamori
 

Similar to iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East (20)

MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
MVPパターンによる設計アプローチ「あなたのアプリ報連相できてますか」
 
RoboVM
RoboVMRoboVM
RoboVM
 
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
わんくま同盟名古屋勉強会18回目 ASP.NET MVC3を利用したHTML5な画面開発~クラウドも有るよ!~
 
Windowsストアアプリ開発 オープンセミナー広島
Windowsストアアプリ開発 オープンセミナー広島Windowsストアアプリ開発 オープンセミナー広島
Windowsストアアプリ開発 オープンセミナー広島
 
Building Silverlight Large Scale Application Using MVVM
Building Silverlight Large Scale Application Using MVVMBuilding Silverlight Large Scale Application Using MVVM
Building Silverlight Large Scale Application Using MVVM
 
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
Xamarin 20141212 モバイルカフェスペシャル 「C#で作るiOS/Androidのクロスプラットフォームスマホアプリ開発」
 
2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料2012 05-19第44回cocoa勉強会発表資料
2012 05-19第44回cocoa勉強会発表資料
 
【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -
【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -
【18-C-5】C# で iOS/Androidアプリ開発 - Visual Studio 2015 + Xamarin + MVVMCross -
 
Application Insight Introduction
Application Insight IntroductionApplication Insight Introduction
Application Insight Introduction
 
Azure IoT Edge で Custom Vision
Azure IoT Edge で Custom VisionAzure IoT Edge で Custom Vision
Azure IoT Edge で Custom Vision
 
2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発
2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発
2022.04.23 .NET 6 -7 時代のデスクトップ アプリケーション開発
 
Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)
Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)
Internet Explorer 9 の新機能「固定サイト」 (Pinned sites)
 
スマートフォンアプリケーション開発の最新動向
スマートフォンアプリケーション開発の最新動向スマートフォンアプリケーション開発の最新動向
スマートフォンアプリケーション開発の最新動向
 
20110212 Silverlight から Bing Maps に触れる
20110212 Silverlight から Bing Maps に触れる20110212 Silverlight から Bing Maps に触れる
20110212 Silverlight から Bing Maps に触れる
 
Visual Studio を使わず .NET する
Visual Studio を使わず .NET するVisual Studio を使わず .NET する
Visual Studio を使わず .NET する
 
CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~
CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~
CEDEC2021 Android iOS 実機上での自動テストをより楽に有意義にする為に ~端末管理・イメージ転送・動画記録等の周辺情報のノウハウ共有~
 
NET MAUI for .NET 7 for iOS, Android app development
 NET MAUI for .NET 7 for iOS, Android app development  NET MAUI for .NET 7 for iOS, Android app development
NET MAUI for .NET 7 for iOS, Android app development
 
Windows10の展開手法
Windows10の展開手法Windows10の展開手法
Windows10の展開手法
 
13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs13016 n分で作るtype scriptでnodejs
13016 n分で作るtype scriptでnodejs
 
ABC2012Spring 20120324
ABC2012Spring 20120324ABC2012Spring 20120324
ABC2012Spring 20120324
 

Recently uploaded

情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法ssuser370dd7
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦Sadao Tokuyama
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見Shumpei Kishi
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-LoopへTetsuya Nihonmatsu
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)ssuser539845
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor arts yokohama
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfMatsushita Laboratory
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdfAyachika Kitazaki
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~arts yokohama
 

Recently uploaded (12)

情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
情報処理学会86回全国大会_Generic OAMをDeep Learning技術によって実現するための課題と解決方法
 
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
ARスタートアップOnePlanetの Apple Vision Proへの情熱と挑戦
 
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
持続可能なDrupal Meetupのコツ - Drupal Meetup Tokyoの知見
 
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
「今からでも間に合う」GPTsによる 活用LT会 - 人とAIが協調するHumani-in-the-Loopへ
 
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
IFIP IP3での資格制度を対象とする国際認定(IPSJ86全国大会シンポジウム)
 
2024 04 minnanoito
2024 04 minnanoito2024 04 minnanoito
2024 04 minnanoito
 
2024 01 Virtual_Counselor
2024 01 Virtual_Counselor 2024 01 Virtual_Counselor
2024 01 Virtual_Counselor
 
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdfTaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
TaketoFujikawa_台本中の動作表現に基づくアニメーション原画システムの提案_SIGEC71.pdf
 
2024 03 CTEA
2024 03 CTEA2024 03 CTEA
2024 03 CTEA
 
20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf20240326_IoTLT_vol109_kitazaki_v1___.pdf
20240326_IoTLT_vol109_kitazaki_v1___.pdf
 
What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?What is the world where you can make your own semiconductors?
What is the world where you can make your own semiconductors?
 
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
2024 02 Nihon-Tanken ~Towards a More Inclusive Japan~
 

iOS の動画アプリ開発に Xamarin を使ってみた @JXUG #2 East

  • 1. iOS の動画アプリ開発に Xamarin を使ってみた @irgaly Japan Xamarin User Group JXUG Conference (East) #2 2014/11/22 @日本マイクロソフト 品川本社 セミナールームA
  • 2. 目次 • 自己紹介 • 実績 • アプリ説明/設計 • Xamarin.iOSのメリット/デメリット • メモリ管理の罠 • 原因と対策 • メディアの扱い • 画面回転 • Background Fetch • Jenkinsビルド • まとめ
  • 3. 自己紹介 • 北川大智 / @irgaly • フェンリル株式会社 • 共同開発部 • Android / iOS エンジニア • Android Lollipop, Material Design に興味あり • いずれ Dart の時代が来ると思っている • vim / arch linux とりあえず新しいものに食い付いておくタイプ
  • 5. 過去の実績 • NHK 紅白歌合戦アプリ(2013) ViewModel 実装の担当 • Xamarin/C# エンジニアを名乗れ るようになった • Objective-C からの解脱 NHK紅白アプリ
  • 7. 今回のアプリ • マルチメディア系 iPhone アプリ • iOS 7.0 以上 • Android は開発対象外 • Android 版は先行開発済み • Android 版の移植開発 • 機能 • ソーシャルログイン • Twitter, Facebook • 動画撮影 • ショートムービー、連続撮影、Landscape, Portrait • 動画ダウンロード・再生 • 動画の連続再生
  • 8. 設計 • MVVMCross で MVVM • いつでもクロスプラットフォーム展開できるように • Xamarin を選ぶ理由 • Model, API などは Service で制御。それ以外は ViewModel + View • Service または MVVMCross Plugin • Facobook iOS SDK (Xamarin Components) • Xamarin.Social (Twitter ログイン) (Xamarin Components) • 効果測定ネイティブ SDK バイディング • 録画機能もプラグイン化 (クロスプラットフォーム対応に向けて) • その他 • Mac/Xamarin Studio • Xib/AutoLayout/AssetCatalog...
  • 9. Xamarin.iOS を使って・メリット • モバイルアプリ開発に MVVM を導入できる • C# の恩恵 • LINQ の威力 • Objective-C の闇にはまらない • Attribute, Reflection... • 必要な機能はひととおり NuGet/Xamarin Component で調 達 できる • OS のすべての機能にアクセスでき、ネイティブ Binding も作れる • 業務利用にも耐えられる • C# ノウハウでの知識集約 • クロスプラットフォーム展開 • OS やプロジェクトを越えてのプラグイン利用 • MVVMCross の強力な武器を使える • Service (DI), Messenger, Plugin... ※ iOS/Objective-C 開発と比較した場合
  • 10. Xamarin.iOS を使って・デメリット • MVVM のオーバーヘッド • クラス数/インスタンス数が多く、画面生成のパフォーマン スに難儀 • iOSはもともとMVVM設計ではない → 内部的にリフレク ションを多用することのオーバーヘッド • iOS でのメモリリーク問題 • どう頑張ってもメモリリークを駆逐できない • GC の問題 • 基本的な対策はとりつつ、今後のXamarin社の対応に期 待 • エンジニアの問題 • チームメンバーが多いと、どうしてもメモリリーク対応 漏れが発生する ※ iOS/Objective-C 開発と比較した場合
  • 11. 現実 • 開発スピードが上がったり、コストが削減されるようなも のではない。 • MVVMの採用で品質は向上する • もちろんクロスプラットフォーム対象に開発すれば総合で 見た場合のスピード・コスト・品質に変化あり • エンジニアとしてはモダンな開発環境で揃えられるので心 安らぐ • 構成切り替え、Jenkins ビルド、Reveal、Crashlytics など に対応しており、不便になることはない • Xamarin Profilerなど、今後もツールは充実する方向にあ る • C#を書けるスマホアプリエンジニアの確保が難しい ※ iOS/Objective-C 開発と比較した場合
  • 13. メモリリークに気付く ある日 (絶望) ※当時はXcode Instrumentsでした
  • 14. 調べる • c# - Xamarin iOS memory leaks everywhere - Stack Overflow • http://stackoverflow.com/questions/25532870/xamarin-ios-memory-leaks-everywhere • Best way to recursively dispose UIViews in Xamarin iOS • http://education-eco.blogspot.jp/2014/08/best-way-to-recursively-dispose-uiviews. html • Memory and Performance Best Practices | Xamarin • http://developer.xamarin.com/guides/cross-platform/ deployment,_testing,_and_metrics/memory_perf_best_practices/ • Advanced Memory Management on iOS and Android - Mark Probst and Rodri… • http://www.slideshare.net/Xamarin/advanced-memory-management-on-ios-and-android- mark-probst-and-rodrigo-kumpera • Memory Management Pitfalls in Xamarin iOS - Introduction • http://bluetubeinc.com/blog/2013/6/memory-management-pitfalls-in-xamarin-ios-introduction 奥が深そう
  • 15. 原因は? • 二つのGCが同時に機能している • Xamarin.iOS の GC と iOS の GC の相性が悪い • 参照カウンタ方式の闇 • UIView でだいたいリークする
  • 16. 原因と発生パターン • ネイティブオブジェクト間での循環参照 • サブクラス化と EventHandler • アンマネージリソースを Dispose していない
  • 17. UIView の循環参照 • NSObject を継承したクラスを作ると発生
  • 18. 対策 1 public class MyView : UIView { 2 WeakReference<UIViewController> _parent; 3 public MyView (UIViewController parent) { 4 _parent = new WeakReference<UIViewController>(parent); 5 } 6 } • WeakReference を使う • Objective-C ではおなじみの習慣 • C#で書いていると忘れがちになるが、同じように対応す る
  • 19. サブクラス化とEventHandler 1 public class CustomButton : UIButton {} 2 3 public class MyViewController : UIViewController { 4 public override void ViewDidLoad () { 5 var button = new CustomButton(); 6 View.Add(button); 7 button.TouchUpInside += (s, e) => { 8 ButtonClick(); 9 }; 10 } 11 } • EventHandler で循環参照発生
  • 20. 対策 1 public override void ViewWillAppear(bool animated) 2 3 { 4 UIButton.TouchUpInside += ButtonClick; 5 } 6 7 public override void ViewWillDisappear(bool animated) 8 { 9 UIButton.TouchUpInside -= ButtonClick; 10 } • EventHandler の削除
  • 21. アンマネージリソースの Dispose 漏れ 1 public override void ViewDidLoad () { 2 var imageView = ...; 3 var image = UIImage.FromBundle ("hoge.png"); 4 imageView.Image = image; 5 6 _otherButton.TouchUpInside += (s, e) => { 7 imageView.RemoveFromSuperview();// UIImageを解放できていない 8 } 9 }
  • 22. 対策 1 public override void ViewDidLoad () { 2 var imageView = ...; 3 var image = UIImage.FromBundle ("hoge.png"); 4 imageView.Image = image; 5 6 _otherButton.TouchUpInside += (s, e) => { 7 imageView.RemoveFromSuperview(); 8 imageView.Dispose(); 9 image.Dispose(); // すぐに解放する 10 } 11 }
  • 23. 対策まとめ • 親の参照には WeakReference を使う • 不要になったら EventHandler の削除 • 怪しかったら Dispose する • → むしろ Touch プロジェクト(Xamarin.iOS) 側のコードビ ハインドをできる限り減らす • Core プロジェクト(PCL) プロジェクトのコードはこれら の危険が少ない
  • 25. メディアの扱い • 動画撮影 • プラグインを独自実装 • PlatformService • プラットフォーム固有の機能について • 機能紹介 DIを使うことで、Core プロジェクトから プラットフォームの機能を扱えるようにする。
  • 26. 独自のMVVMCross Plugin • PCLとプラットフォームとでプロジェクトを分ける
  • 27. IMvxVideoCapture 1 public interface IMvxVideoCapture 2 { 3 Task<bool> SetupCaptureSessionAsync(); 4 bool StartRecording(string filePath); 5 Task<bool> StopRecording(); 6 bool SwitchCamera(); 7 bool UpdateOrientation(VideoOrientation orientation); 8 } 9 10 public interface IMvxVideoCapture<TPreviewView> : IMvxVideoCapture 11 { 12 bool StartPreview(IMvxVideoDisplay<TPreviewView> display); 13 bool StopPreview(); 14 } • プラットフォームに依存しないインタフェースを定義する
  • 28. MvxVideoCapture 初期化からプレビュー開始まで(part1) 1 var session = new AVCaptureSession 2 { 3 SessionPreset = AVCaptureSession.PresetHigh 4 }; 5 var camera = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Video); 6 var mic = AVCaptureDevice.DefaultDeviceWithMediaType(AVMediaType.Audio); 7 var cameraInput = AVCaptureDeviceInput.FromDevice(camera); 8 session.AddInput(cameraInput); 9 var micInput = AVCaptureDeviceInput.FromDevice(mic); 10 session.AddInput(micInput); • Touch プロジェクト側で実装を書く • iOS AVFoundation クラスを C# からそのまま扱える
  • 29. MvxVideoCapture 初期化からプレビュー開始まで(part2) 11 var queue = new DispatchQueue("CaptureBuffer"); 12 var videoOutput = new AVCaptureVideoDataOutput(); 13 session.AddOutput(videoOutput); 14 videoOutput.SetSampleBufferDelegate(this, queue); 15 var connection = videoOutput.ConnectionFromMediaType(AVMediaType.Video); 16 connection.VideoOrientation = GetCaptureOrientation(_currentOrientation); 17 var audioOutput = new AVCaptureAudioDataOutput(); 18 session.AddOutput(audioOutput); 19 audioOutput.SetSampleBufferDelegateQueue(this, queue); 20 var previewLayer = new AVCaptureVideoPreviewLayer(session); 21 session.StartRunning(); • Touch プロジェクト側で実装を書く • iOS AVFoundation クラスを C# からそのまま扱える
  • 30. MvxVideoCapture コーデックの設定から撮影開始部分(part1) 1 var videoSettings = new NSMutableDictionary(); 2 videoSettings.Add(AVVideo.CodecKey, AVVideo.CodecH264); 3 videoSettings.Add(AVVideo.WidthKey, new NSNumber(640)); 4 videoSettings.Add(AVVideo.HeightKey, new NSNumber(480)); 5 var compressionSettings = new NSMutableDictionary(); 6 compressionSettings.Add(AVVideo.AverageBitRateKey, new NSNumber(2413000)); 7 videoSettings.Add(AVVideo.CompressionPropertiesKey, compressionSettings); 8 videoSettings.Add(AVVideo.ScalingModeKey, AVVideoScalingModeKey. 9 ResizeAspectFill); 10 11 var videoInput = new AVAssetWriterInput(AVMediaType.Video, new 12 AVVideoSettingsCompressed(videoSettings)); 13 videoInput.ExpectsMediaDataInRealTime = true; 14 writer.AddInput(videoInput); • AVAssetWriterInput の引数を作成するために、 NSMutableDictionary を C# から扱っています。
  • 31. MvxVideoCapture コーデックの設定から撮影開始部分(part2) 15 16 var audioSettings = new NSMutableDictionary(); 17 audioSettings.Add(AVAudioSettings.AVFormatIDKey, NSNumber.FromInt32((int) 18 AudioFormatType.MPEG4AAC)); 19 audioSettings.Add(AVAudioSettings.AVNumberOfChannelsKey, NSNumber.FromInt16(2)) 20 ; 21 audioSettings.Add(AVAudioSettings.AVSampleRateKey, NSNumber.FromFloat(44100.0f) 22 ); 23 var audioInput = new AVAssetWriterInput(AVMediaType.Audio, new AudioSettings( 24 audioSettings)); 25 writer.AddInput(audioInput); • AVAssetWriterInput の引数を作成するために、 NSMutableDictionary を C# から扱っています。
  • 32. Core プロジェクトから MvxVideoCapture を使う 1 ... 2 var videoCapture = Mvx.Resolve<IMvxVideoCapture>(); 3 videoCapture.StartRecording(filePath); 4 5 ... 6 7 await videoCapture.StopRecording(); • MVVMCross プラグインとしてインタフェースとプラットフォーム固有の実 装を分けたため、ViewModel 側の PCL プロジェクトへこれを記述できる
  • 33. PlatformService 1 public class TouchPlatformService : IPlatformService 2 { 3 public IMediaFile GetMediaFile(string path) 4 { 5 return new TouchMediaFile(path); 6 } 7 8 public async Task Share(string shareText) 9 { 10 var items = new NSObject[] { 11 new NSString(shareText) 12 }; 13 var activity = new UIActivityViewController(items, null); 14 var vc = ...; 15 ... 16 await vc.PresentViewControllerAsync(activity, true); 17 } 18 19 public string VersionName() 20 { 21 return NSBundle.MainBundle.ObjectForInfoDictionary("CFBundleVersion"). 22 ToString(); 23 } 24 25 ... • プラットフォーム固有の機能を呼び出すユーティリティサービ ス
  • 35. 画面回転 • 現在の iPhone の傾きや、傾きの変化を取得する • 動画撮影の縦、横切り替えに使用 • BeginGeneratingDeviceOrientationNotifications で判定する • 画面ロック時には回転通知は発生しない
  • 36. 画面回転 1 public override void ViewWillAppear(bool animated) 2 { 3 base.ViewWillAppear(animated); 4 5 UIDevice.CurrentDevice.BeginGeneratingDeviceOrientationNotifications(); 6 var notificationAvailable = false; 7 _orientationObserverToken = NSNotificationCenter.DefaultCenter.AddObserver( 8 UIDevice.OrientationDidChangeNotification, notification => 9 { 10 notificationAvailable = true; // 傾き取得成功 11 ... // 傾きに応じた処理 12 }); 13 14 Task.Run(async () => 15 { 16 await Task.Delay(500); 17 if(!notificationAvailable) { 18 … // 傾きロックされている可能性がある。Portraitであるとみなして処理 19 } 20 }).Forget(); 21 }
  • 37. 画面回転 1 public override void ViewWillDisappear(bool animated) 2 3 { 4 base.ViewWillDisappear(animated); 5 UIDevice.CurrentDevice.EndGeneratingDeviceOrientationNotifications(); 6 if (_orientationObserverToken != null) 7 { 8 NSNotificationCenter.DefaultCenter.RemoveObserver(_orientationObserverT 9 oken); 10 _orientationObserverToken = null; 11 } 12 }
  • 39. Background Fetch • iOS7 以上で、バックグラウンドのアプリが一定期間ごとに起動し、な んらかの処理を実行できる機能 • 起動の間隔はOSが決定するため、指定することはできない • 30秒間のみ処理可能であり、できることは限られてくる • 主にAPIとの通信で、データ更新をチェックするための機能 • 30秒を過ぎるとプロセスが殺される
  • 41. Background Fetch 1 public override bool FinishedLaunching(UIApplication app, NSDictionary options) 2 3 { 4 ... 5 6 // BackgrondFetchの呼び出し間隔指定 7 UIApplication.SharedApplication 8 .SetMinimumBackgroundFetchInterval( 9 UIApplication.BackgroundFetchIntervalMinimum); 10 11 return true; 12 } • AppDelegateで、起動時に Background Fetch の間隔を設定
  • 42. PerformFetchの実装 1 public override async void PerformFetch(UIApplication application, Action< 2 UIBackgroundFetchResult> 3 completionHandler) 4 5 { 6 var cancelToken = new CancellationTokenSource(); 7 try 8 { 9 // 25秒で強制中断 10 cancelToken.CancelAfter(25000); 11 12 // API通信などを実行 13 … completionHandler(UIBackgroundFetchResult.NewData); 14 } 15 catch (OperationCanceledException) 16 { 17 completionHandler(UIBackgroundFetchResult.Failed); 18 } 19 } • 保険として25秒制限をしているが、安全に対応するならBackground Transfer (NSURLSession Background mode)で対応する • Xamarin はアップデートが早いため、OSの最新機能もすぐ使えるようになる • マイナーな機能は SDK にバグがあることもある
  • 44. Jenkins ビルド • 弊社ではすべてのプロダクトは Jenkins でビルドしています • 納品時のトラブルを防ぐ • エンジニア不在の時でも最新のアプリの動作確認を行える • Xamarin.iOS x Jenkins は公式ガイドあり • http://developer.xamarin.com/guides/cross-platform/ci/jenkins_walkthrough/ • Jenkins は Mac 上で実行されている • Jenkins ビルドでの構成(定数)切り替えビルド対応
  • 45. プロジェクト側の準備 • mdtool コマンドは定数切り替えに対応していない • 定数切り替え対応のため、Touchプロジェクトにシンボル を定義しておく
  • 46. Jenkins 環境の準備 Jenkins 環境で作業します • Xamarin Studio をインストールする • ライセンス認証する • Stable の最新バージョンにアップデートしておく • 開発チームとJenkinsで、「常にXamarin StudioのStable最新 環境で作業する」という取り決めをしておく • Xcode も一度は起動して使える状態にしておく(念のため) • プロビジョニングプロファイルと署名をインポートしておく
  • 47. ビルド構成を作成 • フリースタイルビルド構成 • ビルド環境 > ビルドプロセスに環境変数をインジェクト (Environment Injector Plugin)
  • 48. ビルド構成を作成 • ビルド > シェルの実行 > シェルスクリプト 1 sed -i '' -Ee "s/__JENKINS__;/${Options};/g" MyProject.*/MyProject.*.csproj 2 4 /Applications/Xamarin Studio.app/Contents/MacOS/mdtool -v build -t:Build -c:$ (BuildConfiguration}|iPhone -p:MyProject.Touch MyProject/MyProject.sln 5 6 find MyProject/MyProject.Touch/bin/${BuildConfiguration} -name '*.ipa' -exec 7 mv {} MyProject/MyProject.Touch/bin/${ 8 BuildConfiguration}/MyProject-${ 9 BuildConfiguration}-${BUILD_ID}.ipa ;
  • 50. まとめ • iOS寄りの各機能の紹介をコードレベルで紹介しました • PCLとプラットフォームのプロジェクトを分けて実装する • パッケージマネージャなどの機能は揃っており、Xamarin は開発プラットフォームとしては強力 • プラットフォーム固有の機能へのアクセスもできるため、 業務に耐えうる • プラットフォームごとの対応の手間はかかる、罠も多い