SlideShare une entreprise Scribd logo
1  sur  58
Télécharger pour lire hors ligne
Swift
Cam-Built
Brought to you by…
Movel
Programming Plus
Operator Overloading
var dollarSigns = ""
for _ in 0..<3 {
dollarSigns += "$"
}
the normal way
Repeat a String a Specified Number of Times
var dollarSigns =
"".stringByPaddingToLength(3, withString: "$", startingAtIndex: 0)
or
the extreme way
Repeat a String a Specified Number of Times
let dollarSigns = "$" * 3
Repeat a String a Specified Number of Times
let dollarSigns = "$" * 3
func * (left:String, right:Int) -> String
{
return right == 0 ? "" : "".stringByPaddingToLength(right,
withString: left, startingAtIndex: 0)
}
Function must be given global scope e.g.
defined outside of a class.
Operator Overloading
the extreme way
Repeat a String a Specified Number of Times
the extreme way with Emoji
let 🍊🍊🍊🍊🍊 = 🍊 * 5
let 🍊 = "🍎 "
print(🍊 🍊 🍊 🍊 🍊 )
?
Repeat a String a Specified Number of Times
the extreme way
🍎 🍎 🍎 🍎 🍎
Custom Operators
normal
Get a Substring of a String
var message = "[Extreme] Swift (What was Apple thinking?)”
message = message.substring(0, length: 15)
// [Extreme Swift]
Get a Substring of a String
var message = "[Extreme] Swift (What was Apple thinking?)”
message >= 15
// [Extreme Swift]
extreme
Get a Substring of a String
extreme
infix operator <= { associativity left }
func <= (inout left:String, right:Int) {
left = left.substring(0, length: right)
}
var message = "[Extreme] Swift (What was Apple thinking?)”
message <= 15
// [Extreme Swift]
Pop Quiz!
var places = [Place]()
var place = Place()
place.address = "718 7th St. NW, Washington DC"
place.name = "WeWork"
place.website = "https://www.wework.com/locations/washington-d-c/chinatown"
places.append(place)
place = Place()
place.address = "21165 Whitfield Pl. Ste#206 Sterling, VA"
place.name = "Movel"
place.website = "http://www.movel.co"
places.append(place)
place = Place()
place.address = "One Microsoft Way Redmond, WA"
place.name = "Microsoft"
place.website = "http://www.microsoft.com"
places.append(place)
place = Place()
place.address = "4938 Hampden Lane PO Box 264, Bethesda MD"
place.name = "Cam-Built"
place.website = "http://www.movel.co"
places.append(place)
Let’s say you have this…
class Place {
var name:String?
var address:String?
var website:String?
}
Pop Quiz
What will this do?
places -= "Microsoft"
Pop Quiz
You got it!
func -= (inout left:[Place], right:String)
{
for index in 0..<left.count {
if left[index].name == right {
left.removeAtIndex(index)
break
}
}
}
Note that no infix operator needs to be defined
since -= already exists.
Comparison Protocols
Include this protocol in your custom class when
you want to compare instances using ==.
Equatable Protocol
Your class must implement the == operator function.
func == (left:SearchResult, right:SearchResult) -> Bool {
return left.name == right.name && left.address ==
right.address && left.city == right.city
}
class SearchResult: NSManagedObject, Equatable
You can implement more than one == operator function.
Equatable Protocol
func == (left:[String:AnyObject?], right:SearchResult) -> Bool {
if let leftName = left["name"] as! String?, rightName = right.name as String? {
var leftNameClean = SearchResult.cleanCompareString(leftName)
var rightNameClean = SearchResult.cleanCompareString(rightName)
if leftNameClean.hasPrefix(rightNameClean) ||
rightNameClean.hasPrefix(leftNameClean) {
return true
} else {
if let leftPhone = left["phone"] as? String {
if leftPhone == right.phone {
return true
}
}
}
}
return false
}
Foursquare search results are stored in a dictionary (left) and compared
with results from Yelp and TripAdvisor. If there is a match on name after
cleaning punctuation and white space, Foursquare data is merged.
Pop Quiz!
Which class is better?
class MeetupMembers
{
var members:[String]?
}
class MeetupMembership
{
private var members = [String:String]()
func addMember(name:String) {
members[name] = name
}
func memberForKey(name:String) -> String? {
return members[name]
}
func memberForIndex(index:Int) -> String? {
return members.keys.array[index]
}
}
or…
Pop Quiz
The answer is the one that is most like a black box.
class MeetupMembership
{
private var members = [String:String]()
func addMember(name:String) {
members[name] = name
}
func memberForKey(name:String) -> String? {
return members[name]
}
func memberForIndex(index:Int) -> String? {
return members.keys.array[index]
}
}
Anyone that uses MeetupMembership doesn’t have to know if
“members” is an array, dictionary or any other kind of collection.
Thus, the Law of Demeter!
The Law of Demeter
Demeter is the Greek goddess of agriculture. Like plants, the
Law of Demeter adheres to a bottom-up philosophy.
The ground does not offer its water to the leaves of a plant.
The ground only passes the water parameter to the roots.
If you have a dog and it’s time to go walkies, you do not expect a dog’s
legs to have a “walk” method. You call the dog’s “walk” method.
However, if you do not obey to the Law of Demeter, you will
have less code and probably finish your projects sooner.
Swift encourages you to follow the Law of Demeter, and not just
for objects but for stand-alone functions and value types.
The Swift Perspective
No Class Required
//
// NoClass.swift
// Camtinerary
//
// Created by Cameron Conway on 4/26/15.
// Copyright (c) 2015 cambuilt. All rights reserved.
//
func helloWorld() {
println("hello world")
}
internal func showSecretMessage(code:String) {
if code == "Abc123(*)" {
println(secretMessage())
}
}
private func secretMessage() -> String {
return "Swift knows about AOP."
}
Swift is both OO and AO (Aspect Oriented). Code files in Swift do not
require a class definition, but follow the same rules of access control.
Swift Access Control
private makes a function or variable invisible to code outside
of the file containing it. The benefits are that the project global
namespace is kept clean and the compiler can do a better job
optimizing.
internal is the default access level that makes access
available across your project, but not to outside consumers of your
framework or to any Objective C code.
public should be rarely used and makes access available to
everybody.
Now, more about me!
Who am I?
● Learned COBOL programming on punch cards in 1985.
● dBASE III and Clipper from 1987 to 1989.
● Visual Basic from 1990 to 2000.
● C#, SQL Server, JavaScript from 2001 to present.
● Objective C from 2009 to present.
● Swift from 2014 to present.
● BASIC, Fortran and SPSS in college (American University) 1977 to 1981
“Design is not just what it
looks like and feels like.
Design is how it works.”
Steve Jobs, October 27 2003 as quoted in Newsweek.
Some apps that I am not.
Tripomatic
A picture is worth a thousand words. Or is it?
TripAdvisor
Lots of dots. Not much information unless you dig.
Yelp
Pins are numbered so you can cross reference. Not fun.
Foursquare
More cross referencing.
The app that is me.
Camtinerary
Microsoft Bing Image Search
Google Street View
I have lots of friends.
Search result contains content from multiple well-known sources. Pins are small and
tagged with the place name to provide useful information.
Camtinerary API Code Samples
func searchYelp()
{
let client = YelpClient(consumerKey: yelpKey, consumerSecret: yelpSecret,
accessToken: yelpToken, accessSecret: yelpTokenSecret)
client.searchWithCategory("hotels", ll: "(lat),(lng)", radius:rad, offset:offset, success:
{ (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in
for searchResult in jsonResult["businesses"] as! Array<NSDictionary> {
yelpSearchResults.append(searchResult)
ctr++
}
}) { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in
println(error)
}
}
Using a Yelp client from GitHub and adding results to an array.
Camtinerary API Code Samples
let url = NSURL(string: "https://api.locu.com/v2/venue/search")
var request = NSMutableURLRequest(URL: url!)
request.HTTPMethod = “POST"
var params = ["api_key":LOCU_API_KEY,"fields":["name", "menu_url"],
“venue_queries":[["name":name,"location":["locality":city]]]]
as [String:AnyObject!]
var err: NSError?
request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(),
completionHandler: { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
if error == nil {
var err:NSError?
let httpResponse = response as! NSHTTPURLResponse!
if httpResponse.statusCode == 200 {
if var json = NSJSONSerialization.JSONObjectWithData(data, options:
NSJSONReadingOptions.MutableContainers, error:&err) as? NSDictionary {
if let venues = json["venues"] as? Array<NSDictionary> {
for venue in venues {
println(venue["name"])
println(venue["menu_url"])
}
}
}
}
}
}) Using standard Cocoa routines for Locu data.
Driving and walking time from place to place is determined by
getting directions in code using MapKit.
Camtinerary API Code Samples
let request = MKDirectionsRequest()
request.setSource(MKMapItem(placemark: startMark)); request.setDestination(MKMapItem(placemark: endMark))
request.transportType = travelType; request.requestsAlternateRoutes = true
let directions = MKDirections(request: request)
directions.calculateDirectionsWithCompletionHandler( {(response: MKDirectionsResponse!, error: NSError!) -> () in
if error == nil {
if response.routes.count > 0 {
let route = response.routes[0] as! MKRoute
switch travelType {
case .Walking:
destination.walkingTime = route.expectedTravelTime
case.Automobile:
destination.drivingTime = route.expectedTravelTime
default:
break
}
Util.i.save()
}
} else {
if !self.travelTimeError && self.refreshButtonTapped {
self.travelTimeError = true
self.refreshButtonTapped = false
let alert = UIAlertView(title: "Travel time", message: "Travel time unavailable.",
delegate: self, cancelButtonTitle: "OK")
alert.show()
}
}
})
MapKit code for getting directions and travel times.
CLGeocoder used to get coordinates from street address. Web
photos using Bing Image Search API.
Camtinerary API Code Samples
CLGeocoder().geocodeAddressString("502 Park Ave New York NY", completionHandler:
{(placemarks: [AnyObject]!, error:NSError!) -> Void in
if error == nil {
for placemark in placemarks as [CLPlacemark] {
println(placemark.location.coordinate.longitude)
println(placemark.location.coordinate.latitude)
}
}
})
CLGeocoder for looking up coordinates with a given address.
Camtinerary API Code Samples
let queryString = "502 Park Ave New York NY"
let urlString = "https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?$format=json&Query=(queryString)"
let request = NSMutableURLRequest(URL: NSURL(string: urlString)!)
let keyString = BING_SEARCH_API_KEY + ":" + BING_SEARCH_API_KEY
let plainTextData = keyString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) as NSData!
let base64String = plainTextData.base64EncodedStringWithOptions(.EncodingEndLineWithLineFeed) as String!
request.setValue("Basic " + base64String!, forHTTPHeaderField: "Authorization")
NSURLConnection.sendAsynchronousRequest(request, queue: .mainQueue(), completionHandler:
{ (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
if error == nil {
var err:NSError?
if var json = NSJSONSerialization.JSONObjectWithData(data, options:
.MutableContainers, error:&err) as? NSDictionary {
for result in (json["d"] as! NSDictionary)["results"] as! Array<NSDictionary> {
if webURLs[result["MediaUrl"] as! String] == nil {
result.setValue(false, forKey: "Selected")
self.webImageURLs.append(result)
}
}
}
}
}) Bing Image Search API.
Street View stills using Google Maps API.
Camtinerary API Code Samples
var address = "502 Park Ave New York NY"
var urlString = "https://maps.googleapis.com/maps/api/geocode/json?address=(address)&key=(GOOGLE_API_KEY)"
let url:NSURL! = NSURL(string: urlString)
if url != nil {
let request = NSURLRequest(URL: url)
var err:NSError?
NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler:
{ (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in
if error == nil {
if var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error:&err)
as? NSDictionary {
var resDict = (json["results"] as! NSArray)[0] as! NSDictionary
var geoDict = resDict["geometry"] as! NSDictionary
var locDict = geoDict["location"] as! NSDictionary
var lat = locDict["lat"] as! Double
var lng = locDict["lng"] as! Double
for index in 0..<4 {
let url = "http://maps.googleapis.com/maps/api/streetview?location=(lat),(lng)&" +
"size=150x150&heading=(index * 90)"
let request = NSURLRequest(URL: NSURL(string: url)!)
var response:NSURLResponse?; var error:NSError?
let data = NSURLConnection.sendSynchronousRequest(request, returningResponse:
&response, error: &error)
self.streetViewImages.append(UIImage(data: data!)!)
}
self.photoCollectionView.reloadData()
self.closeLoadingView()
}
}
})
} Google API to retrieve StreetView photos.
Enlarged photos contained in UICollectionView object.
Using iOS 8 Share App Extensions, you share a link to
this review that you found in Safari…
…with a trip and place in your itinerary.
Sharing from Camtinerary uses UIActivityController with custom
UIActivity objects to email or text the entire list of search results or
itinerary.
Tweet from Camtinerary and the name of selected place
is included along with a Bitly version of the website URL.
“Long Touch” on a list item displays a menu to read reviews on
multiple sites, restaurant menus, websites, etc.
When available, restaurant menus are displayed from
Locu with lots of rich information.
Everything you didn’t know you needed to know, even Noise Level.
Includes buttons to quickly switch to different meal menus.
Options allow change in sort order, map style and price filter setting.
Photos can be excluded to save cell data.
That was me.
Camtinerary
Hungry for more
Keep watching the Meetup calendar for great new events and meetings.
?
Resources
http://nshipster.com
The Swift Programming Language
Apple iBookstore
Apple Swift Blog
https://developer.apple.com/swift/blog/
iOS 8 Swift Programming Cookbook
Apple iBookstore and Barnes & Nobles
NSHipster, Second Edition
Obscure Topics in Cocoa & Swift

Contenu connexe

Tendances

Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeKevlin Henney
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1José Paumard
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?osfameron
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2José Paumard
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Paulo Morgado
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the WildJosé Paumard
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!Brendan Eich
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Paulo Morgado
 
Java 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJava 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJosé Paumard
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsMichael Pirnat
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesGanesh Samarthyam
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of AtrocityMichael Pirnat
 
The many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptThe many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptLeonardo Borges
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScriptTodd Anglin
 
Java 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven editionJava 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven editionJosé Paumard
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116Paulo Morgado
 

Tendances (20)

Free your lambdas
Free your lambdasFree your lambdas
Free your lambdas
 
Declarative Thinking, Declarative Practice
Declarative Thinking, Declarative PracticeDeclarative Thinking, Declarative Practice
Declarative Thinking, Declarative Practice
 
Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1Lambda and Stream Master class - part 1
Lambda and Stream Master class - part 1
 
Why Haskell
Why HaskellWhy Haskell
Why Haskell
 
Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?Is Haskell an acceptable Perl?
Is Haskell an acceptable Perl?
 
Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2Lambdas and Streams Master Class Part 2
Lambdas and Streams Master Class Part 2
 
Go Java, Go!
Go Java, Go!Go Java, Go!
Go Java, Go!
 
Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6Tuga it 2016 - What's New In C# 6
Tuga it 2016 - What's New In C# 6
 
Java Class Design
Java Class DesignJava Class Design
Java Class Design
 
Collectors in the Wild
Collectors in the WildCollectors in the Wild
Collectors in the Wild
 
Proxies are Awesome!
Proxies are Awesome!Proxies are Awesome!
Proxies are Awesome!
 
Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7Tuga IT 2017 - What's new in C# 7
Tuga IT 2017 - What's new in C# 7
 
Java 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelizationJava 8, Streams & Collectors, patterns, performances and parallelization
Java 8, Streams & Collectors, patterns, performances and parallelization
 
A Few of My Favorite (Python) Things
A Few of My Favorite (Python) ThingsA Few of My Favorite (Python) Things
A Few of My Favorite (Python) Things
 
Design Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on ExamplesDesign Patterns - Compiler Case Study - Hands-on Examples
Design Patterns - Compiler Case Study - Hands-on Examples
 
Exhibition of Atrocity
Exhibition of AtrocityExhibition of Atrocity
Exhibition of Atrocity
 
The many facets of code reuse in JavaScript
The many facets of code reuse in JavaScriptThe many facets of code reuse in JavaScript
The many facets of code reuse in JavaScript
 
5 Tips for Better JavaScript
5 Tips for Better JavaScript5 Tips for Better JavaScript
5 Tips for Better JavaScript
 
Java 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven editionJava 8 Streams & Collectors : the Leuven edition
Java 8 Streams & Collectors : the Leuven edition
 
What's new in C# 6 - NetPonto Porto 20160116
What's new in C# 6  - NetPonto Porto 20160116What's new in C# 6  - NetPonto Porto 20160116
What's new in C# 6 - NetPonto Porto 20160116
 

En vedette

Ecabo 2012 open generatiekloof
Ecabo 2012 open generatiekloofEcabo 2012 open generatiekloof
Ecabo 2012 open generatiekloofEmiel Brok
 
Nioc 2011 og_kv2
Nioc 2011 og_kv2Nioc 2011 og_kv2
Nioc 2011 og_kv2Emiel Brok
 
Soft skills for hard hackers osbc
Soft skills for hard hackers   osbcSoft skills for hard hackers   osbc
Soft skills for hard hackers osbcEmiel Brok
 
Ict kring delft_2011
Ict kring delft_2011Ict kring delft_2011
Ict kring delft_2011Emiel Brok
 
Continuous Delivery for Cross-Platform Mobile Apps
Continuous Delivery for Cross-Platform Mobile AppsContinuous Delivery for Cross-Platform Mobile Apps
Continuous Delivery for Cross-Platform Mobile AppsMovel
 
W01 Levent Gurses X
W01 Levent Gurses XW01 Levent Gurses X
W01 Levent Gurses XMovel
 
Zarafa sc 2012_ogg
Zarafa sc 2012_oggZarafa sc 2012_ogg
Zarafa sc 2012_oggEmiel Brok
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineMovel
 
OpenSUSEconf2016
OpenSUSEconf2016OpenSUSEconf2016
OpenSUSEconf2016Emiel Brok
 
Functional Prototyping For Mobile Apps
Functional Prototyping For Mobile AppsFunctional Prototyping For Mobile Apps
Functional Prototyping For Mobile AppsMovel
 
Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)
Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)
Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)Movel
 
Cross-Platform Mobile Development with Ionic Framework and Angular
Cross-Platform Mobile Development with Ionic Framework and AngularCross-Platform Mobile Development with Ionic Framework and Angular
Cross-Platform Mobile Development with Ionic Framework and AngularMovel
 
Trends in Mobile FinTech
Trends in Mobile FinTechTrends in Mobile FinTech
Trends in Mobile FinTechMovel
 
Cross-Functional Teams: A Product Manager's Nirvana
Cross-Functional Teams: A Product Manager's NirvanaCross-Functional Teams: A Product Manager's Nirvana
Cross-Functional Teams: A Product Manager's NirvanaMovel
 
The Art of the Minimum Viable Product (MVP)
The Art of the Minimum Viable Product (MVP)The Art of the Minimum Viable Product (MVP)
The Art of the Minimum Viable Product (MVP)Movel
 

En vedette (16)

Ecabo 2012 open generatiekloof
Ecabo 2012 open generatiekloofEcabo 2012 open generatiekloof
Ecabo 2012 open generatiekloof
 
Lugn 2013
Lugn 2013Lugn 2013
Lugn 2013
 
Nioc 2011 og_kv2
Nioc 2011 og_kv2Nioc 2011 og_kv2
Nioc 2011 og_kv2
 
Soft skills for hard hackers osbc
Soft skills for hard hackers   osbcSoft skills for hard hackers   osbc
Soft skills for hard hackers osbc
 
Ict kring delft_2011
Ict kring delft_2011Ict kring delft_2011
Ict kring delft_2011
 
Continuous Delivery for Cross-Platform Mobile Apps
Continuous Delivery for Cross-Platform Mobile AppsContinuous Delivery for Cross-Platform Mobile Apps
Continuous Delivery for Cross-Platform Mobile Apps
 
W01 Levent Gurses X
W01 Levent Gurses XW01 Levent Gurses X
W01 Levent Gurses X
 
Zarafa sc 2012_ogg
Zarafa sc 2012_oggZarafa sc 2012_ogg
Zarafa sc 2012_ogg
 
Introduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy CresineIntroduction to ES6 with Tommy Cresine
Introduction to ES6 with Tommy Cresine
 
OpenSUSEconf2016
OpenSUSEconf2016OpenSUSEconf2016
OpenSUSEconf2016
 
Functional Prototyping For Mobile Apps
Functional Prototyping For Mobile AppsFunctional Prototyping For Mobile Apps
Functional Prototyping For Mobile Apps
 
Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)
Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)
Scaling AngularJS: Enterprise SOA on the MEAN Stack (Responsive Web & Mobile)
 
Cross-Platform Mobile Development with Ionic Framework and Angular
Cross-Platform Mobile Development with Ionic Framework and AngularCross-Platform Mobile Development with Ionic Framework and Angular
Cross-Platform Mobile Development with Ionic Framework and Angular
 
Trends in Mobile FinTech
Trends in Mobile FinTechTrends in Mobile FinTech
Trends in Mobile FinTech
 
Cross-Functional Teams: A Product Manager's Nirvana
Cross-Functional Teams: A Product Manager's NirvanaCross-Functional Teams: A Product Manager's Nirvana
Cross-Functional Teams: A Product Manager's Nirvana
 
The Art of the Minimum Viable Product (MVP)
The Art of the Minimum Viable Product (MVP)The Art of the Minimum Viable Product (MVP)
The Art of the Minimum Viable Product (MVP)
 

Similaire à Extreme Swift

Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachablePamela Fox
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescriptDavid Furber
 
Cocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftCocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftMichele Titolo
 
FITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endFITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endThibault Imbert
 
Technology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertTechnology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertFITC
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonAlex Payne
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to GoJaehue Jang
 
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티JaeYeoul Ahn
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanJimin Hsieh
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)Pavlo Baron
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimizedWoody Pewitt
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreXavier Coulon
 

Similaire à Extreme Swift (20)

Making JavaScript Libraries More Approachable
Making JavaScript Libraries More ApproachableMaking JavaScript Libraries More Approachable
Making JavaScript Libraries More Approachable
 
Real life-coffeescript
Real life-coffeescriptReal life-coffeescript
Real life-coffeescript
 
lab4_php
lab4_phplab4_php
lab4_php
 
lab4_php
lab4_phplab4_php
lab4_php
 
Cocoa Design Patterns in Swift
Cocoa Design Patterns in SwiftCocoa Design Patterns in Swift
Cocoa Design Patterns in Swift
 
Scala introduction
Scala introductionScala introduction
Scala introduction
 
FITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an endFITC '14 Toronto - Technology, a means to an end
FITC '14 Toronto - Technology, a means to an end
 
Technology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault ImbertTechnology: A Means to an End with Thibault Imbert
Technology: A Means to an End with Thibault Imbert
 
Emerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the HorizonEmerging Languages: A Tour of the Horizon
Emerging Languages: A Tour of the Horizon
 
Introduction to Go
Introduction to GoIntroduction to Go
Introduction to Go
 
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
Go 프로그래밍 소개 - 장재휴, DomainDriven커뮤니티
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
 
Ruby Programming Assignment Help
Ruby Programming Assignment HelpRuby Programming Assignment Help
Ruby Programming Assignment Help
 
Introduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf TaiwanIntroduction to Scala for JCConf Taiwan
Introduction to Scala for JCConf Taiwan
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)What can be done with Java, but should better be done with Erlang (@pavlobaron)
What can be done with Java, but should better be done with Erlang (@pavlobaron)
 
SOLID Ruby, SOLID Rails
SOLID Ruby, SOLID RailsSOLID Ruby, SOLID Rails
SOLID Ruby, SOLID Rails
 
Is your C# optimized
Is your C# optimizedIs your C# optimized
Is your C# optimized
 
Lambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter LawreyLambdas puzzler - Peter Lawrey
Lambdas puzzler - Peter Lawrey
 
DevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a DatastoreDevNation'15 - Using Lambda Expressions to Query a Datastore
DevNation'15 - Using Lambda Expressions to Query a Datastore
 

Dernier

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024Scott Keck-Warren
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Allon Mureinik
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGSujit Pal
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...shyamraj55
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Igalia
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Paola De la Torre
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxMalak Abu Hammad
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhisoniya singh
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsEnterprise Knowledge
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Miguel Araújo
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationMichael W. Hawkins
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking MenDelhi Call girls
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking MenDelhi Call girls
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountPuma Security, LLC
 

Dernier (20)

SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024SQL Database Design For Developers at php[tek] 2024
SQL Database Design For Developers at php[tek] 2024
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)Injustice - Developers Among Us (SciFiDevCon 2024)
Injustice - Developers Among Us (SciFiDevCon 2024)
 
Google AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAGGoogle AI Hackathon: LLM based Evaluator for RAG
Google AI Hackathon: LLM based Evaluator for RAG
 
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
Automating Business Process via MuleSoft Composer | Bangalore MuleSoft Meetup...
 
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
Raspberry Pi 5: Challenges and Solutions in Bringing up an OpenGL/Vulkan Driv...
 
Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101Salesforce Community Group Quito, Salesforce 101
Salesforce Community Group Quito, Salesforce 101
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
The Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptxThe Codex of Business Writing Software for Real-World Solutions 2.pptx
The Codex of Business Writing Software for Real-World Solutions 2.pptx
 
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | DelhiFULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
FULL ENJOY 🔝 8264348440 🔝 Call Girls in Diplomatic Enclave | Delhi
 
IAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI SolutionsIAC 2024 - IA Fast Track to Search Focused AI Solutions
IAC 2024 - IA Fast Track to Search Focused AI Solutions
 
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
Neo4j - How KGs are shaping the future of Generative AI at AWS Summit London ...
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
Mastering MySQL Database Architecture: Deep Dive into MySQL Shell and MySQL R...
 
GenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day PresentationGenCyber Cyber Security Day Presentation
GenCyber Cyber Security Day Presentation
 
08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men08448380779 Call Girls In Friends Colony Women Seeking Men
08448380779 Call Girls In Friends Colony Women Seeking Men
 
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
08448380779 Call Girls In Diplomatic Enclave Women Seeking Men
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
Breaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path MountBreaking the Kubernetes Kill Chain: Host Path Mount
Breaking the Kubernetes Kill Chain: Host Path Mount
 

Extreme Swift

  • 1. Swift Cam-Built Brought to you by… Movel Programming Plus
  • 3. var dollarSigns = "" for _ in 0..<3 { dollarSigns += "$" } the normal way Repeat a String a Specified Number of Times var dollarSigns = "".stringByPaddingToLength(3, withString: "$", startingAtIndex: 0) or
  • 4. the extreme way Repeat a String a Specified Number of Times let dollarSigns = "$" * 3
  • 5. Repeat a String a Specified Number of Times let dollarSigns = "$" * 3 func * (left:String, right:Int) -> String { return right == 0 ? "" : "".stringByPaddingToLength(right, withString: left, startingAtIndex: 0) } Function must be given global scope e.g. defined outside of a class. Operator Overloading the extreme way
  • 6. Repeat a String a Specified Number of Times the extreme way with Emoji let 🍊🍊🍊🍊🍊 = 🍊 * 5 let 🍊 = "🍎 " print(🍊 🍊 🍊 🍊 🍊 ) ?
  • 7. Repeat a String a Specified Number of Times the extreme way 🍎 🍎 🍎 🍎 🍎
  • 9. normal Get a Substring of a String var message = "[Extreme] Swift (What was Apple thinking?)” message = message.substring(0, length: 15) // [Extreme Swift]
  • 10. Get a Substring of a String var message = "[Extreme] Swift (What was Apple thinking?)” message >= 15 // [Extreme Swift] extreme
  • 11. Get a Substring of a String extreme infix operator <= { associativity left } func <= (inout left:String, right:Int) { left = left.substring(0, length: right) } var message = "[Extreme] Swift (What was Apple thinking?)” message <= 15 // [Extreme Swift]
  • 12. Pop Quiz! var places = [Place]() var place = Place() place.address = "718 7th St. NW, Washington DC" place.name = "WeWork" place.website = "https://www.wework.com/locations/washington-d-c/chinatown" places.append(place) place = Place() place.address = "21165 Whitfield Pl. Ste#206 Sterling, VA" place.name = "Movel" place.website = "http://www.movel.co" places.append(place) place = Place() place.address = "One Microsoft Way Redmond, WA" place.name = "Microsoft" place.website = "http://www.microsoft.com" places.append(place) place = Place() place.address = "4938 Hampden Lane PO Box 264, Bethesda MD" place.name = "Cam-Built" place.website = "http://www.movel.co" places.append(place) Let’s say you have this… class Place { var name:String? var address:String? var website:String? }
  • 13. Pop Quiz What will this do? places -= "Microsoft"
  • 14. Pop Quiz You got it! func -= (inout left:[Place], right:String) { for index in 0..<left.count { if left[index].name == right { left.removeAtIndex(index) break } } } Note that no infix operator needs to be defined since -= already exists.
  • 16. Include this protocol in your custom class when you want to compare instances using ==. Equatable Protocol Your class must implement the == operator function. func == (left:SearchResult, right:SearchResult) -> Bool { return left.name == right.name && left.address == right.address && left.city == right.city } class SearchResult: NSManagedObject, Equatable
  • 17. You can implement more than one == operator function. Equatable Protocol func == (left:[String:AnyObject?], right:SearchResult) -> Bool { if let leftName = left["name"] as! String?, rightName = right.name as String? { var leftNameClean = SearchResult.cleanCompareString(leftName) var rightNameClean = SearchResult.cleanCompareString(rightName) if leftNameClean.hasPrefix(rightNameClean) || rightNameClean.hasPrefix(leftNameClean) { return true } else { if let leftPhone = left["phone"] as? String { if leftPhone == right.phone { return true } } } } return false } Foursquare search results are stored in a dictionary (left) and compared with results from Yelp and TripAdvisor. If there is a match on name after cleaning punctuation and white space, Foursquare data is merged.
  • 18. Pop Quiz! Which class is better? class MeetupMembers { var members:[String]? } class MeetupMembership { private var members = [String:String]() func addMember(name:String) { members[name] = name } func memberForKey(name:String) -> String? { return members[name] } func memberForIndex(index:Int) -> String? { return members.keys.array[index] } } or…
  • 19. Pop Quiz The answer is the one that is most like a black box. class MeetupMembership { private var members = [String:String]() func addMember(name:String) { members[name] = name } func memberForKey(name:String) -> String? { return members[name] } func memberForIndex(index:Int) -> String? { return members.keys.array[index] } } Anyone that uses MeetupMembership doesn’t have to know if “members” is an array, dictionary or any other kind of collection. Thus, the Law of Demeter!
  • 20. The Law of Demeter
  • 21. Demeter is the Greek goddess of agriculture. Like plants, the Law of Demeter adheres to a bottom-up philosophy. The ground does not offer its water to the leaves of a plant. The ground only passes the water parameter to the roots. If you have a dog and it’s time to go walkies, you do not expect a dog’s legs to have a “walk” method. You call the dog’s “walk” method.
  • 22. However, if you do not obey to the Law of Demeter, you will have less code and probably finish your projects sooner.
  • 23. Swift encourages you to follow the Law of Demeter, and not just for objects but for stand-alone functions and value types. The Swift Perspective
  • 24. No Class Required // // NoClass.swift // Camtinerary // // Created by Cameron Conway on 4/26/15. // Copyright (c) 2015 cambuilt. All rights reserved. // func helloWorld() { println("hello world") } internal func showSecretMessage(code:String) { if code == "Abc123(*)" { println(secretMessage()) } } private func secretMessage() -> String { return "Swift knows about AOP." } Swift is both OO and AO (Aspect Oriented). Code files in Swift do not require a class definition, but follow the same rules of access control.
  • 25. Swift Access Control private makes a function or variable invisible to code outside of the file containing it. The benefits are that the project global namespace is kept clean and the compiler can do a better job optimizing. internal is the default access level that makes access available across your project, but not to outside consumers of your framework or to any Objective C code. public should be rarely used and makes access available to everybody.
  • 27. Who am I? ● Learned COBOL programming on punch cards in 1985. ● dBASE III and Clipper from 1987 to 1989. ● Visual Basic from 1990 to 2000. ● C#, SQL Server, JavaScript from 2001 to present. ● Objective C from 2009 to present. ● Swift from 2014 to present. ● BASIC, Fortran and SPSS in college (American University) 1977 to 1981
  • 28. “Design is not just what it looks like and feels like. Design is how it works.” Steve Jobs, October 27 2003 as quoted in Newsweek.
  • 29. Some apps that I am not.
  • 30. Tripomatic A picture is worth a thousand words. Or is it?
  • 31. TripAdvisor Lots of dots. Not much information unless you dig.
  • 32. Yelp Pins are numbered so you can cross reference. Not fun.
  • 34. The app that is me. Camtinerary
  • 35. Microsoft Bing Image Search Google Street View I have lots of friends.
  • 36. Search result contains content from multiple well-known sources. Pins are small and tagged with the place name to provide useful information.
  • 37. Camtinerary API Code Samples func searchYelp() { let client = YelpClient(consumerKey: yelpKey, consumerSecret: yelpSecret, accessToken: yelpToken, accessSecret: yelpTokenSecret) client.searchWithCategory("hotels", ll: "(lat),(lng)", radius:rad, offset:offset, success: { (operation: AFHTTPRequestOperation!, response: AnyObject!) -> Void in for searchResult in jsonResult["businesses"] as! Array<NSDictionary> { yelpSearchResults.append(searchResult) ctr++ } }) { (operation: AFHTTPRequestOperation!, error: NSError!) -> Void in println(error) } } Using a Yelp client from GitHub and adding results to an array.
  • 38. Camtinerary API Code Samples let url = NSURL(string: "https://api.locu.com/v2/venue/search") var request = NSMutableURLRequest(URL: url!) request.HTTPMethod = “POST" var params = ["api_key":LOCU_API_KEY,"fields":["name", "menu_url"], “venue_queries":[["name":name,"location":["locality":city]]]] as [String:AnyObject!] var err: NSError? request.HTTPBody = NSJSONSerialization.dataWithJSONObject(params, options: nil, error: &err) request.addValue("application/json", forHTTPHeaderField: "Content-Type") request.addValue("application/json", forHTTPHeaderField: "Accept") NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in if error == nil { var err:NSError? let httpResponse = response as! NSHTTPURLResponse! if httpResponse.statusCode == 200 { if var json = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.MutableContainers, error:&err) as? NSDictionary { if let venues = json["venues"] as? Array<NSDictionary> { for venue in venues { println(venue["name"]) println(venue["menu_url"]) } } } } } }) Using standard Cocoa routines for Locu data.
  • 39. Driving and walking time from place to place is determined by getting directions in code using MapKit.
  • 40. Camtinerary API Code Samples let request = MKDirectionsRequest() request.setSource(MKMapItem(placemark: startMark)); request.setDestination(MKMapItem(placemark: endMark)) request.transportType = travelType; request.requestsAlternateRoutes = true let directions = MKDirections(request: request) directions.calculateDirectionsWithCompletionHandler( {(response: MKDirectionsResponse!, error: NSError!) -> () in if error == nil { if response.routes.count > 0 { let route = response.routes[0] as! MKRoute switch travelType { case .Walking: destination.walkingTime = route.expectedTravelTime case.Automobile: destination.drivingTime = route.expectedTravelTime default: break } Util.i.save() } } else { if !self.travelTimeError && self.refreshButtonTapped { self.travelTimeError = true self.refreshButtonTapped = false let alert = UIAlertView(title: "Travel time", message: "Travel time unavailable.", delegate: self, cancelButtonTitle: "OK") alert.show() } } }) MapKit code for getting directions and travel times.
  • 41. CLGeocoder used to get coordinates from street address. Web photos using Bing Image Search API.
  • 42. Camtinerary API Code Samples CLGeocoder().geocodeAddressString("502 Park Ave New York NY", completionHandler: {(placemarks: [AnyObject]!, error:NSError!) -> Void in if error == nil { for placemark in placemarks as [CLPlacemark] { println(placemark.location.coordinate.longitude) println(placemark.location.coordinate.latitude) } } }) CLGeocoder for looking up coordinates with a given address.
  • 43. Camtinerary API Code Samples let queryString = "502 Park Ave New York NY" let urlString = "https://api.datamarket.azure.com/Data.ashx/Bing/Search/Image?$format=json&Query=(queryString)" let request = NSMutableURLRequest(URL: NSURL(string: urlString)!) let keyString = BING_SEARCH_API_KEY + ":" + BING_SEARCH_API_KEY let plainTextData = keyString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false) as NSData! let base64String = plainTextData.base64EncodedStringWithOptions(.EncodingEndLineWithLineFeed) as String! request.setValue("Basic " + base64String!, forHTTPHeaderField: "Authorization") NSURLConnection.sendAsynchronousRequest(request, queue: .mainQueue(), completionHandler: { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in if error == nil { var err:NSError? if var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error:&err) as? NSDictionary { for result in (json["d"] as! NSDictionary)["results"] as! Array<NSDictionary> { if webURLs[result["MediaUrl"] as! String] == nil { result.setValue(false, forKey: "Selected") self.webImageURLs.append(result) } } } } }) Bing Image Search API.
  • 44. Street View stills using Google Maps API.
  • 45. Camtinerary API Code Samples var address = "502 Park Ave New York NY" var urlString = "https://maps.googleapis.com/maps/api/geocode/json?address=(address)&key=(GOOGLE_API_KEY)" let url:NSURL! = NSURL(string: urlString) if url != nil { let request = NSURLRequest(URL: url) var err:NSError? NSURLConnection.sendAsynchronousRequest(request, queue: NSOperationQueue.mainQueue(), completionHandler: { (response:NSURLResponse!, data:NSData!, error:NSError!) -> Void in if error == nil { if var json = NSJSONSerialization.JSONObjectWithData(data, options: .MutableContainers, error:&err) as? NSDictionary { var resDict = (json["results"] as! NSArray)[0] as! NSDictionary var geoDict = resDict["geometry"] as! NSDictionary var locDict = geoDict["location"] as! NSDictionary var lat = locDict["lat"] as! Double var lng = locDict["lng"] as! Double for index in 0..<4 { let url = "http://maps.googleapis.com/maps/api/streetview?location=(lat),(lng)&" + "size=150x150&heading=(index * 90)" let request = NSURLRequest(URL: NSURL(string: url)!) var response:NSURLResponse?; var error:NSError? let data = NSURLConnection.sendSynchronousRequest(request, returningResponse: &response, error: &error) self.streetViewImages.append(UIImage(data: data!)!) } self.photoCollectionView.reloadData() self.closeLoadingView() } } }) } Google API to retrieve StreetView photos.
  • 46. Enlarged photos contained in UICollectionView object.
  • 47. Using iOS 8 Share App Extensions, you share a link to this review that you found in Safari…
  • 48. …with a trip and place in your itinerary.
  • 49. Sharing from Camtinerary uses UIActivityController with custom UIActivity objects to email or text the entire list of search results or itinerary.
  • 50. Tweet from Camtinerary and the name of selected place is included along with a Bitly version of the website URL.
  • 51. “Long Touch” on a list item displays a menu to read reviews on multiple sites, restaurant menus, websites, etc.
  • 52. When available, restaurant menus are displayed from Locu with lots of rich information.
  • 53. Everything you didn’t know you needed to know, even Noise Level.
  • 54. Includes buttons to quickly switch to different meal menus.
  • 55. Options allow change in sort order, map style and price filter setting. Photos can be excluded to save cell data.
  • 57. Hungry for more Keep watching the Meetup calendar for great new events and meetings. ?
  • 58. Resources http://nshipster.com The Swift Programming Language Apple iBookstore Apple Swift Blog https://developer.apple.com/swift/blog/ iOS 8 Swift Programming Cookbook Apple iBookstore and Barnes & Nobles NSHipster, Second Edition Obscure Topics in Cocoa & Swift