The Notification Center is probably one of the most exciting features added in iOS 5.0. You have easy access to notifications sent by all sort of apps. You also have quick access to the weather and even stock market info. But why keep it there? When iOS 5.0 was released, the jailbreak community started working on tools that allow developers to extend the notification center widget’s capabilities to a whole new level. So why only show info on the weather or stocks market, when you can extend it to show info on anything you can think of? You could write a widget that will show the user the results of baseball games. Or a widget that will display the latest discounts on any given store… Your options are only limited by your imagination! You don’t have to limit yourself to informational widgets either: You can write “interactive widgets” too. You can, for example, write a widget that will show a button that, when pushed, will display a small window that will allow the user to compose a tweet. Hey, in fact, that’s what we are going to do in this tutorial!

In this small tutorial, I’m going to teach you how to write a small notification center widget for iOS using Theos. We’ll be building a simple widget that contains a custom button that, when pushed, will present a TWTweetComposeViewController modally so you can write tweets from the notification center.

(Theos is the set of tools used to write Cydia tweaks, like mobile substrate tweaks and notification center widgets. Explaining Theos is beyond this tutorial, but you will get to play with it and experience a little of what it can do).

Along the way I will show you how to:

  • Add official iOS frameworks for your Theos projects.
  • How to load images (because with Theos it isn’t as easy as [UIImage imageNamed:]!)
  • How to install other templates for Theos to use.

That’s it. You’ll be building a very simple widget but it should help you getting started with Theos and notification center widgets.

This is not a tutorial for people new to iPhone development, so please make sure you have experience with iOS development before proceeding. There are many websites and books that will teach you iPhone development, so if you don’t know anything about iOS development, spend a few months building (or attempting to build) an app or two first: I’ll wait for you and this tutorial won’t be going anywhere.

Finally, I’ not going to teach you how to install Theos on your computer. Please refer to this page to learn how to install and configure Theos properly for your machine. The good thing about Theos is that you don’t need a Mac to write your widgets, you can use Linux and Windows as well. Once you have everything ready, we can get started!

1. Getting the Templates

First things first: Theos doesn’t come with the needed template to write Notification Center widgets, so you have to download that first.

Dustin L. Howett (@DHowett), the creator of Theos, is hosting the Notification Center widget and a few other templates on big Github here. Feel free to download all of them, but we only need “notification_center_widget.nic” for this tutorial.

Once you download the template (shouldn’t take long since it is a small file), save it on the YOUR_THEOS_DIRECTORY/templates/iphone/ directory (On Mac OS X, the default location is /opt/theos/templates/iphone/).

Once you have that, you don’t need to do anything else as part of the setup.

2. Creating the Project

Time to create the actual project, and to know that Theos is “command-line heavy”. Open up the Terminal Window/Windows command prompt and navigate to a directory of your choice. I recommend you you create the project in a folder under your account’s folder to avoid permission issues. Another recommendation is to avoid having folders with spaces in their names. At least to me under Mac OS X, Theos had problems creating and compiling the source when the project path had spaces or other special characters.

Once you navigate to the folder of your choice on your terminal window, type in this command (it will vary according to your OS, but it’s just the directory of the nic.pl file):

1
/opt/theos/bin/nic.pl

That will show you the list of available templates for Theos to use (the option should 5, so go ahead and press that).

It will ask you for a project name. Something like “iNotitweet” or anything you want will do.

Next it will ask you for a package name, which is the reverse-DNS notation you used on normal iPhone projects before. I named my package “com.leonnears.openDev.inotitweet”.

Author/Maintainer name is self explanatory.

If for some reason you got lost in the wizard, here you have a screenshot of the terminal window once it is complete. It shows all the commands you need to put in order to create your project:

Theos Instructions.

Building the Actual Project

Okay, time to get started with the juice!

Go to your project’s folder. Theos has created a project folder with the project name (with no caps) in the folder you were in when you executed the commands.

In your folder, you will have the following files and folders:

  • BBWeeAppController-Protocol.h: This is the protocol needed by the widget. You won’t need to modify this file 99% of the time.
  • control: This is an interesting file. It contains all the metadata about your project such as iOS Firmware requirements, the author, project name, identifier. Additionally, in this file you can define it’s Cydia details, such as the tweak’s description, what folder it should be located in, etc.. In the end you will need to modify this file a bit, at least to change it’s description.
  • {YOUR_PROJECT_NAME}Controller.m (In my case, and in your case if you named the project iNotitweet, iNotitweetController.m): This is the main of your whole project. Here you will write absolutely all the code needed for your widget.
  • Makefile: Another very important file. In this file you tell your widget which iOS frameworks it needs and so on. You may or may not need to modify this file, depending on your project (in our case, we will modify this file).
  • Resources Folder: Here you need to save all the resources for your project, including but not limited to images.
  • Theos (shortcut): This is just a shortcut to the Theos directory in your PC.

So let’s start. Open up your favorite code editor, and open iNotitweetController.m. Time to get our hands dirty.

The first thing you will notice is that there is no companion iNotitweetController.h file for the file you have open. This is because for tweak development, it is a lot better to both define and implement classes in the same file. It’s a lot better to compile and deploy them that way.

Look for the implementation of loadPlaceHolderView, and you will find this. Don’t erase or modify this code unless you need to! This code will load the placeHolder view where your widget goes. Unless you want more customization or want to change the widget’s size, you don’t need to modify the coded provided to you here. Of course we can add more code below it, but the rest of the work is done in other methods of the template (such as loadFullView).

Go get some buttons for the project and save them in your project’s Resources Folder. You will need both a retina and a low resolution button. Well since this is not an official project, you can just use one or the other. If you don’t want to look for buttons, I have made this for an imomplete widget I was writing. Feel free to use this buttons for this test project only:

Tweet Button (Retina) Tweet Button (Small)

Now it’s time to start writing some code, and keep in mind one important thing. You need to write all your UI objects by hand. You cannot use Interface Builder for your widgets or other Theos template projects. So make sure you know how to build objects with code (if you can’t, you can pick this up along the way since it’s not a hard thing to do).

In the templates, you can code as you would with any other iOS projects. The process of creating is exactly the same. Only deployment is different compared to official iOS development.

Go to the loadFullView method. Here we create the objects to the views created by loadPlaceholderView.

Before proceeding, you will need to add a button, but like I said at the beginning of this tutorial, it’s not as easy as [IImage imageNamed:]. When it comes to tweak development, using imageNamed would look for an image on your device’s Springboard, which won’t work 99% of the time (unless you guess the name of a springboard image!).

At the beginning of your code there is a method called +(void)initialize. The only code here is the creation of an NSBundle that looks like this:


1
_iQuickCommunicatorWeeAppBundle = [[NSBundle bundleForClass:[self class]] retain];

You will need to use this object to fetch all the resources in your Resources folder. It may look obvious, but the truth is that at first when I started making widgets, I literally spent around 9 hours trying to figure out how to load images, because none of the methods worked. Luckily for me, DHowett came to my rescue and explained to me how things work, and now I’ explaining this to you to save a wasteful afternoon or even whole day!

Now that you know that and have those tweet buttons saved in your Resources folder, we may proceed.

We are going to create the UI first an later we will concern ourselves with the actual functioning of the tweak. So create a single custom UIButton, and, based on the explanation above, set the tweet buttons as the button’s background. Then just add it as a subview of _view:

This is what I did:


1
2
3
4
5
6
7
8
9
10
-(void)loadFullView {
    // Add subviews to _backgroundView (or _view) here.
    UIButton *tweet = [UIButton buttonWithType:UIButtonTypeCustom];
    [tweet setBackgroundImage:[UIImage imageWithContentsOfFile:
                    [_iNotitweetWeeAppBundle pathForResource:@"tweet"
                    ofType:@"png"]] forState:UIControlStateNormal];
    tweet.frame = CGRectMake(2, 0, 79, 33);
    [tweet addTarget:self action:@selector(composeTweet) forControlEvents:UIControlEventTouchDown];
    [_view addSubview:tweet];
}

You may have noticed the selector doesn’t exist. So just scroll all the way up and add it to the class definition at first as -(void)composeTweet. Then go back down to the class implementation and write it’s skeleton like this:


1
2
3
-(void)composeTweet {

}

Finally, we will actually modify our widget’s size to be as tall as the button, so go down to the loadPlaceholderView, and look for this line:


1
_view = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, {316.f, <strong>[self viewHeight]</strong>}}];

This line should be the first one in the method. Do the following small change:


1
_view = [[UIView alloc] initWithFrame:(CGRect){CGPointZero, {316.f, <strong>33.f</strong>}}];

The button is 33 points high, so our widget should be just as big.

Time to compile and see what we got! We are not finished yet, but so far it’s a great point to see if what we have looks fine. So in your terminal window type the following commands:

1
2
export THEOS_DEVICE_IP=INSERT_YOUR_DEVICES_IP_HERE
make package install

Theos will create a deb file and install it over sftp to your device automatically. So make sure your computer where you are developing and your phone are connected to the same network before running those commands.

Once it compiles, Theos will put it in your device and your device will respiring afterwards. Now you need to enable your widget in the Notification Center settings before you can see it, so go to Settings > Notifications > scroll down till you find iNotitweet (or the name of your project), dig in and enable it.

Once you enable it, if you have been following along, you should see the widget in the notification center like this:

What Your New Shiny Widget Looks Like.

We’re almost done. Everything that is left is to actually show the TWTweetComposeViewController view when the button is tapped. And that is easy as pie.

First, you need to include the Twitter framework at the beginning of your code:

1
#import &lt;Twitter/Twitter.h&gt;

But that alone won’t link your project to the Twitter framework. Now open up the Makefile file and look for this line.

1
iNotitweet_FRAMEWORKS = UIKit CoreGraphics

Like you can see, linking to frameworks is pretty straightforward. You just add an space and the name of the framework you are linking against. Since we want to link Twitter, everything you have to do is:

1
iNotitweet_FRAMEWORKS = UIKit CoreGraphics Twitter

And that’s it! You can now save this file and forget about it for the rest of the tutorial.

The final step is to implement composetTweet. For that, you have to create the TWTweetComposeViewController first and present it modally. Now this is a bit tricky and you may be asking yourself how can we present it modally if our widget is a subclass of NSObject rather than of an object that implements presentModalViewController:animated? I actually scratched my head against this problem before but I finally found the solution. The trick is to create a normal UIViewController object below the tweet composer, and set this UIViewController’s view property to your widget’s _view property. After you do that, just configure the tweet composer to dismiss when cancel is pushed and the rest of the configurations. Configuring the tweet compose view is out of the scope of this tutorial, so I will just show you the code (it should be pretty easy to understand):


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-(void)composeTweet {
    TWTweetComposeViewController *twtComposer = [[TWTweetComposeViewController alloc] init];
    UIViewController *someVc = [[UIViewController alloc] init];
    twtComposer.completionHandler = ^(TWTweetComposeViewControllerResult result)
    {
        if(result == TWTweetComposeViewControllerResultCancelled)
        {
            [someVc dismissModalViewControllerAnimated:YES];
        }
    };
    someVc.view = _view;
    [someVc presentModalViewController:twtComposer animated:YES];
    [someVc release];
    [twtComposer release];
}

And that’s it! make package install it into your phone and push the button. The tweet composer will show up and you can tweet from it, or you can dismiss the window in case you change your mind.

Tweet Composer View, All Shiny and Working.

That’s it folks! If you were/are having problems following the tutorial, I have put the full iNotitweetController.m file on my Pastebin, so feel free to download the code to compare it with yours, or to play with it in order to understand it more. Additionally, you may follow me on Twitter (@Leonnears) or leave your questions in the comments.

Oh, one more thing before I forget, to uninstall the widget, go to Cydia and look for your widget in the installed packages. You can uninstall it from there.

I will appreciate any feedback. This is the second tutorial I have ever written.

Problems?

We have a new Questions and Answers section so you can get help from the awesome community.

Ask a Question

Enjoyed this post?

Subscribe to our RSS Feed or Follow us on twitter to keep up to date with the latest from iOS-Blog. Remember, Sharing is caring so please click one of the following options:

Tags: , , , ,