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:@"%@ %@",,]; }
  • 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)

// 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:@""]; 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) }
@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:@""]; // create instance of url request    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url]; [self.detailView loadRequest:urlRequest]; // load default webpage using @property detailView



No comments:

Post a Comment