Archive for the ‘objective-c’ Category.

Thank you MacInCloud for my “A” in my iOS course

I was provided service for this post. I was in no other way compensated. All opinions are my own.

As many of you know, I am getting a Masters of Computer Science from Utah State University. I am taking classes remotely in the evenings. When it came time to take a course in iOS development, I had some problems I needed to resolve.

  1. I don’t own an computer with an Apple Operating System.
  2. You can only compile code for iOS on OS X.

macincloud_homeSo I started considering investing in a Mac laptop, but it was too pricey of an option.  Sure as I am already well into my career as a Senior Software Engineer, I could afford it, but just because I have money doesn’t mean I want to waste it. I already have a nice Lenovo T530 from work. I have an older Lenovo T61p that I own (mostly a paperweight since I never use it). I have a nice HP desktop, and my wife has a nice HP laptop. What would I do with another computer?

I looked at a Mac mini and even it was too pricey, so I started looking at used ones. But no matter what I purchased, it was too much money for something that, as a Senior .NET Developer, I likely wouldn’t use once the class was over.

Then I found MacInCloud. MacInCloud is exactly what it sounds like. A Mac in the cloud. I could remote desktop to this Mac and write and compile my iOS apps for my class. With academic plans starting at $16 a month, I couldn’t pass it up.

Well, I used MacInCloud exclusively throughout my iOS course and I am happy to say I got an A. I want to personally thank this company for existing. Some members of my class did pay for the service. I probably should have gotten some feedback from some of them, but they were on-campus and I am a remote student so I didn’t make the effort.

MacInCloud Pros

  1. Everything I need was already on the box: Xcode, iOS emulator. If I had purchased my own Mac, I would have spend a few hours setting it up, including installing the development tools. But with MacInCloud, those tools were already there.
  2. The remote control was for the most part quite fast.
  3. I used Dropbox and stored my files in a Dropbox folder, so everything I wrote automatically synced to my personal machine.
  4. MacInCloud was the cheapest solution by a long ways. In fact, with the price of a nice Mac laptop, I could pay for MacInCloud’s service for close to two years.

MacInCloud Cons

  1. Well, it is in the cloud, so it has the same con that everything in the cloud has. When my internet was down, I couldn’t use it. My cable modem needed to be reset a few times and one day Comcast’s service was really bad (less that .5 Mb down one day).
  2. I couldn’t get the remote control screen to autofit to the size of my local screen.
  3.  The refresh of the screen wasn’t perfect through remote control. Sometimes I had to move a window to get the contents to refresh.

Would I recommend MacInCloud?

Yes. The con’s didn’t prevent me from getting an A in my iOS course. I would recommend it to anybody.

About 18 months ago, my company had a Mac training and didn’t have enough Macs. This service probably existed and if my company had known about it, we probably would have bought a dozen developers a month or two of service.

iOS – Simple trick to allow typing string instead of NSString

So it drives me crazy to type string in C#, then try to type NSString in objective-c. This is a simple fix and for a while, I didn’t think about it, then it hit me: typedef.

I opened the -Prefix.pch file and added the following line:

typedef NSString string

Yes, it was that easy. Now I can type string instead of NSString.

Objective-c for iOS Cheat Sheet

This Objective-c for iOS Cheat Sheet is written for my midterm for my Masters of Computer Science course on iOS Mobile Development. The class didn’t fill up like I thought it should. Perhaps that has to do with the fact that the class name was misspelled as ISO Mobile Development. Oops.

Creating an objective-c class

  1. All objects should inherit NSObject which is found in Foundation.h.
  2. Objects should be created in the following two files.
#import <Foundation/Foundation.h>
@interface MyObject : NSObject
@end
#import "MyObject.h"
@implementation MyObject
@end

Adding a local variable to an objective-c class

A variable is added to the .h file that is only used by the code in the .m file.

#import <Foundation/Foundation.h>
@interface Person : NSObject
{
    string name;
}
@end
#import "Person.h"
@end

Adding a property to an objective-c class

A property is a short cut for a variable wrapped in a getter and setter.

  1. Add an @property line in the .h file as shown below.
  2. Add an @synthesize line for the property in the .m file as shown below.
#import <Foundation/Foundation.h>
@interface Person : NSObject
@property string name;
@end
#import "Person.h"
@implementation Person 
@synthesize name;
@end

Adding a method to an objective-c class

Here is an example of two methods:

  1. a method without a parameter
  2. a method with two parameters.

In many other languages, these methods signatures would look as follows:

double getPI();
double add(double x, double y);

In ojbective-c, the methods look like this:

#import <Foundation/Foundation.h>
@interface calc: NSObject
-(double)getPI;
-(double)multiply:(double) x and: (double) y;
@end
#import "calc.h"
@implementation calc
-(double)getPI
{
    return 3.14159265359;
}

-(double)multiply:(double) x and: (double) y
{
    return x * y;
}
@end

Now you call the methods different than other languages, too.

double pi = [myCalc getPI];
[myCalc add:1 and: pi;

Overriding the getter for the description property

Add the following method to your .m file. Inheriting NSObject already provides the method signature so nothing needs to be added to the .h file.

-(NSString *)description
{
    return @"Your custom description here";
}

Using NSString stringWithFormat

In many languages you can write a string with tokens inside it and just replace the token. You can do this in objective-c as well.

// cart.items is an integer
return [NSString stringWithFormat:@"You have @d items in your cart.", cart.items];
// cart.total is a double and since it is money, you only want to show
// two characters
return [NSString stringWithFormat:@"Total: %.2f", cart.Total];

Any object that is not a primitive, such as NSString, uses %@.

// account.username is an NSString
return [NSString stringWithFormat:@"Welcome %@", account.username];

Adding a UI Element (Label, TextBox, Button)

  1. You use the UI editor to add an the elements to the UI.
  2. Then you create a variable for each element.
  3. Then you link the field to the element in the xib.
#import <Foundation/Foundation.h>
@interface PersonViewController: UIViewController
{
    IBOutlet UILabel *nameLabel;
    IBOutlet UITextField *nameTextField;
    IBOutlet UIButton *submitNameButton;
}
@end
#import "PersonViewController.h"
@implementation PersonViewController
@end

Notice nothing is in the .m file. Of course, you could add these variables as properties and then you would an @synthesize call for these variables in the .m file.

Adding an event for clicking a button

This is pretty much the same as adding a method to an objective-c class. The only difference is you attach this method to a button in the xib.
Note: The button variable doesn’t really matter, it can by a property or just a member.

#import <Foundation/Foundation.h>
@interface PersonViewController: UIViewController
@property (nonatomic) IBOutlet UIButton *submitNameButton;
-(IBAction)buttonPressed:(id)sender;
@end
#import "PersonViewController.h"
@implementation PersonViewController
-(IBAction)buttonPressed:(id)sender
{
    // Button code here
}
@end

Wrap a ViewController in a UINavigationController

In AppDelegate.m, change the default application method to look as follows:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
   
    ViewController *viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    UINavigationController *navCtrl = [[UINavigationController alloc] initWithRootViewController: viewController];
    self.window.rootViewController = navCtrl;
    
    [self.window makeKeyAndVisible];
    return YES;
}

Add Buttons to the top bar (UIBar)

        // Setright bar button
        UIBarButtonItem * rightBarButton = [[UIBarButtonItem alloc]initWithTitle:@"Summary" style:UIBarButtonItemStyleBordered target:self action:@selector(summaryButton:)];
        self.navigationItem.rightBarButtonItem = rightBarButton;
        
        // Set left bar button
        UIBarButtonItem *leftBarButton = [[UIBarButtonItem alloc]initWithTitle:@"Map" style:UIBarButtonItemStyleBordered target:self action:@selector(mapButton:)];
        self.navigationItem.leftBarButtonItem = leftBarButton;

Launch a ViewController

If you have a UIViewController called MapViewController, you can launch it as follows.

    MapViewController *mapVC = [[MapViewController alloc] initWithNibName:@"MapViewController" bundle:nil];
    [[self navigationController] pushViewController:mapVC animated:YES];

Launch a ViewController and pass it data using a property

This passes a property called database into the SummaryViewController.

    SummaryViewController *summaryVC = [[SummaryViewController alloc] initWithNibName:@"SummaryViewController" bundle:nil];
    summaryVC.database = self.database;
    [[self navigationController] pushViewController:summaryVC animated:YES];

Other ways to pass it a property include:

  1. Using a custom init method such as initWithDatabase.
  2. Using a segue.

Get current date and time as string

NSString* currentTimeAsString()
{
    NSDate *date = [NSDate date];
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
    [dateFormat setDateFormat:@"d MMM YYYY, h:mm a"];
    NSString *dateString = [dateFormat stringFromDate:date];
    return dateString;
}

Using a UITabBarController

Change the application method in the AppDelegate.m file.

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    
    UITabBarController *tabBarController = [[UITabBarController alloc] init];
    UIViewController *mileageView = [[MileageViewController alloc] init];
    UIViewController *mapView = [[MapViewController alloc] init];
    
    NSArray *controllers = [NSArray arrayWithObjects:mileageView, mapView, nil];
    [tabBarController setViewControllers:controllers];
    
    self.window.rootViewController = tabBarController;
    [self.window makeKeyAndVisible];
    return YES;
}

Add image to TabBarItem

In the ViewController that is added as part of an array to the TabBarItem, override the iniWithNibName method as follows:

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self)
    {
        UITabBarItem *tbi = [self tabBarItem];
        tbi.Title = @"Contacts";
        tbi.Image = [UIImage imageNamed:@"Contact-image.png"];
    }
    return self;
}

Map

Change the map view type.
-(IBAction) changeMap
{
    if (mapView.mapType == MKMapTypeStandard)
    {
        mapView.mapType = MKMapTypeSatellite;
    }
    else
    {
        mapView.mapType = MKMapTypeStandard;
    }
}

Update the user location on a map.

-(void)mapView:(MKMapView *)map didUpdateUserLocation:(MKUserLocation *)userLocation
{
    MKCoordinateRegion region;
    coord = userLocation.coordinate;
    // Start
    region = MKCoordinateRegionMakeWithDistance(coord, START_LATITUDE_SIZE, START_LONGITUDE_SIZE);
    
    [mapView setRegion:region animated:YES];
}

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

TextBox resignFirstResponder

How to sort an NSArray

http://developer.apple.com/library/ios/documentation/Cocoa/Reference/Foundation/Classes/NSArray_Class/NSArray.html#//apple_ref/occ/instm/NSArray/sortedArrayHint

Categories (iOS version of Extension Methods in C#)

If an object is missing a method you think it should just have, such as NSDate returning the date in a specified format, you can simply create that method as follows and then use it anywhere you import the .h file.

#import <Foundation/Foundation.h>
@interface NSDate (DateExtender)
-(NSString *)getDateWithFormat:(NSString *)format;
@end
#import "DateExtender.h"
@implementation NSDate (DateExtender)
-(NSString *)getDateWithFormat:(NSString *)format
{
    NSDateFormatter *dateFormat = [[NSDateFormatter alloc]init];
    [dateFormat setDateFormat:format];
    return [dateFormat stringFromDate:self];
}
@end

Notice the class name is the same as the object you wish to extend: NSDate.
Notice there is a group name in paranthesis.

UITable

NSTimer

see Notice project.

Use a plist

see car project.