Wednesday, December 05, 2012

Core Data Helper Macro

I pretty much love core data.  It can be frustrating sometimes but for the most part it's pretty awesome.

One of the crazy things about it is if you get an error and try to figure things out by doing this:


    NSError *error;
    if (![managedObjectContext save:&error])
    {
        NSLog(@"Error saving User: %@", [error localizedDescription]);
    }
    

You get a good error - something like "Operation could not be completed: cocoa error code 1560".

Not very helpful.  I just stumbled across this little nugget of information from back in 2009!  All of these years of suffering I have been through.  Basically the gist of the article is you create a macro like this:

#define FT_SAVE_MOC(_ft_moc) \
do { \
    NSError* _ft_save_error; \
    if(![_ft_moc save:&_ft_save_error]) { \
        NSLog(@"Failed to save to data store: %@", [_ft_save_error localizedDescription]); \
        NSArray* _ft_detailedErrors = [[_ft_save_error userInfo] objectForKey:NSDetailedErrorsKey]; \
        if(_ft_detailedErrors != nil && [_ft_detailedErrors count] > 0) { \
            for(NSError* _ft_detailedError in _ft_detailedErrors) { \
                NSLog(@"DetailedError: %@", [_ft_detailedError userInfo]); \
            } \
        } \
        else { \
            NSLog(@"%@", [_ft_save_error userInfo]); \
        } \
    } \
} while(0);

and when you save like this:

FT_SAVE_MOC(managedObjectContext);



If you get an error you actually get useful information! 

Core Data just got better!

-Aaron

Monday, November 19, 2012

Irritating things I seem to forget how to do (Android Version)

So one of the most basic things you can do in Android is start a new intent it is super simple (this is not what I forget - I'll get to that in a minute):


Intent i = new Intent(this, AwesomeIntent.class);
startActivity(i);

See? very simple.  Now if you want to pass data back from an activity that you just created you have to start the Inent slightly different:

Intent i = new Intent(this, AwesomeIntent.class);
startActivityForResult(i, REQUEST_CODE_FOR_MY_INTENT);

Even that was pretty easy wasn't it?  

It doesn't take long though before you want to pass information into an intent, and of course you have to return data from the intent (and process it as well).  Here is how you do that:

Intent i = new Intent(this, AwesomeIntent.class);
i.putExtra(Key, Value);

The documentation says that should work however this seems to work better:

Intent i = new Intent(this, AwesomeIntent.class);
Bundle b = new Bundle();
b.putString("KEY", "VALUE");
i.putExtras(b);

startActivity(i);


You can get that extra data you passed in (often in the onCreate method) like this:

Bundle b = getIntent().getExtras();
magicKey = b.getString(key);

Now the whole reason I created the post when you are in an Activity that was created by a "startActivityForResult".  Inside the method where your activity finishes up just do this:

Intent intent = this.getIntent();
intent.putExtra("SOMETHING", "EXTRAS");
this.setResult(RESULT_OK, intent);
finish();

And lastly the class that started it all needs to implement this method:

protected void onActivityResult(int requestCode, int resultCode, Intent intentData) 
{
   if (requestCode == REQUEST_CODE_FOR_MY_INTENT)
   {
     //do some cool stuff here
   }
}


Pretty simple basic stuff - but for whatever reason I always seem to have to look it up.

Happy Coding!

-Aaron

Friday, November 16, 2012

Removing SVN cruft

I'm slowly converting some of my old SVN projects to bitbucket (using git).  Bit Bucket is really the coolest thing when it comes to source code control.  If you can get over the GIT learning curve there are so many features that bit bucket gives you free (Issue Tracking, WIKI, source code browsing - just to name a few).  I don't know how or why but I love those guys...

 One of the odd / irritating svn does is create that .svn folder in all of your directories if you check a project out.  I suppose you could use the .gitignore for these but I stumbled upon a much better way to do this.  At the root of your project execute this command:
find . -type d -name .svn -exec rm -rf {} \;

Now if you are running windows... well... stop that go get linux or a mac!

By the way I found this little goody over at stackoverflow.


-Aaron

Tuesday, February 21, 2012

SSH Public Key Authentication

Here is a link to a super simple explanation of how to set this up: http://www.petefreitag.com/item/532.cfm

In case it goes away here is the content copied and pasted - this is not my work it is from Pete Freitag :



Setting up public key authentication over SSH

Every time I want to setup public key authentication over SSH, I have to look it up, and I've never found a simple guide, so here's mine.
Generate key on local machine

ssh-keygen -t rsa
It will ask you for a password but you can leave it blank.
Note you could also pick -t dsa if you prefer.
Ensure that the remote server has a .ssh directory

Make sure the server your connecting to has a .ssh directory in your home directory. If it doesn't exist you can run the ssh-keygen command above, and it will create one with the correct permissions.
Copy your local public key to the remote server

If your remote server doesn't have a file called ~/.ssh/authorized_keys2 then we can create it. If that file already exists, you need to append to it instead of overwriting it, which the command below would do:
scp ~/.ssh/id_rsa.pub remote.server.com:.ssh/authorized_keys2
Now ssh to the remote server

Now you can ssh to the remote server without entering your password.
Security

Now keep in mind that all someone needs to login to the remote server, is the file on your local machine~/.ssh/id_rsa, so make sure it is secure.

Tuesday, January 17, 2012

Git and Dropbox


I've been using git along with Dropbox for a little while and think it is a pretty awesome way to setup a code repository.

This is usually how I end up doing.  Create a new project happily coding along and then it occurs to me I should probably start versioning this little gem.  Which is very easy to do with git simply "git init" and you're done.

So that is all find and good but then I start to get nervous... what if my hard drive crashes... how can I keep this repository save and sound?

Again git has a very easy to use command that if you put it in your dropbox folder you have a code repository that easy to manage and access!

Here is the command for git:

git clone --bare  /gitrepo/gitproject.git

I get tired of having to type git push /gitrepo/gitproject.git  whenever I want to push code out into the safe region of Dropbox so I usually end up writing a simple little script that looks like this:


#!/bin/sh
git push /gitrepo/gitproject.git

obviously pull is just as easy....

Enjoy!

-A

Monday, January 09, 2012

Making Xcode less difficult

Writing Objective-C code in Xcode can be very difficult.  Especially if you're coming from a different language like Java; not only do you have to learn the new syntax of Objective-C you also have to learn the new development environment and remember what it's like to code in a non-managed environment (i.e. not having the JVM hold your hand when things go awry).

I started working with Xcode and Objective-C about 4 years ago and after many frustrating days (and nights) I found out some great information in an iTunes University video called Advanced IOS Development put out by Madison College.  

It's a very long video, about 3 hours and I'm only about half way through it but I have found some great information in it already that I wanted to share.

Problem: you're running your app on the emulator and it seeming crashes randomly.  You don't get any information about why it crashed the app just quits.

Solution: in Xcode you can set global break points that can stop your app when it crashes, the debugger puts you right on the line that causes the problem!  
Here is how you do it:
  • In Xcode open the Breakpoint Navigator
  • In the bottom left corner of the view is a plus sign click on it to add a new breakpoint.  You will be asked to add an "Exception Breakpoint" or a "Symbolic Breakpoint" choose symbolic.
  • After selecting "Symbolic Breakpoint" a popover window will open fill it in as follows:
    • Symbol: objc_exception_throw
    • Module: libobjc.A.dylib

  • Follow those same steps again to add a new symbolic breakpoint as follows:
    • Symbol: -[NSException raise]
    • Module: CoreFoundation


  • To make the breakpoints global right click (command click - double finger tab - whatever) the break points to move them to the User context


And there you have next time you make a mistake Xcode will stop your app where it breaks - assuming it breaks in your code.  If you tell the frameworks to do something that doesn't work (such as loading a ViewController that won't load for some reason) you're back to the drawing board.

Hope that helps!

-Aaron