WPF Control Development Unleashed

Readers of the blog might think I am only working on iPhone stuff, but in fact I am programming WPF for 40 hours a week. I am glad, because C# / WPF is a lot better then Objective-C / Cocoa Touch.

WPF Control Development Unleashed

Last week I got the latest book of SAMS publishing about WPF. I did recommend the Windows Presentation Foundation Unleashed before, but now they have a new book. It’s called WPF Control Development Unleashed.

The previous book is still the best book out there, if you want to get started on WPF development. If you’re already an experienced WPF developer and develop your own WPF controls or use advanced layout scenarios, then the new book is for you. I am an experienced WPF developer (over two years 40 hours/week pure WPF programming), but there was enough in this book to pay $50 for it.

When you’re serious about WPF programming and think you know already a lot about it, then you should order this book right away.

Create applications for the iPhone

I little while ago I figured out how to disable A2DP on my iPhone. It requires some changes to property lists, which requires additional tooling and makes it less accessible to less experienced users. If it was a Windows based device, then I would have created an application to make the changes. So why not do this for the iPhone?

The iPhone also has a compiler and SDK, but it uses the Objective C language and the Cocoa Touch framework. I am used to Windows programming for the last 15 years and I can tell you that iPhone development is completely different. I bought two books that got me started on Objective C and iPhone development:

Useful books

Title: Learn Objective-C on the Mac
Author: Mark Dalrymple & Scott Knaster
ISBN: 978-1-4302-1815-9

This book describes all the aspects of Objective-C. I think it is a little verbose and when you already familiar with object-oriented programming, then you probably want to skip a lot of details. I bought it, because I wanted to make sure I didn’t miss anything. Make sure you know Objective-C, because it’s not just a different C++ dialect.

Title: Beginning iPhone 3 Development: Exploring the iPhone SDK
Author: Dave Mark & Jeff LaMarche
ISBN: 978-1-4302-2459-4

I first downloaded a PDF version of this book via a torrent site and liked it so much that I decided to buy the (updated) paper version of the book. It describes iPhone development from the ground up, so it’s a good starter for iPhone development. It describes all the common controls and views that are used in iPhone applications. I am not a Cocoa expert, but I think that if you are then this book is not for you and you should look for a bit more in-depth book.

Get the right tools

Developing iPhone applications is only possible on Mac OS X, so you need an Apple computer. The standard development environment is called Xcode. You need to obtain an Apple Developer Connection membership to be able to download Xcode. The online membership is free, so make sure you register.

Once you have been registered, then you should download and install Xcode. Make sure you download the right version. If you are running OS X v10.5 you need to download Xcode v3.1.x. Snow Leopard users (OS X v10.6) need Xcode v3.2.x. This is all you need to develop software for Mac OS X, but it doesn’t contain the iPhone bits. Go to the iPhone section on the developer website and download the iPhone SDK.

This is all you need to create iPhone applications and test the applications in the iPhone simulator.

Test application on your own iPhone

Once you are ready developing and testing your application in the simulator, then you need to test it on your own iPhone. You can enroll in the iPhone Developer Program, which will cost you at least $99. If you plan to put the application in Apple’s AppStore, then you need to do this. There is no other way to get your application in the AppStore.

My application will not be approved in the AppStore, because it changes system settings and this is not allowed or possible from applications in the AppStore. My application will be distributed via Cydia (only for jailbroken iPhones). You don’t need to enroll for the iPhone Developer Program, but you need to make some modifications to your Xcode installation to make sure you can sign your application.

Obtain a code signing identity

You need to obtain a code signing identity. Fire up Keychain Access and choose Keychain Access – Certificate Assistant – Create a certificate… and use the following settings:

KeyChain

Note that you create a certificate with the name iPhone developer for code signing and you want to override defaults. Click continue and accept the defaults (although you can change your email address). Make sure the certificate is stored in your login keychain.

Patch Xcode v3.2 to deploy

There are two ways to patch Xcode to allow the application to be build. This first method is to patch Xcode v3.2 to be able to sign applications without a provisioning profile (note that this patch is only valid for v3.2!!!):

#!/bin/bash
cd /Developer/Platforms/iPhoneOS.platform/Developer/Library/Xcode/Plug-ins/iPhoneOS\ Build\ System\ Support.xcplugin/Contents/MacOS/
dd if=iPhoneOS\ Build\ System\ Support of=working bs=1 count=300752
printf "\xc8\x2f\x00\x00" >> working
dd if=iPhoneOS\ Build\ System\ Support of=working bs=1 skip=300756 seek=300756
/bin/mv -n iPhoneOS\ Build\ System\ Support iPhoneOS\ Build\ System\ Support.original
/bin/mv working iPhoneOS\ Build\ System\ Support
chmod a+x iPhoneOS\ Build\ System\ Support

Another approach seems more elegant. Create a backup of /Developer/Platforms/iPhoneOS.platform/Info.plist and modify the Info.plist by replacing the two occurrences of XCiPhoneOSCodeSignContext with XCCodeSignContext.

Update project settings for code signing

Application signing Project – Edit Project Settings, select the Build tab and find the Code signing section. Select the Code Signing Identity. At the lower left part of the dialog, there is a popup menu and you should select the Add Build Setting Condition. Change the Any SDK to Device – iPhone OS 3.0. Select the iPhone developer certificate in the right column. If it doesn’t show up, then you didn’t create a proper certificate. The screen below shows the correct settings:

ProjectSettings

Sign your application

Applications on the iPhone need to be signed. You can use the official Apple signing method, which is pretty complicated, or use Saurik’s pseudo-signing method. In this tutorial I will use the pseudo-signing, because it’s easy and codesign checking has been hacked out of the jailbroken kernels anyway. There are two ways to pseudo-sign your application:

  1. Sign the applications on the iPhone itself. SSH to your iPhone and run apt-get install ldid. This will install the ldid utility in the /usr/bin directory. After you have copied your executable to the iPhone, then you need to run ldid -S <ProgramName>. This will sign the application, so you can run it.
  2. Sign the application on your Mac. Download ldid from TheBigBoss site to /usr/bin. Make sure that you can execute it (chmod 755 /usr/bin/ldid). Make sure you sign you applications at the end of the build process. In XCode select Project – New Build Phase – New Run Script Build Phase and use the following script:

    /usr/bin/ldid -S $TARGET_BUILD_DIR/$TARGET_NAME.app/$TARGET_NAME

If you forget to sign the application, then your application will crash immediately after starting.

Create a deployment package

I could have copied the text on Saurik’s website, but if you look here then you find everything that you need to create packages to deploy you application. After transferring the package to your iPhone, then you can install it using dpkg -i package.deb. You need to refresh your springboard to make sure the application is shown on screen. I use gUICache (available through Cydia) to refresh. Cydia refreshes automatically, after you (un)install a package.

Submit the application to a repository

When your application is ready, then you probably want to release it. You need to host the application via a repository, such as TheBigBoss.org. This repository is available in most Cydia configurations, so you are sure that users with a jailbroken iPhone can find your application. You need to have a Debian compliant package and need to fill in a form. The application will be hosted in the repository within 24 hours.

Resources

Bluetooth profile selector [jailbreak]

A little while back I described how to disable A2DP on your iPhone. It required manual modification of some files on the iPhone, which is not for the faint of heart. Now, I have created an application that allows you to change the Bluetooth profiles on a per-device basis. It works very easy.

Bluetooth device selectionBluetooth profilesAbout BTPS

Go to Cydia and look for the Bluetooth Profile Selector application. It is hosted with the BigBoss repository that is installed with Cydia by default. After installation you should see a red box with a Bluetooth icon inside of it.

The application shows all Bluetooth devices that have been detected. Just tap on one of the devices and the next screen is displayed that contains all the profiles that the iPhone can use on that device. The default setting enables all profiles, but you can choose which profiles that you want to enable. When you’re finished, just press the home button and the settings will be applied. During this process the Bluetooth server is restarted, so you’ll lose any active Bluetooth connections for a short while.

You can also download the package here. Put it on your iPhone and use SSH to run dpkg -i BTPS.deb to install it.

UPDATE: Apple has changed something in v4.3.1 and the profile selector cannot be used since then. Unfortunately, I don’t have an iPhone with v4.3.1, so I cannot test it. There has been some people that claim that they can fix it, so you can download the code here.

I received several requests from people if they could donate. You can donate via Paypal if you like:


Parallel processing

Did you know that the first 3Ghz Pentium CPU was introduced over 8 years ago? When you now look for a state-of-the-art processor, you’ll find the Intel Xeon “Nahelem” CPU, which runs only at 2.66Ghz. From the start of the Pentium processor (66Mhz, 1993) the clock speed doubled almost every 2 years. 10 year later we hit the 3Ghz barrier and since then we haven’t seen higher clock speeds anymore. So what happened since 2002? Well… Modern CPUs can do more in a cycle then the Pentium 4 could, but this is not the major speed improvement. The number of cores per CPU is the big difference. The current Nahelem processor is a quad-core processor, while the Pentium 4 was a processor with just a single core.

The hardware industry choose multi-core as a solution to increase performance. There are only two ways to benefit of multiple cores:

  1. You need to run multiple CPU intensive programs that can run in parallel.
  2. The application needs to take advantage of multiple cores.

Server applications typically handle more requests at the same time, so these are great for multi-core computers. Normal end-users often have only one CPU intensive application running. If the application isn’t written for a multi-core CPU, then the program is running at maximum performance, but only utilizes 50% (or less) of your CPU power. This is a waste of CPU power.

[h2]Why do programmers ignore multi-core[/h2]
Why do these programs don’t use these additional cores? Well… I think most programmers are not used to think about multicore programming, because multi-cores were only common in a server-based applications. Another issue is that multi-threading is difficult. Typical problems of multi-threaded applications are:

  • Race conditions and deadlocks, because multiple threads access the same resources and are not synchronized correctly. These bugs are often very hard to reproduce and to track down.
  • Threading limitations in libraries. Some libraries are not thread-safe or haven’t been tested well on multi-core systems.
  • Single threaded GUI frameworks (Windows GUI applications can only access the UI on the main GUI thread), so you need to synchronize GUI actions. Note that this restriction also applies to Apple OS X applications.
  • Additional coding effort to create and manage threads.
  • Multi-threading has overhead too.

Programmers need to know about these issues and because of constant time pressure, it is easier to ignore multi-threading and perform all work on the main thread. Microsoft and Apple understand to get more power from their systems, they should address these issues. Solving the fundamental problems, such as deadlocks, race conditions, … cannot be solved. It was possible to make multithreading more programmer-friendly and to significantly reduce the overhead.

Apple introduced Grand Central Dispatch (GCD) in Snow Leopard (OS X v10.6) and Microsoft will introduce Parallel extensions for .NET as an integrated part of .NET 4 (which will be released at the end of the year). Both technologies are similar in theory.

Grand Central Dispatch

Grand Central Dispatch was introduced with Snow Leopard (OS X v10.6) in August 2009. Apple claims that only 11 CPU instructions are required to schedule a task for GCD. It is also pretty easy to use. I will provide an example of using GCD (taken from Wikipedia). This is the single-threaded example:

- (IBAction)analyseDocument:(NSButton *)sender {
    NSDictionary *stats = [myDoc analyse];
    [myModel setDict:stats];
    [myStatsView setNeedsDisplay:YES];
    [stats release];
}

Using GCD it will look like this:

- (IBAction)analyzeDocument:(NSButton *)sender
{
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSDictionary *stats = [myDoc analyze];
        dispatch_async(dispatch_get_main_queue(), ^{
            [myModel setDict:stats];
            [myStatsView setNeedsDisplay:YES];
            [stats release];
        });
    });
}

The document will be analyzed by any available thread, but the GUI will be updated on the main thread (OS X GUI applications need to use the main thread for GUI interaction). As you can see, it’s pretty easy to dispatch blocks of code on another thread. Multi-threading is even more useful when you can use it in loops, like this:

for (i = 0; i < count; i++) {
      results[i] = do_work(data, i);
}
total = summarize(results, count);

Which can be rewritten to use GCD like this:

dispatch_apply(count, dispatch_get_global_queue(0, 0), ^(size_t i) {
    results[i] = do_work(data, i);
});
total = summarize(results, count);

Of course you must rely that all calls to do_work are complete independent of each other, but this code will probably execute up to 4 times faster on a quad-core system then the version without GCD.

.NET 4

Microsoft decided to introduce their technology in .NET 4 instead of the operating system itself. The drawback is that it is only available for .NET based applications, but this will be the majority of the future applications. The advantage is that Windows XP and Windows Vista will also benefit of this extension making it available to a broader audience.

I think the parallel extensions are more thought out than GCD, because they are more elegant to use. I think this applies to the entire .NET framework compared to Apple’s Objective C with Cocoa alternative. The parallel extensions can be used like this:

Parallel.For(0,count, delegate(int i) { results[i] = do_work(data, i); };
total = summarize(results, count);

As you can see, it looks very similar to the GCD approach. The major advantage of .NET 4 is that the parallel extensions are also included in LINQ, called P/LINQ. So the code listed above can also be rewritten as:

data.AsParallel().Select(t => do_work(t)).Count();

Adding AsParallel(). to an enumeration translates the enumeration in a parallel enumeration, which makes it very easy to use.

Conclusion

Using multiple threads is much more convenient and more lightweight to use in Snow Leopard and .NET 4. For complex operations, you will benefit from these technologies, so make sure you are prepared.

WPF TextBox differences

WPF control share no code with the old-style Win32 controls that are used in traditional Windows applications. The WinForms controls wrap the native Win32 controls and extend them in some areas. The WPF library complete rewrites these controls in native .NET code, so some differences may occur. In this post I will describe two small differences that might be annoying.

Using US international keyboard on Windows XP
Using a keyboard setting that allows composing letters with diacritics have some issues on Windows XP. If you set your keyboard to US international and you want to type a (double) quotation mark, then you are used to press ” and then hit the space bar. This doesn’t work correctly on Windows XP, because it will show a space instead of the quotation mark. It will only show the quotation mark when you press a letter. This behaviour is only on Windows XP with this keyboard setting, but because a lot of European end-users will use this setting it can become quite annoying. Typing quotation marks is engraved in one’s brain and it’s hard to get used to a different behaviour. I think this behaviour is wrong and filed an issue with Microsoft that can be tracked here.

Microsoft confirms that this is a bug and a hotfix is available (hotfix ID 376849), but you need to have QFE privileges to obtain the hotfix. Unfortunately, MS Netherlands doesn’t know anything about the QFE :-( . The issue is resolved in .NET Framework 4.0.

No initial selection
When you focus the textbox in Win32 or WinForms, then the text is automatically selected. WPF doesn’t select the text by default.

Default selection is different from old-style textbox
If you type the string “Ramon@foo.com” (without the quotation marks) and you double click on the word “Ramon”, then an old-style textbox will select the entire email address, but WPF textboxes will only select the word “Ramon”. Due to this different kind of finding “spaces”, other functionality that depends on it works different too. If you use CTRL-LEFT or CTRL-RIGHT, then it also is different. It’s different behaviour and I consider it a bug, because people are so used to the old-style functionality that this change might be difficult for end-users to get used to. A bug has been filed, but MS doesn’t consider this to be a bug.

Visual Studio 2010 is expected this year and I am looking forward how the changes reflect the Visual Studio IDE or if the IDE team uses its own controls.