Friday 23 May 2014

iOS Unit Testing

Challenges
  • Error 'Parse/Parse.h' file not found (Unit Testing in iOS)
    • Background: I added the following Unit Testing lines of code in appropriate sections of my RibbitTests.m file in Xcode 5 to import the view controller header file that I wanted to test.
#import "ImageViewController.h"
@property (nonatomicImageViewController *imageViewController;
#pragma mark - App Test Cases
- (void) testImageViewController{   XCTAssertNotNil(self.imageViewController@"imageViewController model was not nil");}
    • Problem: Received error message 'Parse/Parse.h' file not found 
    • Solution: 
      • Deleted Parse.framework in Xcode 5 (use Apple Finder to check that there is no Parse.framework folder still in your project directory) 
      • Re-downloaded the Parse.com iOS SDK
      • Dragged the downloaded Parse.framework folder into the Frameworks directory within Xcode 5, and ensure that you tick the following boxes (noting that the initial error message you received may have been caused because when you initially installed Parse.com's SDK, you may not have also added a tick next to RibbitTests)
      • Dragged the downloaded Parse.framework folder into the Frameworks directory within Xcode 5, and ensure that you tick the following boxes (noting that the initial error message you received may have been caused because when you initially installed Parse.com's SDK, you may not have also added a tick next to RibbitTests)
Activities @ TeamTreeHouse - 

Unit Testing for iOS (using Xcode 5 IDE) with Amit Bijlani

DONE (using Ribbit iPhone App)
  • Unit Testing { 
    • Runtime errors (insufficient type testing)
    • Logic errors (insufficient scenarios)
    • Regressions (team scenario bugs)
    • XCTest.framework { write tests that a subclasses of XCTestCase }
    • XCT Assertion types
    • Running Unit Tests
      • CMD + U { Product > Tests }
      • Re-Testing { Product > Perform Action > Test Again }
      • Method Testing { Press 'Play' Button in gutter to the left of the method }
    • Navigating Unit Tests
      • Test Navigator (in the Project Navigator)
        • Running Specific Tests { Press 'Play' Button shown on right of: }
          • Test Suite
          • Test Cases
          • Test Methods
    • Creating Tests { Press + Button in bottom left corner of Test Navigator }
      • Test Classes
      • Test Targets
    • Matching Test Case Methods with corresponding Code Methods { Assistant Editor > Click Breadcrumb Navigation bar (at top right), then scroll down and Click either:
      • Test Classes
      • Test Callers { identifies other methods that call the method, including Unit Testing methods }
    • Continuous Integration 
    • Shortcuts 
      • CMD + U  { Runs Unit Test }
      • CMD + Click { Press this combination when hovering a method to toggle between the methods location in the header and implementation files } 

Monday 12 May 2014

Post WDI - iOS Dev App (User Accounts, BaaS, Mobile Design, Parse.com Framework API, Asynchronous, Helper Methods, Git Ignore, RubyMotion)

Challenges
  • Debugged extensively trying to solve why checkmarks were appearing on currently selected cells in the table view only after clicking another different cell in the table view 
    • Solution: Incorrect method chosen when creating instance method with autocomplete, should have used didSelectRowAtIndexPath (NOT 
      didDeselectRowAtIndexPath)
Activities @ TeamTreeHouse - 

iOS Development (using Xcode 5 IDE) with Ben Jakuben

DONE Ribbit iPhone App
  • Xcode 5 Tabs for Open Files { Xcode5  > Preferences > Navigation > Double Click > Use Separate Tab }
  • View Controller Lifecycle 
    • Start App (First Time)
      1. view not exist
      2. call viewDidLoad (only called if no view controller exists in memory)
      3. call viewWillAppear 
      4. call viewDidAppear
      5. view controller appears on screen in ready state (user can view and interact)
    • Navigating Away from current ViewController
      1. call viewWillDisappear
      2. call viewDidDisappear
      3. view controller remains in memory for future use as long as memory avail
    • Start App (After First Time)
      1. skips viewDidLoad (as it already exists)
      2. call viewWillAppear
      3. call viewDidAppear
    • Typical Usage
      • viewDidLoad { use for code that only needs to run once when view first loaded (i.e. creating, loading data, config display) }
      • viewWillAppear { use to display something every time view controller displays on screen (i.e. refresh data, animation) }
  • Stack (of View Controllers) (Nav Controller maintains VC's pushed onto or pulled off the array stack above Root VC)
    • pushViewController
    • popViewController
  • Import Types (used in Header file)
    • " "   means search current project for header file
    • < >  means search certain present system paths (i.e. frameworks)
  • UITabBarController (switches between different tab areas of app) UITabBarItem
    • selectedIndex property
    • setSelectedIndex
    • badgeValue property
  • UIAlertView { [alertView show] }
  • UITableViewCellAccessoryCheckmark (or None)
    • accessoryType 
    • Prevent Scrolling Cell Reuse { explicitly set each cell only when user corresponding to current table view row is in an array to prevent reuse of cells and incorrectly mirrored checkmarks being displayed }
  • UIImagePickerController (capturing photos and videos with either Default (presented modally) or Customer implementation type )
    • Protocols { Custom View Controller created in conformance with UIImagePickerController delegate, which in turn conforms to UINavigationController delegate protocol, so when user cancels or captures images or video the system notifies the cameras delegate of the users choice }
    • presentViewController used to display the the camera view modally
    • imagePickerControllerDidCancel { delegate method of UIImagePickerController where Custom Class that we've named 'CameraViewController' is the delegate }
    • didFinishPickingMediaWithInfo { stores image info in NSDictionary with a key }
    • UIImagePickerControllerMediaType { key method constant passed in and used to retrieve different media types stored as constants as part of Mobile Core Services Framework }
      • #import <MobileCoreServices/UTCoreTypes.h> (constant values of media types obtained)
      • kUTTypeImage { image media type from Core Foundation (CF) that needs to be converted to Next Step (NS) String counterpart type of data structure using Cast (NSString *). use @properties to store images retrieved for use throughout view controller and to set it to be stored in NSDictionary key }
    • UIImagePickerControllerMediaURL { key path method constant passed in and used to retrieve local iOS internal path as a string and stored in @property defined in header (videos not stored in NSDictionary like images are) }
    • Simulator Testing with Photo Album (the iPhone camera is not available unless testing using the device so to test within the simulator using the photo album instead perform the following actions in Xcode Simulator)
      • Hardware > Home, Open Safari in Simulator, Drag a photo to Safari browser, Click the 'Share' button, Click 'Save to Camera Roll'
    • Help Menu Keywords { camera programming topics for iOS }
  • Video Player 
    • Options on iPhone
      • Default Video Player (MPMoviePlayerController)
      • Embedded Video Player
    • #import <MediaPlayer/MediaPlayer.h>
    • Media Player Framework (MediaPlayer.framework)
      • Project > Build Phases > Link Binary Libraries
  • NSTimer 
    • scheduleTimerWithTimeInterval
  • Testing 
    • respondsToSelector (check if method exists before calling it in code block)
  • Modal Control Dfn { UI of VC requiring user input before proceed with app }
    • Modal View Controller { layer over current VC, child of current VC (i.e. UIAlertView) } 
  • NavigationController (NavC) (help navigate different sections of app screen flow)
    • Set NavC for the TableVC and TabBarC { pairs NavCs with TabBarController and used to control the Manual Segues with VC, Click VC, Menu > Embed In > Navigation Controller  }
      • popToRootViewControllerAnimated
      • Remove Default Back Button Setup by NavC { self.navigationItem.hidesBackButton = YES; }
      • Remove Tab Bar  { Add method to prepareForSegue setHideBottomBarWhenPushed before VC pushed onto the stack of the workflow 
  • Segue (With)
    • VC onto NavC { CTRL+click, Drag to ViewController(VC), select Action Segue }
    • Button to VC { CTRL+click button, Drag to VC, select Action Segue }
  • Segue (Without)
    • VC onto TableVC { access VC without Segue attached to Action, CTRL+click 'yellow icon' below VC, Drag to VC, select Manual Segue }
  • Segue (Identifier)
    • Click Segue between VC, Add "Identifier" to pass Data between VCs
    • Create method to perform segue to second view controller { -(void)___ { [self perfomSegueWithIdentifier:@"<insert identifier>" sender:self]; }
  • Linking the Prototype Cell of VC in Storyboard with Class Method (Attributes Inspector > Identifier > "Cell", to match CellIdentifier in code) 
  • @property Storage { Data Source 'Weak' for Text Fields on Sign Up and Sign In forms as dependent on life of View Controller itself }
  • IBOutlet { used for Text Fields for user input, dragged to @interface using Assistant Editor View }
  • IBAction { used for Button to submit, dragged to @interface }
  • Refactoring Code { Select code for refactoring (encapsulating into separate method to comply with DRY principle) into a new Helper method and then go to Edit > Refactor > Extract > <enter name for method> 
  • Stub { i.e. - (void)___ { } }
  • API  { Application Programming Interface to interact with sub systems and third party systems i.e. UIKit and Foundation frameworks }
  • Black Box { System designed with Interfaces (i.e. sets of methods and properties defined in publicly viewable header file) clearly defined between components }
  • Web Interface { between Front-End Black Box and Back-End (i.e. Parse.com Back-end-as-a-Service (BaaS) dynamically creates what is needed in Back-End) }
  • Parse.com Framework SDK Setup { extra Frameworks required as Dependencies by Parse Framework installed per Parse.com instructions via Project > Target (Ribbit) > Build Phases (tab) > Click “Link Binary with Libraries” }
  • Parse.com API Calls { iOS Guide, iOS API
    • objectWithClassName (PFObject) (creates Parse.com database table object) saveInBackground (save data to Parse.com back-end)
    • signUpInBackgroundWithBlock (PFUser) (asynchronous multi threaded approach using Block construct set up as callback mechanism with Parse.com response, receipt and processing in block with success and error handling)
    • currentUser (PFUser) (returned value is automatically Cached on device and user session logged in)
    • logOut (PFUser)
    • loginHandler block (PFUser)
    • loginWithUsernameInBackground (PFUser)
    • findObjectsInBackgroundWithBlock (PFQuery) (block that returns array of PFObjects)
    • relationForKey (PFRelation)
    • saveInBackgroundWithBlock 
    • reloadData (method to refresh the Table View data)
    • addObject
    • saveInBackground
  • Parse.com Classes { 
    • PFObject (iOS Guide > Users)
    • PFUser
    • PFRelation  (ensures Parse.com not dealing with too much Data at once. Relations are stored in Parse.com Table Object under column (property of Class) with designated Key. PFRelation has a PFQuery property to use to retrieve data linked by relation)
    • PFQuery (retrieving and viewing data 
    • PFFile (uploading files and associate them with a message PFObject that will be )
  • Uploading Files to Parse.com
    • PFFile to upload file itself
    • PFObject uploaded separately as message Object (created dynamically at Parse.com) associated with PFFile
      • Message Object 
        • Message Contents
        • Sender
        • Recipient
      • Schemaless means not req'd to specify keys existing on each PFObject, just set KV pair and back-end stores them
    • Chaining Asynchronous Calls { upload file itself and then other details if initial asynchronous call succeeded improves UX by not delaying user }
  • Deleting Files on Parse.com
    • Options
      • RESTful API's 
      • Clean Up Files (Dashboard > Settings > Clean Up Files) { deletes all files that we have uploaded that are no longer referenced by any other objects in back-end }
  • Asynchronous Indeterminant Nature (amount of Time) of calls as data not always returned in order expected. Multiple Callback Blocks must be managed. Avoid where possible by implementing DRY principle and sharing data between methods of VC's with prepareForSegue method
  • Block { ^ (<parameters defined inside parenthesise>) { curly braces with code } }
  • Helper Methods (i.e. looping mechanism to check for friends against current user)
    • Alternative is Hash or Cache for efficiency with high volume of users 
  • Shortcuts 
    • Hidden Files (show hidden files with CMD + Shift + . }
    • Indentation CMD + ]  or CMD + [
  • Git Ignore { store API keys in .plist file using this guide https://teamtreehouse.com/forum/hiding-api-credentials-in-github-for-xcode-5-projects }
  • Mobile Design

Events:
  • ATTENDED SydInMotion - Ruby & iOS development (awesome! early stage community)
    • @fluffyjack (inspiring presentation, RubyInMotion time after exams finish mid June '14)

Curiosity:

Purchases:
  • RubyMotion a personal leap of faith inspired by SydInMotion! Now I just need to buy some coding friends...

Links:

Sunday 11 May 2014

Google Cloud Print Review

Google Cloud Print Review

  • Benefit: Wirelessly print to an existing non-wireless home printer. 
  • Setup: Install Google Chrome. Add the printer using Google Cloud Print (Beta) https://www.google.com/cloudprint/. Click the printer and Share access to it with other people who have a Gmail account. Select Google Cloud Print as the destination printer to Print (instead of a Local Printer) to from any device. Use Google Drive for added flexibility.

Wednesday 7 May 2014

Post WDI - iOS Dev App (Web View, Custom Classes, Date Formatting, Dynamic Binding, Super, Self, Segue, View Controller Stack)


Activities @ TeamTreeHouse - 

iOS Development (using Xcode 5 IDE) with Amit Bijlani (Cont'd)

DONE Building API Reader (Table View) iPhone App
  • @synthesise { replace setter and getter methods in .m file associated with @property instance variables in .h file }
  • @interface declaration { NSString *title; } (optional in latest Xcode!)
  • Scoping instance variables { only visible in Class declared within unless use getters and setters }
  • Setter method (in .h) { - (void) setTitle:(NSString *)title; }
  • Getter method (in .h) { - (NSString *) title; }
  • Setter method implementation (in .m, returns instance so use *) { - (void) setTitle:(NSString *)_title { title = _title; }
  • Getter method implementation (in .m) { - (NSString *) title { return title; } }
  • Primitive Type (i.e. int) declaration { @property (nonatomic) int views  } (not require 'strong'/'weak', etc)
  • Legibility Alternative for Primitive Type (Boolean)
.m@property (nonatomic) BOOL unread;
// alternative@property (nonatomic, getter = isUnread) BOOL unread; 

ViewControllerif (blogPost.isUnread) {   NSLog(@"%@", @"hi");}
  • Custom Class instance variable setter access approaches {
    • Dot Notation { NSString *string = blogPost.title; }
    • Convenience Constructor { NSString *string = [blogPost title];
    • Set Method { [blogPost setTitle:@"my title"]; }
  • Self 
    • directly accesses Setter and Getters of the instance variable in @interface
    • allows multiple instance vars to refer to a particular instance of a Class
    • where Class has Parent Class like NSObject, the instance of a Class ('self') needs to refer to the Parent from which it inherits properties and methods (using 'super')
  • Super { refers to Parent Class within implementation }
    • i.e. self = [super init]; // self refers to particular instance of the Class. calls Super/Parent Class to use its methods (i.e. init, dealloc, etc) to initialise instance of Custom Class
  • Customer Class { benefits in that code is more maintainable than with say NSDictionary for data }
  • Dedicated Initializers { responsible to initialize new instances of Class with data, ensures that when a Custom Class is initialized, it must have a title for example }
    • init (NSString, etc)
    • initWithObjects (NSArray, NSDictionary)
    • i.e. - (id) initWithTitle:(NSString *)someTitle;
  • Convenience Constructors { Class methods (i.e. + sign in Help) that performs Alloc and Init in one step and returns an instance }
    • alloc init
    • arrayWithObjects
    • i.e. + (id) blogPostWithTitle:(NSString *)someTitle;  // 'someTitle' passed as argument with this Class method (uses + sign)
  • id { general purpose data type that follows Dynamic Binding Design Pattern where Class of an Instance is not specified immediately (i.e. only definition created in Controller, but it is Bound at Runtime when run app which causes the Object to become a specific type like NSString). it can create instance of any Class and not always know return type. not required to use asterix * (i.e. id *myObject) to indicate instance when specifying 'id', as this is already implied }
  • Dynamic Binding { see above }
  • Display Images from JSON URL { NSURL (i.e. URLWithString) downloaded as UIData (i.e. dataWithContentsOfURL) object (binary), parsed to convert to UIImage object (i.e. imageWithData), and set to the UIImageView (i.e. imageView) }
  • Debugging Malformed and Erroneous Data { i.e. JSON with empty fields ( if ( [blogPost.thumbnail isKindOfClass:[NSString class]] ) { // only display if not NSNull ) }
  • Concatenating Data { [NSString stringWithFormat:@"%@ %@", blogPost.author, blogPost.date]; }
  • Custom Date Styles with NSDateFormatterStyle {
NSDATE *today = [[NSDate alloc] init]; // or use convenience constructor [NSDate date]

NSLog@“%@“, today); // prints today’s date
// NSDate Object stores in ‘seconds’ from Jan 1 2001 until today (represented internally). where 60 sec/min, 60 min/hour, 24 hr/day
NSTimeInterval secondsPerDay = 60 * 60 * 24; // typedef double used with the Date object
NSDate *tomorrow = [NSDate dateWithTimeIntervalSinceNow:secondsPerDay]; // add time to now NSDate *yesterday = [NSDate dateWithTimeIntervalSinceNow:-secondsPerDay]; // minus seconds per day
// create instance of NSDateFormatter NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; [dateFormatter setDateFormat:@“EE MMM, dd”];(see Help Menu "Date Formatting Guide > Date Formatters > Fixed Formats (depends on iOS version)http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns

// pass date object *today through date formatter and output a string NSString *todayString = [dateFormatter stringFromDate:today];
  • URL open in Default Browser
NSURL *url = [NSURL URLWithString:@"http://www.lukeschoen.com"]; UIApplication *application = [UIApplication sharedApplication]; // retrieves shared instance of singleton application object UIApplicationMain (see Support Files > main.m)[application openURL:url]; // call UIApplicationMain's method 'openURL'
  • Navigation Controller { manages presentation of hierarchy of data in app. manages multiple View Controllers and navigation between them. Navigation Controller has following elements:
      • Nav Bar (back button, title)
      • View (custom content)
      • Toobar (optional)
    • View Hierarchy
      • Stack of View Controllers { LIFO (Last In First Out) }
        • viewControllers (NSArray)
      • rootViewController
    • Stack Manipulation
      • Push (View Controller) on Stack (point to same View Controller unless there is a Modal View Controller)
        • Properties set
          • topViewController
          • visibleViewController (points to last one pushed onto the Stack)
  • Link ViewControllers in Storyboard { click Cell, press CTRL and Drag, select say 'push' (push View Controller on the Stack by creating a Segue aka Scene between the View Controllers) }
  • Link & Intercept Segue Event with Code { click Segue (connection between View Controllers), Attributes Inspector > Storyboard Segue > Identifier > "___" (i.e. showBlogPost) }
.h
@property (strong, nonatomic) IBOutlet UIWebView *detailView;@property (strong, nonatomic) NSURL *blogPostURL;
.m (of Master View Controller)

// check 'identifier' given to the segue in the storyboard.    // prepareForSegue is part of UIViewController- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {   NSLog(@"%@",segue.identifier);
// use BlogPost Custom Class (on event where segue for DetailView is fired). DetailViewController (segue object) has @properties 'detailView' and 'blogPostURL' defined if ([[segue identifier] isEqualToString:@"showBlogPost"]) {  // access blogpost object from blogposts array that was selected from Table View       NSIndexPath *indexPath = [self.tableView indexPathForSelectedRow];   BlogPost *blogPost = [self.blogPosts objectAtIndex:indexPath.row]; [segue.destinationViewController setBlogPostURL:blogPost.url];

.m (of Detail/Web View Controller)
- (void)viewDidLoad {    [super viewDidLoad];// below refers to @property blogPostURL that was set in Master View Controller to prepare segue and show URL details associated with list itemNSURLRequest *urlRequest = [NSURLRequest requestWithURL:self.blogPostURL]; 
  • WebView { subclass of UIView, uses WebKit rendering engine to display webpages }
  • UIWebView { control dragged to Storyboard and instantiated in code to load webpage by clicking the UIWebView in Assistant Editor, pressing CTRL and dragging the UIWebView from Storyboard to section of code in @interface }
  • Embed WebView and Display Common DetailView (in viewDidLoad method)
NSURL *url = [NSURL URLWithString:@"http://www.lukeschoen.com"]; // create instance of url request    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; [self.detailView loadRequest:urlRequest]; // load default webpage using @property detailView

Links:

Purchases:

Monday 5 May 2014

MBT Update - NPD

  • Unit 8 - Phase 5 - Preparation for Launch - DONE
  • Unit 9 - Phase 6 - Post-Launch Monitoring - DONE
  • Unit 10 - Organising the NPD Effort - DONE
  • Unit 11 - Reducing Lead Times - DONE
  • Unit 12 - Challenges to Products and Services -  DONE
  • Assignment 2 - 35% DONE
  • Quiz Units 11 & 12 DONE

Saturday 3 May 2014

Post WDI - iOS Development App (Master-Detail Table View, JSON, API, Mutable, Memory Management)

Activities @ TeamTreeHouse - 

iOS Development (using Xcode 5 IDE) with Amit Bijlani (Cont'd)

DONE Building API Reader (Table View) iPhone App
  • Table View (List) with Master-Detail App
    • Manual
    • Master-Detail Template
  • UIApplication { single instance, only allowed one UIApplication object for a single app. watches for Events and Routes to appropriate targets }
  • AppDelegate
    • Dfn: capability to Intercept Events at an App level so can Add Custom code. all apps have it to hook into UIApplication (app lifecycle). responsible to ensure app has a Window 
    • .h { defines lifecycle of app }
    • .m { implementation of .h containing methods }
  • UIWindow object { coordinates presentation of Views on screen. hosting Views and working with UIApplication object to deliver Events to Views and View Controller }
  • View Controller object { manages presentation of app Content on screen, including Single MainView (property) and its Collection of Sub Views  i.e. self.view (where View is property of ViewController) }
  • UIViewController class { base class for all ViewController objects, provides Default functionality for Views' ability to load, display, respond, etc }
  • View object { draws Content in designated Rect area and Responds to Events in that area }
  • Controls { specialised Views responsible for implementing interface objects (i.e. buttons, text fields, toggle switches) }
  • Data { ways to store data in app (i.e. Core Data, etc) }
  • Storyboard (defines flow between ViewControllers)
    • MasterViewController { inherits from UITableViewController and UIViewController as displays List of TableView UITableView with Rows(UITableViewCells) attributes and behaviour and where tap event shows DetailViewController }
    • DetailViewController  { inherits from UIViewController as displays Single View Text from Table View Cell }
    • Scene { ViewControllers }
    • Segue {  connection between Scenes of type UIStoryboardSegue (arrow Transition between each View Controller). it has Properties: identifier, sourceViewController, destinationViewController }
      • identifier { read-only shown in View. accessed in code with method prepareForSegue. use Method notation (instead of Dot Notation) when dealing with 'read-only' info as indicated in Help }
      • prepareForSegue { intercepts Segue once it is triggered and takes two args }
        • Segue param { contains info about Segue }
        • sender { originator of Segue }
(UIStoryboardSegue *)segue sender:(id)sender
  • Shortcuts
    • Double-Click - Zoom in/out of Storyboard canvas 
    • CMD+N - New File
  • UITableViewController { is declared in NSObjCRuntime.h (according to hover+CMD+Click) and implements two Protocols. It contains a @property 'tableView' of type UITableView which implements the two Protocols }
    • UITableViewDataSource { defines what is displayed in Table View. it mediates between Table View and Data }
    • UITableViewDelegate { defines how Data displayed with Methods to configure Table Views (i.e. row heights, section headers/footers, tap event or editing actions) }
@property (nonatomic, retain) UITableView *tableView;

  • indexPath { object with two Properties (Section, and Row in that Section) }
  • Memory Management
    • No Table View Cell Reuse { alloc and init new table view cell for each row to be displayed in table view. slow with large quantities of rows in the array to be alloc'ed }
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"Cell"];
    • Efficient Reuse of Table View Cells { allows table view to efficiently manage cells with each one having an identifier in storyboard so when table view cell scrolls beyond screen the table view re-marks it for reuse and recycles it on new row }
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];

  • NSDictionary 
    • objectForKey { type 'id' is generic data type (any Object) }
    • valueForKey { always expects String }
// declaration for key value pair NSDictionary *blogPost1 = [[NSDictionary alloc] initWithObjectsAndKeys:@"Blogpost1", @"title", @"Luke Schoen", @"author", nil]; 
// ALTERNATIVE convenience constructor for NSDictionary NSDictionary *blogPost1 = [NSDictionary dictionaryWithObjectsAndKeys:@"Blogpost1", @"title",@"Luke Schoen", @"author", nil];



  • SubTitles { Storyboard > Change Type (of TableViewCell) in Attribute Inspector > subTitle }
  • UITableViewCell Properties:
    • textLabel
    • detailTextLabel
  • Mutable 
    • Memory Inefficency { performance overhead when want to modify Contents of object, mem alloc needs to change and find mem space for additional Content }
    • NSMutableArray (subclass of NSArray)
NSMutableArray *titles = [NSMutableArray arrayWithCapacity:0]; // if capacity 0, use below NSMutableArray *titles = [NSMutableArray array]; // memory alloc minimal to hold pointer to array [titles addObject:@“My Book”]; // add object to array. mem dynamically alloc. array size grows [titles insertObject:@“abc” atIndex:0];  [titles removeLastObject]; [titles removeObjectAtIndex:0]; 
    • NSMutableDictionary (subclass of NSDictionary)
      • Declare with Memory Capacity
NSMutableDictionary *book = [NSMutableDictionary dictionary]; [book setObject:@“My Book”, forKey:@”title”]; [book setObject:@“Luke Schoen”, forKey:@”author"]; [book removeObjectForKey:@“title”]; [book removeAllObjects]; // removes all objects from a dictionary
    • NSMutableString (subclass of NSString) 
NSMutableString *string = [NSMutableString string];[string appendString:@"Title: My Book"];[string appendString:@"Author: Luke Schoen"];[string insertString:@" -- " atIndex:10]; 
  • Immutable { cannot be modified } 
    • Memory Efficient { when variable for object alloc, mem req'd known (knows qty objects and kind of objects. pass around without need to modify }
    • NSArray
  • JSON Parsing (JavaScript Object Notation)
// create NSURL class object (convenience class to breakdown url) 
// download the data (NSData object stream from JSON)   
NSURL *movieURL = [NSURL URLWithString:@"http://www.omdbapi.com/?s=Terminator"]; 
// parse data  
NSData *jsonData = [NSData dataWithContentsOfURL:blogURL]; 
// declare pointer in memory 
NSError *error = nil; 
// deserialise data into JSON object format to stored in dictionary 
// pass pointer reference to NSError so value can be modified by the method it is being passed to (otherwise just passing by value and can only read 
// i.e. &__ means value can be modified by the method 
// i.e. ___ means just passing its value and it can only read your object NSDictionary *dataDictionary = [NSJSONSerialization JSONObjectWithData:jsonData options:0 error:&error]; NSLog(@"%@", dataDictionary);
self.
moviePosts = [dataDictionary objectForKey:@"Search”];

// extract 'title' from NSDictionary and set
cell.textLabel.text = [moviePost valueForKey:@"Title"];
cell.detailTextLabel.text = [
moviePost valueForKey:@"Year"];


Events Upcoming
    • ATTENDED - RORO Syd Dev Hub - 6:30pm 6th May 2014 (Level 15, 2 Market St)
    • UNABLE - RORO USer Group - 7pm 13th May 2014 (Trinity Bar, 505 Crown St Surry Hills)
    • UNABLE - Sydney Drupal Meetup - 7pm, 15th May 2014 (Level 5, 48 Pirrama Rd)