This document discusses interoperability between Swift and Objective-C. It covers topics like initializing and interacting with Objective-C APIs from Swift, bridging optionals, nullability, lightweight generics, extensions, closures and blocks, object comparison, hashing, selectors, key paths, and more. It also discusses adopting Cocoa design patterns like delegation, lazy initialization, error handling, and key-value observing when using Swift with Cocoa.
FITC events. For digital creators.
Save 10% off ANY FITC event with discount code 'slideshare'
See our upcoming events at www.fitc.ca
An Intro To ES6
with Grant Skinner
OVERVIEW
ECMAScript 6 is the approved and published standard for the next version of JavaScript. It offers new syntax and language features that provide new ways of tackling coding problems, and increase your productivity.
This session will introduce ES6 and delve into many of the new features of the language. It will also cover real-world use, including transpilers, runtimes, and browser support.
OBJECTIVE
Create confidence in evaluating and getting started using ES6.
TARGET AUDIENCE
JavaScript developers.
ASSUMED AUDIENCE KNOWLEDGE
JavaScript.
FOUR THINGS AUDIENCE MEMBERS WILL LEARN
Status of ES6
How to get started with ES6
ES6 feature overview
Practical considerations for adopting ES6
FITC events. For digital creators.
Save 10% off ANY FITC event with discount code 'slideshare'
See our upcoming events at www.fitc.ca
An Intro To ES6
with Grant Skinner
OVERVIEW
ECMAScript 6 is the approved and published standard for the next version of JavaScript. It offers new syntax and language features that provide new ways of tackling coding problems, and increase your productivity.
This session will introduce ES6 and delve into many of the new features of the language. It will also cover real-world use, including transpilers, runtimes, and browser support.
OBJECTIVE
Create confidence in evaluating and getting started using ES6.
TARGET AUDIENCE
JavaScript developers.
ASSUMED AUDIENCE KNOWLEDGE
JavaScript.
FOUR THINGS AUDIENCE MEMBERS WILL LEARN
Status of ES6
How to get started with ES6
ES6 feature overview
Practical considerations for adopting ES6
A brief look at the new features coming in Javascript ES6:
- Scope and control
- Iterators and Generators
- Collections
- Typed objects
- Direct proxies
- Template strings
- API improvements
- Modularity
In this talk I presented three important topics in Kotlin Standard Library: Scope Functions (let, apply, also, run and with); Annotations (Deprecated, Experimental, Jvm*, DslMarker); and Delegates (lazy, vetoable, observable)
Objective-C Crash Course for Web DevelopersJoris Verbogt
These are the slides of my SXSW 2010 Objective-C Crash Course for Web Developers.
The code samples (and the keynote document) can also be downloaded from http://workshop.verbogt.nl/
This is brief presentation on the Scala programming language. It is aimed at Java developers who are curious about Scala. It was given at a San Francisco Java User Group in January 2009.
Explaining ES6: JavaScript History and What is to ComeCory Forsyth
An overview of some of the history of JavaScript, how it became ECMAScript (and what Ecma is), as well as highlights of the new features and syntax in ES6 aka ES2015.
Originally presented to the New York Public Library on June 4 2015.
Python's "batteries included" philosophy means that it comes with an astonishing amount of great stuff. On top of that, there's a vibrant world of third-party libraries that help make Python even more wonderful. We'll go on a breezy, example-filled tour through some of my favorites, from treasures in the standard library to great third-party packages that I don't think I could live without, and we'll touch on some of the fuzzier aspects of the Python culture that make it such a joy to be part of.
A brief look at the new features coming in Javascript ES6:
- Scope and control
- Iterators and Generators
- Collections
- Typed objects
- Direct proxies
- Template strings
- API improvements
- Modularity
In this talk I presented three important topics in Kotlin Standard Library: Scope Functions (let, apply, also, run and with); Annotations (Deprecated, Experimental, Jvm*, DslMarker); and Delegates (lazy, vetoable, observable)
Objective-C Crash Course for Web DevelopersJoris Verbogt
These are the slides of my SXSW 2010 Objective-C Crash Course for Web Developers.
The code samples (and the keynote document) can also be downloaded from http://workshop.verbogt.nl/
This is brief presentation on the Scala programming language. It is aimed at Java developers who are curious about Scala. It was given at a San Francisco Java User Group in January 2009.
Explaining ES6: JavaScript History and What is to ComeCory Forsyth
An overview of some of the history of JavaScript, how it became ECMAScript (and what Ecma is), as well as highlights of the new features and syntax in ES6 aka ES2015.
Originally presented to the New York Public Library on June 4 2015.
Python's "batteries included" philosophy means that it comes with an astonishing amount of great stuff. On top of that, there's a vibrant world of third-party libraries that help make Python even more wonderful. We'll go on a breezy, example-filled tour through some of my favorites, from treasures in the standard library to great third-party packages that I don't think I could live without, and we'll touch on some of the fuzzier aspects of the Python culture that make it such a joy to be part of.
Scaladroids: Developing Android Apps with ScalaOstap Andrusiv
Android is a fast-growing mobile operating system with millions of users worldwide.
Scala is a modern programming language designed to express common programming patterns in a concise, elegant, and type-safe way. Why not combine both of them?
자프링(자바 + 스프링) 외길 12년차 서버 개발자가 코프링(코틀린 + 스프링)을 만난 후 코틀린의 특징과 스프링의 코틀린 지원을 알아가며 코프링 월드에서 살아남은 이야기…
코드 저장소: https://github.com/arawn/kotlin-support-in-spring
My attempts to make my experience developing Play 2 web-applications (in Scala) more Rails-like.
I show 3 frameworks employed that draw nearer to the Ruby/Rails spirit than Play's default offerings.
My talk at BarCamp London 5: An introduction to Cocoa development and how web developers can cheat.
Source code to go with this presentation is available here: http://georgebrock.com/conferences/barcamplondon5
This was a talk given at HTML5DevConf SF in 2015.
Ever wanted to write your own Browserify or Babel? Maybe have an idea for something new? This talk will get you started understanding how to use a JavaScript AST to transform and generate new code.
ITT 2015 - Saul Mora - Object Oriented Function ProgrammingIstanbul Tech Talks
Functional programming is finally a first class citizen in the Cocoa toolset! But, as you may have heard, Swift is not necessarily a pure functional language. And in embracing the functional paradigm, do you need to throw out your knowledge and experience with Object Oriented programming? Saul Mora shows that it turns out you can have your cake and eat it too!
An Approach to Detecting Writing Styles Based on Clustering Techniquesambekarshweta25
An Approach to Detecting Writing Styles Based on Clustering Techniques
Authors:
-Devkinandan Jagtap
-Shweta Ambekar
-Harshit Singh
-Nakul Sharma (Assistant Professor)
Institution:
VIIT Pune, India
Abstract:
This paper proposes a system to differentiate between human-generated and AI-generated texts using stylometric analysis. The system analyzes text files and classifies writing styles by employing various clustering algorithms, such as k-means, k-means++, hierarchical, and DBSCAN. The effectiveness of these algorithms is measured using silhouette scores. The system successfully identifies distinct writing styles within documents, demonstrating its potential for plagiarism detection.
Introduction:
Stylometry, the study of linguistic and structural features in texts, is used for tasks like plagiarism detection, genre separation, and author verification. This paper leverages stylometric analysis to identify different writing styles and improve plagiarism detection methods.
Methodology:
The system includes data collection, preprocessing, feature extraction, dimensional reduction, machine learning models for clustering, and performance comparison using silhouette scores. Feature extraction focuses on lexical features, vocabulary richness, and readability scores. The study uses a small dataset of texts from various authors and employs algorithms like k-means, k-means++, hierarchical clustering, and DBSCAN for clustering.
Results:
Experiments show that the system effectively identifies writing styles, with silhouette scores indicating reasonable to strong clustering when k=2. As the number of clusters increases, the silhouette scores decrease, indicating a drop in accuracy. K-means and k-means++ perform similarly, while hierarchical clustering is less optimized.
Conclusion and Future Work:
The system works well for distinguishing writing styles with two clusters but becomes less accurate as the number of clusters increases. Future research could focus on adding more parameters and optimizing the methodology to improve accuracy with higher cluster values. This system can enhance existing plagiarism detection tools, especially in academic settings.
Student information management system project report ii.pdfKamal Acharya
Our project explains about the student management. This project mainly explains the various actions related to student details. This project shows some ease in adding, editing and deleting the student details. It also provides a less time consuming process for viewing, adding, editing and deleting the marks of the students.
Harnessing WebAssembly for Real-time Stateless Streaming PipelinesChristina Lin
Traditionally, dealing with real-time data pipelines has involved significant overhead, even for straightforward tasks like data transformation or masking. However, in this talk, we’ll venture into the dynamic realm of WebAssembly (WASM) and discover how it can revolutionize the creation of stateless streaming pipelines within a Kafka (Redpanda) broker. These pipelines are adept at managing low-latency, high-data-volume scenarios.
KuberTENes Birthday Bash Guadalajara - K8sGPT first impressionsVictor Morales
K8sGPT is a tool that analyzes and diagnoses Kubernetes clusters. This presentation was used to share the requirements and dependencies to deploy K8sGPT in a local environment.
Final project report on grocery store management system..pdfKamal Acharya
In today’s fast-changing business environment, it’s extremely important to be able to respond to client needs in the most effective and timely manner. If your customers wish to see your business online and have instant access to your products or services.
Online Grocery Store is an e-commerce website, which retails various grocery products. This project allows viewing various products available enables registered users to purchase desired products instantly using Paytm, UPI payment processor (Instant Pay) and also can place order by using Cash on Delivery (Pay Later) option. This project provides an easy access to Administrators and Managers to view orders placed using Pay Later and Instant Pay options.
In order to develop an e-commerce website, a number of Technologies must be studied and understood. These include multi-tiered architecture, server and client-side scripting techniques, implementation technologies, programming language (such as PHP, HTML, CSS, JavaScript) and MySQL relational databases. This is a project with the objective to develop a basic website where a consumer is provided with a shopping cart website and also to know about the technologies used to develop such a website.
This document will discuss each of the underlying technologies to create and implement an e- commerce website.
6th International Conference on Machine Learning & Applications (CMLA 2024)ClaraZara1
6th International Conference on Machine Learning & Applications (CMLA 2024) will provide an excellent international forum for sharing knowledge and results in theory, methodology and applications of on Machine Learning & Applications.
Welcome to WIPAC Monthly the magazine brought to you by the LinkedIn Group Water Industry Process Automation & Control.
In this month's edition, along with this month's industry news to celebrate the 13 years since the group was created we have articles including
A case study of the used of Advanced Process Control at the Wastewater Treatment works at Lleida in Spain
A look back on an article on smart wastewater networks in order to see how the industry has measured up in the interim around the adoption of Digital Transformation in the Water Industry.
Literature Review Basics and Understanding Reference Management.pptxDr Ramhari Poudyal
Three-day training on academic research focuses on analytical tools at United Technical College, supported by the University Grant Commission, Nepal. 24-26 May 2024
5. Interacting with Objective-C APIs
UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];
let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)
Convenience Initializers
• Objective-C
• Swift
To be used with the same syntax as initializers.
6. Interacting with Objective-C APIs
if let image = UIImage(contentsOfFile: "MyImage.png") {
// loaded the image successfully
} else {
// could not load the image
}
Failable Initialization
• Objective-C
• Swift
Initializers directly return the object they initialize. To inform the caller when
initialization has failed, an Objective-C initializer can return nil.
7. Interacting with Objective-C APIs
Nullability Properties
• Swift
• Objective-C @property (nullable) id nullableProperty;
@property (nonnull) id nonNullProperty;
@property id unannotatedProperty;
NS_ASSUME_NONNULL_BEGIN
- (id)returnsNonNullValue;
- (void)takesNonNullParameter:(id)value;
NS_ASSUME_NONNULL_END
- (nullable id)returnsNullableValue;
- (void)takesNullableParameter:(nullable id)value;
- (id)returnsUnannotatedValue;
- (void)takesUnannotatedParameter:(id)value;
var nullableProperty: Any?
var nonNullProperty: Any
var unannotatedProperty: Any!
func returnsNonNullValue() -> Any
func takesNonNullParameter(value: Any)
func returnsNullableValue() -> Any?
func takesNullableParameter(value: Any?)
func returnsUnannotatedValue() -> Any!
func takesUnannotatedParameter(value: Any!)
8. Interacting with Objective-C APIs
Accessing Properties
• readonly = computed property { get }
• weak = weak (weak var)
• assign, copy, strong, unsafe_unretained
• Class = Type
• Atomic
• Accessor (getter= / setter=)
9. Interacting with Objective-C APIs
myTableView.insertSubview(mySubview, at: 2)
Working with Methods
• Objective-C
• Swift
[myTableView insertSubview:mySubview atIndex:2];
myTableView.layoutIfNeeded()
Can call Objective-C methods from Swift using dot syntax.
10. Interacting with Objective-C APIs
var x: Any = "hello" as String
x as? String // String with value "hello"
x as? NSString // NSString with value "hello"
x = "goodbye" as NSString
x as? String // String with value "goodbye"
x as? NSString // NSString with value "goodbye"
id
• Objective-C
• Swift
The Objective-C id type is imported by Swift as the Any type.
11. Interacting with Objective-C APIs
let userDefaults = UserDefaults.standard
let lastRefreshDate = userDefaults.object(forKey: "LastRefreshDate")
// lastRefreshDate is of type Any?
if let date = lastRefreshDate as? Date {
print("(date.timeIntervalSinceReferenceDate)")
}
Downcasting Any
let myDate = lastRefreshDate as! Date
let timeInterval = myDate.timeIntervalSinceReferenceDate
let myDate = lastRefreshDate as! String // Error
Forced downcast operator (as!)
Forced downcast error
Conditional type cast operator (as?)
12. Interacting with Objective-C APIs
var myObject: AnyObject = UITableViewCell()
myObject = NSDate()
let futureDate = myObject.addingTimeInterval(10)
let timeSinceNow = myObject.timeIntervalSinceNow
Dynamic Method Lookup & Optional chaining
AnyObject type lookup @objc method dynamically
myObject.character(at: 5)
// crash, myObject doesn't respond to that method
let myCount = myObject.count
// myCount has Int? type and nil value
let myChar = myObject.character?(at: 5)
// myChar has unichar? type and nil value
if let fifthCharacter = myObject.character?(at: 5) {
print("Found (fifthCharacter) at index 5")
}
// conditional branch not executed
13. Interacting with Objective-C APIs
Bridging Optionals to Nonnullable Objects
@implementation OptionalBridging
+ (void)logSomeValue:(nonnull id)valueFromSwift {
if ([valueFromSwift isKindOfClass: [NSNull class]]) {
os_log(OS_LOG_DEFAULT, "Received an NSNull value.");
} else {
os_log(OS_LOG_DEFAULT, "%s", [valueFromSwift UTF8String]);
}
}
@end
let someValue: String? = "Bridge me, please."
let nilValue: String? = nil
OptionalBridging.logSomeValue(someValue as Any) // String
OptionalBridging.logSomeValue(nilValue as Any) // an NSNull value.
Optional nil NSNull ,
Optional unwrapped value [T?] => NSArray<T>
14. Interacting with Objective-C APIs
Lightweight Generics
@property NSArray<NSDate *> *dates;
@property NSCache<NSObject *, id<NSDiscardableContent>> *cachedData;
@property NSDictionary <NSString *, NSArray<NSLocale *>> *supportedLocales;
var dates: [Date]
var cachedData: NSCache<AnyObject, NSDiscardableContent>
var supportedLocales: [String: [Locale]]
• Objective-C
• Swift
19. Interacting with Objective-C APIs
Hashing
• Swift
• Objective-C
@property NSDictionary *unqualifiedDictionary;
@property NSDictionary<NSString *, NSDate *> *qualifiedDictionary;
@property NSSet *unqualifiedSet;
@property NSSet<NSString *> *qualifiedSet;
var unqualifiedDictionary: [AnyHashable: Any]
var qualifiedDictionary: [String: Date]
var unqualifiedSet: Set<AnyHashable>
var qualifiedSet: Set<String>
20. Interacting with Objective-C APIs
Excludes Swift-only
• Generics
• Tuples
• Enumerations defined in Swift without Int raw value type
• Structures defined in Swift
• Top-level functions defined in Swift
• Global variables defined in Swift
• Typealiases defined in Swift
• Swift-style variadics
• Nested types
• Curried functions
21. Interacting with Objective-C APIs
Swift Type Compatibility
class Jukebox: NSObject {
var library: Set<String>
var nowPlaying: String?
var isCurrentlyPlaying: Bool {
return nowPlaying != nil
}
class var favoritesPlaylist: [String] {
// return an array of song names
}
init(songs: String...) {
self.library = Set<String>(songs)
}
func playSong(named name: String) throws {
// play song or throw an error if unavailable
}
}
@interface Jukebox : NSObject
@property (nonatomic, strong, nonnull) NSSet<NSString *> *library;
@property (nonatomic, copy, nullable) NSString *nowPlaying;
@property (nonatomic, readonly, getter=isCurrentlyPlaying) BOOL currentlyPlaying;
@property (nonatomic, class, readonly, nonnull) NSArray<NSString *> * favoritesPlaylist;
- (nonnull instancetype)initWithSongs:(NSArray<NSString *> * __nonnull)songs
OBJC_DESIGNATED_INITIALIZER;
- (BOOL)playSong:(NSString * __nonnull)name
error:(NSError * __nullable * __null_unspecified)error;
@end
22. Interacting with Objective-C APIs
Configuring Swift Interfaces
@objc(Color)
enum Цвет: Int {
@objc(Red)
case Красный
@objc(Black)
case Черный
}
@objc(Squirrel)
class Белка: NSObject {
@objc(color)
var цвет: Цвет = .Красный
@objc(initWithName:)
init (имя: String) {
// ...
}
@objc(hideNuts:inTree:)
func прячьОрехи(количество: Int, вДереве дерево: Дерево) {
// ...
}
}
24. Interacting with Objective-C APIs
Unsafe Invocation of Objective-C Methods
let string: NSString = "Hello, Cocoa!"
let selector = #selector(NSString.lowercased(with:))
let locale = Locale.current
if let result = string.perform(selector, with: locale) {
print(result.takeUnretainedValue())
}
// Prints "hello, cocoa!"
let array: NSArray = ["delta", "alpha", "zulu"]
// Not a compile-time error because NSDictionary has this selector.
let selector = #selector(NSDictionary.allKeysForObject)
// Raises an exception because NSArray does not respond to this selector.
array.perform(selector)
Perform Selector
Unsafe invocation
25. Interacting with Objective-C APIs
Keys & Key Paths
class Person: NSObject {
var name: String
var friends: [Person] = []
var bestFriend: Person? = nil
init(name: String) {
self.name = name
}
}
let gabrielle = Person(name: "Gabrielle")
let jim = Person(name: "Jim")
let yuanyuan = Person(name: "Yuanyuan")
gabrielle.friends = [jim, yuanyuan]
gabrielle.bestFriend = yuanyuan
#keyPath(Person.name)
// "name"
gabrielle.value(forKey: #keyPath(Person.name))
// "Gabrielle"
#keyPath(Person.bestFriend.name)
// "bestFriend.name"
gabrielle.value(forKeyPath: #keyPath(Person.bestFriend.name))
// "Yuanyuan"
#keyPath(Person.friends.name)
// "friends.name"
gabrielle.value(forKeyPath: #keyPath(Person.friends.name))
// ["Yuanyuan", "Jim"]
26. Objective-C Behavior
Inheriting from Objective-C Classes
@IBDesignable, @IBInpectable
let myPersonClass: AnyClass? = NSClassFromString("MyGreatApp.Person")
28. Working with Cocoa Frameworks
Core Foundation
CFStringRef StringByAddingTwoStrings(CFStringRef s1, CFStringRef s2)
func StringByAddingTwoStrings(_: CFString!, _: CFString!) -> Unmanaged<CFString>! {
// ...
}
let memoryManagedResult = StringByAddingTwoStrings(str1, str2).takeUnretainedValue()
CFTypeRef remaps to the AnyObject
CFStringRef remaps to the CFString class
takeRetainedValue()
29. Working with Cocoa Frameworks
Unified Logging
import os.log
os_log("This is a log message.”)
let fileSize = 1234567890
os_log("Finished downloading file. Size: %{iec-bytes}d", fileSize)
os_log("This is additional info that may be helpful for troubleshooting.", type: .info)
let customLog = OSLog("com.your_company.your_subsystem_name.plist", "your_category_name")
os_log("This is info that may be helpful during development or debugging.",
log: customLog, type: .debug)
31. Adopting Cocoa Design Patterns
Delegation
1)Check that myDelegate is not nil.
2)Check that myDelegate implements the method
window:willUseFullScreenContentSize:.
3)If 1 and 2 hold true, invoke the method and assign the result of the method
to the value named fullScreenSize.
4)Print the return value of the method.
class MyDelegate: NSObject, NSWindowDelegate {
func window(_ window: NSWindow, willUseFullScreenContentSize proposedSize: NSSize) -> NSSize {
return proposedSize
}
}
//…
myWindow.delegate = MyDelegate()
if let fullScreenSize = myWindow.delegate?.window(myWindow, willUseFullScreenContentSize: mySize) {
print(NSStringFromSize(fullScreenSize))
}
33. Adopting Cocoa Design Patterns
Lazy property
var pattern: String
lazy var regex: NSRegularExpression = try! NSRegularExpression(pattern: self.pattern,
options: [])
lazy var currencyFormatter: NumberFormatter = {
let formatter = NumberFormatter()
formatter.numberStyle = .currency
formatter.currencySymbol = "¤"
return formatter
}()
• Swift
use self-evaluating closure
34. Adopting Cocoa Design Patterns
Error Handling
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *fromURL = [NSURL fileURLWithPath:@"/path/to/old"];
NSURL *toURL = [NSURL fileURLWithPath:@"/path/to/new"];
NSError *error = nil;
BOOL success = [fileManager moveItemAtURL:fromURL toURL:toURL error:&error];
if (!success) {
NSLog(@"Error: %@", error.domain);
}
• Swift
• Objective-C
let fileManager = FileManager.default
let fromURL = URL(fileURLWithPath: "/path/to/old")
let toURL = URL(fileURLWithPath: "/path/to/new")
do {
try fileManager.moveItem(at: fromURL, to: toURL)
} catch let error as NSError {
print("Error: (error.domain)")
}
35. Adopting Cocoa Design Patterns
Converting errors to Optional values
• Swift
• Objective-C
NSFileManager *fileManager = [NSFileManager defaultManager];
NSURL *tmpURL = [fileManager URLForDirectory:NSCachesDirectory
inDomain:NSUserDomainMask
appropriateForURL:nil
create:YES
error:nil];
if (tmpURL != nil) {
// ...
}
let fileManager = FileManager.default
if let tmpURL = try? fileManager.url(for: .cachesDirectory, in: .userDomainMask,
appropriateFor: nil, create: true) {
// ...
}
36. Adopting Cocoa Design Patterns
Throwing error
• Swift
• Objective-C
// an error occurred
if (errorPtr) {
*errorPtr = [NSError errorWithDomain:NSURLErrorDomain
code:NSURLErrorCannotOpenFile
userInfo:nil];
}
// an error occurred
throw NSError(domain: NSURLErrorDomain, code: NSURLErrorCannotOpenFile, userInfo: nil)
37. Adopting Cocoa Design Patterns
Key-value Observing
KVO with a Swift class inherits from NSObject class
1) Add dynamic modifier to any property
2) Create a global context variable
3) Add an observer for the key-path, override the observeValue() method
and remove the observer in deinit.
class MyObjectToObserve: NSObject {
dynamic var myDate = NSDate()
func updateDate() {
myDate = NSDate()
}
}
private var myContext = 0
class MyObserver: NSObject {
var objectToObserve = MyObjectToObserve()
override init() {
super.init()
objectToObserve.addObserver(self, forKeyPath: #keyPath(MyObjectToObserve.myDate),
options: .new, context: &myContext)
}
override func observeValue(forKeyPath keyPath: String?, of object: Any?, change:
[NSKeyValueChangeKey : Any]?, context: UnsafeMutableRawPointer?) {
if context == &myContext {
if let newValue = change?[.newKey] { print("Date changed: (newValue)”) }
} else {
super.observeValue(forKeyPath: keyPath, of: object, change: change, context: context)
}
}
deinit {
objectToObserve.removeObserver(self, forKeyPath: #keyPath(MyObjectToObserve.myDate),
context: &myContext)
}
}
38. Adopting Cocoa Design Patterns
Undo architecture
Create an undo operation using an NSInvocation
@IBOutlet var remainingLabel: NSTextView!
func mark(task: Task, asCompleted completed: Bool) {
if let target = undoManager?.prepare(withInvocationTarget: self) as? ToDoListController {
target.mark(task: task, asCompleted: !completed)
undoManager?.setActionName(NSLocalizedString("todo.task.mark",
comment: "Mark As Completed"))
}
task.completed = completed
tableView.reloadData()
let numberRemaining = tasks.filter{ $0.completed }.count
remainingLabel.string = String(format: NSLocalizedString("todo.task.remaining",
comment: "Tasks Remaining: %d"), numberRemaining)
}
39. Adopting Cocoa Design Patterns
Singleton
initialization in a call the dispatch_once function
+ (instancetype)sharedInstance {
static id _sharedInstance = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
_sharedInstance = [[self alloc] init];
});
return _sharedInstance;
}
class Singleton {
static let sharedInstance = Singleton()
}
class Singleton {
static let sharedInstance: Singleton = {
let instance = Singleton()
// setup code
return instance
}()
}
40. Adopting Cocoa Design Patterns
Introspection
use the isKindOfClass: method or conformsToProtocol: method
if object is UIButton {
// object is of type UIButton
} else {
// object is not of type UIButton
}
if let button = object as? UIButton {
// object is successfully cast to type UIButton and bound to button
} else {
// object could not be cast to type UIButton
}
if let dataSource = object as? UITableViewDataSource {
// object conforms to UITableViewDataSource and is bound to dataSource
} else {
// object not conform to UITableViewDataSource
}
• Swift
• Objective-C
41. Adopting Cocoa Design Patterns
Serialization
To encode and decode objects to and from architecture-independent representations.
Use NSJSONSerialization and NSPropertyListSerialization
import Foundation
import CoreLocation
struct Venue {
enum Category: String {
case entertainment
case food
case nightlife
case shopping
}
var name: String
var coordinates: CLLocationCoordinate2D
var category: Category
}
{
"name": "Caffè Macs",
"coordinates": {
"lat": 37.330576,
"lng": -122.029739
},
"category": "food"
}
42. Adopting Cocoa Design Patterns
Serialization : Initializer
init?(attributes: [String: Any]) {
guard let name = attributes["name"] as? String,
let coordinates = attributes["coordinates"] as? [String: Double],
let latitude = coordinates["lat"],
let longitude = coordinates["lng"],
let category = Category(rawValue: attributes["category"] as? String ?? "Invalid")
else {
return nil
}
self.name = name
self.coordinates = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
self.category = category
}
let JSON = "{"name": "Caffè Macs","coordinates": {"lat": 37.330576,"lng": -122.029739},
"category": "food"}"
let data = JSON.data(using: String.Encoding.utf8)!
let attributes = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
let venue = Venue(attributes: attributes)!
print(venue.name)
// Prints "Caffè Macs"
Initialize with Dictionary<String, Any>
Create a Venue from a JSON representation
43. Adopting Cocoa Design Patterns
Serialization : Validating
enum ValidationError: Error {
case missing(String)
case invalid(String)
}
init(attributes: [String: Any]) throws {
guard let name = attributes["name"] as? String else {
throw ValidationError.missing("name")
}
guard let coordinates = attributes["coordinates"] as? [String: Double] else {
throw ValidationError.missing("coordinates")
}
guard let latitude = coordinates["lat"],
let longitude = coordinates["lng"]
else {
throw ValidationError.invalid("coordinates")
}
guard let categoryName = attributes["category"] as? String else {
throw ValidationError.missing("category")
}
guard let category = Category(rawValue: categoryName) else {
throw ValidationError.invalid("category")
}
self.name = name
self.coordinates = CLLocationCoordinate2D(latitude: latitude, longitude: longitude)
self.category = category
}
44. Adopting Cocoa Design Patterns
Localization
use NSLocalizedString, NSLocalizedStringFromTable,
NSLocalizedStringFromTableInBundle, NSLocalizedStringWithDefaultValue
• Objective-C
• Swift
A single function: NSLocalizedString(_:tableName:bundle:value:comment:)
let format = NSLocalizedString("Hello, %@!", comment: "Hello, {given name}!")
let name = "Mei"
let greeting = String(format: format, arguments: [name as CVarArg])
print(greeting)
// Prints "Hello, Mei!"
if let path = Bundle.main.path(forResource: "Localization", ofType: "strings",
inDirectory: nil, forLocalization: "ja"),
let bundle = Bundle(path: path) {
let translation = NSLocalizedString("Hello", bundle: bundle, comment: "")
print(translation)
}
// Prints " "
45. Adopting Cocoa Design Patterns
API Availability
use respondsToSelector: and instancesRespondToSelector: methods
• Objective-C
• Swift
let locationManager = CLLocationManager()
if #available(iOS 8.0, macOS 10.10, *) {
locationManager.requestWhenInUseAuthorization()
}
if ([CLLocationManager instancesRespondToSelector:@selector(requestWhenInUseAuthorization)]) {
// Method is available for use.
} else {
// Method is not available.
}
let locationManager = CLLocationManager()
guard #available(iOS 8.0, macOS 10.10, *) else { return }
locationManager.requestWhenInUseAuthorization()
46. Adopting Cocoa Design Patterns
Processing Command-Line Arguments
for argument in CommandLine.arguments {
print(argument)
}
// prints "/path/to/app"
// prints "--argumentName"
// prints "value"
$ /path/to/app --argumentName value
47. Interacting with C APIs
Primitive Types
C Type Swift Type
bool CBool
char, signed char CChar
unsigned char CUnsignedChar
short CShort
unsigned short CUnsignedShort
int CInt
unsigned int CUnsignedInt
long CLong
unsigned long CUnsignedLong
long long CLongLong
unsigned long long CUnsignedLongLong
wchar_t CWideChar
char16_t CChar16
char32_t CChar32
float CFloat
double CDouble
48. Interacting with C APIs
Importing Constant Enumerations and Structures
Annotate an typedef declaration with the NS_STRING_ENUM or
NS_EXTENSIBLE_STRING_ENUM
• Objective-C
• Swift
struct TrafficLightColor: RawRepresentable {
typealias RawValue = String
init(rawValue: RawValue)
var rawValue: RawValue { get }
static var red: TrafficLightColor { get }
static var yellow: TrafficLightColor { get }
static var green: TrafficLightColor { get }
}
typedef NSString * TrafficLightColor NS_STRING_ENUM;
TrafficLightColor const TrafficLightColorRed;
TrafficLightColor const TrafficLightColorYellow;
TrafficLightColor const TrafficLightColorGreen;
49. Interacting with C APIs
Functions
Any function declared in a C header as a Swift global function.
• Objective-C
• Swift
func product(_ multiplier: Int32, _ multiplicand: Int32) -> Int32
func quotient(_ dividend: Int32, _ divisor: Int32, _ remainder:
UnsafeMutablePointer<Int32>) -> Int32
func createPoint2D(_ x: Float, _ y: Float) -> Point2D
func distance(_ from: Point2D, _ to: Point2D) -> Float
int product(int multiplier, int multiplicand);
int quotient(int dividend, int divisor, int *remainder);
struct Point2D createPoint2D(float x, float y);
float distance(struct Point2D from, struct Point2D to);
50. Interacting with C APIs
Variadic Functions
Call C variadic functions, such as vasprintf, using the getVaList() or withVaList()
func swiftprintf(format: String, arguments: CVarArg...) -> String? {
return withVaList(arguments) { va_list in
var buffer: UnsafeMutablePointer<Int8>? = nil
return format.withCString { CString in
guard vasprintf(&buffer, CString, va_list) != 0 else {
return nil
}
return String(validatingUTF8: buffer!)
}
}
}
print(swiftprintf(format: "√2 ≅ %g", arguments: sqrt(2.0))!)
// Prints "√2 ≅ 1.41421"
51. Interacting with C APIs
Structures
Any C Structure declared in a C header as a Swift structure.
struct Color {
float r, g, b;
};
typedef struct Color Color;
public struct Color {
var r: Float
var g: Float
var b: Float
init()
init(r: Float, g: Float, b: Float)
}
• Swift
52. Interacting with C APIs
Importing Functions as Type Members
Use CF_SWIFT_NAME macro in you own code
Color ColorCreateWithCMYK(float c, float m, float y, float k) CF_SWIFT_NAME(Color.init(c:m:y:k:));
float ColorGetHue(Color color) CF_SWIFT_NAME(getter:Color.hue(self:));
void ColorSetHue(Color color, float hue) CF_SWIFT_NAME(setter:Color.hue(self:newValue:));
Color ColorDarkenColor(Color color, float amount) CF_SWIFT_NAME(Color.darken(self:amount:));
extern const Color ColorBondiBlue CF_SWIFT_NAME(Color.bondiBlue);
Color ColorGetCalibrationColor(void) CF_SWIFT_NAME(getter:Color.calibration());
Color ColorSetCalibrationColor(Color color) CF_SWIFT_NAME(setter:Color.calibration(newValue:));
extension Color {
init(c: Float, m: Float, y: Float, k: Float)
var hue: Float { get set }
func darken(amount: Float) -> Color
static var bondiBlue: Color
static var calibration: Color
}
• Swift
53. Interacting with C APIs
Enumerations
Any C enumeration marked with the NS_ENUM macro as a Swift Enumeration(Int)
typedef NS_ENUM(NSInteger, UITableViewCellStyle) {
UITableViewCellStyleDefault,
UITableViewCellStyleValue1,
UITableViewCellStyleValue2,
UITableViewCellStyleSubtitle
};
enum UITableViewCellStyle: Int {
case `default`
case value1
case value2
case subtitle
}
• Swift
let cellStyle: UITableViewCellStyle = .default
54. Interacting with C APIs
Enumerations : Option Sets
Any C enumeration marked with the NS_OPTIONS macro as a Swift option set.
typedef NS_OPTIONS(NSUInteger, UIViewAutoresizing) {
UIViewAutoresizingNone = 0,
UIViewAutoresizingFlexibleLeftMargin = 1 << 0,
UIViewAutoresizingFlexibleWidth = 1 << 1,
UIViewAutoresizingFlexibleRightMargin = 1 << 2,
UIViewAutoresizingFlexibleTopMargin = 1 << 3,
UIViewAutoresizingFlexibleHeight = 1 << 4,
UIViewAutoresizingFlexibleBottomMargin = 1 << 5
};
public struct UIViewAutoresizing : OptionSet {
public init(rawValue: UInt)
public static var flexibleLeftMargin: UIViewAutoresizing { get }
public static var flexibleWidth: UIViewAutoresizing { get }
public static var flexibleRightMargin: UIViewAutoresizing { get }
public static var flexibleTopMargin: UIViewAutoresizing { get }
public static var flexibleHeight: UIViewAutoresizing { get }
public static var flexibleBottomMargin: UIViewAutoresizing { get }
}
• Swift
55. Interacting with C APIs
Unions
Swift imports C unions as Swift structures, not support unions.
union SchroedingersCat {
bool isAlive;
bool isDead;
};
struct SchroedingersCat {
var isAlive: Bool { get set }
var isDead: Bool { get set }
init(isAlive: Bool)
init(isDead: Bool)
init()
}
• Swift
56. Interacting with C APIs
Unnamed Structure and Union Fields
C struct and union types can define fields that have no name or that are of an
unnamed type.
struct Cake {
union {
int layers;
double height;
};
struct {
bool icing;
bool sprinkles;
} toppings;
};
var simpleCake = Cake()
simpleCake.layers = 5
print(simpleCake.toppings.icing)
// Prints "false"
let cake = Cake(
.init(layers: 2),
toppings: .init(icing: true, sprinkles: false)
)
print("The cake has (cake.layers) layers.")
// Prints "The cake has 2 layers."
print("Does it have sprinkles?", cake.toppings.sprinkles ? "Yes." : "No.")
// Prints "Does it have sprinkles? No."
57. Interacting with C APIs
Pointers
C Syntax Swift Syntax
const Type * UnsafePointer<Type>
Type * UnsafeMutablePointer<Type>
C Syntax Swift Syntax
Type * const * UnsafePointer<Type>
Type * __strong * UnsafeMutablePointer<Type>
Type ** AutoreleasingUnsafeMutablePointer<Type>
C Syntax Swift Syntax
const void * UnsafePointer
void * UnsafeMutablePointer
For return types, variables, and arguments
For class types
For pointers to untyped, raw memory
58. Interacting with C APIs
Constant Pointers
func takesAPointer(_ p: UnsafePointer<Float>) {
// ...
}
var x: Float = 0.0
takesAPointer(&x)
takesAPointer([1.0, 2.0, 3.0])
var x: Float = 0.0, y: Int = 0
takesARawPointer(&x)
takesARawPointer(&y)
takesARawPointer([1.0, 2.0, 3.0] as [Float])
let intArray = [1, 2, 3]
takesARawPointer(intArray)
func takesARawPointer(_ p: UnsafeRawPointer?) {
// ...
}
59. Interacting with C APIs
Mutable Pointers
func takesAMutablePointer(_ p: UnsafeMutablePointer<Float>) {
// ...
}
var x: Float = 0.0
var a: [Float] = [1.0, 2.0, 3.0]
takesAMutablePointer(&x)
takesAMutablePointer(&a)
var x: Float = 0.0, y: Int = 0
var a: [Float] = [1.0, 2.0, 3.0], b: [Int] = [1, 2, 3]
takesAMutableRawPointer(&x)
takesAMutableRawPointer(&y)
takesAMutableRawPointer(&a)
takesAMutableRawPointer(&b)
func takesAMutableRawPointer(_ p: UnsafeMutableRawPointer?) {
// ...
}
60. Interacting with C APIs
Autoreleasing Pointers
func takesAnAutoreleasingPointer(_ p: AutoreleasingUnsafeMutablePointer<NSDate?>) {
// ...
}
var x: NSDate? = nil
takesAnAutoreleasingPointer(&x)
61. Interacting with C APIs
Function Pointers
func customCopyDescription(_ p: UnsafeRawPointer?) -> Unmanaged<CFString>? {
// return an Unmanaged<CFString>? value
}
var callbacks = CFArrayCallBacks(
version: 0,
retain: nil,
release: nil,
copyDescription: customCopyDescription,
equal: { (p1, p2) -> DarwinBoolean in
// return Bool value
}
)
var mutableArray = CFArrayCreateMutable(nil, 0, &callbacks)
C function pointers are imported into Swift as closures with C function pointer calling
convention, denoted by the @convention(c) attribute.
62. Interacting with C APIs
Buffer Pointers & Null Pointers
Buffer Pointers : Used for low-level access to a region of memory.
UnsafeBufferPointer
UnsafeMutableBufferPointer
UnsafeRawBufferPointer
UnsafeMutableRawBufferPointer
Objective-C Syntax Swift Syntax
const Type * _Nonnull UnsafePointer<Type>
const Type * _Nullable UnsafePointer<Type>?
const Type * _Null_unspecified UnsafePointer<Type>!
Null Pointers
Pointers Arithmatic
let pointer: UnsafePointer<Int8>
let offsetPointer = pointer + 24
// offsetPointer is 24 strides ahead of pointer
63. Interacting with C APIs
Data Type Size Calculation
In C, the sizeof and alignof operators return the size and alignment
In Swift, you use MemoryLayout<T> to access the memory layout of the
parameterized type T through the size, stride, and alignment properties.
print(MemoryLayout<timeval>.size)
// Prints "16"
print(MemoryLayout<timeval>.stride)
// Prints "16"
print(MemoryLayout<timeval>.alignment)
// Prints "8"
let sockfd = socket(AF_INET, SOCK_STREAM, 0)
var optval = timeval(tv_sec: 30, tv_usec: 0)
let optlen = socklen_t(MemoryLayout<timeval>.size)
if setsockopt(sockfd, SOL_SOCKET, SO_RCVTIMEO, &optval, optlen) == 0 {
// ...
}
64. Interacting with C APIs
Preprocessor Directives
Simple Macro
Complex Macro, no counterpart in Swift
Conditional Compilation Blocks
#if DEBUG_LOGGING
print("Flag enabled.")
#endif
#define FADE_ANIMATION_DURATION 0.35 let FADE_ANIMATION_DURATION = 0.35
Function Valid arguments
os() macOS, iOS, watchOS, tvOS, Linux
arch() x86_64, arm, arm64, i386
swift() >= followed by a version number
#if arch(arm) || arch(arm64)
#if swift(>=3.0)
print("Using Swift 3 ARM code")
#else
print("Using Swift 2.2 ARM code")
#endif
#elseif arch(x86_64)
print("Using 64-bit x86 code.")
#else
print("Using general code.")
#endif
67. Swift & Objective-C in the Same Project
Importing Objective-C into Swift
rely on an Objective-C bridging header to expose those files to Swift
{product module name} + "-Bridging-Header.h"
ex. = CodesquadApp CodesquadApp-Bridging-Header.h
To import Objective-C code into Swift from the same target
1) In your Objective-C bridging header file, import every Objective-C header
2) In Build Settings > Swift Compiler - Code Generation, make sure the Objective-C
Bridging Header build setting has a path to the bridging header file
68. Swift & Objective-C in the Same Project
Importing Swift into Objective-C
rely on an Xcode-generated header file to expose those files to Objective-C
{product module name} + "-Swift.h"
ex. = CodesquadApp CodesquadApp-Swift.h
The generated header contains interfaces for Swift declarations marked with the
public or open modifier.
An umbrella header for your Swift code
Marked with the internal modifier if your app target has bridging header.
To import Swift code into Objective-C from the same target
#import "ProductModuleName-Swift.h"
69. Swift & Objective-C in the Same Project
Importing External Frameworks
Swift code
import FrameworkName @import FrameworkName;
Objective-C code
Import into Swift Import into Objective-C
Any language
framework
import FrameworkName @import FrameworkName;
70. Swift & Objective-C in the Same Project
Using Swift from Objective-C
Swift class
MySwiftClass *swiftObject = [[MySwiftClass alloc] init];
[swiftObject swiftMethod];
// MyObjcClass.h
@class MySwiftClass;
@protocol MySwiftProtocol;
@interface MyObjcClass : NSObject
- (MySwiftClass *)returnSwiftClassInstance;
- (id <MySwiftProtocol>)returnInstanceAdoptingSwiftProtocol;
// ...
@end
Referencing a Swift Class or Protocol in an Objective-C Header
71. Swift & Objective-C in the Same Project
Using Swift from Objective-C
Declaring a Swift Protocol That Can Be Adopted by an Objective-C Class
@objc public protocol MySwiftProtocol {
func requiredMethod()
@objc optional func optionalMethod()
}
// MyObjcClass.m
#import "ProductModuleName-Swift.h"
@interface MyObjcClass () <MySwiftProtocol>
// ...
@end
@implementation MyObjcClass
// ...
@end
Adopting a Swift Protocol in an Objective-C Implementation
72. Swift & Objective-C in the Same Project
Using Swift from Objective-C
Declaring a Swift Error Type That Can Be Used from Objective-C
@objc public enum CustomError: Int, Error {
case a, b, c
}
// Project-Swift.h
typedef SWIFT_ENUM(NSInteger, CustomError) {
CustomErrorA = 0,
CustomErrorB = 1,
CustomErrorC = 2,
};
static NSString * const CustomErrorDomain = @"Project.CustomError";
In generated header:
73. Swift & Objective-C in the Same Project
Overriding Swift Names for Objective-C Interfaces
Class Factory Methods
+ (instancetype)recordWithRPM:(NSUInteger)RPM NS_SWIFT_NAME(init(rpm:));
+ (id)recordWithQuality:(double)quality NS_SWIFT_NAME(record(quality:));
typedef NS_ENUM(NSInteger, ABCRecordSide) {
ABCRecordSideA,
ABCRecordSideB NS_SWIFT_NAME(flipSide),
};
Enumerations
Swift compiler automatically imports Objective-C code as conventional Swift code.
74. Swift & Objective-C in the Same Project
Making Objective-C Interfaces Unavailable in Swift
Convenience Initializer
+ (instancetype)collectionWithValues:(NSArray *)values forKeys:
(NSArray<NSCopying> *)keys NS_SWIFT_UNAVAILABLE("Use a dictionary literal
instead");
Some Objective-C interfaces may not be suitable or necessary to be exposed as Swift
Objective-C class providing a convenience initializer that takes variadic arguments for keys-value
pairs may advise a Swift consumer to use a dictionary literal instead:
75. Swift & Objective-C in the Same Project
Refining Objective-C Declarations
use the NS_REFINED_FOR_SWIFT macro on an Objective-C method declaration to
provide a refined Swift interface in an extension
@interface Color : NSObject
- (void)getRed:(nullable CGFloat *)red
green:(nullable CGFloat *)green
blue:(nullable CGFloat *)blue
alpha:(nullable CGFloat *)alpha NS_REFINED_FOR_SWIFT;
@end
extension Color {
var RGBA: (red: CGFloat, green: CGFloat, blue: CGFloat, alpha: CGFloat) {
var r: CGFloat = 0.0
var g: CGFloat = 0.0
var b: CGFloat = 0.0
var a: CGFloat = 0.0
__getRed(red: &r, green: &g, blue: &b, alpha: &a)
return (red: r, green: g, blue: b, alpha: a)
}
}