A technology-agnostic blog about technology.

MonoTouch UIApplication and AppDelegate explained

By ESCOZ posted February 15th, 2010

When you create a new MonoTouch project, one of the first lines of code you see is the FinishedLauching() function, in the AppDelegate class. That’s also one of the first things to change when you’re following basically any tutorial. But what exactly is it? And why is it getting called?

When developing iPhone applications with MonoTouch, there’s always a lot of “magic” that happens behind the scenes; one of these is the AppDelegate class. Unlike most WinForms app, where all the events are always generated within your application, in the iPhone the OS generates a lot of notifications that get sent to the application. The AppDelegate object is one of the ways to receive those notifications from the OS (the other being the NSNotificationCenter). During the application startup, the iPhone OS deserializes the main NIB file (created from the MainWindow.xib file), which contains the UIApplication object and the UIApplicationDelegate object; you won’t need to create these objects, the framework takes care of that for you.

Every iPhone application contains one and only one UIApplication instance, which is a singleton and can be accessed via UIApplication.SharedApplication. Its main role is to handle the proper initialization of the application, and to maintain the list of Windows in the application (which contain all the UIViews objects). The UIApplication also helps routing URL requests and even takes care of things like the badge number displayed by the icon and orientation of the app. Anybody developing an iPhone store should consider taking a quick look at this class before releasing the app, to make sure all the settings are correct.

Together with the UIApplication instance, an UIApplicationDelegate is created. Its function is to receive the notifications from the OS that may affect the application. MonoTouch automatically creates a partial C# class called AppDelegate that inherits from the UIApplicationDelegate, which is kept in the Main.cs file. This is very handy, as every application should always implement at least 2 methods, also created automatically by MonoTouch: FinishedLaunching (UIApplication app, NSDictionary options) and OnActivated (UIApplication application). The default code created by MonoTouch can be seen below:

public partial class AppDelegate : UIApplicationDelegate
{

	public override bool FinishedLaunching (UIApplication app, NSDictionary options)
		{
			window.AddSubview (navigationController.View);
			window.MakeKeyAndVisible ();

			return true;
		}

		// This method is required in iPhoneOS 3.0
		public override void OnActivated (UIApplication application)
		{
		}
	}
}

Very important here is the FinishedLaunching method, where you should define the objects in your window, and return true. If you’re using Interface Builder, the UIWindow object will already be created (like above), so all you have to do is add subviews to it. Also, be careful about how much work you do on this method: the app will get killed by the OS if you take longer than a few seconds to return (5-6 in my experience, but I couldn’t find a documented number anywhere). So if you’re planning on loading data from the web, or opening a big database, make sure you do that in a separate thread.

There are several other methods in the UIApplicationDelegate class that you should seriously consider implementing:

  • ReceiveMemoryWarning: which is called when the iPhone is running out of memory and you should release memory right away or your app will be killed
  • WillTerminate: called after the user presses the Home button, gives you the opportunity to save the app state so that next time the user comes back the app looks like it was when it was closed. You’ll have to write all the logic to do this yourself, but this is essential for a good iPhone HIG “compliant” app.

The UIApplicationDelegate also handles Notifications, with the RegisteredForRemoteNotifications and the ReceivedRemoteNotification methods. To see a full list of methods in MonoDevelop, simply put the cursor after the closing statement of a class and type “override”. The full list of methods available will show up.



Cracklytics in the Apple iTunes store!

By ESCOZ posted February 12th, 2010

Yesterday the app I submitted to Apple was finally approved! The name is Cracklytics, and If you haven’t seen it yet, take a look at its website.

If you use Google Analytics, its a great tool to have!


Paging controllers with MonoTouch

By ESCOZ posted February 9th, 2010

I have just pushed a new control into my open source collection of MonoTouch controls, called PagedViewController.

I created this control during the development of my new iPhone application, Cracklytics (available soon in the AppStore, recommended!) mainly to simplify the usage of the UIScrollView to make applications that use pagination, such as the Apple’s Weather app.

Usage of the control is quite simple. All you need to do is create a new object of type PagedViewController, and pass a data source to it, like below (executed from inside a UIViewController):

var pagedViewController = new PagedViewController{
	PagedViewDataSource = new TestPagesDataSource()
};
this.View.AddSubview(pagedViewController);

The most important part of the code is the actual implementation of the TestPagesDataSource, used above. The class works as a factory of UIViewControllers, much like a UITableViewDataSource is used by the UITableViewControllers. The class needs to implement the IPagedViewDataSource interface, like the sample implementation below:

public class TestPagesDataSource : IPagedViewDataSource {
	private List _colors = new List{
				UIColor.Blue,
				UIColor.Red,
				UIColor.Yellow,
				UIColor.Cyan
	};

	public int Pages {get {return 4;} }

	public UIViewController GetPage(int i){
		UIViewController c = new UIViewController();
		c.View.BackgroundColor = _colors[i];
		c.View.AddSubview(new UILabel{
				Text= "Swipe to change view",
				TextAlignment = UITextAlignment.Center,
				Frame = new RectangleF(0,0,320,100),
				BackgroundColor = UIColor.Clear
		});
		return c;
	}

	public void Reload(){}
}

The most important methods there are the Pages counter and the GetPage(int i), which should return a new UIViewController. The Reload() method is called automatically when the Reload() method of the PagedViewController is called; you can use this to, for example, load more data from the web, or from a local database.

The control currently works fine if you don’t have lots of pages, probably a few dozen, because the controller automatically loads all the pages during startup. If you have more than that, though, the pages would end up using too much memory, so you would have to modify the controller so that only the current page, as well as the previous and the next pages are loaded.

To see this control working, download the entire solution from github.


Notes from an (officially new) iPhone developer

By ESCOZ posted February 6th, 2010

I have just finished uploading a new application to the App Store. While it’s waiting for Apple’s approval (hopefully that will happen soon), I decided to write down some information about how the application was developed. This won’t be a technical guide or a how-to; rather, these are some random thoughts that new developers to this platform can probably learn from.

Step 1 – Get the idea right

This is the first and the most important step: make sure your idea is rock solid, and that it’ll work well for the iPhone. The iPhone is an extremely constrained platform (small screen, no keyboard, no mouse, etc), so you need to make sure your application is doing the perfect thing for your user. Back in 2008, I attended an Apple Developer Day specifically for the iPhone, and the one thing I took out of that presentation were the ingredients to create a good iPhone app. You can watch that video here – Seven Qualities of Successfull iPhone Apps. Always remember that iPhone apps are not supposed to do everything, and that 90% of the ideas you’ll have won’t fit well in the Phone.

Step 2 – Go back to paper and pencil

Now its time to put write your idea down, and design how your app will look. There are some online tools available to do that, but nothing is easier and simpler than a sketch book and a pencil. I always use Erik Loehelm’s great template, and recommend everybody else to do so.

Iterate over your design multiple times. I mean, really, multiple times. Think about the position of every element, and how you could remove that element in the first place. The iPhone is very different from a normal page or desktop app, so saving space and finding innovative ways of displaying data is fundamental.

Step 3 – Do it!

Not much to say here, other than that this is hard and will take a long time to be done. Choose your tools wisely, based on what you know and what you want to learn, and just do it. Many times during development you’ll feel the urge to add new features to the app; many new features will be only a couple of lines away from you. Resist the temptation! Focus on your original wireframes, and getting that done.

Technically speaking, make sure you do things the right way: web calls should always be done asynchronously, UI elements should always be preloaded, memory should be freed as quick as possible. Get very used to write threaded code, and be extra careful with memory leaks. The iPhone is a fast computer in many ways, but you’ll often be amazed at how it is slow at some things.

Step 4 – Test it, and test it again!

Be very serious about testing. Nothing is worse than spending your users time by having your app crash every once in a while. Make sure you test special conditions: network on/off, rotating the app, different versions of the iPhone OS, multiple touches at the same time, and so on. Make sure you keep lists of all the bugs you have found. In my case, I like to use 37Signal’s Backpack application for that, but it really doesn’t matter which tool you use.

Make sure you always test in the iPhone, not on the simulator. The simulator only simulates the iPhone OS, not the hardware, and there are thousands of differences between each platform. You’ll find a lot of bugs in the phone that simply do not happen in the simulator.

Step 5 – Make it pretty

This step really should happen all along the way, but I thought it would be better to have a different topic for it. Along the way, you’ll have to develop multiple controls for your applications, buttons, align text, show different icons, decide on colors to use, and many other things.

Here’s my tip: Hire a designer.

If you can’t, do not try to do the design the app right away. Rather, try to first become a little bit of a designer. Learn about colors, learn about photoshop, learn about UI design. Apple provides lots of guidelines on UI design for the iPhone. Read it all, multiple times. Also learn about animations, and how give the user the right feedback at the right time.

UI design is hard stuff, a lot harder than most developers (me included) would like to give credit for.

Step 6 – Enjoy

Yes, you have just finished developing your new app. You have just submitted it to the App Store, and now you’re contemplating what to do. This is the step I am at right at this moment (February 6th 2010, 4pm).

Thinking back, it seems that the fact you need Apple’s approval to run your application on the iPhone is not entirely bad. It definitely forces you to focus a lot more on the steps above, which translates into a better application for your users.

It also translates to a lot more work, but nobody ever said this was going to be easy. Apple’s frameworks make it a fairly easy task to develop an iPhone app, but all the things around the platform in general end up taking a lot more work than you were probably expecting (at least that happened for me).

Overall, spending the last 3 weeks developing the new application all by myself was an amazingly gratifying experience, different from any other experience I’ve had developing for the web. Highly recommended.


MonoTouch Presentation at the ChiPhone Group

By ESCOZ posted February 5th, 2010

Later this month I’ll also be talking about MonoTouch at the chiPhone User Group. I’ll also have the pleasure of hosting the meeting this month at our offices at the Willis Tower (old Sears tower):

The presentation will be pretty much the same as the one I’ll give to the Chicago ALT.NET group, but because most people in the group already develop iPhone apps using XCode I’ll try to talk more about .NET in general and C#, instead of on the iPhone library.


ALT.NET Chicago MonoTouch Presentation

By ESCOZ posted January 28th, 2010


Next month I’ll be presenting about MonoTouch at the ALT.NET Chicago February 2010 Meeting:

MonoTouch is a new SDK based on Novell’s Mono platform that allows developers to create native iPhone (and soon iPad) applications using .NET languages and APIs. In this presentation, I’ll be talking about the iPhone platform in general, how MonoTouch fits in that ecosystem, and I’ll show how to create a quick sample application.

If you’re coming to the meeting, and have any questions or things you would like to see in the presentation, please contact me!

As many of you know, I’ve been co-hosting the ALT.NET meetings the great Sergio Pereira at our Redpoint office for the last two years, so it’s was big pleasure to be invited to present. Thanks goes to Sergio for the opportunity!


Developing with MonoTouch on Windows and Visual Studio

By ESCOZ posted January 28th, 2010

Here’s how to develop with MonoTouch on Windows and Visual Studio 2008. You won’t be able to compile the code, as it depends on libraries that simply do not exist on Windows, but tools like Resharper will work perfectly. This will allow you to write the code faster, but you’ll still need the mac to run the app on the Simulator or the iPhone.

On the mac:

  1. Create a new project with MonoTouch
  2. Put it in a network share, or a code repository, so it can be accessed from Windows.

On Windows:

  1. Download 7-zip and install
  2. Download MonoTouch’s trial version. We’ll need one DLL from this package.
  3. Open the pkg file with 7-zip and go to this directory: monotouch-eval-1.4.7.pkg\monotouch.pkg\Payload\Payload~\.\usr\lib\mono\2.1\
  4. Extract all the DLLs to a directory of your choice (not inside the project).
  5. Make copies of your SLN and CSPROJ files, and call them “mysolutionVS.sln” and “myprojectVS.csproj
  6. Edit your new mysolutionVS.sln:
    • Change the two references (at the top and bottom of the file) to point to the new myprojectVS.csproj.
  7. Edit your newmyprojectVS.csproj file:
    • Delete the “ProjectTypeGuids” line. In my case, the line to be deleted contains the following:
      <ProjectTypeGuids>{E613F3A2-FE9C-494F-B74E-F63BCB86FEA6};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
  8. Create a new file in the same directory called “myproject.csproj.user”, with the following content:
    <Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    	<PropertyGroup>
    		<ReferencePath>C:\path\to\monotouchlibrary\</ReferencePath>
    	</PropertyGroup>
    </Project>

    The ReferencePath above should point to the directory where you saved the DLL files in step 3. Do not include the dll name.

  9. Open the new solution with Visual Studio.
  10. Finally, remove the current references in that the project contains, and add references to the DLLs from the directory in step 3.

That’s it! You’ll now be able to open the solution in Visual Studio, and use tools like Intellisense, Resharper and others to facilitate the development. To compile the app, use the original solution file in MonoTouch. If you add or remove files, make sure you add them again when you go back to MonoTouch.

While I prefer to make these changes manually, as they’re quite simple, that may not be the case for you. In that case, Manfred Pohler created a little application that automatically does it for you, called VSMTouch. I haven’t used it, but it seems to do something similar to the steps above.


MonoTouch Calendar control is here!

By ESCOZ posted January 22nd, 2010

Here’s a new MonoTouch UIView many people will probably find useful: CalendarMonthView. As you can see in the picture on the side, this control is a copy of the built in Month View calendar control, used in Apple’s calendar app. This includes animations when moving between months, highlighting of the cells being selected and current day, etc.

Even if you’re not going to use the control anytime soon, I would still recommend taking a look at the code simply an example of how to develop a control like it. This code is based on the calendar control from the great Tapku Library, created by Devin Ross, and reading over that was a great way of learning more about the UIKit.

Using this control is really simple, as you can see in the  sample CalendarMonthViewController. All you have to do is instantiate a new CalendarMonthView control, and add it as a subview to the current view:

public class CalendarMonthViewController : UIViewController
{
	public CalendarMonthView MonthView;

        public override void ViewDidLoad()
        {
            MonthView = new CalendarMonthView();

			MonthView.OnDateSelected += (date) => {
				Console.WriteLine(String.Format("Selected {0}", date.ToShortDateString()));
			};
			MonthView.OnFinishedDateSelection += (date) => {
				Console.WriteLine(String.Format("Finished selecting {0}", date.ToShortDateString()));
			};
			MonthView.IsDayMarkedDelegate += (date) => {
				return (date.Day % 2==0) ? true : false;
			};

            View.AddSubview(MonthView);
        }
}

During the next few days, I’ll be adding a few new features to the control, like Range selection, more events, etc. The code still have a few small rendering bugs, which I’m working on. If there’s anything you would like to see implemented, let me know!

The full source code can be downloaded from my samples library in GitHub.

Update: I just committed a couple of changes to the control, one of them being the new delegate IsDateMarkedDelegate, which is used to display a mark for a day in the grid. To use this, simply create a new delegate or lambda expression (as above), and return true to display the mark. This to me seems considerably easier to implement then passing a list of DateTime objects that should have the dates, which is how this is implemented in the Tapku control.


TapkuLibrary’s LoadingHUDView control ported to MonoTouch

By ESCOZ posted January 19th, 2010

I have just pushed to github a port of the great TapkuLibrary’s LoadingHUDVIew control to MonoTouch. You can find the C# LoadingHUDView implementation here, or just download the entire solution to see the control working.

The code was translated mostly line-by-line, so the two classes still look very much alike. For comparison, the Obj-C code has around 130 LOC, plus another 10 for the Interface and around 20 of extension methods being used. The C# code has 140 in total. Not much of a difference, really. There’s quite a few things in the code that could be refactored, though, so the line count can probably be a bit lower than that.

To use the control, simply create a new object in code, and add it to the View, like below:

var hud = new LoadingHUDView("Loading", "This is the long message");
View.AddSubview(hud);
hud.StartAnimating();
NSTimer.CreateScheduledTimer(TimeSpan.FromSeconds(5),
                 ()=>hud.StopAnimating());

The code above will display a popup, and close it after 5 seconds. In the real world, you’ll likely call the StopAnimating() method after a web service returns, or a calculation completes, for example. Take a look at this Controller class for a better example of how to use the control.

MonoTouch makes it possible to load Objective-C compiled libraries to the compilation of the project, but C# bindings still need to be created to access those classes during runtime. The MonoTouch API documentation is fairly helpful; the only problem is it mentions a Binding Generator, but there’s no documentation for it in the wiki yet. Anyway, the major problem for me with that approach is that in order to make changes to the control, you have to fire XCode again, recompile, and then recompile in MonoDevelop. After doing that a few times, I just decided that translating the code was easier.

My thanks goes to Devin Ross, creator of the open source Tapku Library, for the great work! I’ll likely be rewriting some of the other controls as well, like the Calendar view.


Editing Decimal Numbers with UITextField control with MonoTouch

By ESCOZ posted January 16th, 2010

Here’s another control I created while developing an iphone app for a client: UIDecimalField. The entire source code can be found on github, together with the other controls I have created so far. You can see the control in use in the image on the right.

The new control inherits from the UITextField control, and allows the user to edit decimal values using the NumberPad keyboard, instead of the normal keyboard. Again, as I mentioned in my previous post, inheritance provides a much better way of adding functionality to existing UIKit controls, instead of doing composition.

First, we need to change the Keyboard type used by the control. That is as simple as changing the property during the initialization of the control:

public partial class UIDecimalField : UITextField
{
	public decimal Value {
		get { return UIDecimalField.GetAmountFromString(Text); }
		set { Text = value.ToString("N2"); }
	}

	public UIDecimalField (IntPtr ptr) : base(ptr) {
		Initialize();
	}

	protected void Initialize() {
		KeyboardType = UIKeyboardType.NumberPad;
		Delegate = new UIDecimalFieldDelegate();
	}
}

Now we need to handle the user input and transform the text in the control, so that numbers are always formatted as a decimals, including rounding and decimal/thousand separators. That is done by creating a new class that inherits from UITextFieldDelegate, and overriding the ShouldChangeCharacters() method, as below:

public partial class UIDecimalField : UITextField
{
	public decimal Value {
		get { return UIDecimalField.GetAmountFromString(Text); }
		set { Text = value.ToString("N2"); }
	}

	public UIDecimalField (Decimal currentValue): base() {
		Value = currentValue;
		Initialize();
	}

	public UIDecimalField (IntPtr ptr) : base(ptr) {
		Initialize();
	}

	protected void Initialize() {
		KeyboardType = UIKeyboardType.NumberPad;
		Delegate = new UIDecimalFieldDelegate();
	}

	private class UIDecimalFieldDelegate : UITextFieldDelegate {
		public override bool ShouldChangeCharacters (UITextField textField,
			NSRange range, string replacementString) {

			var newText = textField.Text.Remove(range.Location, range.Length)
							.Insert(range.Location, replacementString);

			if (newText.Length>0){
				textField.Text = (UIDecimalField.GetAmountFromString(newText)).ToString("N2");
			}
			return false;
		}
	}
}

Overriding this method means that we’ll have to rewrite the way a normal UITextField handles user input. That is done using the Insert()/Remove() methods in the first line. With the new text, we’ll have to convert the value to a decimal and reformat it, which is done by the static method listed below. Finally, we return false to prevent the base class from handling the user input.

Here’s the static method to convert the text:

private static decimal GetAmountFromString(string text){
	if (text.Length==0)
		return 0;

	var cleanedUpText = "";
	foreach (char c in text)
		if (Char.IsDigit(c)) cleanedUpText+=c;

	return (decimal.Parse(cleanedUpText))/100;
}

The code above rounds the decimals to 2 decimal places; modifying the code for different rounding should be just a matter of adding an additional property in the class and modifying the last row of the method above and the ToString(“N2″) above.