• Share
  • Email
  • Embed
  • Like
  • Save
  • Private Content
Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover
 

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

on

  • 1,445 views

 

Statistics

Views

Total Views
1,445
Views on SlideShare
1,445
Embed Views
0

Actions

Likes
1
Downloads
29
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

    Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover Writing native Mac apps in C# with Xamarin.Mac - Aaron Bockover Presentation Transcript

    • Aaron BockoverXamarinabock@xamarin.com@abockWriting Native Mac Appsin C# with Xamarin.Mac
    • 2.6 Billion Devices
    • MacOSXThe world’s most advanceddesktop operating systemC#
    • It’s all about sharing codeShared C# CodeXamarin.MobileBusiness LogicCloud AccessDatabase AccessDesktopDesktop MobileMobileMobileWindows iOSWindowsPhoneAndroid
    • It’s all about sharing codeShared C# CodeXamarin.MobileBusiness LogicCloud AccessDatabase AccessDesktopDesktop MobileMobileMobileWindows iOSWindowsPhoneAndroidMac
    • TouchDraw runs on iPad,Android, and Mac, achievingover 70% code reuse acrossthe platforms.39%61%TouchDrawfor iPad24%76%TouchDrawfor Mac28%72%TouchDrawfor AndroidShared CodePlatform Specific
    • 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
    • Xamarin.Mac at a glanceXamarin.MacFrameworksXamarin Toolsand SDK• Binder• Bundler• Linker• Packager Mono Runtime.NET Base Class Libraries System LibrariesDarwin OSCocoa FrameworksXcode(UI designer)Xamarin Studio IDE
    • Xamarin.Mac at a glanceXamarin.MacFrameworksXamarin Toolsand SDK• Binder• Bundler• Linker• Packager Mono Runtime.NET Base Class Libraries System LibrariesDarwin OSCocoa FrameworksXcode(UI designer)Xamarin Studio IDE
    • Xamarin.Mac FrameworksGraphicsGraphicsCoreGraphics ImageKitCoreImage ImageIOCoreText OpenGLCoreVideo PDFKitUser InterfaceUser InterfaceAppKit QuickLookCoreAnima?on SceneKitQCComposer WebKitAudio and VideoAudio and VideoAVFounda?on CoreMidiAudioToolbox CoreMediaAudioUnit OpenALSystem ServicesSystem ServicesAddressBook CoreWLANBluetooth Scrip?ngBridgeCoreLoca?on StoreKitCoreServicesInfrastructureInfrastructureCoreData Founda?onCoreFounda?on ObjCRun?meDarwin Security
    • Many are shared with Xamarin.iOSGraphicsGraphicsCoreGraphics ImageKitCoreImage ImageIOCoreText OpenGLCoreVideo PDFKitUser InterfaceUser InterfaceAppKit QuickLookCoreAnima?on SceneKitQCComposer WebKitAudio and VideoAudio and VideoAVFounda?on CoreMidiAudioToolbox CoreMediaAudioUnit OpenALSystem ServicesSystem ServicesAddressBook CoreWLANBluetooth Scrip?ngBridgeCoreLoca?on StoreKitCoreServicesInfrastructureInfrastructureCoreData Founda?onCoreFounda?on ObjCRun?meDarwin Security
    • The BasicsGraphicsGraphicsCoreGraphics ImageKitCoreImage ImageIOCoreText OpenGLCoreVideo PDFKitUser InterfaceUser InterfaceAppKit QuickLookCoreAnima?on SceneKitQCComposer WebKitAudio and VideoAudio and VideoAVFounda?on CoreMidiAudioToolbox CoreMediaAudioUnit OpenALSystem ServicesSystem ServicesAddressBook CoreWLANBluetooth Scrip?ngBridgeCoreLoca?on StoreKitCoreServicesInfrastructureInfrastructureCoreData Founda5onCoreFounda?on ObjCRun?meDarwin Security
    • How does Xamarin.Mac work?
    • How does Xamarin.Mac work?• OS X APIs are projected into C#1:1 mapping for full platform coverage
    • 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
    • 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
    • How does Xamarin.Mac work?• OS X APIs are projected into C#1:1 mapping for full platform coverageCheck out “BindingObjective-C Libraries” for adeep 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
    • DIVE IN
    • Anatomy of a Xamarin.Mac application
    • Anatomy of a Xamarin.Mac applicationInfo.plistApplication metadata, used by Mac OS(app name, version, publisher, etc.)
    • Anatomy of a Xamarin.Mac applicationInfo.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
    • Anatomy of a Xamarin.Mac applicationApplication DelegateCalled with application events such asFinishedLaunching or OpenFilesInfo.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
    • Anatomy of a Xamarin.Mac applicationApplication DelegateCalled with application events such asFinishedLaunching or OpenFilesInfo.plistApplication metadata, used by Mac OS(app name, version, publisher, etc.)Application Main MenuInterface definition pre-populated withmany common defaultsResources FolderPlace any resources (images, icons,static data) to be bundled with the app
    • Anatomy of a Xamarin.Mac applicationApplication DelegateCalled with application events such asFinishedLaunching or OpenFilesInfo.plistApplication metadata, used by Mac OS(app name, version, publisher, etc.)Application Main MenuInterface definition pre-populated withmany common defaultsMain Window User InterfaceThe primary window definitioneditable in the Xcode UI BuilderResources FolderPlace any resources (images, icons,static data) to be bundled with the app
    • Anatomy of a Xamarin.Mac applicationApplication DelegateCalled with application events such asFinishedLaunching or OpenFilesInfo.plistApplication metadata, used by Mac OS(app name, version, publisher, etc.)Application Main MenuInterface definition pre-populated withmany common defaultsMain Window User InterfaceThe primary window definitioneditable in the Xcode UI BuilderMain Window ImplementationClass for implementing the features ofyour Main WindowResources FolderPlace any resources (images, icons,static data) to be bundled with the app
    • First Run
    • 01020304050607080910111213141516Building 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);}
    • 01020304050607080910111213141516Building 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
    • 01020304050607080910111213141516Building 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’ versionAllocate andconfigure a button
    • 01020304050607080910111213141516Building 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’ versionAllocate andconfigure a buttonConnect a lambdato run whenactivated (clicked)
    • 01020304050607080910111213141516Building 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’ versionAllocate andconfigure a buttonConnect a lambdato run whenactivated (clicked)Add the button to thedocument window
    • Hello Mac!
    • Hello Mac!
    • Hello Mac!
    • Designing the UI: Xcode Interface BuilderDouble click .xibfiles to open inXcode
    • Designing the UI: Xcode Interface Builder
    • Designing the UI: Xcode Interface BuilderInspectorsApplies to the selected control:• Properties• Sizing• Connections
    • Designing the UI: Xcode Interface BuilderInspectorsApplies to the selected control:• Properties• Sizing• ConnectionsObject LibraryDrag controls toyour window
    • Connecting the UI• UI built in Interface Builder connects to code in two waysActionsOutlets
    • Connecting the UI: Actions• Methods defined in C#; invoked directly by controls• Partial methods and always have the same signature
    • 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-CC#
    • Connecting the UI: Outlets• Surface controls from Interface Builder to C# properties• The property type is that of the connected control
    • 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-CC#
    • Connecting the UISwitch to theAssistant editor(aka Butler mode)
    • Connecting the UISwitch to theAssistant editor(aka Butler mode)
    • Connecting the UIControl-Drag from the selected control into the @interface  inside the header file to create an outlet or action
    • Connecting the UIControl-Drag from the selected control into the @interface  inside the header file to create an outlet or action
    • 01020304050607080910111213141516Connecting the UI@interface  MyDocument  :  NSDocument  {        NSTextField  *CounterLabel;}@property  (assign)  IBOutlet  NSTextField  *CounterLabel;-­‐  (IBAction)IncreaseButtonActivated:(id)sender;@end
    • 01020304050607080910111213141516Behind the Scenes in Xamarin.Mac[Register  ("MyDocument")]partial  class  MyDocument{        [Outlet]        TextField  CounterLabel  {  get;  set;  }        [Action  ("IncreaseButtonActivated:")]        partial  void  IncreaseButtonActivated  (NSObject  sender);}
    • Events and Callbacks• In C#, events are a very common communication pattern:var  window  =  new  NSWindow  ();window.DidBecomeKey  +=  HandleDidBecomeKey;window.DidResignKey  +=  HandleDidResignKey;NSWindowHandleDidBecomeKeyHandleDidResignKey
    • Events and Callbacks• With Apple’s pattern however, objects send interesting events,or messages, to a delegate:new  NSWindow  {        Delegate  =  new  MyWindowDelegate  ()};NSWindowMyWindowDelegateclass  MyWindowDelegate  :  NSWindowDelegate{        override  void  DidBecomeKey  (...)        override  void  DidResignKey  (...)}
    • Events and Callbacks
    • Events and Callbacks• Xamarin.Mac supports both modelsYou are free to choose on a per-instance basis
    • 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 tosubscribed event handlers
    • 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 tosubscribed event handlers• One pattern replaces the other
    • AppKit
    • AppKit• Pervasive use of Model-View-ControllerAll logic goes in the controller classUnless writing a custom control (NSView)Controller orchestrates the work of views
    • 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
    • NSDocument
    • override  void  WindowControllerDidLoadNib  (NSWindowController  windowController)NSDocument
    • override  void  WindowControllerDidLoadNib  (NSWindowController  windowController)override  bool  ReadFromUrl  (NSUrl  url,                                                      string  typeName,                                                      out  NSError  outError)NSDocument
    • 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
    • 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)
    • Structure of the UI• Some controls have many faces and rolesNSTextField implements both “label” and “entry” rolesInstead of being discrete controls, properties are modifiedto fit the desired roleXcode provides pre-set properties for controls
    • NSView: a powerful container• Can contain (and perform layout of) subviews• Handles events• Paints itself• Can be backed by a CALayerCALayers are GPU accelerated• Its properties can be animated
    • SHIP IT
    • 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
    • Gatekeeper• Apple recently turned on Gatekeeper which prevents unsignedapps from running by default☹
    • Gatekeeper• Apple recently turned on Gatekeeper which prevents unsignedapps from running by default☹BADText
    • Gatekeeper• Code sign your app for the best user experience• Xamarin Studio supports this for Xamarin.Mac☺
    • Gatekeeper• Code sign your app for the best user experience• Xamarin Studio supports this for Xamarin.MacProject Options → Mac OS X Packaging☺
    • Ship Your App: in the App Store
    • Ship Your App: in the App Store• Must apply for the Mac developer program through Apple• Must sign app• App is submitted for review
    • 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
    • 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
    • Mac OS X Sandbox• Kernel-enforced sandbox• Limits access to the systemLimitations on filesystem accessUse of special open/save panelsLimits access to some services and APIs
    • Mac OS X Sandbox• Edit Sandbox entitlements in Info.plist in Xamarin Studio
    • ?
    • Xamarin makes for Happy DevicesLearn more:xamarin.com/macdocs.xamarin.com/macgithub.com/xamarin/mac-samplesAaron Bockover@abockabock@xamarin.com