Rapture in Venice

:: Mobile Design and Development Shop specializing in iPhone, iPad, and Android

wdf-carousel
pholium-carousel-flat
Movementum
finds-carousel
spec-hd-carousel
aa-carousel
passtouch-carousel
tasklist-carousel
ss-carousel
fuzz-carousel
wwp-carousel
kindercards-carousel
hoya-carousel
<<<   |   play   |   >>>

Getting the Charles Debugging Proxy to Work with iOS and Genymotion

The Charles Web Debugging Proxy is a near mandatory tool for any developer. Getting it to work with your desktop apps is usually very easy since it just…works. However, for use with mobile, there are a couple tricks.

Configuring for the iOS Simulator

The iOS Simulator is a native app that “imitates” your iTouch device. Because of that, the only configuration you need is to install the Charles certificate. You can do that by downloading and running this special script on your Mac. (There’s no Windows configuration for this because you can’t run the iOS simulator on windows.)

Restart Charles and your simulator to be assured of a working connection.

Configuring for Genymotion/Android

We’re going to ignore the official Android emulator because you shouldn’t be using it anymore anyway. So, we’ll use Genymotion for this example. Since it’s a virtual machine, and not native, you need to relay the network connection to your local machine. If you don’t, Charles can’t see the internal Genymotion network and none of the requests will be seen.

First, we’ll need the Charles certificate:

  1. Download the Charles certificate for Android.
  2. Unzip and drag and drop it on to your running Genymotion device.
  3. Run the “File Manager” app on your Genymotion device and open your Download directory there.
  4. Tap the certificate to install and name it however you wish. (You may be asked to set up a security code first.)

With that done, now you need to configure a proxy to get the network traffic running through your desktop. Follow these steps exactly:

  1. Open Settings and tap Wi-Fi to see your wireless connections.
  2. You should see something like “WiredSSID”. Tap and hold it until a menu appears.
  3. Select “Modify network”.
  4. Change the “Proxy settings” to Manual.
  5. Change the “Proxy hostname” field to 10.0.3.2. This is a special Genymotion IP address so don’t try setting it in the original Android emulator. It won’t work!
  6. Change the “Proxy port” field to 8888.
  7. Tap Save.

    Restart Charles and Genymotion to be assured of a working connection. And remember, you’ll need to perform these two operations for every new Android device you create because they’re all physically separate.

    If you now run an app you’ll see the network connections appear. You’ll still have to configure SSL settings to see encrypted traffic, but that’s explained clearly in Charles and is up to you.

    Go forth!

    • Print
    • Facebook
    • Twitter
    permalink

    , , , , , , ,

Speeding up Android Studio

I’ve been using Android Studio for about a year now, adopting it early to get a jump on things. And in that time, I’ve certainly had my share of frustrations with it, but it’s going to be a superior tool to ADT when it comes out of beta, so it’s worth it to use it now.

Here’s a few tips I’d like to share with you if you do plan on using it.

The Command/Control-E Menu

I use many IDE’s, from XCode to Sublime Text to Android Studio, and I use each one differently when it comes to file navigation. In XCode, for example, I tend to toggle the “Recent Files” option a lot so that the Project Navigator is only displaying the files I’m mucking with at that moment. In Android Studio, though, I use the Command-E menu.

Open up a bunch of files in Android Studio and then press Command-E (Control-E on inferior OS’s). You’ll see something like this:

You’ll see two columns. On the right are your most recently opened files, in descending order. You instantly have keyboard access so you can arrow up or down and press Enter to open the file you want. This is extremely handy and the optimal way to move between files in Android Studio I think.

As a bonus, on the left you’ll see a list of views you can open. This is also very useful for navigating around the IDE itself, but I encourage learning the individual keyboard shortcuts for them as that’ll be faster. Start with Command-6!

And before we continue on, you might be asking why not just navigate using the tabs? You can do that, yes. However, I find it slower, especially with a mouse. Even with the keyboard, it’s a three-key combo by default. The Command-E popup really is the fastest way to navigate…give it a try!

Avoid the Wizards

Android Studio improves on ADT when it comes to wizards that create activities, resources files, etc. for you. They are more detailed and provide more options. There’s only one problem: you shouldn’t use them.

Well, that’s not totally true. Sometimes I use a couple of them early on in a project, but I still suggest to avoid them after that. Why? Well, several reasons:

  • You should be creating a lot more fragments.
  • You shouldn’t be creating many activities that actually do anything.
  • You can’t avoid creating menu XML for each activity.
  • It’s faster not to.

Do you put all your logic in activities? You really shouldn’t. For the most part, you should be creating “shell” activities that do nothing but host a fragment for your phone-form views (or multiple fragments for your table-form views). This leaves near-empty activities in your code and, rightfully, puts that code in fragment-land!

So, why not use the wizard? Well, the wizard wants to create activities for you, not fragments, and that’s wrong. So what I’ll do when creating a new screen is to clone a previous screen from the bottom-up:

  1. Copy and paste the fragment XML from a similar screen. (Enter new filename.)
  2. Change the XML to match my screen requirements.
  3. Copy and paste the fragment class from that screen. (Enter new filename.)
  4. Change the code and handlers for my screen requirements.
  5. Copy and paste the activity class from that screen. (Enter new filename.)
  6. Direct that class to load your new fragment.
  7. Add the activity to the AndroidManifest.xml. (Or crash!)

A bunch of steps, but it’s many times faster than using an activity creation wizard. Plus, you’ll have to create your fragment yourself and re-jigger everything anyway. If you’re like me, you have a base activity that simply loads a fragment and your fragment logic always looks similar. Same for resource files.

Copy and paste is your friend…well…this time!

Genymotion

There’s no argument. You must be using Genymotion for Android development. Why? Oh, well for one thing you won’t have to wait around for an hour for your simulator to load, and you DO need simulators to test on various devices so don’t tell me to just use a device…plus, it’s nice not having a phone wired to your computer all the time, and Genymotion runs so fast and smooth and, yes, yes, I know there’s that Intel thing to make the real simulator faster and that works (after an hour of trying!) but you still have all the other problems like when you run the app and the simulator comes up and it never runs your app because it’s freakin’ disconnected and it sometimes takes forever for the app to run anyway and WHY THE HELL CAN’T GOOGLE GET THEIR SIMULATOR RIGHT ANYWAY!!!?!?!!

OK, let me breathe.

Alright, so yeah, use Genymotion. It’s not only a way better environment than Google could ever provide, but it’s super simple to install, too! (Which you wouldn’t expect from a “virtual” environment.) All you need to do is install Virtual Box (hell, you don’t even need to run in, just install it) and then install Genymotion. You’ll be shown how to create your virtual device and…oh man, it’s just so easy. Android Studio sees Genymotion as just another device like the simulator or your Nexus. It’s awesome.

And to make launching Genymotion easier right from Android Studio, there’s even a plugin.

This isn’t even a recommendation. Go get it. Stop arguing.

Download Everything

This one doesn’t really just apply to Android Studio, but I’m including it here anyway.

Download everything Google offers you. Every SDK. Every bit of sample code. Everything. Do you only use SDK 10 and the latest stuff? Whatever…just download everything!

There’s a lot of reasons for this. For one, you’ll open existing projects that will fail because they use a different SDK. You will inevitably be testing against different devices in the future. Have you considered Kindle? So, when you install Android Studio and need to download what you need to use it, do yourself a favor and just get it all now. It won’t take that long and it’ll be way better than stopping multiple times later.

DOWNLOAD ALL THE THINGS!!!

  • Print
  • Facebook
  • Twitter
permalink

, , ,

How to Create a Flappy Bird Clone with SpriteKit in 20 Minutes

First, create a project in XCode. We’ll call it “Floaty Avian.” Next, bring in the SpriteKit and…

WHY ARE YOU READING THIS? WHAT IS WRONG WITH YOU?? THERE’S A MILLION GREAT GAMES ON THE APP STORE, AND YOU’RE **STILL** HUNG UP ON THIS ONE? IT’S GONE. YOU’RE AN IPHONE DEVELOPER! I CAN’T BELIEVE YOU CLICKED THIS LINK! YOU REALIZE IRRATIONAL GAMES WENT OUT OF BUSINESS YESTERDAY, RIGHT? GO PORT BIOSHOCK! FLAPPY BIRD? YOU CAME HERE TO REMAKE FLAPPY BIRD?!

WHAT WERE YOU THINKING?!

  • Print
  • Facebook
  • Twitter
permalink

How to Memorize Block Syntax

Since block syntax came out alongside iOS 4, I’ve struggled to memorize it. Sure, blocks without return types or parameters = ^{ return @”super easy to recall”;}, but once you factor in arguments and want to accept a block argument in a method, thingsBecome:(CGFloat (^)(NSInteger way, id more, CGRect complex))dontYaThink?

It’s no wonder that Fucking Block Syntax has become one of my most beloved websites.

But if you’re not the Rain Man and, like me, have trouble remembering the syntax accurately, there’s hope! I have a full-proof way to memorize it.

The Two Basic Forms

There are two basic forms to memorize. The first is when your block has a name, and the second when your block is a value (anonymous):

  1. NSInteger (^myBlockName)(CGFloat param1)
  2. ^NSInteger(CGFloat param1)

Take a minute to look at these two forms. The first form is as normal and expected as could be. REMEMBER, put the block name in parenthesis. If you do that, it’s easy pickings. The ^ is like a * if the function was a pointer. Just remember those parenthesis. Visualize how the parenthesis cuddle the name of the block. Think: Cuddle The Name.

The second form is ridiculous. Backwards almost. Since there is no name associated with the block, the return type flips to the other side of the carat. No cuddling needed, either. Clearly, tho, dropping the name means we can compact the syntax. I like to remember the phrase, Flip No Cuddle. To me, we flip the side of the carat the return type is on and lose the parentheses.

Apply It Everywhere

With these two concepts in mind, the named block and the anonymous block, let’s see them all applied. Read the following sample code and identify each one, repeating the above phrases as you see each one. Recognize if the block is named or not, then say either Cuddle The Name or Flip No Cuddle:

// pass block to method
[self makeNumberFromString:^NSNumber *(NSString *str) { ... }];

// define block locally
NSNumber * (^local)(NSString *str) = nil;

// property
@property (copy, nonatomic) NSNumber * (^myProp)(NSString *str);

// the defined method
- (void)makeNumberFromString:(NSNumber * (^)(NSString *str))named {
    ...
}

How did you do? Your answers should have been Flip No Cuddle, Cuddle The Name, Cuddle The Name, and WHAT THE F*** ARE YOU KIDDING ME? Yep, sorry, method parameters bend the Cuddle The Name mold a bit by flipping the method name to the outside. However, this too is easy to remember because the carat remains and, hey, ALL method parameters put their name on the outside. Right?

- (BOOL)textFieldShouldReturn:(UITextField *)textField { ... }

So, just put the whole expression in parens and the parameter name on the outside like you always do.

Typedefs? Cuddle The Name!

I’m not a huge fan of typedefs for blocks, but you’ll see them used often and you should recognize easily that defining them is Cuddle The Name:

typedef BOOL (^IsItSafeType)(NSInteger);

With it defined, assigning to it is what pattern? RIGHT! It’s Flip No Cuddle because you assign an anonymous value to the variable!

IsItSafeType alwaysSafe = ^BOOL(NSInteger x) { return YES; };

OK, Let’s Summarize!

Alright, so we have our two basic forms:

  • NSInteger (^myBlockName)(CGFloat param1) <-- Cuddle The Name for named blocks
  • ^NSInteger(CGFloat param1) <-- Flip No Cuddle for anonymous blocks

The one exception is with Cuddle The Name for method parameters where we cuddle the whole thing and pull the parameter name outside:

  • ((NSInteger (^)(CGFloat param1))outsideName <-- Cuddle The Name wants to be like other parameters!

But as you can see, since it’s a named block, using Cuddle The Name is perfectly consistent. Then, defining typedefs, we still have a named block and so we use Cuddle The Name there, too! And assigning to the typedef? Yep. Flip No Cuddle.

Simple! Hopefully, this helps us memorize this very strange syntax. :-)

  • Print
  • Facebook
  • Twitter
permalink

, ,

Don’t Write a Class, Write a Category!

As an iPhone freelancer, I develop a lot of iOS apps. A lot. And one of the most important things to my business is that I leverage as much of my past work as possible when it comes to new projects. I have several strategies, but today I wanted to share one of my favorites: categorization.

If you’re an experienced developer who’s worked with various languages and platforms over the years, you’ll know that the classic way to add “core” functionality was to either extend a class or create a new (probably static) class. We’d create classes like BetterString (extends String) or StringUtils as ways to add functionality to the platform we think could be handy later.

Of course, the problem with extending classes is that they’re not always interoperable with library code. Taking the example above, you might have to wrap your String in a BetterString before passing it to your code. It gets ugly. Creating new classes separates the functionality out a bit, but providing a bunch of static methods from StringUtils just feels disconnected and incorrect. (Hint: it is.)

Abuse the $*#@&^ Out of Categories!

Generally, when we think about categories, the first thing that comes to mind is adding useful NSString or UIColor methods. In InnerBand, I provide popular UIColor#-colorWithHex: and NSString#contains: methods that can be re-used all over the place without interfering with the categorized classes.

But what if I told you that using categories for app-specific functionality unlocks their true power?

You see, the best use for categories is dropping ALLLL the reusable bits you need down to the microscopic level. How much do you use categories? Answer yes or no to these questions:

  1. Do you specify fonts or font sizes in place when you need them?
  2. Do you specify colors all over your code?
  3. Do you access NSUserDefaults values by providing keys where you access them?
  4. Do you check for NSNull when you’re parsing JSON?

Did you answer yes to any of these? If so, you need to abuse categories more. You see, as a Clean Coder, it’s your mission to isolate these kinds of choices and checks as much as possible.

If you’re still reading, you want to know more. So let’s inspire you! Here’s how we can put categories to good use!

Pre-Define Your Fonts in a Category

If you’re specifying a font face or size in your view controller, you’re doing it wrong. You should define the fonts you’ll use in one place and reference them elsewhere. And we’ll use a category:

@implementation UIFont (AppFonts)

+ (UIFont *)titleFont {
    return [self bebasFontOfSize:20];
}

+ (UIFont *)subtitleFont {
    return [self bebasFontOfSize:15];
}

+ (UIFont *)bebasFontOfSize:(NSInteger)size {
    return [UIFont fontWithName:@"Bebas Neue" size:size];
}

@end

As a bonus, notice how I even have a convenient private method for creating the Bebas Nueue font in case I ever need to change it.

Create Your Colors in a Category

Colors are tough in XCode. First, I DO NOT LIKE the Apple format of using decimal numbers to define them. Designers don’t use that format, it’s harder to eyeball the distributed syntax, and sooo many apps that can help you with color will output in Hex rather than Apple’s format. (If you insist on using the Apple format, I use and recommend Color Snapper.)

Past that, even if you do use hex colors, you should confine them to a category:

@implementation UIColor (AppColors)

+ (UIColor *)headlineColor {
    return [UIColor colorWithString:@"#ff0000"];
}

+ (UIColor *)standardBackgroundColor {
    return [UIColor colorWithString:@"#111111"];
}

@end

Categorizing your colors in this way makes them easy to change and locates them right on the class you’ll find the most convenient. Look at the client code:

    self.view.backgroundColor = [UIColor standardBackgroundColor];

Contrast that with this macro/function usage:

    self.view.backgroundColor = MA_COLOR_STANDARD_BACKGROUND_COLOR();

The former just feels so natural. Naming is shorter and more readable, and I know where to find it should I need to look at it.

Don’t Re-Use the Key, Re-Use the Access

One of the more prevalent anti-patterns I’ve seen is to create a constant for use as an NSUserDefaults key. I know, my old code does it, too. :-) And yes, constants are good for this sort of thing to avoid typos, but using categories we can make saving and restoring these values even more reusable and easy to do:

// keys
static NSString * const kUserDefaultsDealerId = @"kUserDefaultsDealerId";

@implementation NSUserDefaults (AppDefaults)

- (void)setDealerId:(NSString *)dealerId {
    [self setObject:dealerId forKey:kUserDefaultsDealerId];
}

- (NSString *)dealerId {
    return [self objectForKey:kUserDefaultsDealerId];
}

@end

You can see that I use a constant for the key, but the constant and the accessors are all here on this NSUserDefaults category and, again, all very logically located. (Assuming you don’t have a separate model class.) I can read and write the value, and I do it right on the class:

    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];

    [defaults setDealerId:@"ABCDE"];
    [defaults synchronize];

It just feels so natural to perform these operations on the very class we intend to interact with. Notice I don’t do the synchronize in the call because there are cases where doing so would be very ineffecient, such as when you were setting the value within a loop.

Even the Lowest Level Code Can Be Categorized

I love JSON, but it can be a bit annoying to constantly check for NSNull in values you receive. (You are doing that, right?). In the old days, you may have seen a lot of code looking this:

    NSString *firstName = [json valueForKey:@"first_name"];
    self.firstName = (firstName && firstName != (NSString *)[NSNull null]) ? firstName : nil;

Repeated everywhere. Well, let’s categorize!

    self.firstName = [json safeValueForKey:@"first_name"];

We can reuse it everywhere. What’s it look like?

@implementation NSDictionary (Nulls)

- (id)safeValueForKey:(NSString *)key {
    id value = [self valueForKey:key];

    if (value && value != [NSNull null]) {
        return value;
    }

    return nil;
}

@end

Final Thoughts

Categories are a powerful part of the Objective-C language and, for once, one that’s been there quite a while. (*cough* blocks *cough*) They get decent use in every codebase I’ve seen, but I think many stop short of truly abusing them. Hopefully, I’ve turned you into a frequent abuser today!

One last thing, I am a proponent of importing these in the PCH. Every one. Why? Well, if you take the concept of “forgotten code” as code that doesn’t get used by developers who weren’t aware the functionality was there, then the advantage of importing these in the PCH is that a new developer can more easily stumble on these without even being told. They go to define a new font and…hey, what’s that? A -headlineFont method? I think it’s a great way to help developers find their way around the codebase.

Alright, that’s all I got. Code away!

  • Print
  • Facebook
  • Twitter
permalink

, , ,

Previous Posts