• Skip to main content
  • Skip to primary sidebar

Ravi Shankar

Tweaking Apps

  • About
  • Portfolio
  • Privacy Policy

Programming

DatePicker Demo in Swift

June 17, 2015 By Ravi Shankar 6 Comments

In this short tutorial, we are going to see the steps required use DatePicker in a iOS / Swift project. This demo is done by adding the DatePicker controls to Interface Builder and not programmatically.

Date Picker Mode

Date Picker control allow developers to specify the mode such as Date, Time, Date and Time and Count Down Timer. Listed below are the screenshots of each Date Picker mode.

Date Picker (Mode – Time)

Date Picker Mode set to time

Date Picker (Mode – Date)

Date Picker Mode set to Date

Date Picker (Mode – Date and Time)

Date and Time mode set for Date Picker

Using the Date and Time mode does not provide option to pick year. Hence in this demo we are going to use two date picker controls, one for date and another for time.

Add ViewContoller and Controls

Add a View Controller (or use existing ViewController) to storyboard then drag and drop 2 date picker controls to the View Controller. Also add a UILabel for displaying the selected date and time values. For the first Date Picker set the mode to Date and for the second as Time.

Add DatePickerController class

Now add a new file to the project and choose the template as Cocoa Touch class. Provde the name for your class file as DatePickerController. Add the following lines of code that adds IBOutlets to the ViewController

[code language=”swift”]@IBOutlet var datePicker:UIDatePicker!
@IBOutlet var timePicker:UIDatePicker!
@IBOutlet var dateTimeDisplay:UILabel![/code]

Select the ViewController in the Storyboard and set the class in the Identity Inspector to DatePickerController. Now click Show Assistant Editor then Control + drag and drop date picker to class file. Select connect as Action and provide the name for the function as datePickerChanged.

Now you should see the following function added to your class file.

[code language=”swift”]
@IBAction func datePickerChanged(sender: AnyObject) {
}[/code]

Repeat this exercise for the TimePicker (second date picker control) with function name as timePickerChanged.

[code language=”swift”]@IBAction func timePickerChanged(sender: AnyObject) {
}[/code]

Also make sure to connect all the IBOutlets from the class file to the corresponding controls in View Controller.

Set Date and Time

Add the following piece of Date Formatter code just below the IBOutlets definition. We are using two instance of NSDateFormatter to specify the date and time style for each date picker controls.

[code language=”swift”]let dateFormatter = NSDateFormatter()
let timeFormatter = NSDateFormatter()[/code]

Add the following function that formats the date and time and assigns the value to UILabel.

[code language=”swift”]//MARK:- Date and time
func setDateAndTime() {
dateFormatter.dateStyle = NSDateFormatterStyle.ShortStyle
timeFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
dateTimeDisplay.text = dateFormatter.stringFromDate(datePicker.date) + ” ” + timeFormatter.stringFromDate(timePicker.date)
}[/code]

Add the function call to the date picker’s Value Changed methods.

[code language=”swift”]@IBAction func datePickerChanged(sender: AnyObject) {
setDateAndTime()
}
@IBAction func timePickerChanged(sender: AnyObject) {
setDateAndTime()
}[/code]

Download the source code from here (SwiftDemo -> DatePicker)

Filed Under: Programming, Xcode Tagged With: DatePicker, Swift

Closures, Extensions and Generics in Swift

May 22, 2015 By Ravi Shankar Leave a Comment

Closures

Closures are self contained lines of code that can be passed around the application and similar to blocks in Objective-C. A typical closure syntax in Swift looks as shown below

Closure Syntax

[code language=”swift”]{ (parameters) -> return type in
statements
}[/code]

Example closure in Swift

[code language=”swift”]{ (name:String, message:String -> (String) in
message + ” ” + name + ” !!!”
}
greetings(“Ravi”,”Welcome”)
[/code]

 

In the above code example, a closure has been assigned to a variable. The purpose of this closure is to concatenate the string parameters and return the appended message as return parameter.

Type Inference

The example closure can modified to ignore to the parameter types and closure supports type inference.

[code language=”swift”]var greetings = { (name, message) -> (String) in
return message + ” ” + name + ” !!!”
}

greetings(“Ravi”,”Welcome”)[/code]

Implicit return

In single expression closure, you can omit the return keyword.

[code language=”swift”]var numbers = [23,45,67,89,89,78]
numbers.sort { (number1, number2) -> Bool in
return number1 < number2
}

// numbers.sort { number1, number2 in return number1 < number2 }
numbers.sort { number1, number2 in number1 < number2 } // Shorthand argument syntax
numbers.sort { $0 < swift }[/code]

Shorthand Argument Syntax

Swift supports shorthand argument names for inline closures. In the above example used for implicit returns, the two parameters can be removed and represented in shorthand arguments as shown below.

[code language=”swift”]numbers.sort { $0 < swift }
[/code]

Trailing Closure

In a function with closure as the last parameter, the closure can be treated as trailing closures i.e closures outside the function parenthesis call. This is quite helpful in reducing the long closure expression. For example, the sorted function has closure as the last parameter and with trailing closure this becomes as shown below.

[code language=”swift”]var numbers = [23,45,67,89,89,78]
var sortedNumbers = sorted(numbers, {$0 > swift}) // Without trailing closure
// var sortedNumbers = sorted(numbers) {$0 > swift} // represented as trailing closure

sortedNumbers[/code]

Extensions

Swift extensions are similar to category in Objective-C which adds new functionally to existing class, enumeration or Struct. Extension does not require the source code of original class or enumeration type or struct to extend their functionality.

Listed below is an example which extends String class. A new function fromDouble has been added to String class which takes a double value and returns String.

[code language=”swift”] extension String {
static func fromDouble(doubleValue: Double) -> String {
var temp = String(format: “%.2f”, doubleValue)
return temp as String
}
}
String.fromDouble(24.50)[/code]

Generics

Generics are code that produces the same result irrespective of the data type. Listed below is a function that accepts an array of type string and reverses the array items.

[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]

// reverse array with String
func reverseString(items: Array) -> Array {
var temp = Array()
return items.reverse()
}
reverseString(strTemp)[/code]

Now the below function accepts array of number and reverses the items

[code language=”swift”] let numbers = [23,45,56,78,98]
// reverse array with numbers
func reverseNumber(items: Array) -> Array {
return items.reverse()
}
reverseNumber(numbers)[/code]

Generics solves the problem of having different set of code for different data types by implemting the functionality for a generic type.

[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]
let numbers = [23,45,56,78,98]

func reverseItems(items:[T])-> [T] {
return items.reverse()
}
reverseItems(strTemp)
reverseItems(numbers)[/code]

You can also implement a Generic class with this function as shown below.

[code language=”swift”]let strTemp = [“Deepak”,”John”,”Steve”,”Ravi”,”Ganesh”]

class ReverseDemo {
func reverseItems(items:[P])-> [P] {
return items.reverse()
}
}
let reverseDemo = ReverseDemo()
reverseDemo.reverseItems(strTemp)
[/code]

Swift Operations with Generics

Let us say you want to create a generic function that returns the square value of the given number. The immediate solution that comes to your mind is

[code language=”swift”]func squareOfNumber(number:M -> M{
return number * number
}
[/code]

This is not as straight forward as we think, you would notice an error – “Binary operator ‘*’ cannot be applied to two M operands”. The generic data type does not recogonize the operator ‘*’. We can fix this by creating a new protocol that tells about this operator ‘*’ and Generic type should conform to this protocol as shown below.

[code language=”swift”]protocol Multipliable {
func *(lhs:Self, rhs: Self) -> Self
}

func squareOfNumber(number:M -> M{
return number * number
}
[/code]

Then add an extension to Int, Float and other required types and make them conform to Multipliable protocol.

[code language=”swift”]extension Int: Multipliable {}
extension Float: Multipliable {}

squareOfNumber(20)[/code]

Download source code from gitHub (Generic)

Filed Under: Apple, Develop, Programming Tagged With: Closures, Extensions

Tuples, Enums and Protocols in Swift

May 14, 2015 By Ravi Shankar Leave a Comment

Tuples in Swift allows user to assign group of values to a variable, constant and even return parameter of a function. In the below example, a employee constant is assigned Int and String values. And to access these parameters, we need to use .0 and .1

[code language=”swift”]let employee = (103, “Deepak”)
employee.0
employee.1[/code]

Now let us say you want to assign proper name for these parameters so that you could access these values using those names instead of 0 and 1.

[code language=”swift”]let employee = (id:103, name:“Deepak”)
employee.id
employee.name[/code]

Here id and name are parameter names provided for employee id and employee name. You can also declare the data types for the tuple values like Int and String

[code language=”swift”]let employee:(id:Int, name:String = (102, “Deepak”)
employee.id
employee.name[/code]

Tuples and switch cases are powerful combination, look at an example below where Tuple has been used with switch cases. The _ is used for matching any values.

[code language=”swift”]let employee:(id:Int, name:String) = (102, “Deepak”)
switch (employee) {
case (103…105,_):
println(“developer”)
case (106…108,_):
println(“tester”)
case (_,“Deepak”):
println(“CEO”)
default:
println(“Contractor”)
}[/code]

Enums

Enum in Swift allows users to group related values to a single data type. Swift enum has lot of new features compared to its predecessor Objective-C. Let us see this with an example enum type for all Months in a year.

[code language=”swift”]enum Months {
case January, February, March, April, May, June, July, August, September, October, November, December
}

enum Month {
case January, February, March, April, May, June, July, August, September, October, November, December
}[/code]

Now you can define a variable or a constant of type month as shown below.

[code language=”swift”]let currentMonth = Month.May[/code]

And variable or constant is declared with the data type then you can use the short form.

[code language=”swift”]let currentMonth:Month = .May[/code]

Enum with Raw Value

Enum in Swift can be assigned a RawValue when declaring and the value can be of any data type. Let us day you want to specify the String value of each Month

[code language=”swift”]enum Month: String {
case January = “January”, February = “February”, March = “March”, April = “April”, May = “May”, June = “June”, July = “July”, August = “August”, September = “September”, October = “October”, November = “November”, December = “December”
}[/code]

The RawValue can be printed by accessing .rawValue on the enum variable or constant.

[code language=”swift”]let currentMonth:Month = .May
currentMonth.rawValue[/code]

Enum with Associated Value

Same like RawValue, enum can also have associated value and of data type.

[code language=”swift”]enum Month {
case January(String), February(String), March(String), April(String), May(String), June(String), July(String), August(String), September(String), October(String), November(String), December(String)
}

let currentMonth:Month = .May(“Summer Vacation”)

switch currentMonth {
case .May(let message):
println(message)
default:
println(“No Values”)
}[/code]

In the above example, Month enum values are declared with an associated value of data type String. And while assign the enum value the associated value is also provided to the currentMonth constant. Using the switch the associated value is retrieved.

Enum can have member function

Enum in Swift can also have member function. In the below example code, we have declared the Month enum with rawValue of type Int. Now add a member function to calculate the number of months left from the currently assigned value.

[code language=”swift”]enum Month: Int {
case January = 1, February, March, April, May, June, July, August, September, October, November, December func monthsLeftForYearEnd() -&gt; Int {
return Month.December.rawValue – self.rawValue
}
}

let month: Month = .May
month.monthsLeftForYearEnd()[/code]

Constant month is assigned a enum value of .May and you can find out the number of months left for the year end by accessing the monthsLeftForYearEnd.

Enum can have Initialiser

Swift’s enum can have initialiser too where you can set the default enum value or do some initial processing. If you add init function as shown below, the default enum value will be set to July.

[code language=”swift”]enum Month: Int {
case January = 1, February, March, April, May, June, July, August, September, October, November, December
init() {
self = .July
}

func monthsLeftForYearEnd() -&gt; Int {
return Month.December.rawValue – self.rawValue
}
}

let month = Month()
month.monthsLeftForYearEnd()[/code]

Protocols

Protocol in Swift defines the contract for a class or struct. This is similar to the interface in other languages like java. Protocol only defines the member function or variables and the actual implementation should be done in the conforming class or struct. Protocol can be be useful in the following ways

  • To add common behaviour across related or unrelated classes.
  • Supports in the implementation of delegation pattern

Let us see a typical example of protocol in Swift where we defining a Protocol called LivingThings with one method eat.

[code language=”swift”]protocol LivingThings {
func eat() -&gt; String
}[/code]

Any class or struct conforming to this Protocol should add implementation to eat method. In the below code example, we have got two classes Animal and Human which conform to LivingThings. implementation for the eat method has been added to both the classes.

[code language=”swift”]class Animal: LivingThings {
func eat() -&gt; String {
return “Animal Food"
}
}

class Human: LivingThings {
func eat() -&gt; String {
return "Human Food"
}
}

let john = Human()
john.eat()

let cat = Animal()
cat.eat()[/code]

If a class conforming to a Protocol does not implement the required methods then you will find error message “error: type ‘Human’ does not conform to protocol ‘LivingThings’”

Protocol with Optional Methods

In Swift, Protocol with optional method can be defined by specifying the optional before the method definition and adding @objc keyword before protocol. Listed below is an example with Speakable protocol that has an optional method speak

[code language=”swift”]
protocol LivingThings {
func eat() -&gt; String
}

@objc protocol Speakable {
optional func speak() -&gt; String
}

class Human: LivingThings, Speakable {
func eat() -&gt; String {
return "Human Food"
}

func speak() -&gt; String {
return "Human can Speak"
}
}

let john = Human()
john.eat()
john.speak()[/code]

Protocol and Delegation Pattern

A delegate pattern is used when you want a class to act on behalf of another class or for a callback mechanism. In the below code example we have defined a protocol (ImportDataDelegate) with two methods startImport and finishedImport. The DataImport class conforms to this Protocol and adds implementation to these methods. The DemoImport class acts on behalf of DataImport class by declaring a variable delegate of type ImportDataDelegate.

[code language=”swift”]protocol ImportDataDelegate {
func startImport()
func finishedImport()
}

class DataImport: ImportDataDelegate {
func startImport() {
println("Import started")
}

func finishedImport() {
println("Import finished")
}
}

class DemoImport {
var delegate: ImportDataDelegate?

func startProcess() {
delegate?.startImport()
println("Doing some work …")
delegate?.finishedImport()
}
}[/code]

This is how you pass the DataImport class to delegate variable of the DemoImport.

[code language=”swift”]let demoImport = DemoImport()
demoImport.delegate = DataImport()
demoImport.startProcess()[/code]

Filed Under: Apple, Develop, Programming Tagged With: Apple, delegate pattern, Optional Methods, Protocol

Class and Struct in Swift

May 10, 2015 By Ravi Shankar 3 Comments

Download the playground file from github (Classes and Struct)

Class

A class is a blue print for a real-word entity such Player, Person etc. and it is used for creating objects. Class can have properties to store values and methods to add behaviour. Let us see this with an example class called Rectangle which has some properties and two methods for calculating area and for drawing a rectangle.

[code language=”swift”]class Rectangle {

var name:String = ””
var length:Double = 0
var breadth:Double = 0

func area() -&gt; Double {
return length * breadth
}

func draw() -&gt; String {
return “Draw rectangle with area \(area()) “
}
}

let rect = Rectangle()

rect.length = 20
rect.breadth = 10
rect.draw()
[/code]

 

In the above example, we have a class named Rectangle, with name, length and breadth as properties, area and draw are functions. rect is a instance variable or object of Rectangle class. On setting the length and breadth and calling draw function should provide the following output in Playground.

201505101309.jpg

Similarly the below code create a Square class

[code language=”swift”]class Square {

var name:String = ””
var length:Double = 0

func area() -&gt; Double {
return length * length
}

func draw() -&gt; String {
return “Draw a square with area \(area()) “
}
}

let squr = Square()
squr.length = 20
squr.draw()
[/code]

 

Now instead of repeating property and functions in each classes let us use class inheritance to simplify these classes.

Class Inheritance

Let us create a parent class called Shape and its properties and functions will be inherited by Sub Classes Rectangle and Square.

Parent Class – Shape

[code language=”swift”]class Shape {
var name: String = ””

func area() -&gt; Double {
return 0
}

func draw() -&gt; String {
return “Draw a \(name) with area \(area()) “
}
}
[/code]

 

Sub Class – Square

[code language=”swift”]class Square:Shape {

var length: Double = 0
override func area() -&gt; Double {
return length * length
}
}

let squr = Square()
squr.name = “My Square”
squr.length = 5
squr.draw()
[/code]

 

Sub Class – Rectangle

[code language=”swift”]class Rectangle:Shape {
var length: Double = 0
var breadth: Double = 0

override func area() -&gt; Double {
return length * breadth
}
}

let rect = Rectangle()
rect.name = “My Rectangle”
rect.length = 5
rect.breadth = 10
rect.draw()
[/code]

 

Parent class Shape has been created with name property and functions area and draw. The child class Square and Rectangle will inherit these property and methods. Apart from the parent class property, Square can have its own property length and Rectangle has length and breadth. The parent class area function has been overridden by Square and Rectangle class to calculate corresponding areas. Now if you want add one more Shape such as Triangle, Circle etc the new class has to inherit Parent class (Shape) and add its own property and methods (or override methods).

Initialisers

Initialisers in Class and Struct are used for setting the default values for properties and for doing some initial setup. Here is a typical example of initialiser in a Class where the name property is initialised at the time of creating an instance.

[code language=”swift”]class Shape {

var name: String
init(name: String) {
self.name = name
}

func area() -&gt; Double {
return 0
}

func draw() -&gt; String {
return “Draw a \(name) with area \(area()) “
}
}

class Square: Shape {
var length: Double = 0

init() {
super.init(name: “MySquare”)
}

override func area() -&gt; Double {
return length * length
}

override func draw() -&gt; String {
return “Draw a \(name) with area \(area()) “
}
}

let squr = Square()
squr.length = 10
squr.draw()
[/code]

 

The sub class Square initialises the name property in init function by calling super.init and after creating the Square instance you need to pass value for the length property.

Designated and Convenience Initialisers

Initialiser which initialises all the properties in a class is known as designated initialiser. A convenience initialiser will initialise only selected properties and in turn will call the designated initialiser in init function. Listed below is a Square class with designated initialiser and convenience initialiser

[code language=”swift”]class Shape {
var name: String
init(name: String) {
self.name = name
}

func area() -&gt; Double {
return 0
}

func draw() -&gt; String {
return “Draw a \(name) with area \(area()) “
}
}

class Square: Shape {
var length: Double

// Designated Initializer
init(length:Double, name:String) {
self.length = length
super.init(name: name)
}

// Convenience Initializer
convenience init(length: Double) {
self.init(length:length, name:“MySquare”)
}

override func area() -&gt; Double {
return length * length
}

override func draw() -&gt; String {
return “Draw a \(name) with area \(area()) “
}
}

let squr = Square(length: 10,name: “MySquare”)
squr.draw()

let squrNew = Square(length: 20)
squrNew.draw()[/code]

Computed Property

A property in swift can be used for performing operation at the time of assigning value. Here is an example, where the length of Square is computed based on assigned area.

[code language=”swift”]class Sqaure {
var length: Double = 0
var area: Double {
get {
return length * length
}

set (newArea) {
self.length = sqrt(newArea)
}
}
}

let square = Sqaure()
square.area = 4 // set call
square.length = 6
square.area // get call[/code]

lazy Property

Swift also provides lazy property whose value is assigned when the user access the property.

[code language=”swift”]class Person {
var name: String
init (name: String) {
self.name = name
}

lazy var message: String = self.getMessage()

func getMessage() -&gt; String {
return “Hello \(name)”
}
}

let person = Person(name: “Jason”)
person.message[/code]

in the above code example, the value for message property is not set at the initialisation and will be set only when call the message property in person object. Some typical where you could due lazy property is when retrieving values from performance intensify operation such as Network or Read/Write.

Property Observers

Swift provides two property observers, willSet and didSet. These methods gets triggered when a value is about to be set for a property or after setting the property.

[code language=”swift”]class Square {
var length: Double = 0 {
willSet(newLength) {
println("Setting length \(self.length) to new length \(newLength)")
}

didSet {
println(“Length is modified – do some action here”)
}
}

var area: Double {
get {
return length * length
}

set (newArea) {
self.length = sqrt(newArea)
}
}
}

let square = Square()
square.length = -6
square.area
[/code]

 

In the above example, Square class length property has a willSet and didSet observers.

Struct

Struct and Class can both have properties, methods, protocols, extensions and initialisers. You can use struct to hold simple values and when you want to pass around those across your program. A typical example would be using Struct to hold values from a web service call. Listed below is a web service call that we had seen earlier in Xcode and Playground overview. In the below code example you should find a GeoDetails struct for storing the values returned from geoip web service.

[code language=”swift”]struct GeoDetails {
var country: String
var ip: String
var isp: String
var latitude: Double
var longitude: Double
var timeZone: String

init(country: String, ip: String, isp: String, latitude:Double, longitude:Double, timeZone:String) {
self.country = country
self.ip = ip
self.isp = isp
self.latitude = latitude
self.longitude = longitude
self.timeZone = timeZone
}

func description() -&gt; String {
return “Country ” + self.country + “, ip ” + self.ip + “, isp ” + self.isp + “, latitude \(self.latitude), longitude \(self.longitude) “
}
}

var geoDetails: GeoDetails?
XCPSetExecutionShouldContinueIndefinitely(continueIndefinitely: true)

let url = NSURL(string: “http://www.telize.com/geoip”)

NSURLSession.sharedSession().dataTaskWithURL(url!, completionHandler: { (data: NSData!, response: NSURLResponse!, error: NSError!) -&gt; Void in
if error == nil {
var error:NSError?
if let result = data {
if let dict = NSJSONSerialization.JSONObjectWithData(result, options: NSJSONReadingOptions.AllowFragments, error: &amp;error) as? NSDictionary {
geoDetails = GeoDetails(country: dict[“country”] as! String, ip: dict[“ip”] as! String, isp: dict[“isp”] as! String, latitude: dict[“latitude”] as! Double, longitude: dict[“longitude”] as! Double, timeZone: dict[“timezone”] as! String)
println(geoDetails?.description())
} else {
println("Error")
}
}[/code]

Download the playground file from github (Classes and Struct)

Filed Under: Apple, Programming Tagged With: Apple, Classes, Structures, Swift

Retrieve list of Twitter followers using Swift

April 21, 2015 By Ravi Shankar 5 Comments

This article provides details about the the steps required to retrieve the followers in from your twitter account. You will learn the following by going through this article

  1. Use oAuth to retrieve bearer token.
  2. Retrieve twitter followers using API call.
  3. Last 20 followers name and profile image will be displayed in a tableview.

Download the source code from here.

201504202245.jpg

Consumer Key and Consumer Secret

First step is to register your app in apps.twitter.com and get the Consumer Key and Consumer Secret from Application Settings.

Service Wrapper

Now create a service wrapper which retrieves the bearer token and uses the retrieved token for the service call. In this example the service call will be made to retrieve followers of your Twitter account.

[code language=”swift”]public class TwitterServiceWrapper:NSObject {
let consumerKey = “”
let consumerSecret = “”
let authURL = “https://api.twitter.com/oauth2/token”
}[/code]

Create a TwitterServiceWrapper class with constants for storing the consumer key, consumer secret and oAuth URL. Replace the consumer_key and consumer_secret from your apps.twitter.com account. Next add the following function to retrieve the bearer token using base64 encoded string. We have used Application – only authentication for this example, for more info refer to this documentation.

[code language=”swift”]// MARK:- Bearer Token

func getBearerToken(completion:(bearerToken: String) -&gt;Void) {
var request = NSMutableURLRequest(URL: NSURL(string: authURL)!)
request.HTTPMethod = “POST”
request.addValue(“Basic “ + getBase64EncodeString(), forHTTPHeaderField: “Authorization”)
request.addValue(“application/x-www-form-urlencoded;charset=UTF-8”, forHTTPHeaderField: “Content-Type”)
var grantType = “grant_type=client_credentials”
request.HTTPBody = grantType.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)

NSURLSession.sharedSession() .dataTaskWithRequest(request, completionHandler: { (data: NSData!, response:NSURLResponse!, error: NSError!) -&gt; Void in

var errorPointer : NSErrorPointer = nil

if let results: NSDictionary = NSJSONSerialization .JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments , error: errorPointer) as? NSDictionary {

if let token = results[“access_token”] as? String {
completion(bearerToken: token)
} else {
println(results[“errors”])
}
}

}).resume()
}

// MARK:- base64Encode String

func getBase64EncodeString() -&gt; String {

let consumerKeyRFC1738 = consumerKey.stringByAddingPercentEscapesUsingEncoding(NSASCIIStringEncoding)

let consumerSecretRFC1738 = consumerSecret.stringByAddingPercentEscapesUsingEncoding(NSASCIIStringEncoding)

let concatenateKeyAndSecret = consumerKeyRFC1738! + ”:” + consumerSecretRFC1738!

let secretAndKeyData = concatenateKeyAndSecret.dataUsingEncoding(NSASCIIStringEncoding, allowLossyConversion: true)

let base64EncodeKeyAndSecret = secretAndKeyData?.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros)

return base64EncodeKeyAndSecret!
}
[/code]

 

Now add the following functions which would use the bearer token to make the service call then process the results and store them in TwitterFollower struct.

[code language=”swift”]// MARK:- Service Call

func getResponseForRequest(url:String) {
var results:NSDictionary
getBearerToken({ (bearerToken) -&gt; Void in
var request = NSMutableURLRequest(URL: NSURL(string: url)!)
request.HTTPMethod = “GET”
let token = “Bearer “ + bearerToken
request.addValue(token, forHTTPHeaderField: “Authorization”)

NSURLSession.sharedSession() .dataTaskWithRequest(request, completionHandler: { (data: NSData!, response:NSURLResponse!, error: NSError!) -&gt; Void in

self.processResult(data, response: response, error: error)
}).resume()
})
}

// MARK:- Process results
func processResult(data: NSData, response:NSURLResponse, error: NSError?) {

var errorPointer : NSErrorPointer = nil

if let results: NSDictionary = NSJSONSerialization .JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments , error: errorPointer) as? NSDictionary {

if var users = results["users"] as? NSMutableArray {
for user in users {
let follower = TwitterFollower(name: user["name"] as! String, url: user["profile_image_url"] as! String)
self.delegate?.finishedDownloading(follower)
}

} else {
println(results["errors"])
}
}
}
[/code]

 

TwitterFollowerDelegate

We also need to create a protocol in TwitterServiceWrapper class. This will inform the delegates once the data is downloaded from the service

[code language=”swift”]protocol TwitterFollowerDelegate{
func finishedDownloading(follower:TwitterFollower)
}[/code]

TwitterFollower – Place holder struct

TwitterFollower struct will just act as a place holder for storing followers’s name, profile URL and description. TwitterFollower struct looks as shown below.

[code language=”swift”] struct TwitterFollower {
var name: String?
var description: String?
var profileURL: NSData?

init (name: String, url: String) {
self.name = name
let pictureURL = NSURL(string: url)
profileURL = NSData(contentsOfURL: pictureURL!)
}
}[/code]

Add TableViewController

Now finally we use the followers data retrieved from the service and displayed in a tableview. TwitterFollowerController is a UITableViewController which conforms to TwitterFollowerDelegate protocol. We create an instance of TwitterServiceWrapper class and pass the request URL for retrieving the followers details in viewDidLoad method.

[code language=”swift”]class TwitterFollowerController: UITableViewController, TwitterFollowerDelegate {
var serviceWrapper: TwitterServiceWrapper = TwitterServiceWrapper()
var followers = [TwitterFollower]()

@IBOutlet weak var activityIndicator: UIActivityIndicatorView!

override func viewDidLoad() {
super.viewDidLoad()
serviceWrapper.delegate = self
activityIndicator.startAnimating()
serviceWrapper.getResponseForRequest(“https://api.twitter.com/1.1/followers/list.json? screen_name=rshankra&amp;skip_status=true&amp;include_user_entities=false”)
}[/code]

Implement the Table View Data source methods as shown below

[code language=”swift”]// MARK: – Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -&gt; Int {
return 1
}
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -&gt; Int {
let numberOfRows = followers.count
return numberOfRows
}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -&gt; UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier(“reuseIdentifier”, forIndexPath: indexPath) as! UITableViewCell

let follower = followers[indexPath.row] as TwitterFollower
cell.imageView?.image = UIImage(data: follower.profileURL!)
cell.textLabel?.text = follower.name

return cell
}[/code]

The data for followers array will be populated in the TwitterFollowerDelegate method.

[code language=”swift”] // MARK: – TwitterFollowerDelegate methods

func finishedDownloading(follower: TwitterFollower) {
dispatch_async(dispatch_get_main_queue(), { () -&gt; Void in
self.followers.append(follower)
self.tableView.reloadData()
self.activityIndicator.stopAnimating()
self.activityIndicator.hidden = true
})
}[/code]

We need to make sure that the reloading of data is done in the main thread by calling

[code language=”plain”]dispatch_async(dispatch_get_main_queue()[/code]

Download the source code from here.

Filed Under: Apple, iPhone, Programming Tagged With: Apple, oAuth, Twitter API, Twitter Followers

How to record and play sound in Swift

April 12, 2015 By Ravi Shankar 10 Comments

In this tutorial, we are going to see the required steps to record and play sound in Swift Programming language using AVAudioRecorder and AVAudioPlayer

Download source code from github (SoundController.swift)

User Interface

The user interface for this demo is simple with two buttons, one for recording and another for playing sound.

201504121626.jpg

Create corresponding IBAction and IBOutlets from the two button in the View Controller.

@IBOutlet weak var recordButton: UIButton!

@IBOutlet weak var playButton: UIButton!

@IBAction func recordSound(sender: UIButton)

@IBAction func playSound(sender: UIButton)

Dual Purpose Buttons

The Record button will be used to record and stop recording. Similarly the Play button will used to Play and Stop the audio.

Class level var and let declaration

  var soundRecorder: AVAudioRecorder!

var soundPlayer:AVAudioPlayer!

  

let fileName = “demo.caf”

Declare two class level variable for holding an instance of AVAudioRecorder and AvAudioPlayer. Also create constant for holding the file name.

Create Sound file path

For this demo, the sound file will be created under the Cache directory using the name defined in the constant. Add these two function to your class

  func getCacheDirectory() -> String {

  

let paths = NSSearchPathForDirectoriesInDomains(.CachesDirectory,.UserDomainMask, true) as [String]

  

return paths[0]

}

  

func getFileURL() -> NSURL {

  

let path = getCacheDirectory().stringByAppendingPathComponent(fileName)

let filePath = NSURL(fileURLWithPath: path)

  

return filePath!

}

The getCacheDirectory retrieves the caches directory and getFileURL appends the file name with the cache directory.

Setup Recorder

Create a new function that prepares the recorder and this function will be called during the viewDidLoad operation

func setupRecorder() {

  

//set the settings for recorder

  

var recordSettings = [

AVFormatIDKey: kAudioFormatAppleLossless,

AVEncoderAudioQualityKey : AVAudioQuality.Max.rawValue,

AVEncoderBitRateKey : 320000,

AVNumberOfChannelsKey: 2,

AVSampleRateKey : 44100.0

]

  

var error: NSError?

  

soundRecorder = AVAudioRecorder(URL: getFileURL(), settings: recordSettings, error: &error)

  

if let err = error {

println(“AVAudioRecorder error: \(err.localizedDescription)“)

} else {

soundRecorder.delegate = self

soundRecorder.prepareToRecord()

}

}

To create an AVAudioRecorder instance, you need to pass three parameters,

URL– Specifies the path and name of the file where the sound will be recorded.

settings – Configure AVRecorder settings

error – Capture error while creating AVRecorder instance.

If there is no error while creating Audio Recorder, the delegate it set to the View Controller and recorder is prepared for recording. Make sure the View Controller conforms to AVAudioRecorderDelegate

class SoundController: UIViewController, AVAudioRecorderDelegate {

Prepare Player

Add the following function that prepares the AVAudiPlayer to play the recorded sound

func preparePlayer() {

var error: NSError?

  

soundPlayer = AVAudioPlayer(contentsOfURL: getFileURL(), error: &error)

  

if let err = error {

println(“AVAudioPlayer error: \(err.localizedDescription)“)

} else {

soundPlayer.delegate = self

soundPlayer.prepareToPlay()

soundPlayer.volume = 1.0

}

}

AVAudioPlayer instance is created by passing sound file that needs to be played along with pointer to capture errors while creating AVAudioPlayer instance. Make sure the View Controller conforms to AVAudioPlayerDelegate. Then call the prepareToPlay function on the AVAudioPlayer instance.

Implement IBActions function to record and play sound

Add the following implementation to the IBAction functions which records and plays sound.

@IBAction func recordSound(sender: UIButton) {

if (sender.titleLabel?.text == “Record”){

soundRecorder.record()

sender.setTitle(“Stop”, forState: .Normal)

playButton.enabled = false

} else {

soundRecorder.stop()

sender.setTitle(“Record”, forState: .Normal)

}

}

  

@IBAction func playSound(sender: UIButton) {

if (sender.titleLabel?.text == “Play”){

recordButton.enabled = false

sender.setTitle(“Stop”, forState: .Normal)

preparePlayer()

soundPlayer.play()

} else {

soundPlayer.stop()

sender.setTitle(“Play”, forState: .Normal)

}

}

When the Record button is tapped, the name of the button is changed to Stop and starts recording the sound. Similarly when the title is Stop, the recording the stopped and play button is enabled. The same is done when the user taps the play button.

class SoundController: UIViewController, AVAudioRecorderDelegate, AVAudioPlayerDelegate {

Implement AVAudioRecorderDelegate methods

  func audioRecorderDidFinishRecording(recorder: AVAudioRecorder!, successfully flag: Bool) {

playButton.enabled = true

recordButton.setTitle(“Record”, forState: .Normal)

}

  

func audioRecorderEncodeErrorDidOccur(recorder: AVAudioRecorder!, error: NSError!) {

println(“Error while recording audio \(error.localizedDescription)“)

}

Implement AVAudioPlayerDelegate methods

  func audioPlayerDidFinishPlaying(player: AVAudioPlayer!, successfully flag: Bool) {

recordButton.enabled = true

playButton.setTitle(“Play”, forState: .Normal)

}

  

func audioPlayerDecodeErrorDidOccur(player: AVAudioPlayer!, error: NSError!) {

println(“Error while playing audio \(error.localizedDescription)“)

}

Now you are good to go and try this demo. You can download the source code for recording and playing audio in swift from github.

Filed Under: Develop, Programming, Xcode Tagged With: AvAudioPlayer, AVAudioRecorder, Xcode

UITextFieldDelegate in Swift

April 7, 2015 By Ravi Shankar Leave a Comment

This is a beginners tutorial on UITextFieldDelegate in Swift. We are going to see how to use UITextFieldDelegate by writing a Simple Interest Calculator.

201504071303.jpg

Download the source code from here

This calculator uses UILabels and TextFields for displaying and accepting amount and interest. We are going to use the UITextFieldDelegate method to navigate from “Principal Amount” to “Rate of Interest”. And when the user taps done on “Rate of Interest” UITextField, the interest is calculated and displayed on the corresponding label.

Source Code

import UIKit

class TextFieldDemoController: UIViewController, UITextFieldDelegate {

@IBOutlet weak var amountTextField: UITextField!

  

@IBOutlet weak var rateTextField: UITextField!

  

@IBOutlet weak var interestLabel: UILabel!

  

var textFields:[UITextField] = []

  

override func viewDidLoad() {

super.viewDidLoad()

  

self.amountTextField.delegate = self

self.rateTextField.delegate = self

  

textFields = [amountTextField, rateTextField]

  

}

override func didReceiveMemoryWarning() {

super.didReceiveMemoryWarning()

// Dispose of any resources that can be recreated.

}

  

//MARK :- TextField Delegate

  

func textFieldShouldReturn(textField: UITextField) -> Bool {

  

var currentTextField = textFields[0]

  

if (currentTextField == textField) {

currentTextField = textFields[1]

currentTextField.becomeFirstResponder()

} else {

currentTextField.resignFirstResponder()

interestLabel.text = “\(calculateInterest())“

}

  

return true

}

  

//MARK :- Calculation

  

func calculateInterest() -> Double {

let amount: Double = (amountTextField.text as NSString).doubleValue

let rate:Double = (rateTextField.text as NSString).doubleValue

  

return amount * rate

}

}

Step 1: Make sure your view controller class conforms to UITextFieldDelegate

Step 2: In ViewDidLoad method, set the delegate for the textfields to self (ViewController)
Step 3: Implement textFieldShouldReturn(textField: UITextField) -> Bool(UITextFieldDelegate method) and the code that makes the UITextField FirstResponder and calculates the Interest once the values are entered.
Download the source code from here

Filed Under: Apple, Develop, Programming, Xcode Tagged With: Apple, textFieldShouldReturn, UITextFieldDelegate, Xcode

SplitViewController example in Swift

April 1, 2015 By Ravi Shankar 4 Comments

This is a beginners tutorial on SplitViewController using Interface builder with programming language as Swift. There are also some good articles available on SplitViewController, check them out as well – nhipster and whoisryannystrom.

Create a new Single View Application.

201503290525.jpg

Choose Language option as Swift and provide a product name.

201504011302.jpg

Navigate to Main.Storyboard and select default View Controller and delete it.

201504011304.jpg

Add a Split View Controller from the object library to the interface builder.

201504011305.jpg

Using Attributes Inspector make Split View Controller as the Initial View Controller

201504011307.jpg
Select View Controller in the Interface builder then click Editor menu and select Navigation Controller under Embed In menu option.

201504011308.jpg

Rename ViewController.swift to DetailViewController.swift and change the class name as well.

201504011317.jpg

Navigate to Interface builder and set the class name for ViewController scene to DetailViewController

201504011321.jpg

Now Control + drag and drop TablevIew Prototype cell to NavigationController (DetailViewController) and select segue as show detail. Also set the identifier for the Storyboard Segue as “ShowDetailIdentifier“

201504011323.jpg

201504011326.jpg

Navigate to RootViewController (TableViewController) Provide the Identifier as CellIdentifier for the Prototype Cells.

201504011325.jpg

Right click on the Project Navigator, select New File and Choose the template as Cocoa Touch Class

201504011331.jpg

In the next screen, select subclass as UIViewController and provide a name as SplitViewController

201504011332.jpg

After creating the file, edit SplitViewController subclass to UISplitViewController. Then add the following line to the viewDidLoad method.

  splitViewController?.preferredDisplayMode = .PrimaryOverlay

The above line is to keep the PrimaryViewController (TableViewController) on top of SecondaryViewController (DetailViewController). You can change this behaviour by setting other types, check the documentation for more details.

201504011407.jpg

Now add the PrimaryViewController (TableViewController) by right clicking and selecting New File. Select Cocoa Touch class and in the subclass field pick UITableViewController. Provide the the name for the TableViewController ListTableViewController.

201504011409.jpg

Set the class name for the RootViewController (TableViewController) to the newly created class, ListTableViewController.

201504011424.jpg

Navigate to DetailViewController in the Interface builder, add a label and make it horizontally and vertically centred.

201504011524.jpg

Then add a new IBOutlet in DetailViewController and connect the Outlet to the label in interface builder.

  @IBOutlet var numberLabel:UILabel?

Also add property of type Int and the value for this property will be set during the segue transition.

var selectedIndex:Int = 1

Make changes to the viewDidLoad method, to set the value for the label and to add back button to the navigation bar.

override func viewDidLoad() {

super.viewDidLoad()

  

numberLabel?.text = “\(selectedIndex)“

  

// add back button to the navigation bar.

  

if splitViewController?.respondsToSelector(“displayModeButtonItem”) == true {

navigationItem.leftBarButtonItem = splitViewController?.displayModeButtonItem()

navigationItem.leftItemsSupplementBackButton = true

}

}

In the ListTableViewController, add the following code that sets the datasource.

  let names = [“One”,“Two”,“Three”,“Four”,“Five”,“Six”,“Seven”,“Eight”,“Nine”,“Ten”] (class level declaration)

  // MARK: – Table view data source

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {

return 1

}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {

return names.count

}

override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCellWithIdentifier(“CellIdentifier”, forIndexPath: indexPath) as UITableViewCell

   cell.textLabel?.text = names[indexPath.row]

return cell

}

Then make changes to the prepareForSegue method to navigate to DetailViewController after setting the selectedIndex property

  override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {

if (segue.identifier == “ShowDetailIdentifier”) {

var detail: DetailViewController

if let navigationController = segue.destinationViewController as? UINavigationController {

detail = navigationController.topViewController as DetailViewController

} else {

detail = segue.destinationViewController as DetailViewController

}

  

if let path = tableView.indexPathForSelectedRow() {

detail.selectedIndex = path.row + 1

}

}

}

201504011556.jpg

Download the source from here.

Filed Under: ios, iPad, iPhone, Programming, Xcode Tagged With: Demo, iPad, UISplitViewController, Xcode

  1. Pages:
  2. «
  3. 1
  4. 2
  5. 3
  6. 4
  7. 5
  8. 6
  9. »
« Previous Page
Next Page »

Primary Sidebar

TwitterLinkedin

Recent Posts

  • How to know the size of the folders in iCloud
  • Errors were encountered while preparing your device
  • We have blocked all requests from this device – Firebase Phone Authentication
  • iPhone is not available error message in Xcode
  • Clear CocoaPods cache, re-download and reinstall all pods

Copyright 2021 © rshankar.com