writing native mac apps in c# with xamarin.mac - aaron bockover

80
Aaron Bockover Xamarin [email protected] @abock Writing Native Mac Apps in C# with Xamarin.Mac

Upload: xamarin

Post on 13-Jan-2015

1.750 views

Category:

Technology


4 download

DESCRIPTION

 

TRANSCRIPT

Page 1: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Aaron [email protected]@abock

Writing Native Mac Apps in C# with Xamarin.Mac

Page 2: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

2.6 Billion Devices

Page 3: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Mac OS XThe world’s most advanced desktop operating system

C#

Page 4: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

It’s all about sharing code

Shared C# CodeXamarin.Mobile

Business Logic

Cloud Access

Database Access

DesktopDesktop MobileMobileMobile

Windows iOS Windows Phone Android

Page 5: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

It’s all about sharing code

Shared C# CodeXamarin.Mobile

Business Logic

Cloud Access

Database Access

DesktopDesktop MobileMobileMobile

Windows iOS Windows Phone AndroidMac

Page 6: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

TouchDraw runs on iPad, Android, and Mac, achieving over 70% code reuse across

the platforms.

39%

61%

TouchDrawfor iPad

24%

76%

TouchDrawfor Mac

28%

72%

TouchDrawfor Android

Shared CodePlatform Specific

Page 7: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Xamarin.Mac at a glance

• Write native Mac applications in C#• Access Mac OS X APIs for rich integration• Leverage the full power of C# and .NET• Integrated with the Xamarin experience• Deploy directly to the Mac AppStore

Page 8: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Xamarin.Mac at a glance

Xamarin.Mac Frameworks

Xamarin Toolsand SDK

• Binder • Bundler • Linker • Packager Mono Runtime

.NET Base Class Libraries System Libraries

Darwin OS

Cocoa Frameworks

Xcode(UI designer)

Xamarin Studio IDE

Page 9: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Xamarin.Mac at a glance

Xamarin.Mac Frameworks

Xamarin Toolsand SDK

• Binder • Bundler • Linker • Packager Mono Runtime

.NET Base Class Libraries System Libraries

Darwin OS

Cocoa Frameworks

Xcode(UI designer)

Xamarin Studio IDE

Page 10: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Xamarin.Mac Frameworks

GraphicsGraphicsCoreGraphics ImageKitCoreImage ImageIOCoreText OpenGLCoreVideo PDFKit

User InterfaceUser InterfaceAppKit QuickLookCoreAnima?on SceneKitQCComposer WebKit

Audio and VideoAudio and VideoAVFounda?on CoreMidiAudioToolbox CoreMediaAudioUnit OpenAL

System ServicesSystem ServicesAddressBook CoreWLANBluetooth Scrip?ngBridgeCoreLoca?on StoreKitCoreServices

InfrastructureInfrastructureCoreData Founda?onCoreFounda?on ObjCRun?meDarwin Security

Page 11: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Many are shared with Xamarin.iOS

GraphicsGraphicsCoreGraphics ImageKitCoreImage ImageIOCoreText OpenGLCoreVideo PDFKit

User InterfaceUser InterfaceAppKit QuickLookCoreAnima?on SceneKitQCComposer WebKit

Audio and VideoAudio and VideoAVFounda?on CoreMidiAudioToolbox CoreMediaAudioUnit OpenAL

System ServicesSystem ServicesAddressBook CoreWLANBluetooth Scrip?ngBridgeCoreLoca?on StoreKitCoreServices

InfrastructureInfrastructureCoreData Founda?onCoreFounda?on ObjCRun?meDarwin Security

Page 12: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

The Basics

GraphicsGraphicsCoreGraphics ImageKitCoreImage ImageIOCoreText OpenGLCoreVideo PDFKit

User InterfaceUser InterfaceAppKit QuickLookCoreAnima?on SceneKitQCComposer WebKit

Audio and VideoAudio and VideoAVFounda?on CoreMidiAudioToolbox CoreMediaAudioUnit OpenAL

System ServicesSystem ServicesAddressBook CoreWLANBluetooth Scrip?ngBridgeCoreLoca?on StoreKitCoreServices

InfrastructureInfrastructureCoreData Founda5onCoreFounda?on ObjCRun?meDarwin Security

Page 13: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

How does Xamarin.Mac work?

Page 14: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

How does Xamarin.Mac work?

• OS X APIs are projected into C#1:1 mapping for full platform coverage

Page 15: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

How does Xamarin.Mac work?

• OS X APIs are projected into C#1:1 mapping for full platform coverage

• 80% are Objective-CFull object system is mappedSubclassing and overriding supported

Page 16: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

How does Xamarin.Mac work?

• OS X APIs are projected into C#1:1 mapping for full platform coverage

• 80% are Objective-CFull object system is mappedSubclassing and overriding supported

• 20% are CExposed as C# structs/classes/methodsNo support for subclassing or overriding

Page 17: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

How does Xamarin.Mac work?

• OS X APIs are projected into C#1:1 mapping for full platform coverage

Check out “Binding Objective-C Libraries” for a

deep dive at 1:30!

• 80% are Objective-CFull object system is mappedSubclassing and overriding supported

• 20% are CExposed as C# structs/classes/methodsNo support for subclassing or overriding

Page 18: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

DIVE IN

Page 19: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover
Page 20: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Page 21: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Info.plistApplication metadata, used by Mac OS (app name, version, publisher, etc.)

Page 22: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Info.plistApplication metadata, used by Mac OS (app name, version, publisher, etc.)

Resources FolderPlace any resources (images, icons, static data) to be bundled with the app

Page 23: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Application DelegateCalled with application events such as FinishedLaunching or OpenFiles

Info.plistApplication metadata, used by Mac OS (app name, version, publisher, etc.)

Resources FolderPlace any resources (images, icons, static data) to be bundled with the app

Page 24: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Application DelegateCalled with application events such as FinishedLaunching or OpenFiles

Info.plistApplication metadata, used by Mac OS (app name, version, publisher, etc.)

Application Main MenuInterface definition pre-populated with many common defaults

Resources FolderPlace any resources (images, icons, static data) to be bundled with the app

Page 25: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Application DelegateCalled with application events such as FinishedLaunching or OpenFiles

Info.plistApplication metadata, used by Mac OS (app name, version, publisher, etc.)

Application Main MenuInterface definition pre-populated with many common defaults

Main Window User InterfaceThe primary window definition editable in the Xcode UI Builder

Resources FolderPlace any resources (images, icons, static data) to be bundled with the app

Page 26: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Anatomy of a Xamarin.Mac application

Application DelegateCalled with application events such as FinishedLaunching or OpenFiles

Info.plistApplication metadata, used by Mac OS (app name, version, publisher, etc.)

Application Main MenuInterface definition pre-populated with many common defaults

Main Window User InterfaceThe primary window definition editable in the Xcode UI Builder

Main Window ImplementationClass for implementing the features of your Main Window

Resources FolderPlace any resources (images, icons, static data) to be bundled with the app

Page 27: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

First Run

Page 28: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Building out our NSWindowpublic  override  void  WindowControllerDidLoadNib  (NSWindowController  

                                                                                                 windowController){        base.WindowControllerDidLoadNib  (windowController);

       var  button  =  new  NSButton  (new  RectangleF  (10,  10,  200,  32))  {                Title  =  "Hello  Mac"                BezelStyle  =  NSBezelStyle.Rounded        };                button.Activated  +=  (sender,  e)  =>                new  NSAlert  {  MessageText  =  "You  clicked  me!"  }                        .BeginSheet  (windowController.Window);                windowController.Window.ContentView.AddSubview  (button);}

Page 29: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Building out our NSWindowpublic  override  void  WindowControllerDidLoadNib  (NSWindowController  

                                                                                                 windowController){        base.WindowControllerDidLoadNib  (windowController);

       var  button  =  new  NSButton  (new  RectangleF  (10,  10,  200,  32))  {                Title  =  "Hello  Mac"                BezelStyle  =  NSBezelStyle.Rounded        };                button.Activated  +=  (sender,  e)  =>                new  NSAlert  {  MessageText  =  "You  clicked  me!"  }                        .BeginSheet  (windowController.Window);                windowController.Window.ContentView.AddSubview  (button);}

Call the base class’ version

Page 30: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Building out our NSWindowpublic  override  void  WindowControllerDidLoadNib  (NSWindowController  

                                                                                                 windowController){        base.WindowControllerDidLoadNib  (windowController);

       var  button  =  new  NSButton  (new  RectangleF  (10,  10,  200,  32))  {                Title  =  "Hello  Mac"                BezelStyle  =  NSBezelStyle.Rounded        };                button.Activated  +=  (sender,  e)  =>                new  NSAlert  {  MessageText  =  "You  clicked  me!"  }                        .BeginSheet  (windowController.Window);                windowController.Window.ContentView.AddSubview  (button);}

Call the base class’ version

Allocate and configure a button

Page 31: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Building out our NSWindowpublic  override  void  WindowControllerDidLoadNib  (NSWindowController  

                                                                                                 windowController){        base.WindowControllerDidLoadNib  (windowController);

       var  button  =  new  NSButton  (new  RectangleF  (10,  10,  200,  32))  {                Title  =  "Hello  Mac"                BezelStyle  =  NSBezelStyle.Rounded        };                button.Activated  +=  (sender,  e)  =>                new  NSAlert  {  MessageText  =  "You  clicked  me!"  }                        .BeginSheet  (windowController.Window);                windowController.Window.ContentView.AddSubview  (button);}

Call the base class’ version

Allocate and configure a button

Connect a lambda to run when activated (clicked)

Page 32: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Building out our NSWindowpublic  override  void  WindowControllerDidLoadNib  (NSWindowController  

                                                                                                 windowController){        base.WindowControllerDidLoadNib  (windowController);

       var  button  =  new  NSButton  (new  RectangleF  (10,  10,  200,  32))  {                Title  =  "Hello  Mac"                BezelStyle  =  NSBezelStyle.Rounded        };                button.Activated  +=  (sender,  e)  =>                new  NSAlert  {  MessageText  =  "You  clicked  me!"  }                        .BeginSheet  (windowController.Window);                windowController.Window.ContentView.AddSubview  (button);}

Call the base class’ version

Allocate and configure a button

Connect a lambda to run when activated (clicked)

Add the button to the document window

Page 33: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Hello Mac!

Page 34: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Hello Mac!

Page 35: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Hello Mac!

Page 36: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Designing the UI: Xcode Interface Builder

Double click .xib files to open in

Xcode

Page 37: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Designing the UI: Xcode Interface Builder

Page 38: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Designing the UI: Xcode Interface Builder

InspectorsApplies to the selected control:• Properties• Sizing• Connections

Page 39: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Designing the UI: Xcode Interface Builder

InspectorsApplies to the selected control:• Properties• Sizing• Connections

Object LibraryDrag controls to your window

Page 40: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI

• UI built in Interface Builder connects to code in two waysActionsOutlets

Page 41: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI: Actions

• Methods defined in C#; invoked directly by controls• Partial methods and always have the same signature

Page 42: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI: Actions

• Methods defined in C#; invoked directly by controls• Partial methods and always have the same signature

-­‐  (IBAction)IncreaseButtonActivated:(id)sender;

partial  void  IncreaseButtonActivated  (NSObject  sender);

Objective-C

C#

Page 43: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI: Outlets

• Surface controls from Interface Builder to C# properties• The property type is that of the connected control

Page 44: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI: Outlets

• Surface controls from Interface Builder to C# properties• The property type is that of the connected control

@property  (assign)  IBOutlet  NSButton  *IncreaseButton;

[Outlet]  NSButton  IncreaseButton  {  get;  set;  }

Objective-C

C#

Page 45: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI

Switch to the Assistant editor (aka Butler mode)

Page 46: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI

Switch to the Assistant editor (aka Butler mode)

Page 47: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI

Control-Drag from the selected control into the @interface  inside the header file to create an outlet or action

Page 48: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Connecting the UI

Control-Drag from the selected control into the @interface  inside the header file to create an outlet or action

Page 49: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Connecting the UI@interface  MyDocument  :  NSDocument  {

       NSTextField  *CounterLabel;}

@property  (assign)  IBOutlet  NSTextField  *CounterLabel;-­‐  (IBAction)IncreaseButtonActivated:(id)sender;

@end

Page 50: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

01

02

03

04

05

06

07

08

09

10

11

12

13

14

15

16

Behind the Scenes in Xamarin.Mac[Register  ("MyDocument")]

partial  class  MyDocument{        [Outlet]        TextField  CounterLabel  {  get;  set;  }

       [Action  ("IncreaseButtonActivated:")]        partial  void  IncreaseButtonActivated  (NSObject  sender);}

Page 51: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Events and Callbacks

• In C#, events are a very common communication pattern:

var  window  =  new  NSWindow  ();window.DidBecomeKey  +=  HandleDidBecomeKey;window.DidResignKey  +=  HandleDidResignKey;

NSWindowHandleDidBecomeKey

HandleDidResignKey

Page 52: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Events and Callbacks

• With Apple’s pattern however, objects send interesting events, or messages, to a delegate:

new  NSWindow  {        Delegate  =  new  MyWindowDelegate  ()};

NSWindow MyWindowDelegate

class  MyWindowDelegate  :  NSWindowDelegate{        override  void  DidBecomeKey  (...)        override  void  DidResignKey  (...)}

Page 53: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Events and Callbacks

Page 54: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Events and Callbacks

• Xamarin.Mac supports both modelsYou are free to choose on a per-instance basis

Page 55: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Events and Callbacks

• Xamarin.Mac supports both modelsYou are free to choose on a per-instance basis

• The Apple Delegate pattern maps to C# eventsInternally we create the Delegate class and map it to subscribed event handlers

Page 56: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Events and Callbacks

• Xamarin.Mac supports both modelsYou are free to choose on a per-instance basis

• The Apple Delegate pattern maps to C# eventsInternally we create the Delegate class and map it to subscribed event handlers

• One pattern replaces the other

Page 57: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

AppKit

Page 58: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

AppKit

• Pervasive use of Model-View-ControllerAll logic goes in the controller classUnless writing a custom control (NSView)Controller orchestrates the work of views

Page 59: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

AppKit

• Pervasive use of Model-View-ControllerAll logic goes in the controller classUnless writing a custom control (NSView)Controller orchestrates the work of views

• Goes well beyond the basics of UIHigh-level NSDocument does the heavy li!ingFull menus, saving, loading, window restoration, multi-window support: all for free

Page 60: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

NSDocument

Page 61: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

override  void  WindowControllerDidLoadNib  (NSWindowController  windowController)

NSDocument

Page 62: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

override  void  WindowControllerDidLoadNib  (NSWindowController  windowController)

override  bool  ReadFromUrl  (NSUrl  url,                                                      string  typeName,                                                      out  NSError  outError)

NSDocument

Page 63: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

override  void  WindowControllerDidLoadNib  (NSWindowController  windowController)

override  bool  ReadFromUrl  (NSUrl  url,                                                      string  typeName,                                                      out  NSError  outError)

override  bool  SaveToUrl  (NSUrl  url,                                                  string  typeName,                                                  NSSaveOperationType  saveOperation,                                                  out  NSError  outError)

NSDocument

Page 64: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Structure of the UI

• NSWindowTop-level window

• NSWindow.ContentViewAn NSView that contains controls for the application

• NSView is a class from which most controls deriveCan contain any number of children (NSView.Subviews)

Page 65: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Structure of the UI

• Some controls have many faces and rolesNSTextField implements both “label” and “entry” rolesInstead of being discrete controls, properties are modified to fit the desired roleXcode provides pre-set properties for controls

Page 66: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

NSView: a powerful container

• Can contain (and perform layout of) subviews• Handles events• Paints itself• Can be backed by a CALayer

CALayers are GPU accelerated• Its properties can be animated

Page 67: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

SHIP IT

Page 68: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Ship Your App: by yourself

• The app is unrestricted and has full access to the system• Shipped as a “bundle”

Typically a zipped up .app folderFully self-containedXamarin Studio generates this by default

Page 69: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Gatekeeper

• Apple recently turned on Gatekeeper which prevents unsigned apps from running by default

Page 70: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Gatekeeper

• Apple recently turned on Gatekeeper which prevents unsigned apps from running by default

BADText

Page 71: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Gatekeeper

• Code sign your app for the best user experience• Xamarin Studio supports this for Xamarin.Mac

Page 72: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Gatekeeper

• Code sign your app for the best user experience• Xamarin Studio supports this for Xamarin.Mac

Project Options → Mac OS X Packaging

Page 73: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Ship Your App: in the App Store

Page 74: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Ship Your App: in the App Store

• Must apply for the Mac developer program through Apple• Must sign app• App is submitted for review

Page 75: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Ship Your App: in the App Store

• Must apply for the Mac developer program through Apple• Must sign app• App is submitted for review

• The app will be sandboxed

Page 76: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Ship Your App: in the App Store

• Must apply for the Mac developer program through Apple• Must sign app• App is submitted for review

• The app will be sandboxed

• Xamarin Studio signs, packages, and submits the app• Shipping to the App Store is the best end-user experience

Page 77: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Mac OS X Sandbox

• Kernel-enforced sandbox• Limits access to the system

Limitations on filesystem accessUse of special open/save panelsLimits access to some services and APIs

Page 78: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Mac OS X Sandbox

• Edit Sandbox entitlements in Info.plist in Xamarin Studio

Page 79: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

?

Page 80: Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover

Xamarin makes for Happy Devices

Learn more:xamarin.com/mac

docs.xamarin.com/mac

github.com/xamarin/mac-samples

Aaron Bockover@abock

[email protected]