Tuesday, October 9, 2012

Modern Objective C : Literals

With the Introduction of iOS6 and the new LLVM Compiler Version 4.0, Apple introduced a few very handy and powerful features to the Objective C Language.

Sunday, October 7, 2012

iOS 6 : Add Social Networking with Social Framework

Another Quick and easy Post for everyone who quickly wants to implement a social sharing solution.
Essentially, all you have to do is calling the UIActivityController. 
Sure, you don't always want to show all sharing options but the out-of-the-box solution is fairly good and should suffice for a lot of Projects.

Assuming you have a Button in your View and a Touch Event such as TouchInsideOut is hooked-up to a receiver function, following code is all you need :

NSArray* shareStuff = @[@"Cool stuff to share",[UIImage imageNamed:@"coolimage.png"]];
UIActivityViewController* shareVC = [[UIActivityViewController alloc] initWithActivityItems:shareStuff applicationActivities:Nil];
[self presentViewController:shareVC animated:YES completion:Nil];

You always have to pass an NSArray containing your shared content towards the Activity Controller.
Please note that, if you want to share an Image you have to pass in an UIImage and not UIImageView.

Easy solution, nice effect.

Friday, May 18, 2012

iOS : Convert NSString to Integer or NSNumber

Many beginners struggle to convert an NSString into Integer hence this short example.

Convert NSString to Integer
NSString *string = @"5";
int value = [string intValue];

Convert Integer to NSString

NSString *string = [NSString stringWithFormat:@"%i", theinteger]; 

Thursday, February 2, 2012

iOS - Store CGPoint in NSArray or NSDictionary

Ever tried to add a CGPoint variable to an NSArray or NSDictionary?
Did you received the following error message ?
error: sending 'CGPoint' (aka 'struct CGPoint') to parameter of incompatible type 'id'

If so than following code snippet should be of good help to you:

NSArray *myPoints = [NSArray arrayWithObjects:
                     [NSValue valueWithCGPoint:CGPointMake(10.f,20.f)],

To restore your CGPoint value again just use following :

NSValue *myValue = [myPoints objectAtIndex:0];
CGPoint myPoint = [myValue CGPointValue];
Or in short :

CGPoint myPoint = [[myPoints objectAtIndex:0] CGPointValue] 

In case you never came across NSValue, just have a read through on the NSValue Class Reference.
As you can see, NSValue can come in quite handy.

Monday, January 23, 2012

Python: Convert Object to Dictionary

I recently had to explain how you can convert a Python Object to a Python Dictionary.
The answer is surprisingly simple :

class testclass:
        first = str()
        second = str()
        third = str()
        def __init__(self):
                self.first  = 'Some'
                self.second = 'weird'
                self.third  = 'test'

test = testclass()
print test.__dict__

As you probably guest, the answer is hidden in the last line.

Friday, January 20, 2012

NSJSONSerialization - Convert NSDictionary to JSON

Since iOS5 Apple offers a very simple way to handle JSON Strings with the NSJSONSerialization Class.
In this post I want to show how easy it is to create a JSON String with NSJSONSerialization.

NSMutableData *myData = [[NSMutableData alloc]init];
NSDictionary *myDictionary = [[NSDictionary alloc] init];
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc]initForWritingWithMutableData:myData];
[archiver encodeObject:myDictionary forKey:@"MyKEY"];
[archiver finishEncoding];
id MyJSONObject = [NSJSONSerialization JSONObjectWithData:myData options:0 error:nil];

Please note that I did not put an NSError Object in place to keep the example as simple as possible.

If you still have to support iOS4.X please have a look at Convert NSDictionary to JSON

Retrieve JSON from Web service and Decode JSON String with SBJSON

Now that I showed how to encode something to JSON string using SBJson in the post Convert NSDictionary to JSON I would like to show you how to retrieve and decode an JSON String coming from a Web Service.

You will need the JSON-Framework (https://github.com/stig/json-framework) for this example.

I won't hold a long talk and just go straight down to the code.

#import "myController.h"
#import "SBJSON.h"

@implementation myController

- (id) httpPostJson:(NSString*) JsonString toURL:(NSURL*) serverURL {
    NSData* postData = [JsonString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

    NSString* postLength = [NSString stringWithFormat:@"%d", [postData length]];
    NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] init] autorelease];

    [request setURL:serverURL];
    [request setHTTPMethod:@"POST"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
    [request setHTTPBody:postData];
    NSData *returnData      = [NSURLConnection sendSynchronousRequest: request returningResponse: nil error: nil];

    SBJsonParser* jsonParser = [SBJsonParser new];

    return [jsonParser objectWithString:[[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding] error:NULL];   


We just assume that our imaginary web service is communicating with us in JSON only.
Therefore I created a simple function which we just have to feed with a JSON string containing a Dictionary or Array and the actual URL of the web service.

The Breakdown

- (id) httpPostJson:(NSString*) JsonString toURL:(NSURL*) serverURL

And Yes, for this example I live in a perfect world and do not care about any secure connection ;-)

First thing we do is do create an NSData object that we can use together with NSURLConnection:
NSData* postData = [JsonString dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];

Than we have to figure out how much data we are actually sending to the server
NSString* postLength = [NSString stringWithFormat:@"%d", [postData length]];

and we have to create an NSMutableRequest object

NSMutableURLRequest* request = [[[NSMutableURLRequest alloc] init] autorelease];

Good, now we are almost done.
Next we have to set all Header information .
First we set the Server URL

[request setURL:serverURL];

the Request method is next with

[request setHTTPMethod:@"POST"];

the request size

[request setValue:postLength forHTTPHeaderField:@"Content-Length"];

and, actually important, the Content Type

[request setValue:@"application/json" forHTTPHeaderField:@"Content-Type"];

Please do not forget the Content Type as Programming Frameworks such as Pylons (as an example) can give you a hard time if you do not set the Content Type.

And last but not least we have to set our message body

[request setHTTPBody:postData];

Okay, now we just initialise the JSON Parser with

SBJsonParser* jsonParser = [SBJsonParser new];

and convert our result that will come as NSData to NSString and use the JSON Parser to return the appropriate ObjectiveC object

[jsonParser objectWithString:[[NSString alloc] initWithData:returnData encoding:NSUTF8StringEncoding] error:NULL]; 

In our example I return it as an ID object but you can use whatever is suitable for your situation.
If you know that the service you are connecting to is always returning an NSDictionary replace ID with an NSDictionary etc.
As mentioned in the beginning of this post, I do not care about security and error handling in this post.
I will address SSL connections and how to handle errors in a later post.

And please feel free to leave any comments be it a question, critic, a wish or anything else I can currently not think of.

So long. Happy coding days.

Monday, January 16, 2012

Convert Device Token to NSString

Did you had trouble to convert the Device Token you need for sending push messages to NSString?
Have a look at following example:
- (void)application:(UIApplication *)app didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)devToken {
NSString* deviceTokenString = [[NSString alloc]
                initWithString: [[[[devToken description]
                stringByReplacingOccurrencesOfString: @"<" withString: @""]
                stringByReplacingOccurrencesOfString: @">" withString: @""]
                stringByReplacingOccurrencesOfString: @" " withString: @""]];

That is the only working solution I was able to find. All other attempts, including converting the value to bytes as suggested by Apple, failed to work.
And don't forget to register your application with

[[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeSound)];

somewhere in your Application, preferable within
- (void)applicationDidFinishLaunching:(UIApplication *)app

Thursday, January 12, 2012

Installing ssl for Python (RedHat/CentOS)

Recently, I had to install pythons SSL library (http://docs.python.org/dev/library/ssl.html). After installing the OpenSSL dev Library with YUM I thought to be a good Idea to use easy_install and received following error message:

error: Setup script exited with error: SandboxViolation: open('/usr/lib64/python2.4/test/test_ssl.py', 'wb') {} 

After a few minutes of thinking, I decided to download the source with

wget http://pypi.python.org/packages/source/s/ssl/ssl-1.15.tar.gz#md5=81ea8a1175e437b4c769ae65b3290e0c

 and Install the module by hand :

tar -xzvf ssl-1.15.tar.gz
cd ssl-1.15
sudo python setup.py install

Confident that this will Install the package I started up python and imported the ssl library just to receive following :

Traceback (most recent call last):
  File "<stdin>", line 1, in ?
  File "ssl/__init__.py", line 61, in ?
    import _ssl2             # if we can't import it, let the error propagate
ImportError: No module named _ssl2

Now, what the .....?
After a bit of google research I found out that something is not right with the compiled __init__.pyc and deleted the file:

sudo rm /usr/lib64/python2.4/site-packages/ssl/__init__.pyc

And here we go! From now on the ssl library should work just fine.