My Package 1.2.0

My Package 1.2.0 is approved and hit on the App Store now. Most important update is iOS 4.2 support. Apple changed the behavior around Map component and it broke app’s location mapping feature. It took some time to understand what was going on but I think mapping feature is now working again on iOS 4.2 devices.

Another big fix is finding your location. Apple’s reverse geocoder often fails to find address through API. I stopped using Apple’s reverse geocoder and switched to Google’s Geocoding API. It works more stable.

I also updated the package listing UI with nice little map image to understand the current package location easily.

Version 1.2.0 is available on iTunes App Store in all countries for free.

Enjoy!

My Package 1.1.2

My Package 1.1.2 is approved and hit on the App Store now. With this version, you will see warning message instead of pointing south west of Africa. Also I fixed multiple minor issues in this release. The application must be more stable now.

  1. Changed to show warning message for the package which does not have address or unable to locate
  2. Fixed reordering tracking item problem
  3. Fixed not pointing correct map annotation when it back from history table view
  4. Fixed random crash at low memory status

Version 1.1.2 is available on iTunes App Store in all countries for free.

Enjoy!

My Package 1.1.1

My Package 1.1.1 is just out. This is minor update to fix small bugs. I am also working on fixing showing up package in south west of Africa in some cases. The fix will be in 1.1.2 which is coming in a week or two.

  1. Fixed not showing direction arrow if tracking history has only one item
  2. Changed to show error dialog if communication error occurred
  3. Adjusted ad update timing

Version 1.1.1 is available on iTunes App Store in all countries for free.

Enjoy!

How to switch the code/build for the device or simulator

“My Pacakge” uses AdMob for showing ad in the application. The bad thing about AdMob library is it is not compatible with iOS 4 simulator (so many linking error occurs). I found the way to avoid these errors in the apple document. Switching code with pre-processor macros and exclude AdMob library from simulator build are the answer.

Compiling Source Code Conditionally for iOS Applications
There may be times when you need to run code on the simulator but not on a device, and the other way around. On those occasions, you can use the preprocessor macros TARGET_OS_IPHONE and TARGET_IPHONE_SIMULATOR to conditionally compile code.

So I changed the code like below to remove AdMob lib dependency for the iPhone simulator build.

#if TARGET_IPHONE_SIMULATOR
  UIView *ad;
#else
  AdMobView *ad;
#endif

One more thing necessary for switching the code is library linking. Build setting needs conditional linking otherwise linking error occurs.

Opening Project info dialog then select Build tab. Find “Other Linker Flags” setting and select “Add Build Setting Condition” from Action menu (lower left corner menu).

Custom Linker Setting

You can pick up conditions of sdk (device or simulator and its versions) and specify library or framework link settings (or other build settings).

Link:

Editing Conditional Build Settings (developer.apple.com)

Now you can automatically switch setting based on device or simulator.

My Package 1.1.0

My Package 1.1.0 is just out! It includes the fix for the major reason of application crash in 1.0.0. And it also improvs package location mapping algorithm.

For iPhone 4 user, 1.1.0 includes high-resolution resources. You will see better graphics on your retina display!

New Features:

  • Support iOS4 (Fast App Switching)
  • Added high resolution resources for iPhone 4 retina display
  • Implemented accessory view tap action in package list view
  • Added clear button to the destination address text editor

Fixed Problems:

  • Changed ad handling logic. (This must improve application stability.)
  • Fixed not showing direction arrow problem
  • Improved package location finding logic
  • Fixed minor bugs

Version 1.1.0 is available on iTunes App Store in all countries for free.

Enjoy!

My Package 1.0.0

I have just submitted the first version of “My Package”. This application helps you to track package and find out where it is.

Current version supports packages handled by UPS/Fedex/USPS. Since this application does not use web-scraping trick, it will provide more consistent and accurate result.

The application is simple and easy.  You can just copy and paste tracking number and some optional information, you are ready to go.

(Update: 6/30/2010)
Version 1.0.0 is approved! Now you can download at iTunes Store.

If you have any questions, suggestions or comments, please let me know.

“My Package” uses following icons.

Thanks to their great work!

If you have any questions or suggestions, please leave a comment.

How to trigger MKAnnotationView’s callout view without touching the pin? – Stack Overflow

But there is a catch to get benvolioT's solution to work, the code

for (id currentAnnotation in mapView.annotations) {
  if ([currentAnnotation isEqual:annotationToSelect]) {
    [mapView selectAnnotation:currentAnnotation animated:FALSE];
  }
}

should be called from – (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView, and nowhere else.

The sequence in which the various methods like viewWillAppear, viewDidAppear of UIViewController and the – (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView is called is different between the first time the map is loaded with one particular location and the subsequent times the map is displayed with the same location. This is a bit tricky.

via How to trigger MKAnnotationView’s callout view without touching the pin? – Stack Overflow.

Functions for CGRect

In the cocoa (cocoa touch) framework, CGRect structure are used in many places because its rendering system depends on Core Graphics library. Here are the useful functions for CGRect structure.

Function Description
CGRectMake() Creates CGRect structure from integer values

// creates CGRect with  x=0, y=0, width=100, height=100
CGRect rect = CGRectMake(0, 0, 100, 100);
CGRectFromString() Creates CGRect structure from string

// creates CGRect with x=10, y=20, width=100, height=200
CGRect rect = CGRectFromString(@"{{10, 20}, {100, 200}}");
NSStringFromCGRect() Creates NSString object for specified CGRect structure. It is same format as the argument for CGRectFromString().

CGRect rect = CGRectMake(0, 0, 100, 100);

// outputs {{0, 0}, {100, 100}}
NSLog(@"%@", NSStringFromCGRect(rect));
CGRectEqualToRect() Checks whether given two CGRect are equal in both size and position.

CGRect rect1 = CGRectMake(0, 0, 100, 100);
CGRect rect2 = CGRectMake(10, 20, 100, 100);

// returns false
CGRectEqualToRect(rect1, rect2);
CGRectIntersection() Returns the intersection of two rectangles. Note that if two rectangles do not intersect, it returns the null rectangle.

CGRect rect1 = CGRectMake(0, 0, 100, 100);
CGRect rect2 = CGRectMake(10, 20, 100, 100);
CGRect intersect = CGRectIntersection(rect1, rect2);

// returns {{10, 20},{90, 80}}
NSLog(@"%@", NSStringFromCGRect(intersect));
CGRectIsNull() Checks null

CGRect rect1 = CGRectMake(0, 0, 100, 100);
CGRect rect2 = CGRectMake(200, 200, 100, 100);
CGRect intersect = CGRectIntersection(rect1, rect2);

// returns YES (1)
NSLog(@"%d", CGRectIsNull(intersect));

There are more functions for this purpose. Check Apple’s website for the detail.

How to change the carrier name in the iPhone simulator

iPhone simulator shows “Carrier” as default carrier name. You can change this name whatever text you want.

1. Open ~/Library/Application Support/iPhone Simulator/User/Library/Preferences/com.apple.springboard.plist file with Property List Editor application

2. Add a new Row with key name “SBFakeCarrier”.

3. Set its value as whatever you want.

Property List Editor

4. Save plist file and that’s it. You will see the text you entered in step 3 in the iphone simulator.

Open URL from application

Pretty simple. This call terminates the application and starts Mobile Safari browser with specified URL.

  [[UIApplication sharedApplication] openURL: [NSURL URLWithString: @"http://www.apple.com/"]];