Ready to Level-Up?

This just in! If your rusty iOS skills could use some refining, or if you're just starting out and you want to level-up fast, consider signing up for our upcoming iOS Screencasts

New from iOS Rocket Surgery Swift Video Tutorials: The rapidly evolving Apple-iOS ecosystem has just been thrown into tumult with the recent introduction of the Swift Programming Language. Are you ready to finally try iOS development? Are you needing to switch from Objective-C to Swift? Sign up today for our free video courses!
(By the dear folks at Swift Tutorial Videos, a sister company)

Wednesday, July 31, 2013

Get the Current ViewController in iOS

So, you want to get the topmost ViewController in iOS, eh?

It turns out that there is no straightforward function to obtain the current, top view controller. This is another weird case of Apple being good at constraining you, but bad at helping you. Fortunately, as with many of these hangups, the solution isn't too horrendous as you will see below.

Why do you want to get the current view anyway? Maybe its because you just received a push notification and you want to render a view on the current screen (the "active view"). Whatever your need, this method will be the step in the right direction.

Lets look at the code.

+ (UIViewController*) getTopController
{
    UIViewController *topViewController = [UIApplication sharedApplication].keyWindow.rootViewController;

    while (topController.presentedViewController) {
        topController = topController.presentedViewController;
    }

    return topController;
}

Hey, that's not too bad... but why this approach? Well, this approach is slightly different than other approaches you may have come across in your search for the solution. It differs because it is useful in just about every type of hierarchical view structure, whether you have a NavigationController in the loop or not.




Read More

Tuesday, July 30, 2013

iOS URL Encoding

So, you want to go from NSString to URL, huh?

Occasionally, you come across this dirty bit of iOS, where you want to encode a string to create a URL, so you try something like [mystring stringByAddingPercentEscapesUsingEncoding]... and while this works SOME of the time, it doesn't work all of the time, because it won't escape ALL of the necessary special characters to make this work.

So, here's a quick and dirty implementation that I use with great effect:

First, I define this slick little method here (don't be scared of the old Objective-C syntax and low-level libraries, embrace it!):

-(NSString *)urlenc:(NSString *)val
{
    CFStringRef safeString =
       CFURLCreateStringByAddingPercentEscapes(NULL,
                                               (CFStringRef)val,
                                               NULL,
                                               CFSTR("/%&=?$#+-~@<>|\*,.()[]{}^!"),
                                               kCFStringEncodingUTF8);
    return [NSString stringWithFormat:@"%@", safeString];
}

... and I use it like so:

NSString *query =
    [NSString stringWithFormat:@"http://www.mydomain.com/api/endpoint?test1=%@&test2=%@",
     [self urlenc:@"some(people+-?/{}"],
     [self urlenc:@"just#want@to!watch<the>world,.burn"]];
NSURL *url = [NSURL URLWithString:query];

Which yields:
http://www.mydomain.com/api/endpoint?test1=some%28people%2B%2D%3F%2F%7B%7D&test2=just%23want%40to%21watch%3Cthe%3Eworld%2C%2Eburn

Works like a charm.


Read More

Wednesday, July 24, 2013

Dismissing the iOS Keyboard

So, you want to hide the iOS keyboard when exiting a textfield, huh?


For starters the term you are looking for is "resign first responder". You want your textfield to "resign" from being the "first responder" for input (such as typing) and other events.

This is one of those things that I believe Apple could have handled for you as a built-in convention, but they decided for whatever good reason to make you handle this yourself (as of iOS 7 and prior).

How do you "resign first responder"? Well, I've never seen an implementation of this that I love yet... but most implementations are some twist on overriding the UIView class via a category, and handling taps and other gestures, and the event handler literally iterates over all the child views and asks each textfield to resign as first responder. Yuck, right? Well, this is the state of the art answer I'm afraid.

@implementation UIView (FindAndResignFirstResponder)
- (BOOL)findAndResignFirstResponder
{
    if (self.isFirstResponder) {
        [self resignFirstResponder];
        return YES;  
    }
    for (UIView *subView in self.subviews) {
        if ([subView findAndResignFirstResponder])
            return YES;
    }
    return NO;
}
@end

This is a view category... and basically, you'll need to add a gesture recognizer (probably Tap) on all your controllers that have text fields in order to handle this. I happen to use a common base controller class so, all my controllers inherit this behavior by default.

It isn't pretty, but it does the job... until Apple decides to resolve this for you... which, hopefully they will someday.

Works Sited:
http://stackoverflow.com/questions/1823317/get-the-current-first-responder-without-using-a-private-api


UPDATED: much easier


[self.myTextField addTarget:self action:@selector(textFieldFinished:) forControlEvents: UIControlEventEditingDidEndOnExit];



-(void) textFieldFinished:(id) sender
{
  [sender resignFirstResponder];
}



Read More

Tuesday, July 23, 2013

iOS UUID Replacement

So, you want to track your app install by giving it a unique id, huh?



Ok, easy peasy... we want to setup an iOS UUID Generator.

First, get OpenUDID from GitHub.

Second, write some code that looks like this:
NSString *openUDID = [OpenUDID value];

NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults setObject:openUDID forKey:@"unique_id"];    

What we've just done there is create a randomly generated UDID and stored it in our NSUserDefaults instance. Now, you can fetch it out at some later time, say, when making a remote request like this:

NSString *uniqueId = [defaults objectForKey:@"unique_id"];

I personally use this id to give me a warm fuzzy feeling that I can track multiple devices registered against the same account. You might be using the Push Notification registration ID for this, but in situations where you're not using Push, or when users won't enable push in your app, this is a nice way to track a single app install over multiple requests.

And of, course, the benefit is that the id stored in the preferences will go away when the app is uninstalled. This means that privacy is less of an issue from the user's perspective.

Now, aren't you glad Apple got rid of the UUID? Now, you're doing a service for yourself and giving your users some extra privacy. Everyone wins!



Read More

Creating an iOS Post Request

Creating a Post Request and Parsing a JSON Response in iOS / Xcode. 

Lets look at a simple example...

// The url to our server endpoint
NSString *url = @"http://www.mydomain.com/myserverendpoint";

// Like the post request I showed you before, I'm going to send the deviceId again, because that is generally useful for establishing 

UIDevice *device = [UIDevice currentDevice];
NSString *deviceRef = [device uniqueIdentifier];
    
NSString *post = [NSString stringWithFormat:@"device_ref=", deviceRef];
NSData *postData = [post dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
NSString *postLength = [NSString stringWithFormat:@"%d", [postData length]];
    
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"POST"];
[request setValue:postLength forHTTPHeaderField:@"Content-Length"];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    
[request setHTTPBody:postData];
   
NSURLResponse *response;
NSError *error;
    
NSData *jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error];

NSDictionary *results = jsonData ? [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers|NSJSONReadingMutableLeaves error:&error] : nil;

if (error) NSLog(@"[%@ %@] JSON error: %@", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error.localizedDescription);



Read More

About Me

Easy NSDateFormatter Tool

Save yourself some time in formatting your NSDates to NSStrings, and use the Blind NSDate app, which you can download from iTunes. There's also a website where you can format your NSDates: http://www.blindnsdate.com

Popular Posts

Designed By Seo Blogger Templates