Monday, 4 July 2016

Using Delegate Method

Using Delegate Method




Let's assume an object A calls an object B to perform an action. Once the action is complete, object A should know that B has completed the task and take necessary action. This is achieved with the help of delegates.
The key concepts in the above example are −
  • A is a delegate object of B.
  • B will have a reference of A.
  • A will implement the delegate methods of B.
  • B will notify A through the delegate methods.

Steps in Creating a Delegate


step 1. First, create a single view application.

step 2. Then select File -> New -> File...

iOS Tutorial

step 3. Then select Objective C Class and click Next.

step 4. Give a name to the class, say, SampleProtocol with subclass as NSObject as shown below.

iOS Tutorial

step 5. Then select create.

step 6. Add a protocol to the SampleProtocol.h file and the updated code is as follows −

#import <Foundation/Foundation.h>
// Protocol definition starts here 
@protocol SampleProtocolDelegate <NSObject>
@required
- (void) processCompleted;
@end
// Protocol Definition ends here
@interface SampleProtocol : NSObject

{
   // Delegate to respond back
   id <SampleProtocolDelegate> _delegate; 

}
@property (nonatomic,strong) id delegate;

-(void)startSampleProcess; // Instance method

@end

step 7. Implement the instance method by updating the SampleProtocol.m file as shown below.


#import "SampleProtocol.h"

@implementation SampleProtocol

-(void)startSampleProcess{
    
    [NSTimer scheduledTimerWithTimeInterval:3.0 target:self.delegate 
 selector:@selector(processCompleted) userInfo:nil repeats:NO];
}
@end

step 8. Add a UILabel in the ViewController.xib by dragging the label from the object library to UIView as shown below.

iOS Tutorial

step 9. Create an IBOutlet for the label and name it as myLabel and update the code as follows to adopt SampleProtocolDelegate in ViewController.h.


#import <UIKit/UIKit.h>
#import "SampleProtocol.h"

@interface ViewController : UIViewController<SampleProtocolDelegate>
{
    IBOutlet UILabel *myLabel;
}
@end

step 10. Implement the delegate method, create object for SampleProtocol and call the startSampleProcess method. The Updated ViewController.m file is as follows −

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    SampleProtocol *sampleProtocol = [[SampleProtocol alloc]init];
    sampleProtocol.delegate = self;
    [myLabel setText:@"Processing..."];
    [sampleProtocol startSampleProcess];
 // Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Sample protocol delegate
-(void)processCompleted{    
    [myLabel setText:@"Process Completed"];
}


@end

step 11. We will see an output as follows. Initially the label displays "processing...", which gets updated once the delegate method is called by the SampleProtocol object.

iOS Tutorial








Universal Application Setup

Universal Application Setup



Step 1. Create a simple View based application.

Step 2. Change the File name ViewController.xib file toViewController_iPhone.xib as shown below in the file inspector in the right hand side.
iOS Tutorial


Step 3. Select File -> New -> File... then select the subsection "User Interface" and select View. Click Next.

iOS Tutorial

Step 4. Select the device family as iPad and click next.

iOS Tutorial

Step 5. Save the file as ViewController_iPad.xib and select Create.

Step 6. Add a label in the center of the screen in bothViewController_iPhone.xib and ViewController_iPad.xib.

Step 7. In ViewController_iPad.xib, select the identity inspector and set the custom class as ViewController.

iOS Tutorial

Step 8. Update the application:DidFinishLaunching:withOptions method in AppDelegate.m as follows −

- (BOOL)application:(UIApplication *)application
  didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
   self.window = [[UIWindow alloc] initWithFrame:[[UIScreen 
   mainScreen] bounds]];
   // Override point for customization after application launch.
   if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) {
        self.viewController = [[ViewController alloc] 
        initWithNibName:@"ViewController_iPhone" bundle:nil];
   }
   else{
        self.viewController = [[ViewController alloc] initWithNibName:
        @"ViewController_iPad" bundle:nil];
   }
   self.window.rootViewController = self.viewController;
   [self.window makeKeyAndVisible];
   return YES;
}

Step 9. Update the devices in project summary to Universal as shown below −

iOS Tutorial

Output


When we run the application, we'll get the following output −

iOS Tutorial

When we run the application in iPad simulator, we'll get the following output −

iOS Tutorial








Friday, 24 June 2016

Map Based Location Tracker for iOS

Map Based Tracker For Ios



Anything location based is really cool, and having that information displayed on a map is even better! So … lets track our location and plot it on a map :)
images
The good news about this tutorial is there is very little code! The flip side is, we will have to do some extra setup. Lets begin!
Preface: I’m still very much a beginner to Swift, and I am just sharing my journey to help out other beginners :) I’m also using Xcode beta 5 for this.

Setup

Setting up the project

1
File -> New -> Project
Then select
1
iOS -> Application -> Single View Application
Give it a name and make sure we are using the language Swift :)

Open our Main.storyboard file.

images

Show the document outline. There is a little handle in the lower left window of the storyboard to do this.

images

Highlight our View Controller for this scene, and navigate to the attributes inspector.

images

For this project, we are going to set the size to be “Retina 4-Inch Full Screen” and I’m going to set the Orientation to Portrait.

Setting up the MapKit View

Apple has already provided us with a map view. So we just need to drag one into our scene.

images


Setting up the label


We are also going to have a label to display some debug information about our location. Drag one into the scene as well.

images
Feel free to adjust the attributes in the inspector to make the label look like mine. I centered the text, gave the label 3 lines, and used the awesomely cool font ‘Helvetica Neue Thin’ with a font size of 12 (incorrectly “17.0” in screen shot).

Creating the IBOutlets


Now that we have our mapview and label, we are going to drag them into our ViewController.swift code so we can control them with code.
We want to switch to assistant editor (the view that looks like a suit and bow tie in the upper right), and then “right click drag” our MKMapView into our ViewController.swift file.

images
images

We also want to right click, and drag from the Label to our ViewController.swift file.

images
images

You will see some errors, but this will go away once we fix our imports. If you are dying to fix this now, add this under import UIKit

1
2
import CoreLocation
import MapKit

Editing the info.plist


We need to add 2 keys to our info.plist file, which is located in the “Supporting Files” folder. The two keys are NSLocationWhenInUseUsageDescription and NSLocationAlwaysUsageDescription. Right click on “Information Property List”, click Add Row, and manually enter these two keys.

Programatically Added :- 

<key>NSLocationWhenInUseUsageDescription</key>
    <string>This application requires location services to work</string>
    
    <key>NSLocationAlwaysUsageDescription</key>
    <string>This application requires location services to work</string>


images

The final form should look like this:

images


Simulating your location


The last thing I want to mention is there is no way (I saw) to have the iOS simulator aware of your actual location. However, the simulator DOES allow you to fake this data. Make sure you have a good simulation selected or else this program will just show an empty map.

Once you have the simulator going select a location!!!
images


ViewController.swift and Full Code


Phew! Thank goodness all that setup is out of the way. Time for the code!


//
//  ViewController.swift
//  UpdatePolyline_Swift
//
//  Created by INT MAC 2015 on 24/06/16.
//  Copyright © 2016 INT. All rights reserved.
//

import UIKit
import CoreLocation
import MapKit

class ViewController: UIViewController , CLLocationManagerDelegate, MKMapViewDelegate {

    
    @IBOutlet weak var theMap: MKMapView!
    @IBOutlet weak var theLabel: UILabel!
    
    var manager:CLLocationManager!
    var myLocations: [CLLocation] = []
    
    override func viewDidLoad() {
        super.viewDidLoad()
       
        
        //Setup our Location Manager
        manager = CLLocationManager()
        manager.delegate = self
        manager.desiredAccuracy = kCLLocationAccuracyBest
        manager.requestAlwaysAuthorization()
        manager.startUpdatingLocation()
        
        //Setup our Map View
        theMap.delegate = self
        theMap.mapType = MKMapType.Satellite
        theMap.showsUserLocation = true
        
    }

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
    
        theLabel.text = "\(locations[0])"
        myLocations.append(locations[0] )
        
        let spanX = 0.007
        let spanY = 0.007
        var newRegion = MKCoordinateRegion(center: theMap.userLocation.coordinate, span: MKCoordinateSpanMake(spanX, spanY))
        theMap.setRegion(newRegion, animated: true)
        
        if (myLocations.count > 1){
            var sourceIndex = myLocations.count - 1
            var destinationIndex = myLocations.count - 2
            
            let c1 = myLocations[sourceIndex].coordinate
            let c2 = myLocations[destinationIndex].coordinate
            var a = [c1, c2]
            var polyline = MKPolyline(coordinates: &a, count: a.count)
            theMap.addOverlay(polyline)
        }
    }
    
    func mapView(mapView: MKMapView!, rendererForOverlay overlay: MKOverlay!) -> MKOverlayRenderer! {
        
        if overlay is MKPolyline {
            var polylineRenderer = MKPolylineRenderer(overlay: overlay)
            polylineRenderer.strokeColor = UIColor.blueColor()
            polylineRenderer.lineWidth = 4
            return polylineRenderer
        }
        return nil
    }
    
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }


}