What's New in Cocoa
What's New in Cocoa
What's New in Cocoa
© 2016 Apple Inc. All rights reserved. Redistribution or public display not permitted without written permission from Apple.
Agenda
API Updates
AppKit
Foundation
API Updates
API Updates
Nullability
Properties
Generics
Enumerations
Nested enumerations and options
String enumerations
@noescape
Nullability
// 10.12
func addItem(withTitle: String,
action: Selector?,
keyEquivalent: String) -> NSMenuItem
Properties
Class properties
Properties
Class properties
NSWindow
// 10.12
class var allowsAutomaticWindowTabbing: Bool
Properties
Class properties
NSWindow
// 10.12
class var allowsAutomaticWindowTabbing: Bool
@property (class) BOOL allowsAutomaticWindowTabbing;
Properties
Class properties
NSWindow
// 10.12
class var allowsAutomaticWindowTabbing: Bool
@property (class) BOOL allowsAutomaticWindowTabbing;
NSPersistentStoreCoordinator
// 10.11
class func registeredStoreTypes() -> [String : NSValue]
Properties
Class properties
NSWindow
// 10.12
class var allowsAutomaticWindowTabbing: Bool
@property (class) BOOL allowsAutomaticWindowTabbing;
NSPersistentStoreCoordinator
// 10.11
class func registeredStoreTypes() -> [String : NSValue]
// 10.12
class var registeredStoreTypes: [String : NSValue] { get }
Properties
Class properties
NSWindow
// 10.12
class var allowsAutomaticWindowTabbing: Bool
@property (class) BOOL allowsAutomaticWindowTabbing;
NSPersistentStoreCoordinator
// 10.11
class func registeredStoreTypes() -> [String : NSValue]
// 10.12
class var registeredStoreTypes: [String : NSValue] { get }
@property(class, readonly, strong) NSDictionary<NSString *, NSValue *> *registeredStoreTypes;
Generics
Not just for collections!
Generics
Not just for collections!
NSFetchRequest
Generics
Not just for collections!
NSFetchRequest
// 10.11
class NSFetchRequest : NSPersistentStoreRequest
Generics
Not just for collections!
NSFetchRequest
// 10.11
class NSFetchRequest : NSPersistentStoreRequest
// 10.12
class NSFetchRequest<ResultType : NSFetchRequestResult> : NSPersistentStoreRequest
Generics
Not just for collections!
NSFetchRequest
// 10.11
class NSFetchRequest : NSPersistentStoreRequest
// 10.12
class NSFetchRequest<ResultType : NSFetchRequestResult> : NSPersistentStoreRequest
func execute() throws -> [ResultType]
Generics
Not just for collections!
NSFetchRequest
// 10.11
class NSFetchRequest : NSPersistentStoreRequest
// 10.12
class NSFetchRequest<ResultType : NSFetchRequestResult> : NSPersistentStoreRequest
func execute() throws -> [ResultType]
NSFetchRequest
// 10.11
class NSFetchRequest : NSPersistentStoreRequest
// 10.12
class NSFetchRequest<ResultType : NSFetchRequestResult> : NSPersistentStoreRequest
func execute() throws -> [ResultType]
NSFetchRequest
// 10.11
class NSFetchRequest : NSPersistentStoreRequest
// 10.12
class NSFetchRequest<ResultType : NSFetchRequestResult> : NSPersistentStoreRequest
func execute() throws -> [ResultType]
NSColorPanel.sharedColorPanel().mode = .NSCrayonModeColorPanel
Enumerations
NSColorPanel.shared().mode = .crayon
Enumerations
NSColorPanel.sharedColorPanel().mode = .NSCrayonModeColorPanel
Enumerations
NSColorPanel.shared().mode = .crayon
String Enumerations
// Swift 3
struct StringTransform { ... }
// Swift 2
let NSStringTransformLatinToGreek: String
let NSStringTransformStripDiacritics: String
...
func stringByApplyingTransform(transform: String, reverse: Bool) -> String?
// Swift 3
struct StringTransform { ... }
extension StringTransform {
static let latinToGreek: StringTransform
static let stripDiacritics: StringTransform
...
}
// Swift 2
let NSStringTransformLatinToGreek: String
let NSStringTransformStripDiacritics: String
...
func stringByApplyingTransform(transform: String, reverse: Bool) -> String?
// Swift 3
struct StringTransform { ... }
extension StringTransform {
static let latinToGreek: StringTransform
static let stripDiacritics: StringTransform
...
}
func applyingTransform(_ transform: StringTransform, reverse: Bool) -> String?
// Swift 2
let NSStringTransformLatinToGreek: String
let NSStringTransformStripDiacritics: String
...
func stringByApplyingTransform(transform: String, reverse: Bool) -> String?
// Swift 3
struct StringTransform { ... }
extension StringTransform {
static let latinToGreek: StringTransform
static let stripDiacritics: StringTransform
...
}
func applyingTransform(_ transform: StringTransform, reverse: Bool) -> String?
// Swift 2
let NSStringTransformLatinToGreek: String
let NSStringTransformStripDiacritics: String
...
func stringByApplyingTransform(transform: String, reverse: Bool) -> String?
// Swift 3
struct StringTransform { ... }
extension StringTransform {
static let latinToGreek: StringTransform
static let stripDiacritics: StringTransform
...
}
func applyingTransform(_ transform: StringTransform, reverse: Bool) -> String?
// Swift 2
let NSStringTransformLatinToGreek: String
let NSStringTransformStripDiacritics: String
...
func stringByApplyingTransform(transform: String, reverse: Bool) -> String?
// Swift 3
struct StringTransform { ... }
extension StringTransform {
static let latinToGreek: StringTransform
static let stripDiacritics: StringTransform
...
}
func applyingTransform(_ transform: StringTransform, reverse: Bool) -> String?
// Adding your own
// Adding your own
extension StringTransform {
static let publishing = StringTransform("Any-Publishing")
}
// Adding your own
extension StringTransform {
static let publishing = StringTransform("Any-Publishing")
}
// 10.12
typedef NSString *NSStringTransform NS_EXTENSIBLE_STRING_ENUM;
NSStringTransform const NSStringTransformLatinToGreek;
NSStringTransform const NSStringTransformStripDiacritics;
…
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
struct WritingOptions : OptionSet { … }
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
struct WritingOptions : OptionSet { … }
func write(to: URL, options: WritingOptions = []) throws
}
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
struct WritingOptions : OptionSet { … }
func write(to: URL, options: WritingOptions = []) throws
}
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
struct WritingOptions : OptionSet { … }
func write(to: URL, options: WritingOptions = []) throws
}
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
struct WritingOptions : OptionSet { … }
func write(to: URL, options: WritingOptions = []) throws
}
Nested Enumerations, Options, Globals
// Swift 3
class NSData … {
struct WritingOptions : OptionSet { … }
func write(to: URL, options: WritingOptions = []) throws
}
@noescape
@noescape
Just windows
Window Tabs
Just windows
Window Tabs
Just windows
Every window is visible
Window Tabs
Just windows
Every window is visible
Hidden at system level
Window Tabs
Just windows
Every window is visible
Hidden at system level
Window Tabs
Just windows
Every window is visible
Hidden at system level
Window Tabs
Just windows
Every window is visible
Hidden at system level
Automatic
Window Tabs
Just windows
Every window is visible
Hidden at system level
Automatic
Create tab: orderFront()
Window Tabs
Just windows
Every window is visible
Hidden at system level
Automatic
Create tab: orderFront()
Remove tab: orderOut()
Window Tabs
Just windows
Every window is visible
Hidden at system level
Automatic
Create tab: orderFront()
Remove tab: orderOut()
Window resized on tab switch
Window Tabs
Fully automatic
Window Tabs
NSDocument based app
No changes
Window Tabs
Non-NSDocument based app
extension NSResponder
@IBAction public func newWindowForTab(_ sender: AnyObject?)
Window Tabs
Existing tab implementation
extension NSWindow
extension NSWindow
.manual
.always
.fullScreen
Window Tabs
Customization
extension NSWindow
extension NSWindow
.automatic
.preferred
.disallowed
Window Tabs
Customization
extension NSWindow
extension NSWindow
extension NSWindow
extension NSWindow
System level
Application level
Content level
Right-to-Left Support
System level
Application level
Content level
Right-to-Left Support
System level
Application level
Content level
Development tip
Right-to-Left Support
System level
Right-to-Left Support
System level
Menu bar
Right-to-Left Support
System level
Menu bar
NSScrollView
• Vertical Scroller
• Vertical Ruler
NSBrowser
Right-to-Left Support
Content level
Auto Layout
NSTableView
NSOutlineView
NSCollectionView
NSStackView
NSSplitView
NSPageController
NSButton
….
Right-to-Left Support
Development tip
Right-to-Left Support
Development tip
Right-to-Left Support
Development tip
Related Sessions
P3 color space
Extended range sRGB
Bit depth
Color panel
Wide Gamut
sRGB
Wide Gamut
Wide Gamut
P3
Wide Gamut
P3
EMERALD
17-5641TCX
2013
Color of the
Year
EMERALD
17-5641TCX
2013
Color of the
Year
EMERALD
17-5641TCX
sRGB -0.26, 0.46, 0.57
P3 0.06, 0.46, 0.56
99
99
// Wide Color API: sRGB & P3
extension NSColorSpace {
public class func sRGB() -> NSColorSpace
public class func displayP3() -> NSColorSpace
}
extension NSColor {
public init(sRGBRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
extension UIColor {
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
// Wide Color API: sRGB & P3
extension NSColorSpace {
public class func sRGB() -> NSColorSpace
public class func displayP3() -> NSColorSpace
}
extension NSColor {
public init(sRGBRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
extension UIColor {
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
// Wide Color API: sRGB & P3
extension NSColorSpace {
public class func sRGB() -> NSColorSpace
public class func displayP3() -> NSColorSpace
}
extension NSColor {
public init(sRGBRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
extension UIColor {
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
// Wide Color API: sRGB & P3
extension NSColorSpace {
public class func sRGB() -> NSColorSpace
public class func displayP3() -> NSColorSpace
}
extension NSColor {
public init(sRGBRed red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
extension UIColor {
public init(displayP3Red red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
}
Wide Gamut
Extended range sRGB
Wide Gamut
Extended range sRGB
0, 1.0, 0
1.0, 0, 0
0, 0, 1.0
Wide Gamut
Extended range sRGB
0, 1.0, 0
1.0, 0, 0
0, 0, 1.0
Wide Gamut
Extended range sRGB
0, 1.0, 0
1.0, 0, 0
0, 0, 1.0
Wide Gamut
Extended range sRGB
0, 1.0, 0
1.0, 0, 0
0, 0, 1.0
Wide Gamut
Extended range sRGB
-0.51, 1.02, -0.31
0, 1.0, 0
1.0, 0, 0
0, 0, 1.0
Wide Gamut
Extended range sRGB
-0.51, 1.02, -0.31
0, 1.0, 0
1.0, 0, 0
0, 0, 1.0
// Wide Color API: Extended Range sRGB
extension NSColorSpace {
public class func extendedSRGB() -> NSColorSpace
}
extension NSColor/UIColor {
public init(white: CGFloat, alpha: CGFloat)
public init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)
}
// Wide Color API: Extended Range sRGB
extension NSColorSpace {
public class func extendedSRGB() -> NSColorSpace
}
extension NSColor/UIColor {
public init(white: CGFloat, alpha: CGFloat)
public init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)
}
// Wide Color API: Extended Range sRGB
extension NSColorSpace {
public class func extendedSRGB() -> NSColorSpace
}
extension NSColor/UIColor {
public init(white: CGFloat, alpha: CGFloat)
public init(red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat)
public init(hue: CGFloat, saturation: CGFloat, brightness: CGFloat, alpha: CGFloat)
}
Color Depth
sRGB
Color Depth
sRGB (8 bpc)
Color Depth
P3 (8 bpc)
Color Depth
P3 (16 bpc)
Color Depth
Subtitle
NSWindow
Deep Color API
NSWindow
• Automatically deep on wide gamut displays
Deep Color API
NSWindow
• Automatically deep on wide gamut displays
• depthLimit can be set to 8-bit or 16-bit
Deep Color API
NSWindow
• Automatically deep on wide gamut displays
• depthLimit can be set to 8-bit or 16-bit
NSWindow
• Automatically deep on wide gamut displays
• depthLimit can be set to 8-bit or 16-bit
NSWindow
• Automatically deep on wide gamut displays
• depthLimit can be set to 8-bit or 16-bit
CALayer
Deep Color API
NSWindow
• Automatically deep on wide gamut displays
• depthLimit can be set to 8-bit or 16-bit
CALayer
• contentsFormat can be set to 8-bit, 16-bit (half-float)
NSColorPanel
NSColorPanel
NSColorPanel
NSColorPanel
NSColorPanel
NSColorPanel
NSColorPanel
NSColorPanel
Wide Gamut Colors
Reordering
Keyboard navigation
User hiding and removal
• Status bar apps
Autosave
Status Item Enhancements
Reordering and keyboard navigation
Status Item Enhancements
Reordering and keyboard navigation
Status Item Enhancements
Reordering and keyboard navigation
Status Item Enhancements
Reordering and keyboard navigation
Status Item Enhancements
Reordering and keyboard navigation
Status Item Enhancements
Reordering and keyboard navigation
extension NSStatusItem {
public var behavior: NSStatusItemBehavior
}
public struct NSStatusItemBehavior : OptionSet {
public static var removalAllowed: NSStatusItemBehavior { get }
}
Status Item Enhancements
Hiding and removal
extension NSStatusItem {
public var behavior: NSStatusItemBehavior
public var isVisible: Bool
}
public struct NSStatusItemBehavior : OptionSet {
public static var removalAllowed: NSStatusItemBehavior { get }
}
Status Item Enhancements
Hiding and removal
extension NSStatusItem {
public var behavior: NSStatusItemBehavior
public var isVisible: Bool
}
public struct NSStatusItemBehavior : OptionSet {
public static var removalAllowed: NSStatusItemBehavior { get }
public static var terminationOnRemoval: NSStatusItemBehavior { get }
}
Status Item Enhancements
Autosave
Status Item Enhancements
Autosave
extension NSStatusItem {
public var autosaveName: String!
}
Status Item Enhancements
Autosave
extension NSStatusItem {
public var autosaveName: String!
}
Status Item Enhancements
Autosave
extension NSStatusItem {
public var autosaveName: String!
}
statusItem.autosaveName = “com.example.StarStatusItem”
Control Constructors
Control Constructors
Nullability
Properties
Generics
Enumerations
@noescape
Weak delegates
Designated initializers
API Refinements
Weak delegates
NSComboBox
NSSplitView
NSTokenField
API Refinements
Weak delegates
NSComboBox
NSSplitView
NSTokenField
“NS” prefix
Value types
Unit, Measurement
ISO8601DateFormatter
DateInterval
“NS” Prefix
Drop “NS” prefix in key Foundation types in Swift
“NS” Prefix
Drop “NS” prefix in key Foundation types in Swift
Foundation only
“NS” Prefix
Not dropped everywhere
Foundation only
Not in APIs that are inherently tied to Objective-C
“NS” Prefix
Not dropped everywhere
Foundation only
Not in APIs that are inherently tied to Objective-C
• NSObject, NSProxy, NSAutoreleasePool, …
“NS” Prefix
Not dropped everywhere
Foundation only
Not in APIs that are inherently tied to Objective-C
• NSObject, NSProxy, NSAutoreleasePool, …
Not in platform-specific APIs
“NS” Prefix
Not dropped everywhere
Foundation only
Not in APIs that are inherently tied to Objective-C
• NSObject, NSProxy, NSAutoreleasePool, …
Not in platform-specific APIs
• NSUserNotification, NSXPCConnection, …
“NS” Prefix
Not dropped everywhere
Foundation only
Not in APIs that are inherently tied to Objective-C
• NSObject, NSProxy, NSAutoreleasePool, …
Not in platform-specific APIs
• NSUserNotification, NSXPCConnection, …
Not in classes also exposed as value types
“NS” Prefix
Not dropped everywhere
Foundation only
Not in APIs that are inherently tied to Objective-C
• NSObject, NSProxy, NSAutoreleasePool, …
Not in platform-specific APIs
• NSUserNotification, NSXPCConnection, …
Not in classes also exposed as value types
• NSData, NSURL, …
Value Types
Types where value is important, not identity
Value Types
Types where value is important, not identity
NSString
NSData
NSURL
NSArray
…
New Value Types
AffineTransform Measurement
CharacterSet Notification
Data PersonNameComponents
Date URL
DateComponents URLComponents
Decimal URLRequest
IndexPath URLQueryItem
IndexSet UUID
DateInterval
Value Types
class Unit
• Miles, degrees celsius, km/h, …
Unit, Measurement
Representing measured amounts
class Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, …
Unit, Measurement
Representing measured amounts
class Unit
Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, …
Unit, Measurement
Representing measured amounts
class Unit
Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, … Dimension
Unit, Measurement
Representing measured amounts
class Unit
Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, … Dimension
class Unit
Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, … Dimension
class Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, …
class UnitConverter
• miles km, °C K, km/h knots, …
Unit, Measurement
class Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, …
class UnitConverter
• miles km, °C K, km/h knots, …
struct Measurement
• “10 miles,” “24 degrees celsius,” “42 km/h”, …
Unit, Measurement
class Unit
• Miles, degrees celsius, km/h, …
class Dimension
• Length, temperature, speed, …
class UnitConverter
• miles km, °C K, km/h knots, …
struct Measurement
• “10 miles,” “24 degrees celsius,” “42 km/h”, …
class MeasurementFormatter
Predefined Dimensions
Subclasses of Dimension
To represent a “day”
Handling Dates
Can be tricky
To represent a “day”
let aDay = DateInterval(start: startDate, duration: 24 * 60 * 60)
Handling Dates
Can be tricky
To represent a “day”
let aDay = DateInterval(start: startDate, duration: 24 * 60 * 60)
Handling Dates
Can be tricky
To represent a “day”
let aDay = DateInterval(start: startDate, duration: 24 * 60 * 60)
To represent a “day”
let aDay = DateInterval(start: startDate, duration: 24 * 60 * 60)
URL
• New URL properties, such as canonical path
• New class URLSessionTaskMetrics
Other Foundation Updates
URL
• New URL properties, such as canonical path
• New class URLSessionTaskMetrics
PersonNameComponentsFormatter
• Now parses names
Other Foundation Updates
URL
• New URL properties, such as canonical path
• New class URLSessionTaskMetrics
PersonNameComponentsFormatter
• Now parses names
DateComponentsFormatter
• New brief style
Core Data
Generics
Generational querying
Persistent store description
NSFetchedResultsController
Overview of recent APIs important to creating modern applications for the Mac
Pointers to other sessions of interest
Appropriate for everyone
https://developer.apple.com/wwdc16/203
Related Sessions
Frameworks
Cocoa Lab Lab B
Tuesday 12:30PM
Developer Tools
Swift and Foundation Lab Lab A
Wednesday 9:00AM
Frameworks
Color Lab Lab A
Wednesday 1:00PM
Frameworks
Cocoa Lab Lab D
Thursday 2:00PM
Frameworks
Cocoa Lab Lab A
Friday 1:00PM
Graphics, Games,
Color Lab and Media Lab C
Friday 4:00PM