Objective-C Basics for React-Native Devs
Tags: objectivec, reactnative
Published: 2017-06-10 12:57:59

---
title: Objective-C Basics for React-Native Devs
published: true
description: Some Objective-C syntax explained.
tags: objective-c, react-native
---

You found out that React is more than a Framework and you now can use your React skills to do stuff like [VR](https://facebook.github.io/react-vr/) and [mobile](https://facebook.github.io/react-native/) development. So did your first mobile project, or even your first few projects with React-Native and got around rather well with your JavaScript knowledge. Most of the time you install JS modules via npm and sometimes native ones too, which link easily with `react-native link`.

But now somebody wants you to integrate, for example, the Facebook SDK and suddenly you find yourself reading installation guides, that force you to look into this `ios` directory, full of foreign mysteries.

You have to change some code in the `Info.plist` and `AppDelegate.m`, damn.

Well one of these files doesn't look too intimidating. The `Info.plist` seems to be the regular XML disaster you'd expect from corporate devs, you can work with that.

But the `AppDelegate.m` is another story. You've seen some C in your time, so the `#includes` and comments make kinda sense, but the rest? I don't even!

But fear not, for I shall tell you about this ancient tongue! 

## What

Objective-C is the love child of C and SmallTalk. Like C++ it tries to enhance C with object oriented programming features. So, as you may already thought, the Objective doesn't mean it has less undefined behaviour, but OOP tricks in its sleeve.

It is more like SmallTalk than C++, it incorporates the concept of [messages](https://en.wikipedia.org/wiki/Smalltalk#Messages) instead of method calls. One of their interesting properties seems to be, that they're dynamically typed, which should give the developer more flexibility. 

Also it has strange syntax, which is basically a mix of C and OOP add ons.

So going through the `AppDelegate.m` things are starting simple.

    /**
     * Copyright (c) 2015-present, Facebook, Inc.
     * All rights reserved.
     *
     * This source code is licensed under the BSD-style license found in the
     * LICENSE file in the root directory of this source tree. An additional grant
     * of patent rights can be found in the PATENTS file in the same directory.
     */

Well, that's a comment, izi pizi.

    #import "AppDelegate.h"
    #import <React/RCTBundleURLProvider.h>
    #import <React/RCTRootView.h>

And here are some includes, a bit harder.

These are called directives, which are passed to the C pre-processor. As far as I know they aren't really part of the C language, but of the pre-processor language. Well, what you need to know is, that they're used to include native code into your project before compilation. So when you create a native component, it will call native code sometime and this code has to live in some file your app need to know about.

    @implementation AppDelegate
    ...
    @end

What? Now we going to the interesting part!

Here is one of these OOP additions that Objective-C brings to C.

In some OOP languages definition and implementation is split up between files and Objective-C is such a language.

You may have noticed the `#import "AppDelegate.h"` before, which stitches together this split up.

In the `.h` files you define your interfaces, in the `.m` file you implement these interfaces by importing the `.h` file and using `@implementation` with the name of the interface, in our case `AppDelegate`, to implement and finish the implementation with `@end`.

I got little C/C++ skills, but as far as I know this split is just a convention so you could write it all in one file, but I won't go any deeper into the `.h` here, because I didn't have to look into it on React-Native adventures.

    - (BOOL)application:(UIApplication *)application 
    didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
      ...
    }

So what is going on here now?

As you may guessed, it's a method.

Like I said, Objective-C is quite different from C++ especially when it comes to syntax.

The `-` in the beginning tells that the method is an instance method, a `+` would make it to a static (or class) method.

Maybe a JS example helps here.

    class MyClass {
      instanceMethod() {};
    }
    MyClass.staticMethod = function() {};

    const instance = new MyClass();

    instance.instanceMethod();
    MyClass.staticMethod();

Then there is the whole `(BOOL)` `(UIApplication *)` stuff. I first thought this was the way of Objective-C to set types, but I was wrong, these are simply oldschool C type casts.

Objective-C's OOP is dynamically typed, but since it's still C at the core, the compiler needs to know what to do with all the data, so you have to tell it at runtime what's going on.

Without these casts the method would look like that:

    - application:application didFinishLaunchingWithOptions:launchOptions
    {
      ...
    }

What does it mean?

    - methodName:param1 labelForParam2:param2
    {
    }

The method name is the implicit label for param1 and every other param should have its own label. While these labels are optional, they're recommended, because they're used at call site. SmallTalk did it like that, so why change?

What brings us to ~~calling a method~~ sending a message in Objective-C.

    [object methodName:valueForParam1 labelForParam2:valueForParam2];

In JS it would look like that:

    object.methodName(valueForParam1, valueForParam2);

The reason for the labels seem to be a better readability on the call site.

    [array addObject:myObj at:myIndex];

Instead of 

    array.addObject(myObject, myIndex);

Anyway, the next line is a variable declaration, basic C with type in front, and the one after, we can read now too (almost):

    NSURL *jsCodeLocation;

    jsCodeLocation = [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@"index.ios" fallbackResource:nil];

`[RCTBundleURLProvider sharedSettings]` is a message without parameters, it's result will be used as the receiving object for the following message.

In Js it would look like that:

    let jsCodeLocation;
   
    jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURLForBundleRoot("index.ios", null)

Yes, there is `nil` instead of `null`. Seems to stand for _Not In List_? Also, your string-literals have to be prefixed with `@`.

    RCTRootView *rootView = [[RCTRootView alloc] initWithBundleURL:jsCodeLocation
                                                 moduleName:@"myapp"
                                                 initialProperties:nil
                                                 launchOptions:launchOptions];
    rootView.backgroundColor = [[UIColor alloc] initWithRed:1.0f green:1.0f blue:1.0f alpha:1];

Also, not much new happening here. The `rootView` object gets created with some configuration and then its attribute for background color is set.

What may be interesting here is, that even tho the parameters of messages are labelled, you can't change their positions, as you can see with the `initialProperties:nil`, where the parameter stays at its position and gets explicitly set to no value.

Most of the next lines are now self explaining, but talking about `self`, these lines probably need some explanation, haha.

    self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
    ...
    [self.window makeKeyAndVisible];

`self` is the `this` of Objective-C, so in this case the `AppDelegate` object.

Oh, I almost forgot, the `new`!

    UIViewController *rootViewController = [UIViewController new];

instead of 

    let rootViewController = new UIViewController();

So it's just like calling a static method on `UIViewController` to get a new instance. The _literal_ (but kinda wrong) translation to JS would be

    let rootViewController = UIViewController.new();

So to wrap it all up, the whole `AppDelegate.m` could look like this in JavaScript:

    import "React/RCTBundleURLProvider.h";
    import "React/RCTRootView.h";

    class AppDelegate extends UIResponder {
      application(application, launchOptions) {
         let jsCodeLocation;

         jsCodeLocation = RCTBundleURLProvider.sharedSettings().jsBundleURLForBundleRoot("index.ios", null);

         let rootView = RCTRootView.alloc().(jsCodeLocation, "myblossomapp", null, launchOptions);
         rootView.backgroundColor = UIColor.alloc().initWith(1.0, 1.0, 1.0, 1];

         this.window = RCTRootView.alloc().initWithFrame(UIScreen.mainScreen().bounds);
         let rootViewController = new UIViewController();
         rootViewController.view = rootView;
         self.window.rootViewController = rootViewController;
         self.window.makeKeyAndVisible();
         return true;
      }
    }

This is a translation as literal as it gets and semantically totally wrong at a few places, but I think it could help a few people to wrap their mind around it.

## Conclusion

Well, seems like Objective-C is a beast of a language, but nothing you couldn't tame!

Here I really just touched the basics of the whole thing. Most of the time you run `react-native link` and be done with it and sometimes you have to copy-n-paste code to the `AppDelegate.m`. For this you don't need in-depth knowledge of Objective-C, but it helps to know some syntax, Sometimes you miss a character and get crazy errors and don't know whats happening.

Also I think it makes you more confident about your software, if files you look into often aren't a syntactical mystery.