Author Archive for hristo

UIWebView and anchor links

Today I needed to load a local html file into a UIWebView and jump to a specific section in the file. I thought this is simple enough all I have to do before creating a NSURL is make sure the url string has the correct anchor appended at the end of it. So I tried:

UIWebView *myWebView = [[UIWebView alloc] initWithFrame:frame];
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *stringUrl = [mainBundle pathForResource:@"mypage" ofType:@"html"];
stringUrl = [stringUrl stringByAppendingString:@"#jumpto"];
NSURL *baseUrl = [NSURL fileURLWithPath:stringUrl];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:baseUrl];
 
[myWebView loadRequest:urlRequest];

Unfortunately it turns out that [NSURL fileURLWithPath:stringUrl]; encodes the string converting the # symbol into %23 escape code, which prevents the page from loading. Finally I found the solution by first creating a NSURL variable and then appending the anchor link to it. Here is the code that got the job done:

UIWebView *myWebView = [[UIWebView alloc] initWithFrame:frame];
NSBundle *mainBundle = [NSBundle mainBundle];
NSString *stringUrl = [mainBundle pathForResource:@"mypage" ofType:@"html"];
NSURL *baseUrl = [NSURL fileURLWithPath:stringUrl];
NSURL *fullURL = [NSURL URLWithString:@"#jumpto" relativeToURL:baseUrl];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:fullURL];
 
[myWebView loadRequest:urlRequest];
Comments

XCode error 0xE8000001 while installing app on iPhone

I wasted several hours today trying to understand why my app would not install on the iPhone. Halfway through copying, XCode would throw error message 0xE8000001. A more detailed description appeared in the Console.

MobileDevice: copy_symlink:
Could not create symlink on device: 16


MobileDevice: transfer_package: Could not copy
/Users/username/iphone/MyApp/build/Debug-iphoneos/MyApp.app to PublicStaging/MyApp.app on the device: (null)


MobileDevice: AMDeviceTransferApplication: Could not copy package to device via AFC: kAMDUndefinedError

The app was properly signed and I had installed it on the phone before. After a lot of digging around I found this post.

It turns out that if something prevents XCode from copying an app to the phone, the app is left in this directory:

/private/var/mobile/Media/PublicStaging

Lo and behold I navigated to that folder on the phone and my app was left hanging there. I deleted my app's folder from PublicStaging and ran Build & Go, which installed the app with no problems. I was able to navigate to this folder on my jailbroken iPhone; however, my colleague had the same issue on his virgin iPhone.

To get the app to install on his phone I had to edit the Info.plist file and changed Bundle Name. I also had to change Project -> Edit Project Settings -> Packaging -> Product Name to match the Bundle Name and viola! The app installed successfully. Unfortunately the old app folder will be left lingering in PublicStaging until the next restore.

Comments

Text Rollover on Data Grid with a Custom Item Renderer

I ran into an issue with a data grid and an item renderer. Hopefully this post will help some poor soul out there struggling with the same problem. So how did it all start?

I had a simple datagrid populated with data and specific selection and rollover colors. On mouse over the appropriate selection color and rollover color were displayed on that particular row of the datagrid. I needed to add an image next to the text of the first column. It turned out that after specifying an item renderer for the first datagrid column my text rollover and selection colors did not take effect any longer.

After some browsing around I found the solution was to create a custom item renderer that implements the IDropInListItemRenderer interface. This interface adds a getter and a setter for a property called listData. By overwriting the validateNow() method you can use the listData property to check if the current row is highlighted or selected, then set the correct color of the text.

Look at the example below. You can right click and select View Source to check out the source code. Also you could download the project from svn.

Comments

Installing swftools on Mac OS X Leopard

Some time has passed since my last swftools install documented in this blog post. Two important things have happened since then, first Apple came out with a new OS 10.5 Leopard and swftools is now included under fink. Fink is a utility that allows for the pain free installation of open source *nix software under Darwin. To get swftools running under Leopard we need to first install fink and then use fink to install swftools.

This post would be almost over if fink were available as a binary package for Leopard. Unfortunately at the time of writing in order to get fink running on 10.5 we need to compile it from source. Make sure to check the fink site to see if a binary package has been released for Leopard. To download the source code go to the download section of the fink site located here. I'll be using the latest version, which is fink-0.28.1. Ok let's get started:

1. Make sure you have XCode installed.

2. Go to the directory where you downloaded fink and extract the downloaded archive by running the following command
tar xzvf fink-0.28.1.tar.gz

3. Go to the newly extracted fink-0.28.1 directory.

4. Run the command ./bootstrap.

5. Fink needs root privileges to be installed, when prompted which method to use I chose sudo, which is the default selection [1]. You will then need to enter your password.

6. The installer offers the option of selecting where you would like to install fink. I just left the default location /sw.

7. You will get asked a couple dozen questions to which you could safely leave the default values by hitting the enter key. The important one to change is when the installer prompts you about the "unstable" tree. It is very important that you answer Y so that packages from the "unstable" tree are included with fink. Swftools is currently a part of that tree in version 0.8.1-2.

8. Once everything is done compiling and linking run

fink selfupdate

and leave the default selection of using rsync for the self update method.

9. Now it's time to install swftools. Just run the command

fink install swftools

You will be notified that 16 additional required packages will be installed. Just hit enter to install all of them.

10. Swftools 0.8.1-2 are now installed in /sw/bin/ or whatever directory you specified in step 6.

To verify that you have swftools installed correctly just run /sw/bin/pdf2swf --version. You should see output similar to the one below:

pdf2swf - part of swftools 0.8.1

Hopefully soon enough there will be a binary package for fink so the install will be much simpler.

10 Comments

ActionScript 3 value object generator

It seems every time I start a new project there is always a period of time before the server side and the client side logic begin working in sync. In this post I will present a little tool I created for our last project. The task of this tool is to convert value objects or transfer object (VOs/TOs) from XML into ActionScript. I found it really useful in getting the project off the ground as it allowed the ui team to start creating the interface and using actual tos before the server side was ready to go. Applying the service locator pattern to the service layer allows one to easily switch from XML service implementation to the real services.

In the rest of post I refer to the objects being parsed as TOs or transfer objects. The distinction between a transfer object and a value object is that the latter might contain not only data but also perform some logic as well. Transfer objects simply facilitate the moving of data between the backend and the frontend. They do not perform any logic at all. Now let's start parsing some TOs.

To get the parser going we need to follow several simple steps. First, create an XML file containing the TOs' mock data. Second, setup the parser with the correct directory structure and files. Last, invoke the parser. Here I just use a simple test program to invoke the parser. In a real project you would want to create a separate XML implementation for your services and call the parser from each service.

Before getting started with the parser we need to create a XML file. For our example I'll use 3 classes a UserTO class, a AddressTO class and a RoleTO class. Here is the users.xml file that is to be parsed.

A few things to note about the syntax of the XML file. Each class is contained in a <Class> tag. The type attribute specifies the type of the object. A tag without the type attribute is considered to be a String. The ref tag specifies that the details of the class are located in another file.

After the XML file we need to create TO classes to instantiate and populate with data. These are UserTO.as, AddressTO and RoleTO.as. Since they contain just getters and setters I have omitted the code but you can download the source code from 9mmedia's svn.

So we have our XML ready and our TO objects ready to get populated with data. The last step remaining is to setup the parser. We do this in the XmlToParserConfig.as file. Here is how it's done:

Make sure that the toPackage property is pointing to the correct folder where the TOs are stored and that xmlDirectory is pointing to the folder with the xml files. Also note that all classes you define have to be included in the XmlToParserConfig.createInstances() method. All files need to be referenced at least once so that they are included in the swf. The XmlToParserConfig is passed to the constructor of the XmlToParser as you can see below.

The last step remaining is to run the parser.

Once the file finishes parsing onParseComplete is executed and the users collection is populated with 2 UserTO objects.

You can find the source code in the 9mmedia public svn repository located here.

Certainly there are other ways to accomplish the task of getting the frontend up and running. I have found that using the XmlToParser is an easy way to get a project off the ground quickly without a functioning backend. The greatest part about it being that the switch from mock to real data can be made at anytime in the service locator. Depending on the particular implementation one could set each service individually to use real or mock data.

Comments