BuySellAds.com

Until Dec 3rd, 44% off all Manning books, including Barcodes with iOS! Promo code: mobicftw
Our DNA is written in Objective-C
Jump

Dr. Touch's Parts Store

UPDATE: This article was split into the announcement and the information about individual parts. The annoucement stayed in this article, but the individual parts’ description was moved to the Parts Store page.

I like to reverse-engineer stuff because I learn much from how somebody else (like Apple) solved a UI problem. Most of the solutions I am coming up with are too big for a blog article, instead they found a home on my SVN. Generally when I demo my demos the reactions are entirely positive and I get flooded with requests to license those technologies.

I am not yet entirely certain on how to best organize such an endeavor, but spontaneously I had a title for it spring up from the back of my head:  Dr. Touch’s Parts Store.

Dr. Touch being my online brand, Parts referring to the components that I build to easy integration into a multitude of projects and Store as in “show me the money”. iPhone Development is my livelyhood and passion. So as much I would like to give away all, that’s not the reality I live in. My bank does not yet accept pro bono as legal payment.

So, if you see something on this site or in my YouTube videos that you like to be able to use in your own apps, you can!

By purchasing a source-level license to any of Dr. Touch’s Parts you gain access to my Subversion Repository where I am continuing development on parts as I am fixing bugs or implementing requested features.

Here’s what I have to offer right off the bat. All these components are readily available to license. To order your access please contact me via e-mail. You will receive access and free implementation support.

Go To Parts Store page.

New Year, in Context

What’s the appropriate New Year Greeting for a Cocoa Geek? He reverse-engineers something that Apple made into saying the wishes for him:

This is what my DTMenuViewController will look like or rather already does look like. Just like the one Apple includes since iPhone OS 3.0, but with any kind of labels you like to have. And any kind of colors you like. To prove that point, I made the NEW red. NEW Year. NEW Luck.

2010 will be great, I just know it. I remember that 2010 always was “the future” for me. Cool stuff, near enough to live to see it, yet far away enough so that some technical breakthroughs could happen. Stanley Kubrik’s 2001 was “in the future” and 2010 was even further futuristic. So that’s partially what imprinted this year in the back of my head as a goal to live to see it healthy and hopefully a bit wealth and a bit wise.

2010 will also be great because I am counting on the iSlate to double my market for Cocoa-written apps practically over night, one fateful Summer 2010 day.

Now that 2010 is almost upon us, the future has arrived and in a weird sense it just feels like the present. Duh. What’s the next year we should aim to see without any local or global health disasters?

Stay tuned for what’s coming on this blog in 2010. You ain’t seen nothing yet!

Update Jan 1st: YouTube Demonstration.

Update Jan 2nd: I made a demo showing of DTCalendarController in a Tap&Hold Tableview.

Source Code for this component is available for 100 Euros. A professional invoice is available if you need it for your professional app.

Dr. Touch #009 – "iSlate"

Today is the day after christmas. Mine was very comfortable and relaxing. My biggest present I made to myself, it was my 27″ i7 iMac which I unboxed earlier this month on YouTube. And when I unboxed my other Christmas presents I was excited to find a Microphone desk arm and a pop killer screen. This episode is already being recorded with this and on the new iMac. Ah and by the way, there is a new firmware for the graphics card in the i7 iMacs that supposedly fixes some screen problems. Though I never saw any of these. So I am blessed.

Subscribe to the Podcast in iTunes

My script (aka “Show Notes”) after the fold below.

Read more

MyAppSales 1.0.15 – "Holiday Fix"

The latest version of MyAppSales contains a fix for times when iTunes Connect is offline, but the ITTS reporting site is still running.

This way you still get your daily sales reports throughout the downtime for ITC which was announced to go from December 23rd until December 29th.

Another minor change is that review scraping no longer is requires for the app totals to be loaded because all reviews for all apps are scraped at the same time anyway. This is a minor startup speed benefit.

Merry Christmas and Happy Holidays!

UPDATE Dec 26th: Apple caught up on using the ITTS url for report downloading and shut this down as well, giving this message.

So, there now really IS no way to get to your daily reports anymore. We all have to wait until Dec 29th.

Double Tapping on Buttons

Grinarn asks:

“I got several buttons set up on my view and when the button gets clicked, a detailed view of that item appears.
What I need is another action method like double click or click and hold, to trigger another action.

How can I do this? I just found the events in the IB which seems only supports single touch events.”

Any view in the SDK can receive and process touch events. This gives you the ability to implement any kind of tap or gesture that you might dream up. But for everyday purposes we will find the methods provided by UIControl sufficient. UIControl inherits from UIView which means that it can do everything that views can do, but it adds the Target-Action mechanism.

For this mechanism you can attach a multitude of various events to each control by simply specifying a target (= any object instance), an action (= any selector of the target) and a constant from the following list. “Selector” is only fancy name for method signature, which consists of the method name and the names of the parameters, all with a colon behind them.

General Touch Actions

  • UIControlEventTouchDown
  • UIControlEventTouchDownRepeat
  • UIControlEventTouchDragInside
  • UIControlEventTouchDragOutside
  • UIControlEventTouchDragEnter
  • UIControlEventTouchDragExit
  • UIControlEventTouchUpInside
  • UIControlEventTouchUpOutside
  • UIControlEventTouchCancel

Specific to Editing Controls

  • UIControlEventValueChanged
  • UIControlEventEditingDidBegin
  • UIControlEventEditingChanged
  • UIControlEventEditingDidEnd
  • UIControlEventEditingDidEndOnExit

Generic Constants matching several Actions

  • UIControlEventAllTouchEvents
  • UIControlEventAllEditingEvents
  • UIControlEventApplicationReserved
  • UIControlEventSystemReserved
  • UIControlEventAllEvents

Now generally if you make a button then you would use the UIControlEventTouchUpInside event even though at first you might instinctively go for UIControlEventTouchDown. TouchUpInside is the standard as it allows the user to reconsider and move outside of the button before lifting his finger thus cancelling his action. Otherwise the button would be like a landmine where there is no way back after touching it.

Now there might be cases where you exactly WANT the action to be fired right when you touch the control. Then TouchDown is the right action. You also see a TouchDownRepeat action available, but this always comes in succession after a TouchDown. Therefore some additional trickery is necessary to be able to distinguish between single and double tapping a button.

Read more

Early Christmas, 27" i7 iMac arrives

I had ordered my 27″ i7 iMac on Black Friday and expected for it to arrive on Dec 22nd as per the information on the Apple Store website. I was happily surprised to suddenly have a UPS lady at my doorstep at 5 pm. I had never gotten a package from any package delivery service that late, that was another first.

When I inquired about that, she responded: “We start at 5 am and we don’t stop until all packages are delivered”. I like that kind of service.

My brother-in-law helped me record the unboxing on my iPhone 3GS. To get it from 15 minutes down to the maximum allowed 10 minutes for YouTube I already used iMovie on the new machine.

I got:

  • 27″ gorgeous LED-lit wide display. It’s also huge. Almost twice as wide as my 15″ MacBook Pro display.
  • 8 GB RAM, I chose the cheaper variant where all memory banks are full because I don’t think I will need more RAM for coding
  • i7 CPU, the fastest iMAC machine. It’s also the greenest because between high-power compiling it can idle more thus using less energy.

About this Mac

As a final test of happiness I installed XCode on it and timed a complete build (after clean all) of MyAppSales. I had to first export my certificates including private keys from my MacBook and import them on the iMac’s keychain. Then I also copied the provisioning profiles and installed all things via double click.

  • MacBook Pro 2.8 GHz Intel Core 2 Duo: 12 seconds
  • iMac 2.8 GHz Intel Core i7: 4 seconds

I had to double-check these results, but really the i7 compiles my biggest project 3 times as fast. You wouldn’t think that having the processor speed rated at the same value. But more cores and 2 generations later give you such a turbo-boost. “Roarr!” says the Tiger, pardon, Leopard, pardon SNOW Leopard.

Dr. Touch #008 – "Christmas in Sight"

Apple is planning an outage over Christmas, ’tis the season.

Play

Subscribe to the Podcast in iTunes

My script (aka “Show Notes”) after the fold below.

Read more

Reverse-Engineering the Apple CalendarView

Now that I am able to work on my apps full time I finally get to fulfilling my user’s wishes. Amongst those, for iWoman, was a Calendar view. I did not want to use another person’s code and deconstructing something that Apple made proved to be extremely instructive.

Here a video demonstration of my result so far. Please disregard the incorrect labelling at the top. At least this proves that this is not fake. :-)

The whole thing consists of three classes, a CalendarViewController which takes care of the general management of views, a CalendarDayView which derives it’s capabilities of responding to target/actions from UIButton and a CalendarHeadView which is everything you see at the top.

What makes it look special and professional is that you have multiple gradients at work. Besides of the obvious one at the bottom, there are black and gray gradients shading most of the labels. The regular gray background I custom draw in drawRect, but the blue selected box was too complicated so I opted to use a UIImage for that.

For most of the calendar calculations I needed an NSCalendar, so I made a helper class with category extensions to NSCalendar to give me things like first day of next month, first day of current month, number of days and so on. I found that I could quite reduce my memory footprint by reusing things. Like instantiating the NSCalendar just once for the whole view controller.

By far the trickiest business was to properly set up the grid of CalendarDayViews on an invisible view where I enabled cropping of children so that stuff could appear smoothly from below the gradient at the bottom. The animation itself is trivial, but it took some time to figure out that I would have to overlay the bottom or top line with alpha 0 with another set of days when going forward or backward and then animate it to 1 so that the selected day would move from being a gray rectangle (if you tap on a day that belongs to another month) to being blue.

For quickly switching between months you can tap and hold one of the arrows. For this I did not need any animations, so I pimped the method to set up my sheet with an animated: BOOL parameter. For regular switching this would be YES, for fast-switching it would be NO. Et voila!

That all worked nicely until I started to use it on device. I was asked about the performance on device, especially for fast-scrolling. I found that I could tremendously improve this by reusing the UIViews I am creating one for each day. Before my optimization all subviews to my sheet where removed from superview when they left the visible area. Since the sheet was the only view retaining them this also lead to their deallocation. Then I simply introduced an NSMutableSet to hold onto removed Views and also reuse CalendarDayViews from there. This speed things up quite a bit. Reuse if you can as much as you can!

Next things to do on the CalendarView control is to add a table view below it, so that I can query a data source for table view sections and rows pertaining to the currently selected date. I plan on using this in version 2 of iWoman, the first major update to my best selling app. I owe this to my customers since I did not get to update this app in over a year.

CalendarView will be the first of many things in my “Dr. Touch Parts Store” where you can obtain high quality components to use in your own projects for a small donation. The concept is that this small amount of money pays for the time I need to continue to improve it, support it and help you with implementing it.

Adding Last Build Date & Time

If you need or want the date and/or time the last time your app was built then there are two handy macros you can use. Consider the following example:

char *date = __DATE__;  // e.g. 'Dec 15 2009'
char *time = __TIME__;  // e.g. '15:25:56'
 
NSLog(@"Build date: %s", date);
NSLog(@"Build time: %s", time);

I tested it with GCC 4.0, GCC 4.2 and even the new LLVM GCC 4.2. It worked fine with all three compilers.

Those are precompiler macros which work by getting the precompiler to replace them with the current date and time when the file in which they are located in gets built. Bear in mind that generally building is incremental and therefore these will only get updated if there really IS a new build happening. That’s a drawback if you forget it, but you can or should always do a build – clean before you build a release or distribution version to make certain all got updated.

Since those macros date back to C times they get replaced with C-style strings. That’s a pointer to a char array with a binary zero at the end to terminate the string. To convert them to obj-C NSStrings is simple by means of the %s formatter or by using one of the more complicated initializers of NSString.

char *date = __DATE__;
char *time = __TIME__;
 
NSString *myDate = [NSString stringWithCString:date encoding:NSASCIIStringEncoding];
NSString *myTime = [NSString stringWithFormat:@"%s", time];

Finally if you are really so much “pro” that the build time of your app matters, then you will probably also ask if there is a way to force building of certain files to forego the incremental building. Sure you can. All you need to do is to add an extra script to your target to set the last modified time of the file using these macros to the future.

touch -t 2012310000 "${PROJECT_DIR}/Classes/CalendarAppDelegate.m"

Touching Script

It’s not enough to simply set the modified time once because then the next modification sets it back to the current date. Thus the need for this simple unobtrusive script, in this example I am setting the modified time for CalendarAppDelegate.m to Dec 31st 2020 which is sufficiently far away so that this blog article will work for the next 11 years. :-)

Waiting for Daily Reports

A developer based in the USA would probably never have to wait for the previous day’s sales report. But the iPhone app selling business being a global operation all EMEA and even more so APAC countries have to wait for a while until they can see how they are doing. That’s why I started to collect data on when a daily sales report usually becomes available so that I might be able to see a pattern or draw any interesting conclusions from that.

You might remember that I added anonymous availability reporting to MyAppSales 1.0.10. This way whenever a new report is encountered I am able to send out a push notification and automatically post it to the MyAppSales Twitter feed. The theory was that Apple would not make daily reports available at different times around the globe, but just have a single database that treats all developers the same. After a couple of days testing this hypothesis it was proven correct. In the beginning I was often myself the first person to see a report and thus trigger the notification. But very soon it started to happen that colleagues started to consistently beat me to the punch, be it either because they where more eager to get the report or just because the number of people with newer versions of MyAppSales exploded as I added more and more compelling features.

Now after 2 months Thomas Bonnin (thanks!) suggested to do an analysis, so I created a CSV file for the daily availability times for the past 2 months and Thomas kindly created these two charts from it. Bear in mind that the detection granularity grew over time, so at the beginning of this report the actual availability times might have been actually a bit lower.

Read more