Friday 28 June 2013

Show picker view (UIDatePicker) on tapping text field.


We can use inputView and inputAccessoryView of UITextField. Declare in .h file, and @synthesize in .m file.
@property (nonatomic, retain) IBOutlet UIToolbar    *_accessoryView;
@property (nonatomic, retain) IBOutlet UIDatePicker *_datePickerView;
Connect them to File's Owner in .xib file, make sure that its out of the self.view.
- (void)viewDidLoad
    {   
        _dateOfBirthTextField.inputView = self._datePickerView;
        _dateOfBirthTextField.inputAccessoryView = self._toolbar;
    }
Also write function to fetch date from the picker
#pragma mark- UITextField with UIDatePicker-

- (IBAction)dateChanged:(id)sender {
    UIDatePicker *picker = (UIDatePicker *)sender;
    _dateOfBirthTextField.text = [NSString stringWithFormat:@"%@", picker.date];
}

- (IBAction)doneEditing:(id)sender {
    [_dateOfBirthTextField resignFirstResponder];
}
Add dateChanged: IBAction on valueChanged: action of _datePicker. and doneEditing: IBAction on toolbar barbutton action.

Thursday 27 June 2013

Fetching the images and title of songs and albums ( MPMediaItem ) in the table view. Music Player iOS.


If you want to using default Music player in your app, you can fetch the images of the related song or album using various properties from "MPMediaItemProperty" like MPMediaItemPropertyAlbumTitle, MPMediaItemPropertyArtist, MPMediaItemPropertyTitle, MPMediaItemArtwork.



- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    //static NSString *CellIdentifier = @"Cell";
    NSString *CellIdentifier = [NSString stringWithFormat:@"Cell%d%d",indexPath.section,indexPath.row];

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] ;
    }

    MPMediaItem* mediaItem = [_arrPlaylistOfMediaItems objectAtIndex:indexPath.row] ; 
    //_arrPlaylistOfMediaItems is the array of MPMediaItems 
    NSString* mediaTitle = [mediaItem valueForProperty:MPMediaItemPropertyTitle];
    NSString* title = [[NSString alloc]initWithFormat:@"%@",(mediaTitle.length>0 ? mediaTitle : @"Unknown")];
    NSString* artist = [mediaItem valueForProperty:MPMediaItemPropertyArtist];
    NSString* albumTitle = [mediaItem valueForProperty:MPMediaItemPropertyAlbumTitle];
    NSString* subTitle = [[NSString alloc]initWithFormat:@"%@ - %@",(artist.length>0 ? artist : @"Unknown"),(albumTitle.length>0 ? albumTitle : @"Unknown")];

    cell.textLabel.text = title;
    cell.detailTextLabel.text = subTitle;
    cell.imageView.image = _defaultImg;//[UIImage imageNamed: @"iconThumb"];

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{
        MPMediaItemArtwork* artwork = [mediaItem valueForProperty:MPMediaItemPropertyArtwork];
        if ( !artwork || artwork.bounds.size.width == 0 ) {
            // try album artwork
            NSNumber* albumID = [mediaItem valueForProperty:MPMediaItemPropertyAlbumPersistentID];
            MPMediaQuery*   mediaQuery = [MPMediaQuery albumsQuery];
            MPMediaPropertyPredicate* predicate = [MPMediaPropertyPredicate predicateWithValue:albumID forProperty:MPMediaItemPropertyAlbumPersistentID];
            [mediaQuery addFilterPredicate:predicate];
            NSArray* arrMediaItems = [mediaQuery items];
            if ( [arrMediaItems count] > 0 ) {
                artwork = [[arrMediaItems objectAtIndex:0] valueForProperty:MPMediaItemPropertyArtwork];
                if ( artwork ) {
                    int nBreak = 0;
                    nBreak++;
                }
            }
        }
       dispatch_sync(dispatch_get_main_queue(), ^{
            if ( artwork && artwork.bounds.size.width > 0 ) {
                      cell.imageView.image = [self scale: [artwork imageWithSize:CGSizeMake (50, 50)] toSize:CGSizeMake(55, 55)] ;
                cell.imageView.image =[self scale:[artwork imageWithSize:CGSizeMake(50,50)]toSize:CGSizeMake(45,45)];
            }
            else {
                 NSLog(@"Bad artwork: %@ - %@ - %f-%f", strTitle, strsubTitle, artwork.bounds.size.width, artwork.bounds.size.height);
                
                cell.imageView.image = _defaultImg;
            }
       });
    });
   return cell;
}

GCD - Fetching data for UIImage on background thread, and updating UI on main thread.



// Perform the asynchronous task on the background thread-

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{

       // Perform the asynchronous task in this block like loading data from server

       NSString *ImageURL = 
            @"https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiqAPlN0cfFStsejGreGWs1xiRVBPbEt6e0r86g83drW6RVlBHLVnY75EqG964qZlPv6ZGNwMS-t6Ci8cgdpgwWUsaTJ6DVKDMkKxDc9Ovy4bdKkpmkZrJxCRjPjLCNpwnpPqNZHPwLync/s220-h/smart-software-developer.jpg";

       NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:ImageURL]];


       // Perform the task on the main thread using the main queue-
        dispatch_sync(dispatch_get_main_queue(), ^{

            // Perform the UI update in this block, like showing image.

            _imageObj.image = [UIImage imageWithData:imageData];

        });

 });

Wednesday 26 June 2013

Single UILabel with different color text and fonts possible?


Yes, Its possible in to have different colored text and fonts in single UILabel, from iOS6 onwards using "NSMutableAttributedString".

-(void)AttributedTextInUILabelWithGreenText:(NSString *)greenText withYellowText:(NSString *) yellowText withBlueBoldText:(NSString *)blueBoldText
{
    NSString *text = [NSString stringWithFormat:@"Here are %@, %@ and %@",
                      greenText,
                      yellowText,
                      blueBoldText];

    //Check If attributed text is unsupported (below iOS6+)
    if (![self.label respondsToSelector:@selector(setAttributedText:)]) {   
     self.label.text = text;
    }
    // If attributed text is available
    else {
        // Define general attributes like color and fonts for the entire text
        NSDictionary *attribs = @{
                                  NSForegroundColorAttributeName: self.label.textColor,
                                  NSFontAttributeName: self.label.font
                                  };
        NSMutableAttributedString *attributedText =
        [[NSMutableAttributedString alloc] initWithString:text
                                               attributes:attribs];

        // green text attributes
        UIColor *greenColor = [UIColor greenColor];
        NSRange greenTextRange = [text rangeOfString:redText];
        [attributedText setAttributes:@{NSForegroundColorAttributeName:greenColor}
                                range:greenTextRange];

        // yellow text attributes
        UIColor *yellowColor = [UIColor yellowColor];
        NSRange yellowTextRange = [text rangeOfString:greenText];
        [attributedText setAttributes:@{NSForegroundColorAttributeName:yellowColor}
                                range:yellowTextRange];

        // blue and bold text attributes
        UIColor *blueColor = [UIColor blueColor];
        UIFont *boldFont = [UIFont boldSystemFontOfSize:self.label.font.pointSize];
        NSRange blueBoldTextRange = [text rangeOfString:blueBoldText];
        [attributedText setAttributes:@{NSForegroundColorAttributeName:blueColor,
                  NSFontAttributeName:boldFont}
                                range:blueBoldTextRange];
        self.label.attributedText = attributedText;
        
}

Tuesday 25 June 2013

NSURLConnection connection getting lost? Delegate methods not called.


If you are creating a asynchronous connection and delegates are not called. The possible reason could be that you are creating the connection request on the    background thread, thats why the callback is lost, you should keep the track of the callback using NSRunLoop.

NSURLConnection * connection = [[NSURLConnection alloc] 
                                initWithRequest:request
                                       delegate:self startImmediately:NO];

[connection scheduleInRunLoop:[NSRunLoop mainRunLoop] 
                      forMode:NSDefaultRunLoopMode];
[connection start];

Sending UIImage to server using NSURLConnection synchronous request- iOS.



-(void)createConnectionRequestToURL:(NSString *)urlStr withImage:(UIImage*)image withImageName:(NSString*)imageName
{
    NSData *imageData = UIImageJPEGRepresentation(image, 90);
    NSString *urlString = urlStr;
    // setting up the request object now
    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
    [request setURL:[NSURL URLWithString:urlString]];
    [request setHTTPMethod:@"POST"];

    NSString *boundary = [[NSString alloc]init];
    NSString *contentType = [NSString stringWithFormat:@"multipart/form-data; boundary=%@",boundary];
    [request addValue:contentType forHTTPHeaderField: @"Content-Type"];
    NSMutableData *body = [NSMutableData data];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[@"Content-Disposition: form-data; name=\"file\"; filename=\"test.png\"rn" dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[[NSString stringWithFormat:@"Content-Type: application/%@.jpg\r\n\r\n",imageName] dataUsingEncoding:NSUTF8StringEncoding]];
    [body appendData:[NSData dataWithData:imageData]];
    [body appendData:[[NSString stringWithFormat:@"\r\n--%@--\r\n",boundary] dataUsingEncoding:NSUTF8StringEncoding]];
    [request setHTTPBody:body];

    //Using Synchronous Request. You can also use asynchronous connection and get update in delegates
    NSData *returnData = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
    NSString *returnString = [[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding];
    NSLog(@"--------%@",returnString);
}

Friday 21 June 2013

Fetch data from NSURL synchronously.

- (void)fetchDataSynchronouslyFromURL:(NSString*)urlStr
{
    NSString* serverUrl = urlStr;
    NSData *serverData = [NSData dataWithContentsOfURL:[NSURL URLWithString:serverUrl]];
    NSError* error = nil;
    id serverResponse = [NSJSONSerialization JSONObjectWithData:serverData options:kNilOptions error:&error];
    NSLog(@"Server response:%@",serverResponse);

}

Tuesday 18 June 2013

Force start iOS application in Landscape Mode OR Portrait Mode.


If you want your application to be in Landscape mode.

STEP 1: Click on "MyProject.xcodeproj" file 
STEP 2: Select the TARGET Goto Project summary.
STEP 3: Choose supported interface orientations as landscape.



#import <objc/message.h>

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    //Force start in Landscape Mode
    [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];


 if ([[UIDevice currentDevice] respondsToSelector:@selector(setOrientation:)]) {
            [[UIApplication sharedApplication] setStatusBarOrientation:UIInterfaceOrientationLandscapeRight];
            objc_msgSend([UIDevice currentDevice], @selector(setOrientation:), UIInterfaceOrientationLandscapeRight);
        }

    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
    self.window.rootViewController = self.viewController;
    [self.window makeKeyAndVisible];

    NSLog(@"orientation:%d",[[UIDevice currentDevice]orientation]);

    return YES;
}


You can use the steps for portrait mode, just change the orientation to portrait mode in supported orientation. And in STEP 3: 
[[UIApplication sharedApplicationsetStatusBarOrientation: UIInterfaceOrientationPortraitRight];



If you support all the orientations, then you need to update your configurations in 
Info.p-list.

Either
Using Code:


<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<array>
<string>UIInterfaceOrientationLandscapeRight</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationPortraitUpsideDown</string>
</array>
</plist>

OR

Just add "Supported interface orientations" and values in the array starting with
For Landscape:
  "UIInterfaceOrientationLandscapeRight" or "UIInterfaceOrientationLandscapeLeft"
For Portrait: 
   "UIInterfaceOrientationPortrait" or "UIInterfaceOrientationPortraitUpsideDown"

Read JSON from NSBundle file iOS.


-(void)fetchJSONDict
{
//  Goto the filePath

    NSString *filePath = [[NSBundle mainBundle] pathForResource:@"JsonFile" ofType:@"txt"];
    NSString *jsonContent = [NSString stringWithContentsOfFile:filePath usedEncoding:nil error:nil];
    NSLog(@"content Json is:%@",jsonContent);

    NSData *data = [jsonContent dataUsingEncoding:NSUTF8StringEncoding];
    id object = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil]; //Check out other options NSJSONReadingOptions available. 


//  Check the class type of the object fetched.


    if([object isKindOfClass:[NSDictionary class]]) {
        _dataRXDict = [[NSDictionary alloc]initWithDictionary:object];
        NSLog(@"Json Object recieved is dictionary");
        NSLog(@"Json Object Test:%@",[object valueForKey:@"myKey"]);
    }
    else if([object isKindOfClass:[NSArray class]]) {
        _dataRXArray = [[NSArray alloc]initWithArray:object];

        NSLog(@"Json Object recieved is array");
        NSLog(@"Json Object Test:%@",[object objectAtIndex:0]);
    }
    else if([object isKindOfClass:[NSString class]]) {
        _dataRXString = [[NSDictionary alloc]initWithDictionary:object];

        NSLog(@"Json Object recieved is string");
        NSLog(@"Json Object Test:%@",object);
    }
}


Monday 17 June 2013

iOS Image Gallery Viewer


Making an app for showing an image gallery in iPhone and iPad?
Have a look at various sample available:
Three20 and EGOPhotoViewer developed by enormego.
MWPhotoBrowser which is a better option.

MPMusicPlayerController with AirPlay


When creating an audio app which uses iPod Music Player, 
I need Airplay functionality. I  used RoutePlayButton in MPVolumeView slider. I don't have apple TV to test if it will work or not.
1.) To add Airplay functionality to MPMusicPlayerController
MPVolumeView *myVolumeView;
    [myVolumeView setShowsRouteButton:YES];
2.) To test airplay without Apple T.V.
AirServer is a paid app. I tried the trial version, it was working fine on Mac-Mini. Please let me know if anyone come across any free app. As @Prince suggested.

You can also try AirPlayer 0.28 beta application and transform your Mac into anAirPlay-compatible display. Change Sharing in System Preferences, Tick internet Sharing by making WiFi On. Use same WIFI in device also.

Merge two UIImage to make single UIImage.


- (UIImage*)mergeImage:(UIImage*)first withImage:(UIImage*)second
{
 // get size of the first image
 CGImageRef firstImageRef = first.CGImage;
 CGFloat firstWidth = CGImageGetWidth(firstImageRef);
 CGFloat firstHeight = CGImageGetHeight(firstImageRef);

 // get size of the second image
 CGImageRef secondImageRef = second.CGImage;
 CGFloat secondWidth = CGImageGetWidth(secondImageRef);
 CGFloat secondHeight = CGImageGetHeight(secondImageRef);

 // build merged size
 CGSize mergedSize = CGSizeMake(MAX(firstWidth, secondWidth), MAX(firstHeight, secondHeight));

 // capture image context ref
 UIGraphicsBeginImageContext(mergedSize);

 //Draw images onto the context
 [first drawInRect:CGRectMake(0, 0, firstWidth, firstHeight)];
 [second drawInRect:CGRectMake(0, 0, secondWidth, secondHeight)]; 

 // assign context to new UIImage
 UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();

 // end context
 UIGraphicsEndImageContext();

 return newImage;
}