Slide 1

Slide 1 text

600݅ͷPull Request ͔ΒΈͨ Xamarin ͸·ΓϙΠϯτ Nobuhiro Ito / Fenrir Inc. @ Japan Xamarin User Group Conference #13, 2016/05/07(Sat)

Slide 2

Slide 2 text

@iseebi Nobuhiro Ito Fenrir Inc. Smartphone App Engineer http://iseebi.hatenablog.com/

Slide 3

Slide 3 text

ձࣾͱͯ͠Xamarinྺ2೥൒Ҏ্ ా෵͞Μ͕XamarinऔΓѻ͍͸͡ΊΔલ͔Β΍ͬͯΔ

Slide 4

Slide 4 text

MvvmCross Ψν੎ ͨͩ࠷ۙ͸΋ͬͱଞͷ΋ͷΛࢼ͍ͨ͠ͱࢥͬͯΔ… ※px୯ҐͰϨΠΞ΢τࢦ͕ࣔඈΜͰ͘ΔͷͰFormsͰ͸ରॲͰ͖ͳ͍

Slide 5

Slide 5 text

࠷ۙͷ͓࢓ࣄ ΞϓϦͷ։ൃͷ͔ͨΘΒɺύοέʔδ੡඼ͷϓϩμΫτΦʔφʔ΍ͬͯ·͢ɻ

Slide 6

Slide 6 text

͋ΔϓϩδΣΫτͷ͓࿩Λ͠·͢

Slide 7

Slide 7 text

ϓϩδΣΫτͷ؅ཧମ੍ͷมԽ • 2011, 2012೥
 ωΠςΟϒ / Subversion (2012೥ͷ్த͔ΒgitҠߦ), Redmine • 2013, 2014೥
 Xamarin / git, Redmine, Backlog, TeamGantt • 2015೥
 Xamarin / GitHub Enterprise, Redmine, Backlog, TeamGantt

Slide 8

Slide 8 text

GitHub Enterprise ʹͯ͠Α͔ͬͨ͜ͱ • શ෦ Pull Request ͰϨϏϡʔͰ͖Δ • ͋ͱ͔Β༷ʑͳ͜ͱΛৼΓฦΔ͜ͱ͕Ͱ͖Δɻ

Slide 9

Slide 9 text

͋ͱ͔ΒৼΓฦΔ͜ͱ͕Ͱ͖Δ • ίϛοτͷճ਺ͱ͔ • ͲΜͳίϛοτΛ͔ͨ͠ͱ͔ (શ෦ Pull Request ͰݟΕΔ)

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

4ϲ݄Ͱͪΐ͏ͲͽͬͨΓPR 600݅ ࠓ೔͸͜ͷத͔Β ಛʹʮۤ͠Μͩͳʔʯͱ͍͏ͱ͜ΖΛ ͔͍ͭ·ΜͰ͝঺հ

Slide 12

Slide 12 text

ͦͷ1 HTTPϋϯυϥෆ҆ఆࣄ݅

Slide 13

Slide 13 text

Hello, ModernHttpClient • աڈͷ։ൃ͔ΒɺHttpWebRequest ͩͱ Android Ͱ 
 ·Εʹ DNS ͕1෼΄ͲҾ͚ͳ͘ͳΓɺ௨৴Ͱ͖ͳ͘ͳΔ͜ͱ͕Θ͔͍ͬͯͨɻ • 2015೥͸ModernHttpClientΛ࢖͏͜ͱ͸ܾΊ͍ͯͨɻ • HttpClient ͷҾ਺ʹ౉͢ HttpClientHandler ͱͯ͠౉͢
 NativeMessageHandler Λఏڙͯ͘͠ΕΔɻ • iOS 9 ͷ ATS ରԠͱͯ͠΋ඞਢͩͬͨɻ

Slide 14

Slide 14 text

iOS 8 ͔͋Μ΍Μ… • ModernHttpClient ͷಋೖࣗମ͸ΘΓͱ͢ΜͳΓͰ͖ͨɻ • AutomaticDecompression = true Λࢦఆ͍ͯ͠Δͱ
 iOS ͰΫϥογϡ͢Δͱ͔͸͋ͬͨɻ • ͔͠͠ɺࠓ౓͸ iOS 8 Ͱ HTTP ͕௨Βͳ͘ͳΔݱ৅͕ൃੜ͢Δ…

Slide 15

Slide 15 text

CFNetworkHandler…ࠓ౓͸iOS9͕͔͋Μ… • ModernHttpClientಉ༷ʹɺHttpClientHandlerͱͯ͠࢖͑Δ System.Net.Http.CFNetworkHandler ͕ೖ͍ͬͯͨͷͰ࢖͏ɻ • iOS 8Ͱ͸҆ఆ͢Δ͕ɺiOS 9 Ͱ͸ https ͕௨Βͳ͘ͳͬͨɻ • iOS 8 Ҏલ͸ CFNetworkHandlerɺ
 ͦΕҎ֎Ͱ͸ NativeMessageHandler Λ
 ࢖༻͢ΔΑ͏ʹ͢Δ͜ͱͰղܾɻ • NSUrlSessionHandler/AndroidClientHandler ͕ඪ४౥ࡌ͞Ε(Δ|ͨ)Β͍͠ͷͰظ଴ɻ J04PS&BSMJFS $'/FUXPSL)BOEMFS J04 /BUJWF.FTTBHF)BOEMFS "OESPJE /BUJWF.FTTBHF)BOEMFS

Slide 16

Slide 16 text

ͦͷ2 Content Description จࣈԽ͚ࣄ݅ @Android

Slide 17

Slide 17 text

ࣗಈςετ͠·͠ΐ͏…·͓ͨ·͔͑Galaxy! • Android ͷ UI ςετΛ͢Δ͜ͱʹͳ͍ͬͯͨͷͰɺContent Description Λࢦఆ͍ͯͨ͠ɻ • ೔ຊ୺຤ͷ඼ἧ͑ͷ໰୊Ͱ Xamarin Test Cloud Ͱ͸ͳ͘ɺ
 Remote TestKit ͱUIAutomator ͷ૊Έ߹Θͤɻ • ೔ຊޠͷ Content Description Λࢦఆ͍ͯ͠Δͱ
 Galaxy S6 edge Ͱ͜ͱ͝ͱ͘??????????????ʹจࣈԽ͚ɻ • ݁ہӳޠࢦఆ͠ɺϦϦʔεલʹ໭͢͜ͱͰղܾɻXTC ࢖ͬͯͯ΋໰୊ʹͳΔ͔΋ʁ

Slide 18

Slide 18 text

ͦ΋ͦ΋GalaxyͱXamarinͷ૬ੑ͕ѱ͍ • جຊతʹԿ͔໰୊͋Δͷ͸ GalaxyɻS4, S5, S6 શ෦Ϡό͍ɻ • Galaxy S4 4.2.1 ͕ಛʹϠό͍ɻଞͷ୺຤Ͱಈ͍͍ͯΔίʔυ͕ී௨ʹམͪΔɻ • ͦͯ͜͠ͷ୺຤͸ͳΜͱUSBσόοάͰ͖ͳ͍ʢʂʣ • ͨͩɺ͍͕ͭ͜མ͍ͪͯΔͷ͸࣮૷্ؒҧ͍ͬͯͨͱ͍͏͜ͱ͹͔Γͩͬͨɻ • ͖ͬͪΓςετ͍ͨ͠Ϛκͳํ͸1୆ήοτ͓ͯ͘͠ͱྑ͍͔΋ɻ

Slide 19

Slide 19 text

ͦͷ3 ARM64୺຤Ͱଈࢮࣄ݅ @Android

Slide 20

Slide 20 text

64bit ͷ .so ͕͋Δͱ ABI ΋ 64bit ͳ͍ͱࢮ͵ • Android൛Ͱ͸Realmґଘ͍ͯ͠ΔωΠςΟϒϥΠϒϥϦΛ࢖͍ͬͯͨɻ • Xamarin಺Ͱ͸࢖͍ͬͯͳ͔ͬͨɻωΠςΟϒϥΠϒϥϦ͸ࢀর͍ͯ͠ΔͷΈɻ • ͢ΔͱGalaxy S6ͳͲͷARM64୺຤Ͱଈࢮ͢Δ • libmonodroid.so͕ͳ͍ͱग़ͨɻΞϓϦࣗମ͸ABI͍࣋ͬͯͳ͍͕ɺ
 Realm ͷωΠςΟϒϥΠϒϥϦͷ .so ͕ల։͞Εͨ͜ͱͰඞཁʹͳͬͯ͠·ͬͨɻ • ΞϓϦଆ΋64bit ABI Λαϙʔτͤ͞Δ͜ͱͰղܾɻ

Slide 21

Slide 21 text

ͦͷ4 ऴྃͨ͠͸ͣͷը໘ͷը૾͕ ࢒ͬͯͯϝϞϦෆ଍ࣄ݅

Slide 22

Slide 22 text

͋ͪͪ͜Ͱىͬͨ͜໰୊ • ը૾͕ϝϞϦ্ʹ࢒ͬͯϦʔΫ / OOM • ಛʹ Android ͷ AnimationDrawable ͕͠Ϳͱ͔ͬͨ

Slide 23

Slide 23 text

ίʔυͷதͰ࡞ͬͨΦϒδΣΫτ͸ඞͣղ์ʂ • ϑΟʔϧυʹࢀরΛ࣋ͬͨ
 ΦϒδΣΫτ͸
 ඞͣ Dispose/ࢀর֎͢͠Δ UIButton appendButton;
 
 public override void ViewDidLoad ()
 {
 base.ViewDidLoad ();
 appendButton = new UIButton(new CGRect(10,10, 200, 48));
 View.AddSubview(appendButton);
 }
 
 protected override void Dispose(bool disposing)
 {
 if (disposing)
 {
 if (appendButton != null)
 {
 appendButton.Dispose();
 appendButton = null;
 }
 }
 base.Dispose(disposing);
 }
 


Slide 24

Slide 24 text

iOSͷ৔߹: Image,Layer ͷத਎΋ղ์͢Δ • ϓϩϑΝΠϥͰΈͨͱ͖ը૾͕࢒͍ͬͯͨ͜ͱ͕͋Δ • ͦ͏͍͏ͱ͖͸ ImageView ͷ
 Image, Layer.SubLayers ΋ۭʹͯ͠ɺ
 RemoveFromSuperview ͢Δͱྑ͍ɻ if (HogeImageView != null)
 {
 HogeImageView.Image = null;
 if (HogeImageView.Layer != null)
 {
 HogeImageView.Layer.Sublayers = null;
 } HogeImageView.RemoveFromSuperview();
 }

Slide 25

Slide 25 text

Android: AnimationDrawable ͷ State ղ์ • AnimationDrawable Λ࢖ͬͨ৔߹ɺ
 தͷϑϨʔϜͷBitmap͕
 ղ์͞Εͳ͍ͷͰɺ
 ࣗ෼Ͱத਎ΛRecycleͯ͠
 SetState Ͱࢀর΋ղ์ͯ͠΍Δɻ void RecycleAnimationDrawable()
 {
 if (_drawableAnimation == null)
 {
 return; 
 }
 
 for (int i = 0; i < _drawableAnimation.NumberOfFrames; ++i)
 {
 var frame = _drawableAnimation.GetFrame(i);
 var bitmap = frame as BitmapDrawable;
 if ((bitmap != null) && !bitmap.IsRecycled)
 {
 bitmap.Recycle();
 bitmap.Dispose();
 }
 frame.Callback = null;
 }
 _drawableAnimation.Callback = null;
 _drawableAnimation.SetState(new int[] { });
 _drawableAnimation = null;
 }

Slide 26

Slide 26 text

ͦͷ5 MvvmCross ͷ ListViewAdapter Viewੜ੒࣌ʹແବʹηοτ͕ಈ͘໰୊ @Android

Slide 27

Slide 27 text

MvxListView ͷ MvxAdapter • MvxListView ༻ʹόΠϯσΟϯάՄೳͳ ViewItem Λఏڙ͢Δ Adapter • ͦͷ··࢖͏͜ͱ΋ɺΧελϜͯ͠࢖͏͜ͱ΋Ͱ͖Δɻ • CreateBindableView ΛΦʔόʔϥΠυ͢Δɻ • ͳ͔ͥ CreateBindableView ͷੜ੒࣌ʹΫϥογϡͯ͠͠·͏͜ͱ͕͋ͬͨɻ • ߲໨ View ͷ MvxImageView ͷதͰ SetImageDrawable(null) ͕ಈ͍͍ͯͨɻ

Slide 28

Slide 28 text

CreateBindableView ൈ͚Δલʹ
 Binding ߋ৽͞ΕΔͷμϝ protected override IMvxListItemView CreateBindableView(object dataContext, int templateId)
 {
 var itemView = base.CreateBindableView(dataContext, templateId);
 var view = itemView as View;
 if (view != null)
 {
 var imageView = view.FindViewById(Resource.Id.timeline_image);
 imageView.ErrorImageResourceId = Resource.Drawable.img_live_object_loadfail;
 }
 return itemView;
 } %BUB$POUFYUͷ४උ͕ऴΘͬͯͳ͍λΠϛϯάͰݺ͹ΕΔ ˠը૾͕OVMM͕ೖͬͯ͘ΔՄೳੑ͕͋Δ

Slide 29

Slide 29 text

DataContext ͸ॳظԽऴΘ͔ͬͯΒܨ͙ protected override IMvxListItemView CreateBindableView(object dataContext, int templateId)
 {
 var itemView = base.CreateBindableView(null, templateId);
 var view = itemView as View;
 if (view != null)
 {
 var imageView = view.FindViewById(Resource.Id.timeline_image);
 imageView.ErrorImageResourceId = Resource.Drawable.img_live_object_loadfail;
 }
 itemView.DataContext = dataContext;
 return itemView;
 }
 


Slide 30

Slide 30 text

ͦͷ6 iOS 8 Ͱ୺຤ىಈޙҰൃ໨ͷ
 γϟολʔԻ͕໐Βͳ͍໰୊

Slide 31

Slide 31 text

iOS 8 ͷγϟολʔ໐Βͳ͍όά • ೔ຊࠃ಺޲͚ͷ iPhone Ͱ͸αΠϨϯτϞʔυʹ͍ͯͯ͠΋
 γϟολʔԻ͕ͳΔ • ͔͠͠ɺiOS 8 Ͱ͸ OS ىಈޙ 1 ճ໨ͷγϟολʔԻ͕໐Βͳ͍ɻ • Α͘஌ΒΕͨ iOS ࣗମͷόά

Slide 32

Slide 32 text

iOS 8 ͷॳճͷΈɺ ڧ੍తʹγϟολʔԻΛ໐Β͢ (΍Βͳ͍ํ͕ྑ͍) • iOS ૊ΈࠐΈͷޮՌԻΛ໐Β͢ AudioToolBox.SystemSound • 1108 ൪Λࢦఆ͢ΔͱɺΧϝϥͱಉ͡৚݅Ͱγϟολʔ͕໐Δ • iOS 8 ͷ൑ఆ͸ UIDevice.CurrentDevice.CheckSystemVersion ͰՄೳɻ • ౾஌ࣝɿ͜ͷϝιου͸ Xamarin ಠ֦ࣗு


Slide 33

Slide 33 text

iOS 8 ͷॳճͷΈɺ ڧ੍తʹγϟολʔԻΛ໐Β͢ (΍Βͳ͍ํ͕ྑ͍) needDummyShutterSound = UIDevice.CurrentDevice.CheckSystemVersion(8, 0) 
 && !UIDevice.CurrentDevice.CheckSystemVersion(9, 0)
 && !dummyShutterSoundPlayed;
 : : if (needDummyShutterSound) 
 {
 needDummyShutterSound = false;
 dummyShutterSoundPlayed = true;
 var sound = new AudioToolbox.SystemSound(1108);
 sound.PlaySystemSound();
 } J04Ҏ্ɺJ04Ҏ্Ͱͳ͍ ͔ͭ·ͩ໐Βͯ͠ͳ͍ TUBUJDϑΟʔϧυ ൪ͷγεςϜα΢ϯυΛ໐Β͢

Slide 34

Slide 34 text

·ͱΊ

Slide 35

Slide 35 text

ओͳ͸·ΓϙΠϯτճආํ๏ • HTTP௨৴पΓ͸ 
 ModernHttpClient (΋͘͠͸NSUrlSessionHandler/AndroidSessionHandler)Λ࢖͏ɻ
 iOS 8 ҎԼ͸ CFNetworkHandler Λ࢖ͬͨ΄͏͕Αͦ͞͏ɻ • ࢀরͨ͠ωΠςΟϒΦϒδΣΫτ͸͖ͪΜͱղ์͢Δɻ
 ಛʹը૾पΓ͸ղ์ʹؾΛ͚ͭΔɻ • Galaxyɺઈର͍ͭ͜͸Կ͔͋Δɻ1 ୆͋Δͱσόοάʹศརɻ
 Xamarin Test Cloud ʹ΋͍ͬͺ͍͋Γͦ͏͔ͩΒ׆༻͠Α͏ɻ

Slide 36

Slide 36 text

͍͞͝ʹ