• Skip to main content
  • Skip to primary sidebar

Ravi Shankar

Tweaking Apps

  • About
  • Portfolio
  • Privacy Policy

ios

Binary search

June 26, 2014 By Ravi Shankar Leave a Comment

After a simple bubble sort algorithm (not the most efficient sorting algorithm), let us try to implement Binary search in Swift Programming Language. Binary search algorithm can be applied only on sorted arrays. So let us first generate random numbers and store them in an array. Then call the bubble sort function to sort the numbers by passing the array to the function.

import Cocoa


func swapNumbers(index1 :Int,index2: Int) {

let temp = inputArr[index1]

inputArr[index1] = inputArr[index2]

inputArr[index2] = temp

}


func bubbleSort(inputArray :Int[]) {

for var index: Int = inputArr.count-1; index > 1; --index {

for var jIndex: Int = 0; jIndex < index; ++jIndex {

if inputArr[jIndex] > inputArr[jIndex + 1] {

swapNumbers(jIndex, jIndex+1)

}

}

}

}


var inputArr = Int[]()


// generate random numbers

for rIndex in 0..10 {

inputArr.append(((Int(arc4random()) % 100)))

}


//call bubblesort function to sort the numbers in array

bubbleSort(inputArr)


inputArr

Steps for Binary search algorithm

  • Set lower index to 0 and upper index to total count of elements
  • Set the current index to the median of lower and upper index
  • Repeat these checks in a infinite while loop.
  • Check if passed number is equal to number returned by current index. If it matches then return the current index.
  • If the lower index is greater than upper index, it means the search item does not exist in the array. Hence return the array’s total elements.
  • If current index is greater than the search item then decrease the upper index
  • if current index is less than the search item then increase the lower index.

func findItem(searchItem :Int) -> Int{

var lowerIndex = 0;

var upperIndex = inputArr.count - 1


while (true) {

var currentIndex = (lowerIndex + upperIndex)/2

if(inputArr[currentIndex] == searchItem) {

return currentIndex

} else if (lowerIndex > upperIndex) {

return inputArr.count

} else {

if (inputArr[currentIndex] > searchItem) {

upperIndex = currentIndex - 1

} else {

lowerIndex = currentIndex + 1

}

}

}

}


findItem(78)

Filed Under: Apple, Develop, ios, Programming, Xcode Tagged With: Apple, binary search, bubble sort, Swift, Xcode

Generate random numbers – Example of motion and touch event

April 29, 2014 By Ravi Shankar Leave a Comment

Let us see how to use motion and touch event in iOS by looking through a simple project that displays random number. This project displays random number on a label for a touch and motion event. Check out this link for more about events in iOS

201404291450.jpg

After creating a single view application, add a new class that contains the method for generating random. If you do not want to add new class just for a single method then you can add the method as part of your ViewController class itself. arc4random_uniform accepts a seed value (90) and generated number will be below this seed value.

-(NSInteger)generateNumber {

   return arc4random_uniform(90);

}

Now add a UILabel for displaying the generated random numbers. This includes both adding IBOutlet property and connecting it with UILabel on Interface Builder.


Motion Event

The are three motion-handling methods -(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event, -(void)motionBegan:(UIEventSubtype)motion withEvent:(UIEvent *)event and -(void)motionCancelled:(UIEventSubtype)motion withEvent:(UIEvent *)event

In this example, we can use the motionEnded method to call the displayNumber method

-(void)motionEnded:(UIEventSubtype)motion withEvent:(UIEvent *)event {

if (UIEventSubtypeMotionShake) {

[self displayNumber];

}

}

-(void)displayNumber {

RandomNumber *randomNumber = [[RandomNumber alloc] init];

self.displayRandomNumber.text = [NSString stringWithFormat:@”%d”,[randomNumber generateNumber]];

}

And to test this on Simulator, use the Shake Gesture menu under Hardware to simulate motion event.

201404291717.jpg

Touch Event

There are four touch events corresponding to each touch phase.

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event

-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event

-(void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event

-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event

In this example, we will use the touchesEnded method for displaying the random numbers.

-(void) touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {

[self displayNumber];

}

You can download the source code along with TDD classes for this beginner tutorial on touch and motion event from here.

Filed Under: ios, Programming, Xcode Tagged With: motion events, touch events, Xcode

Test Driven Development in iOS – Beginners tutorial – Part 2

April 14, 2014 By Ravi Shankar 3 Comments

This is in continuation of the Test Driven Development in iOS – Beginners tutorial and this covers writing XCTest user interfaces in iOS. AddingTwoNumbers app will have following controls

1. Three textfields – For entering the numbers and displaying the result.

2. Two buttons – Add button to perform addition and Reset button to clear all the textfields.

Let us create a new Test case class for testing the user interface, AddTwoNumberViewControllerTests.m

201404141732.jpg

201404141743.jpg

The first test written is for checking the App Delegate call, storyboard, view controller and view.

-(void)testViewControllerViewExists {

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:nil];

RSViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:

@”RSViewController”];

XCTAssertNotNil([viewController view], @”ViewController should contain a view”);

}

The following needs to be done for passing this test.

1. Add new Objective-C class, subclass of UIViewController (RSViewController).

201404141858.jpg

2. Add a Storyboard file to your project which would contain the ViewController required for this app.

201404142108.jpg

3. Drag and drop, UIViewController on the storyboard and set the class name for the ViewController as RSViewController and StoryboardID as RSViewViewController.

201404142114.jpg

4. Now add the code required in App Delegate’s didFinishLaunchingWithOptions method. This should load the storyboard then instantiate the view controller and set it as RootViewController.

– (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:[NSBundle mainBundle]];

UIViewController *vc =[storyboard instantiateInitialViewController];

  

// Set root view controller and make windows visible

self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];

self.window.rootViewController = vc;

[self.window makeKeyAndVisible];

return YES;

}

A lot has been added to just pass a single test case, probably this can be broken up by writing some more tests.

201404142126.jpg

Next add the test for checking the FirstNumber UITextField connection.

-(void)testFirstNumberTextFieldConnection {

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:nil];

RSViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:

@”RSViewController”];

XCTAssertNotNil([viewController firstNumberTextField], @”firstNumberTextField should be connected”);

}

Next add the test for checking the FirstNumber UITextField connection.

-(void)testFirstNumberTextFieldConnection {

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:nil];

RSViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:

@”RSViewController”];

[viewController view];

XCTAssertNotNil([viewController firstNumberTextField], @”firstNumberTextField should be connected”);

}

This test would pass after adding the IBOutlet for UITextField in the interface file.

#import <UIKit/UIKit.h>

@interface RSViewController : UIViewController

@property (nonatomic,strong) IBOutlet UITextField *firstNumberTextField;

@end

Then add UITextField to the ViewController and make the connection to UITextField with IBOutlet property.

201404142141.jpg

201404142152.jpg

Then add similar test cases for secondNumber and result textfields. Also make corresponding changes to pass the test.

-(void)testSecondNumberTextFieldConnection {

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:nil];

RSViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:

@”RSViewController”];

[viewController view];

XCTAssertNotNil([viewController secondNumberTextField], @”secondNumberTextField should be connected”);

}

-(void)testresultTextFieldConnection {

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:nil];

RSViewController *viewController = [storyboard instantiateViewControllerWithIdentifier:

@”RSViewController”];

[viewController view];

XCTAssertNotNil([viewController resultTextField], @”resultTextField should be connected”);

}

201404142205.jpg
Before we move on to the Button test cases, let us refactor the test cases code and remove the duplication of code. The common code has been moved to setup method and now the test cases should loo lot simpler.

@implementation AddTwoNumberViewControllerTests

{

RSViewController *viewController;

}

– (void)setUp

{

[super setUp];

UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@”Storyboard” bundle:nil];

viewController = [storyboard instantiateViewControllerWithIdentifier:

@”RSViewController”];

[viewController view];

}

– (void)tearDown

{

[super tearDown];

}

-(void)testViewControllerViewExists {

XCTAssertNotNil([viewController view], @”ViewController should contain a view”);

}

-(void)testFirstNumberTextFieldConnection {

XCTAssertNotNil([viewController firstNumberTextField], @”firstNumberTextField should be connected”);

}

-(void)testSecondNumberTextFieldConnection {

XCTAssertNotNil([viewController secondNumberTextField], @”secondNumberTextField should be connected”);

}

-(void)testresultTextFieldConnection {

XCTAssertNotNil([viewController resultTextField], @”resultTextField should be connected”);

}

Now add the failing test case for Add button and see if the button exists.

-(void)testAddButtonConnection {

XCTAssertNotNil([viewController addButton], @”add button should be connected”);

}

And to pass the above test, add button to ViewController, create a addButton IBOutlet property of type UIButton and make connection to IBOutlet and button field.

@property (nonatomic,strong) IBOutlet UIButton *addButton;


201404142226.jpg

Now add the next test case for checking IBAction method. The below method checks whether addButton call selector method addNumbers on UIControlEventTouchUpInside.

-(void)testAddButtonCheckIBAction {

NSArray *actions = [viewController.addButton actionsForTarget:viewController

forControlEvent:UIControlEventTouchUpInside];

XCTAssertTrue([actions containsObject:@”addNumbers:”], @””);

}

Add this method to RSViewController.m and link this to touchUpInside event of addButton.

-(IBAction)addNumbers:(id)sender {

  

}

Then add the below test cases for checking the addition of two numbers.

-(void)testAddingTenPlusTwentyShouldBeThirty {

viewController.firstNumberTextField.text = @”10″;

viewController.secondNumberTextField.text = @”20″;

[viewController.addButton sendActionsForControlEvents: UIControlEventTouchUpInside];

XCTAssertEqualObjects(viewController.resultTextField.text,@”30″,”Result of the textfield should be 30″);

}

Make changes to the addNumbers method in RSViewController.m by calling application logic method in Addition.m

-(IBAction)addNumbers:(id)sender {

RSAddition *addition = [[RSAddition alloc] init];

NSInteger result = [addition addNumberOne:[self.firstNumberTextField.text integerValue] withNumberTwo:[self.secondNumberTextField.text integerValue]];

self.resultTextField.text = [NSString stringWithFormat:@”%d”,result];

}
Now repeat the test cases for reset button which clears all the textfields.

-(void)testResetButtonConnection {

XCTAssertNotNil([viewController resetButton], @”reset button should be connected”);

}

-(void)testResetButtonCheckIBAction {

NSArray *actions = [viewController.resetButton actionsForTarget:viewController

forControlEvent:UIControlEventTouchUpInside];

XCTAssertTrue([actions containsObject:@”resetFields:”], @””);

}

-(void)testResetButtonShouldClearFields {

viewController.firstNumberTextField.text = @”10″;

viewController.secondNumberTextField.text = @”20″;

viewController.resultTextField.text = @”30″;

[viewController.resetButton sendActionsForControlEvents: UIControlEventTouchUpInside];

XCTAssertEqualObjects(viewController.firstNumberTextField.text, @””, @”FirstNumber textfield should be empty”);

XCTAssertEqualObjects(viewController.secondNumberTextField.text, @””, @”SecondNumber textfield should be empty”);

XCTAssertEqualObjects(viewController.resultTextField.text, @””, @”Result textfield should be empty”);

}

And the corresponding changes to the user interface and RSViewController.m file

-(IBAction)resetFields:(id)sender {

self.firstNumberTextField.text = @””;

self.secondNumberTextField.text = @””;

self.resultTextField.text = @””;

}

Though lot more test cases can be added, I believe this is a decent starter project for learning TDD in iOS. And it is always nice to see the green mark in test navigator.
201404142302.jpg
Now you should be able to run your app and test the functionality.

201404142303.jpg
Source code can be downloaded from here

Filed Under: ios, iPhone, Xcode Tagged With: TDD, User Interface, Xcode, XCTest

Test Driven Development in iOS – Beginners tutorial – Part 1

April 13, 2014 By Ravi Shankar 7 Comments

This is a beginner tutorial on TDD in iOS, explained with an example app that adds two numbers. Let us see try to use some XCTest assertions supported in iOS in this project.

Create a New iOS project select the template as Empty Application

201404132059.jpg

Enter the required details in Choose options for your new project screen.

201404132104.jpg

Step 3: Then specify the folder to save this project.

201404132106.jpg

The project navigator screen will have two targets, one for app and add another for XCTest framework. The folder that ends with “Tests” will contain the default XCTest file .

Lets use the class AddingTwoNumbersTests.m for testing the application logic. Open AddingTwoNumbersTests.m and delete default testExample method.

201404132127.jpg

Create a failing method that tests for existence of new “RSAddition” class that is going to have method for adding two numbers.

201404132155.jpg  

You should notice the errors displayed in the above screenshot after adding testAdditionClassExists. To fix these error, create a new class named RSAddition subclass of NSObject and add the class to both the targets. Then import the Addition.h in “AddingTwoNumbersTests.m”.

201404132152.jpg

201404132153.jpg

Now the tests should pass when it gets executed. You should notice the green tick mark before the class and method and shown in the below screenshot.

201404132158.jpg

Now add the following method to do a simple addition of 2+2.

-(void)testAddTwoPlusTwo {

RSAddition *addition = [[RSAddition alloc] init];

NSInteger result = [addition addNumberOne:2 withNumberTwo:2];

XCTAssertEqual(result, 4, @”Addition of 2 + 2 is 4″);

}

RSAddition class needs to have a new method addNumberOne: withNumberTwo: Add the method definition in RSAddition.h interface file.

-(NSInteger)addNumberOne:(NSInteger) firstNumber withNumberTwo:(NSInteger) secondNumber;

Then add the following method to RSAddition.m implementation file. Let us hardcode the result “4” for time being to pass this test.

-(NSInteger)addNumberOne:(NSInteger) firstNumber withNumberTwo:(NSInteger) secondNumber {

return 4;

}

Now the test should get executed successfully.
201404132209.jpg
Let us add another test to fix the hardcoding problem. This time we will add two different numbers 2 and 7. But before adding the test method, we need to refactor the existing code in the test file. The below code is used by both the test methods and this is the best candidate to be placed under setup method.

  RSAddition *addition = [[RSAddition alloc] init];

The changed code should look as shown in the below screenshot.

201404132223.jpg

Adding the below method should fail as the addition method is hardcoded to return value as 4.

-(void)testAddTwoPlusSeven {

NSInteger result = [addition addNumberOne:2 withNumberTwo:7];

XCTAssertEqual(result, 9, @”Addition of 2 + 7 is 9″);

}

201404132226.jpg

Now edit the addition method to fix this problem. It requires just a one line change and now the test should pass.

201404132229.jpg

201404132231.jpg

The next tutorial will cover the steps for adding the view controller and required fields for adding two numbers using the above added application logic class.

Download source code from here.

Filed Under: ios, iPhone, Xcode Tagged With: Assertions, iOS, TDD, Xcode, XCTest

How to disable arc for specific classes in Xcode

February 4, 2014 By Ravi Shankar 1 Comment

Xcode provides option to disable arc only for specific classes by providing a compiler flag. This is quite useful when you are including framework written prior to iOS 5 in your project. Let us see the steps required for specifying the compiler flag in Xcode.

ARC errors in Xcode

In the above screenshot, you can see errors rested ARC restrictions for NSStream+ SKSMTPExtensions.m class file. You can resolve this error by providing the compiler flag -fno-objc-arc for this class.

201402041850.jpg

Click the Project on Xcode then Build Phases tab. Navigate to Compile Sources section and double click on Compiler flags for the corresponding file. Now enter the flag “ -fno-objc-arc” as shown in the below screenshot.

disable ARC in Xcode

This should resolve all the compilation related with ARC.

Filed Under: Apple, ios, Xcode Tagged With: Apple, disable ARC, Xcode

Quickly copy photos in to photos album in iOS Simulator

January 10, 2014 By Ravi Shankar Leave a Comment

Photos Album in iOS Simulator is generally empty and if you are writing apps using Photos functionality then you might need some photos in them. Listed below are the steps for placing photos under the Photos Album in Simulator.

Step 1: Access the Home screen on iOS simulator. (Hardware > Home)

Access Home Screen on iOS Simulator

If you tap Photos then you should see “No Photos or Videos” message.

No Photos or Videos

Step 2: Now tap Safari icon on your Home screen.

Step 3: Open Finder window, locate the image that you want to copy then drag and drop the image on to Safari browser.

Step 4: Right click and hold for some time until you see the action sheet with an option to Save Image.

Save Image on Simulator

Navigate back to Home screen, tap the Photos option and this should show display the recently added Photo.

Photo Album on Simulator with Photos

Filed Under: ios, iPhone, Xcode Tagged With: iOS, iOS Simulator, Photos Album, Xcode

Simple UITableView and UIAlertView example

January 9, 2014 By Ravi Shankar 1 Comment

In this article, we are going to see how to create a simple UITableView for displaying data. And display an alert on selection of any row using UIAlertView.

Launch Xcode, Click File > New Project and select Single View Application as the project template.

Choose a template for new new project

Enter the project details for Product Name, Organization Name, Company Identifier and Target device as iPhone.

201401091129.jpg

Then choose a location on your Mac to save the project.

201401091131.jpg

Navigate to Main.Storyboard and and delete the ViewController under View Controller Scene. Since we want a TableView, we are going to replace this View Controller with UITableViewController.

201401091134.jpg

Note :- We could have also used UITableView on top of View Controller but we will keep that for another session.

Now select UITableViewController from the Object library, drag and drop it on to the User Interface.

201401091141.jpg

Let us see the how to display list of values in the above table.

Navigate to ViewController.h in the Project Navigator and replace the following line

@interface ViewController : UIViewController

with

@interface ViewController : UITableViewController

Then use the Identity Inspector and specify the class for TableViewController as ViewController.

201401091146.jpg

Edit ViewController.m file and add a new instance variable and populate the cities in ViewDidLoad method.

@implementation ViewController

{

NSArray *cities;

}

– (void)viewDidLoad

{

[super viewDidLoad];

  

//Create the list of cities that will be displayed in the tableview

  

cities = [[NSArray alloc] initWithObjects:@”Chennai”,@”Mumbai”,@”New Delhi”, @”New York”, @”London”,@”Tokyo”,@”Stockholm”,@”Copenhagen”,@”Manchester”,@”Paris”,nil];

}

In the above code, cities is of type NSArray and it is initialised with set of values in the ViewDIdLoad method. These values will be displayed in the UITableView.

The ViewController will act as a delegate and datasource for the UITableViewController. These connections are automatically created and you can verify them by right clicking on the ViewController. If we had used UITableView instead of UITableViewController then these connections have to be made manually.

201401091202.jpg

The data for the tableview is provided by the following methods and these methods needs to be implemented in ViewController.m.

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

numberOfRowsInSection method is used for specifying the total rows in each section for the tableview. In this example, the UITableView has only one section for displaying the cities.

cellForRowAtIndexPath method is used for providing the data to each row in the TableView. The data is populated using the indexPath for each row.

Copy the method implementation to ViewController.m file

-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section

{

return [cities count];

}

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

{

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@”Cities”];

  

cell.textLabel.text = [cities objectAtIndex:indexPath.row];

  

return cell;

}

The numberOfRowsInSection provides the tableview with the total count of rows i.e number of items in the cities array object. In the cellForRowAtIndexPath, we create a reusable UITableViewCell and assign the cities as per the row indexPath. Also make sure to specify the Identifier for prototype cell (User Interface) as Cities using the Attributes Inspector.

Now if you build and run the project, you should see a table with list of cities as shown below.

201401091307.jpg

Display the row selection using UIAlertView

Nothing will happen when you select any of the rows in the above table. Let us use the UIAlertView to display the row selection and for this we need to implement didSelectRowAtIndexPath in ViewController.m. Add the following didSelectRowAtIndexPath method implementation to the file.

-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath

{

NSString *cityName = [cities objectAtIndex:indexPath.row];

  

UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@”City” message:cityName delegate:self cancelButtonTitle:@”Cancel” otherButtonTitles:nil, nil];

  

[alertView show];

}

The above code first retrieves the city name from cities array object using the row’s indexPath. In the second line, we create a instance of UIAlertView with title as “City”, selected city for the message attribute and provide the title for the cancel button. The delegate for UIAlertView will be ViewController and this specified by the delegate attribute. In the last line we use the show method to display the alert.

UITableView showing UIAlertView

Download the source code from here.

Filed Under: Develop, ios, iPhone, Programming, Xcode Tagged With: iOS, iphone, UIAlertView, UITableView, Xcode

How to change page scaling in Xcode

August 15, 2013 By Ravi Shankar Leave a Comment

Xcode provides option to increase or decrease the page scaling. This page scaling option is available as part of the Page Setup. This feature is quite useful when you want reduce the number of pages used for printing any Objective-C code.

201308152115.jpg

The default page scale is set to 100% and you can change this by following the below mentioned steps.

Click File menu and select Page Setup from the menu list.

201308152110.jpg

This should display the following Page Setup screen.

201308152112.jpg

Navigate to the Scale option and change the default value from 100% to say 50%. Then click OK button to confirm and save the changes. Now when you go to print preview screen (Xcode File menu -> Print), you should notice the effect of reduced Scale changes.

201308152118.jpg

Filed Under: Apple, Develop, ios, Xcode Tagged With: Apple, page scale, page setup, Print, Xcode

  1. Pages:
  2. «
  3. 1
  4. 2
  5. 3
  6. 4
  7. 5
  8. »
« 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