Wednesday, November 21, 2012

Some Coding Concepts




NSData General

Convert NSData To String

        NSString *MyString = [[NSString alloc] initWithData:MyData encoding:NSUTF8StringEncoding];



        [MyString release];

Convert String To NSData

        NSData *data = [myString dataUsingEncoding:NSUTF8StringEncoding];

Length

        if (data.length > 0)

Accessing Individual Bytes

        UInt8 *bytes = (UInt8 *)data.bytes;
        if (data.length >= 4)
                NSLog(@"Byte0: %d, Byte1: %d, Byte2: %d, Byte3: %d", bytes[0], bytes[1], bytes[2], bytes[3]);

Create NSData From File

        NSData *data = [NSData dataWithContentsOfFile:filePath];

Create NSData From String

        NSData *TxData = [@"Hello World" dataUsingEncoding:NSUTF8StringEncoding];

Create NSData From Byte Array

        UInt8 TxDataBytes[10];
        int TxDataIndex = 0;

        TxDataBytes[TxDataIndex++] = 0x01;
        TxDataBytes[TxDataIndex++] = 0x02;
        TxDataBytes[TxDataIndex++] = 0x03;
        TxDataBytes[TxDataIndex++] = 0x04;

        NSData *TxData = [NSData dataWithBytes:&TxDataBytes length:TxDataIndex];

Copy Data To Array

        NSMutableArray *ReceivedData = (NSMutableArray *)[data bytes];


Activity Indicator General




Drag onto window and place as requried
Select and turn on ‘Hide When Stopped’ from it’s properties.
Declare in #ViewController.h
        IBOutlet UIActivityIndicatorView *activityIndicator;
In #ViewController.m
//If view could be unloaded
//********** VIEW DID UNLOAD **********
- (void)viewDidUnload
{
        [super viewDidUnload];

        [activityIndicator release];
        activityIndicator = nil;
}

//********** DEALLOC **********
- (void)dealloc
{
        [activityIndicator release];

        [super dealloc];
}

To turn on and off


        [activityIndicator startAnimating];

        [activityIndicator stopAnimating];

Message Box (Action Sheet) General




Show a main window message box

Alert View will automatically adjust for landscape orientation
                UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"The username and password entered are not valid"
                                                                                                                message:nil
                                                                                                           delegate:nil
                                                                                                cancelButtonTitle:@"OK"
                                                                                          otherButtonTitles:nil];
                [alert autorelease];
                [alert show];

Show A Message Box

ActionSheet doesn’t auto adjust for landscape orientation
        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"A Message To Display"
                                                                                                                        delegate:nil
                                                                                                   cancelButtonTitle:@"OK"
                                                                                           destructiveButtonTitle:nil
                                                                                                        otherButtonTitles:nil];
        [actionSheet showInView:[[self view] window]];
        [actionSheet autorelease];

OK Cancel Message Box

In your method that want’s to show the action box
        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"A Message To Display"
                                                                                                                         delegate:self
                                                                                                        cancelButtonTitle:@"Cancel"
                                                                                           destructiveButtonTitle:@"OK"
                                                                                                        otherButtonTitles:nil];
        [actionSheet showInView:self.view];
        [actionSheet autorelease];
Add the delegate to the classes @interface
@interface #ViewController_iPhone : UIViewController
                        <UIActionSheetDelegate>
{
Add the delegate method
//*******************************************
//*******************************************
//********** ACTION SHEET DELEGATE **********
//*******************************************
//*******************************************
- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex
{
        // the user clicked one of the OK/Cancel buttons
        if (buttonIndex == [actionSheet destructiveButtonIndex])
        {
                //----- CLICKED OK -----

        }
        else if (buttonIndex == [actionSheet cancelButtonIndex])
        {
                //----- CLICKED CANCEL -----

        }
}

Multiple Buttons

        UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:@"A Message To Display"
                                                                                                                         delegate:self
                                                                                                        cancelButtonTitle:@"Cancel"
                                                                                           destructiveButtonTitle:nil
                                                                                                        otherButtonTitles:@"Test1",@"Test2",nil];
        [actionSheet showInView:self.view];
        [actionSheet autorelease];
In the actionSheet delegate the buttonIndex starts from 0 being the top most button. If there is a destructiveButtonTitle then this is 0 otherwise it is the first otherButtonTitle.




Downloading a file




Example of downloading a file and saving it in a directory in Documents

In the .h file

@interface AppMain : NSObject
                        //-ADD THIS DELEGATE
{
        FileDownloader *fileDownloader1;        //-ADD THIS
In the .m file
//********** DOWNLOAD FILE **********
- (void) SomeMethodName
{
        NSLog(@"STARTING DOWNLOAD");

        if (!fileDownloader1)
                fileDownloader1 = [[FileDownloader alloc] init];

        [fileDownloader1 setDelegate:self];

        [fileDownloader1 DownloadFile:@"http://www.somedomain.com/somefile.html"];
}

//********** FILE DOWNLOAD FINISHED CALLBACK **********
- (void)FileDownloadFinished:(NSData *)file
{
        NSString *filePath;
        NSError *error;

        NSString *path;
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        path = [[paths objectAtIndex:0] stringByAppendingPathComponent:@"OurFiles"];

        //Create a new cache directory
        if (![[NSFileManager defaultManager] createDirectoryAtPath:path
                                                                   withIntermediateDirectories:NO
                                                                                                        attributes:nil
                                                                                                                         error:&error])
        {
                NSLog(@"Create directory error: %@", error);
        }

        //Save the file
        filePath = [path stringByAppendingPathComponent:@"somefile.html"];

        [[NSFileManager defaultManager] createFileAtPath:filePath
                                                                contents:file
                                                                attributes:nil];
}


Edit Free Disk Space


Based on the example at http://iphoneincubator.com/blog/device-information/how-to-obtain-total-and-available-disk-space-on-your-iphone-or-ipod-touch
//*****************************************
//*****************************************
//********** GET FREE DISK SPACE **********
//*****************************************
//*****************************************
-(float)GetFreeDiskSpaceInBytes
{
    float totalSpace = 0.0f;
    NSError *error = nil;
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    NSDictionary *dictionary = [[NSFileManager defaultManager] attributesOfFileSystemForPath:[paths lastObject] error: &error];  

    if (dictionary)
        {
        NSNumber *fileSystemSizeInBytes = [dictionary objectForKey: NSFileSystemFreeSize];              //Or NSFileSystemSize for total size
        totalSpace = [fileSystemSizeInBytes floatValue];
    }
        else
        {
        NSLog(@"Error Obtaining File System Info: Domain = %@, Code = %@", [error domain], [error code]);
    }  

    return totalSpace;
}

Methods General


No Argument Methods

Declaring The Method
- (void)SomeMethodName;
Coding The Method
- (void)SomeMethodName
{

}
Calling The Method
        [self SomeMethodName];

Single Argument Methods

Declaring The Method
- (int)SomeMethodName:(int)Value1;
Coding The Method
- (int)SomeMethodName:(int)Value1
{

        return 18;
}
Calling The Method
        [self SomeMethodName:34];

Multiple Argument Methods

Declaring The Method
- (void)FileDownloaderCallback:(NSMutableData *)FileData
                                          fileURL1:(NSString *)fileURL;
Coding The Method
- (void)FileDownloaderCallback:(NSMutableData *)FileData
                                          fileURL1:(NSString *)fileURL
Calling The Method
        [self FileDownloaderCallback:fileData fileURL1:DownloadingFileURL];

Memory General


Variable & Object Types

BOOL
Values:- YES, NO
NSLog(@”The answer is %i”, MyValue);
char
UInt8
int
32bits (currently unless the iPhone ever moves to a 64bit chipset).  If you want to future protect pointers for a 64bit system you can use NSInteger instead.
NSLog(@”Value = %i”, MyValue);
long long / unsigned long long
float
NSLog(@”Value = %f”, MyValue);
double
NSLog(@”Value = %f”, MyValue);
NSString
NSDate
NSObject
Most classes in Objective-C are derived from NSObject:
    NSObject *object;
    object = [[NSObject alloc] init];
    NSLog(@"object = %@", object);
    [object release];
id
You may be working with an object but you are not sure what that object will be when the code executes. The id variable can be used as a sort of placeholder for any object. It is often used in the Cocoa-Touch frameworks and it is one of the things that contributes to the powerful flexibility of the Objective-C programming language.
    id someObject;
    someObject = object;
    NSLog(@"some object = %@", someObject);
Currency
A good way is to use NSNumber and NSNumberFormatter together so that the currency will always be localized for whatever country the device is in.
        NSNumber *MyValue = [NSNumber numberWithFloat:29.99];
        NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init];
        numberFormatter.numberStyle = kCFNumberFormatterCurrencyStyle;
        NSLog(@"The cost is %@", [numberFormatter stringFromNumber:MyValue]);
        [numberFormatter release];

static

Use static as for normal C to declare static variables:
        static NSString *SomeStringName;

self (this)

self is the address of the object running the current method.  It’s like ‘this’ in VC++.  Typically it’s used so that an object can send a message to itself:
        [self SomeMethodName];

super

super is used when you want to send a message to the self, but in it’s super class (instead of th method being looked for in the local class first):
        [super SomeMethodName];

Using NSMutableString


Mutable vs. Immutable Strings
NSMutableString – Should be used when you are physically changing the value of an existing string, without completely discarding the old value (i.e. adding a character to the beginning or end, modifying a character in the middle etc).
NSString – Can never be changed after it has been created, only overwritten with a completly new string.  Most NSStrings (including @”Constant Strings”) are autoreleased.  NStrings occupy a fixed number of bytes in memory and are the most efficient.
NSLocalizedString – Return a localized version of a string

General

NSMutableString is a subclass of NSString. So any method which can take an NSString can also take an NSMutableString.

Create A NSMutableString

Examples:
        NSMutableString *MyStringName;
        MyStringName = [[NSMutableString alloc] init];

        //Remember to release
        [MyStringName release];

Set NSMutableString Value

    NSMutableString *MyStringName = [NSMutableString stringWithFormat:@"some text"];
    //or
    [MyStringName setString:@"new text"];    //Actually set the string value

    //BEWARE OF THIS!!
    MyStringName = SomeOtherNSMutableString;
    //This sets the pointer to another string object  - don't use it!!  This is a classic cause of bugs where you think you are writing text values but actually you are just updating the pointer, made worse by this not having requried "alloc] init]" to have been used causing unexplainable null value errors when you do decide to use setString!

Append To String

        [MyStringName setString:@"abcd"];
        [MyStringName appendString:SomeOtherStringName];

Does NSMutableString Equal

    //Test for is equal
    if ([MyStringName isEqualToString:@"SomeText"])

    //Test for NOT equal
    if (![OriginalMediaFileName isEqualToString:@""])

Convert Strings

        myString = [myString lowercaseString];
        myString = [myString capitalizedString];


Add Variable to String

    [TempString setString:[NSString stringWithFormat:@"%d days ago ", days]];

Retain



Using NSString


Mutable vs. Immutable Strings
NSMutableString – Should be used when you are physically changing the value of an existing string, without completely discarding the old value (i.e. adding a character to the beginning or end, modifying a character in the middle etc).
NSString – Can never be changed after it has been created, only overwritten with a completly new string.  Most NSStrings (including @”Constant Strings”) are autoreleased.  NStrings occupy a fixed number of bytes in memory and are the most efficient.
NSLocalizedString – Return a localized version of a string

Guides

iOS Developer

Create A NSString

    //Create a string
    NSString *MyStringName1 = @"Hello";

    //Create new NSString from another string
    NSString *MyStringName2 = [MyStringName1 stringByAppendingString:@", world!"];

Create NSString From Part Of NSString

    NSString *source = @"0123456789";
    NSString *firstFour = [source substringToIndex:4];
    // firstFour is @"0123"

    NSString *allButFirstThree = [source substringFromIndex:3];
    // allButFirstThree is @"3456789"

    NSRange twoToSixRange = NSMakeRange(2, 4);
    NSString *twoToSix = [source substringWithRange:twoToSixRange];
   // twoToSix is @"2345"

Modifying a NSString

Use stringByAppendingString:
This adds a string to an existing one and returns a new string. (Underneath NSString copies the old string to a new larger memory location, adds the argument and returns the new string.

    NSString *MyString;
    MyString = [[MyArray objectAtIndex:0] stringByAppendingString:@"1234"];
    MyString = [MyString stringByAppendingString:@"5678"];

Add Variable to String

    TempString = [NSString stringWithFormat:@"%d days ago ", days]];

    if ([MyStringName length] > 0)

Convert String To Variable

    MyIntValue = [MyString intValue];      //Will equal 0 if string is not numeric

    MyBoolValue = [MyString boolValue];      //Converts MyString to BOOL

NSString intialisation with NSMutableString

        MyNSString = [NSString stringWithString:MyNSMutableString];
        //Doing this instead means you can now release or change MyNSMutableString without affecting MyNSString
        [MyNSMutableString release];

Does String Equal

    if ([MyStringName isEqual:@"SomeText"])
(Don’t use “==”)

Does String Contain

    if ([MyStringToCheck rangeOfString:@".mov" options:(NSCaseInsensitiveSearch)].location != NSNotFound)
    {
        //Yes it does contain string
    }

Modify The End Of A String

        NSRange EndRange = [MediaFileName rangeOfString:@".MOV"];
        if (EndRange.length > 0)
        {
                MediaFileName = [MediaFileName substringToIndex:EndRange.location];
                MediaFileName = [MediaFileName stringByAppendingString:@".mov"];
        }

Get Characters Between Markers Within String

        NSString *SourceString = @"[START]12345[END]";
        NSString *SubString;
        NSRange StartRange = [SourceString rangeOfString:@"[START]"];
        NSRange EndRange = [SourceString rangeOfString:@"[END]"];
        if ((StartRange.length > 0) && (EndRange.length > 0))
        {
                NSRange SubStringRange = NSMakeRange((StartRange.location + StartRange.length), (EndRange.location - (StartRange.location + StartRange.length)));
                SubString = [SourceString substringWithRange:SubStringRange];
        }
        else
        {
                SubString = @"";
        }

Convert Strings

        NSString *MyNewString1 = [MyOtherString lowercaseString];
        NSString *MyNewString2 = [MyOtherString capitalizedString];

Get Character In String

        if ([MyString characterAtIndex:1]  == @"2")

Remove Whitespace From String

        MyString = [MyString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

Convert NSString to ASCII value

        NSString *MyString = @"A";
        int asciiCode = [MyString characterAtIndex:0];  //=65

Convert ASCII value to NSString

        int asciiValue = 65;
        NSString *string = [NSString stringWithFormat:@"%c", asciiValue];       //="A"

Text Field General


Text fields are for single line text.  For multi line text use Text View

Delegates

textFieldShouldReturn
Keyboard return key pressed

Example Of Use

Declaring in #ViewController.h file
        IBOutlet UITextField *MyTextFieldName;
Releasing in #ViewController.m file
//********** VIEW DID UNLOAD **********
- (void)viewDidUnload
{
        [super viewDidUnload];

        [MyTextFieldName release];
        MyTextFieldName = nil;
}

//********** DEALLOC **********
- (void)dealloc
{
        [MyTextFieldName release];

        [super dealloc];
}
Connecting in Interface Builder
Add the text filed to the view
Right click Files Owner
Drag the outlet to your text field

Storing Values Entered In A Text Field

        [SomeIntVariable:[[SomeTextField text] intValue]];

Dismissing The Keyboard & Responding To Input

Open the XIB.
For each of the text fields, right click and drag the ‘delegate’ circle to ‘Files Owner’

Then in #ViewController.m:
//********** TEXT FIELD SHOULD RETURN **********
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
        [textField resignFirstResponder];
        return YES;
}
If you have any methods in #ViewController.m that want to ensure the keyboard is removed:
//********** VIEW WILL DISAPPEAR **********
- (void)viewWillDisappear:(BOOL)animated
{
        [super viewWillDisappear:animated];

        [[self view] endEditing:YES];           //Ensure keyboard is removed
}


TextView General


TextView is the same as TextField apart from TextView allowing multi-line editing.  A TextView’s Return key enters the newline character whereas a TextField’s return key dispatches the delegate method ‘textFieldShouldReturn’.

Example Of Use

Declaring in #ViewController.h file
        IBOutlet UITextView *MyTextViewName;
Releasing in #ViewController.m file
//*************************************
//*************************************
//********** VIEW DID UNLOAD **********
//*************************************
//*************************************

- (void)viewDidUnload
{
        [super viewDidUnload];

        [MyTextViewName release];
        MyTextViewName = nil;
}

//*****************************
//*****************************
//********** DEALLOC **********
//*****************************
//*****************************
- (void)dealloc
{
        [MyTextViewName release];

        [super dealloc];
}
Connecting in Interface Builder
Add the text filed to the view
Right click Files Owner
Drag the outlet to your text field

Storing Values Entered In A Text View

        [SomeIntVariable:[[SomeViewField text] intValue]];

Dismissing The Keyboard & Responding To Input

Open the XIB.
For each of the text views, right click and drag the ‘delegate’ circle to ‘Files Owner’

Then in #ViewController.m:
//************************************************
//************************************************
//********** TEXT VIEW CHECK FOR RETURN **********
//************************************************
//************************************************
- (BOOL)textView:(UITextView *)textView shouldChangeTextInRange:(NSRange)range replacementText:(NSString *)text
{

    if ([text isEqualToString:@"\n"])           //text is the new character being added
    {
        [textView resignFirstResponder];
        return FALSE;                                           //False so the /n doesn't get added
    }
    return TRUE;
}
If you have any methods in #ViewController.m that want to ensure the keyboard is removed:
//*****************************************
//*****************************************
//********** VIEW WILL DISAPPEAR **********
//*****************************************
//*****************************************
- (void)viewWillDisappear:(BOOL)animated
{
        [super viewWillDisappear:animated];

        [[self view] endEditing:YES];           //Ensure keyboard is removed
}

Dismissing the keyboard when the user touches anywhere else (but not on another object)

- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [touches anyObject];

    if ([textView isFirstResponder] && [touch view] != textView)
    {
        //The textView is currently being edited, and the user touched outside the text view
        [textView resignFirstResponder];
    }
}

Detect Entering A Text View

//***************************************
//***************************************
//********** TEXT VIEW ENTERED **********
//***************************************
//***************************************
- (BOOL)textViewShouldBeginEditing:(UITextView *)textView
{
    if (textView == MyTextViewName)
    {
                if (DoSometingVariable)
                {
                        MyTextViewName.text = @"";
                }
    }
    return YES;
}

Set Text Colour

    //Set to RGB value
    myText.textColor = [UIColor colorWithRed:153/255.0 green:204/255.0 blue:51/255.0 alpha:1];




Timer General


In the .h file:
        NSTimer *showInfoBoxAfterDelayTimer1;
In the .m file:
                myTimer1 = [NSTimer scheduledTimerWithTimeInterval:1.5          //seconds (use decimal places if requried)
                                                                                                                                        target:self
                                                                                                                                  selector:@selector(someMethodName)
                                                                                                                                  userInfo:nil
                                                                                                                                   repeats:NO];         //NO = fire only once
                //[myTimer1 fire];  //< Use this to trigger it immediately

- (void)someMethodName
{

To Stop A Timer

    //You can use this, but if you do it to a timer that has already been invalidated you crash
        [myTimer1 invalidate];

    //This avoids that
    if ((myTimer1 != nil) && ([myTimer1 isValid]))
    {
        [myTimer1 invalidate];     //Causes release
        myTimer1 = NULL;
    }

Don’t Use This To Stop A Timer Or To Check It’s Been Released

Don’t use it even after a timers only fire event! This can cause non descript crashing bugs that can be horrible to realize are actually beind caused the release of the timer!! Use the method above not this:
        if (myTimer1)
        {
                [myTimer1 release];
                myTimer1 = nil;
        }

Web View General


Adding a simple WebView to a view

In #ViewController.h
        IBOutlet UIWebView *webView1;
In Interface Builder
Drag the Web View onto the view
Connect the webView outlet to it

Displaying an Internet URL
E.g. in #ViewController.m ViewDidLoad:
        NSString *urlAddress = @"http://www.google.com";
        NSURL *url = [NSURL URLWithString:urlAddress];
        NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
        [webView1 loadRequest:requestObj];

Setting The Zoom Level Of A Web View

        [myWebView stringByEvaluatingJavaScriptFromString:@"document. body.style.zoom = 0.5;"];

Scrolling A Web View

        int scroll=20; //Pixels to scroll
        NSString* s=[[NSString alloc] initWithFormat:@"window.scrollTo(0, %i)",scroll];
        [webView stringByEvaluatingJavaScriptFromString:s];

Displaying Rich Text In A Web View

A useful way of displaying rich text labels etc.
If you are using a webview as a label ensure you select it in the viewcontroller and turn off “user interaction enabled”, otherwise it will be dragable etc
     NSString *MyHtml = @"<html><head><title></title><style type=\"text/css\">BODY {font-family:georgia; font-size: 14px;}</style></head><body>";       //Set default font
     MyHtml = [MyHtml stringByAppendingString:@"<p>Some sample HTML text <strong>bold</strong>, <u>underlined</u>, <span style=\"color:#FF0000\">colored</span>.</p>"];
     MyHtml = [MyHtml stringByAppendingString:@"</body></html>"];       //The text to display
     [webView1 loadHTMLString:MyHtml baseURL:[NSURL URLWithString:@"http://www.google.com"]];     //The baseURL allows relative URLs within a document and can just use a dummy value
Note that even doing this is in viewDidLoad (the earliest point for a view) the web view typically won’t load until the view has been shown the first time (i.e. slid into view) – very annoying.  You can’t force a webview to load before a view is shown, so if you want to do it you have to do it programmatically:

No comments:

Post a Comment