4. It’s all about sharing code
Shared C# Code
Xamarin.Mobile
Business Logic
Cloud Access
Database Access
DesktopDesktop MobileMobileMobile
Windows iOS
Windows
Phone
Android
5. It’s all about sharing code
Shared C# Code
Xamarin.Mobile
Business Logic
Cloud Access
Database Access
DesktopDesktop MobileMobileMobile
Windows iOS
Windows
Phone
AndroidMac
6. TouchDraw runs on iPad,
Android, and Mac, achieving
over 70% code reuse across
the platforms.
39%
61%
TouchDraw
for iPad
24%
76%
TouchDraw
for Mac
28%
72%
TouchDraw
for Android
Shared Code
Platform Specific
7. 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
8. Xamarin.Mac at a glance
Xamarin.Mac
Frameworks
Xamarin Tools
and SDK
• Binder
• Bundler
• Linker
• Packager Mono Runtime
.NET Base Class Libraries System Libraries
Darwin OS
Cocoa Frameworks
Xcode
(UI designer)
Xamarin Studio IDE
9. Xamarin.Mac at a glance
Xamarin.Mac
Frameworks
Xamarin Tools
and SDK
• Binder
• Bundler
• Linker
• Packager Mono Runtime
.NET Base Class Libraries System Libraries
Darwin OS
Cocoa Frameworks
Xcode
(UI designer)
Xamarin Studio IDE
10. Xamarin.Mac Frameworks
GraphicsGraphics
CoreGraphics ImageKit
CoreImage ImageIO
CoreText OpenGL
CoreVideo PDFKit
User InterfaceUser Interface
AppKit QuickLook
CoreAnima?on SceneKit
QCComposer WebKit
Audio and VideoAudio and Video
AVFounda?on CoreMidi
AudioToolbox CoreMedia
AudioUnit OpenAL
System ServicesSystem Services
AddressBook CoreWLAN
Bluetooth Scrip?ngBridge
CoreLoca?on StoreKit
CoreServices
InfrastructureInfrastructure
CoreData Founda?on
CoreFounda?on ObjCRun?me
Darwin Security
11. Many are shared with Xamarin.iOS
GraphicsGraphics
CoreGraphics ImageKit
CoreImage ImageIO
CoreText OpenGL
CoreVideo PDFKit
User InterfaceUser Interface
AppKit QuickLook
CoreAnima?on SceneKit
QCComposer WebKit
Audio and VideoAudio and Video
AVFounda?on CoreMidi
AudioToolbox CoreMedia
AudioUnit OpenAL
System ServicesSystem Services
AddressBook CoreWLAN
Bluetooth Scrip?ngBridge
CoreLoca?on StoreKit
CoreServices
InfrastructureInfrastructure
CoreData Founda?on
CoreFounda?on ObjCRun?me
Darwin Security
12. The Basics
GraphicsGraphics
CoreGraphics ImageKit
CoreImage ImageIO
CoreText OpenGL
CoreVideo PDFKit
User InterfaceUser Interface
AppKit QuickLook
CoreAnima?on SceneKit
QCComposer WebKit
Audio and VideoAudio and Video
AVFounda?on CoreMidi
AudioToolbox CoreMedia
AudioUnit OpenAL
System ServicesSystem Services
AddressBook CoreWLAN
Bluetooth Scrip?ngBridge
CoreLoca?on StoreKit
CoreServices
InfrastructureInfrastructure
CoreData Founda5on
CoreFounda?on ObjCRun?me
Darwin Security
14. How does Xamarin.Mac work?
• OS X APIs are projected into C#
1:1 mapping for full platform coverage
15. How does Xamarin.Mac work?
• OS X APIs are projected into C#
1:1 mapping for full platform coverage
• 80% are Objective-C
Full object system is mapped
Subclassing and overriding supported
16. How does Xamarin.Mac work?
• OS X APIs are projected into C#
1:1 mapping for full platform coverage
• 80% are Objective-C
Full object system is mapped
Subclassing and overriding supported
• 20% are C
Exposed as C# structs/classes/methods
No support for subclassing or overriding
17. 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-C
Full object system is mapped
Subclassing and overriding supported
• 20% are C
Exposed as C# structs/classes/methods
No support for subclassing or overriding
21. Anatomy of a Xamarin.Mac application
Info.plist
Application metadata, used by Mac OS
(app name, version, publisher, etc.)
22. Anatomy of a Xamarin.Mac application
Info.plist
Application metadata, used by Mac OS
(app name, version, publisher, etc.)
Resources Folder
Place any resources (images, icons,
static data) to be bundled with the app
23. Anatomy of a Xamarin.Mac application
Application Delegate
Called with application events such as
FinishedLaunching or OpenFiles
Info.plist
Application metadata, used by Mac OS
(app name, version, publisher, etc.)
Resources Folder
Place any resources (images, icons,
static data) to be bundled with the app
24. Anatomy of a Xamarin.Mac application
Application Delegate
Called with application events such as
FinishedLaunching or OpenFiles
Info.plist
Application metadata, used by Mac OS
(app name, version, publisher, etc.)
Application Main Menu
Interface definition pre-populated with
many common defaults
Resources Folder
Place any resources (images, icons,
static data) to be bundled with the app
25. Anatomy of a Xamarin.Mac application
Application Delegate
Called with application events such as
FinishedLaunching or OpenFiles
Info.plist
Application metadata, used by Mac OS
(app name, version, publisher, etc.)
Application Main Menu
Interface definition pre-populated with
many common defaults
Main Window User Interface
The primary window definition
editable in the Xcode UI Builder
Resources Folder
Place any resources (images, icons,
static data) to be bundled with the app
26. Anatomy of a Xamarin.Mac application
Application Delegate
Called with application events such as
FinishedLaunching or OpenFiles
Info.plist
Application metadata, used by Mac OS
(app name, version, publisher, etc.)
Application Main Menu
Interface definition pre-populated with
many common defaults
Main Window User Interface
The primary window definition
editable in the Xcode UI Builder
Main Window Implementation
Class for implementing the features of
your Main Window
Resources Folder
Place any resources (images, icons,
static data) to be bundled with the app
28. 01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Building out our NSWindow
public
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);
}
29. 01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Building out our NSWindow
public
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
30. 01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Building out our NSWindow
public
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
31. 01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Building out our NSWindow
public
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)
32. 01
02
03
04
05
06
07
08
09
10
11
12
13
14
15
16
Building out our NSWindow
public
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
38. Designing the UI: Xcode Interface Builder
Inspectors
Applies to the selected control:
• Properties
• Sizing
• Connections
39. Designing the UI: Xcode Interface Builder
Inspectors
Applies to the selected control:
• Properties
• Sizing
• Connections
Object Library
Drag controls to
your window
40. Connecting the UI
• UI built in Interface Builder connects to code in two ways
Actions
Outlets
41. Connecting the UI: Actions
• Methods defined in C#; invoked directly by controls
• Partial methods and always have the same signature
42. 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#
43. Connecting the UI: Outlets
• Surface controls from Interface Builder to C# properties
• The property type is that of the connected control
44. 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#
51. Events and Callbacks
• In C#, events are a very common communication pattern:
var
window
=
new
NSWindow
();
window.DidBecomeKey
+=
HandleDidBecomeKey;
window.DidResignKey
+=
HandleDidResignKey;
NSWindow
HandleDidBecomeKey
HandleDidResignKey
52. 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
(...)
}
54. Events and Callbacks
• Xamarin.Mac supports both models
You are free to choose on a per-instance basis
55. Events and Callbacks
• Xamarin.Mac supports both models
You are free to choose on a per-instance basis
• The Apple Delegate pattern maps to C# events
Internally we create the Delegate class and map it to
subscribed event handlers
56. Events and Callbacks
• Xamarin.Mac supports both models
You are free to choose on a per-instance basis
• The Apple Delegate pattern maps to C# events
Internally we create the Delegate class and map it to
subscribed event handlers
• One pattern replaces the other
58. AppKit
• Pervasive use of Model-View-Controller
All logic goes in the controller class
Unless writing a custom control (NSView)
Controller orchestrates the work of views
59. AppKit
• Pervasive use of Model-View-Controller
All logic goes in the controller class
Unless writing a custom control (NSView)
Controller orchestrates the work of views
• Goes well beyond the basics of UI
High-level NSDocument does the heavy li!ing
Full menus, saving, loading, window restoration, multi-
window support: all for free
64. Structure of the UI
• NSWindow
Top-level window
• NSWindow.ContentView
An NSView that contains controls for the application
• NSView is a class from which most controls derive
Can contain any number of children (NSView.Subviews)
65. Structure of the UI
• Some controls have many faces and roles
NSTextField implements both “label” and “entry” roles
Instead of being discrete controls, properties are modified
to fit the desired role
Xcode provides pre-set properties for controls
66. 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
68. 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 folder
Fully self-contained
Xamarin Studio generates this by default
74. Ship Your App: in the App Store
• Must apply for the Mac developer program through Apple
• Must sign app
• App is submitted for review
75. 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
76. 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
77. Mac OS X Sandbox
• Kernel-enforced sandbox
• Limits access to the system
Limitations on filesystem access
Use of special open/save panels
Limits access to some services and APIs
78. Mac OS X Sandbox
• Edit Sandbox entitlements in Info.plist in Xamarin Studio