Skip to content

Posts from the ‘Technology’ Category

24
Jan

200 Million iPads Update

Back in September, I estimated that Apple would sell 200 million iPads by the end of 2012. It looks like I was a little too optimistic.

Apple just reported stellar quarterly results. However, iPad sales growth was not quite as strong as Apple’s initial sales seemed to indicate. Two years after introduction, the iPad is selling better than the iPhone did two years after its debut. But it looks like it may take one extra quarter for Apple to hit 200 million iPads.

Actual Results

Estimated iPad sales through 2012

Estimated Results

  • Jan to Mar 2012: 11.8 million
  • Apr to Jun 2012: 23.4 million
  • Jul to Sep 2012: 28.0 million
  • Oct to Dec 2012: 38.9 million
  • Jan to Mar 2013: 29.9 million

Disclosure: I own AAPL stock.

11
Jan

The First 100 Days of a Startup

Josh Coates, founder of Mozy and current CEO of Instructure, once taught a series of classes at BYU on high-tech startups. I jumped at the chance to audit his class.

One of the things Josh covered was what should happen during the first 100 days (14 weeks) of a high-tech startup.

Week 1 — Research and choose business
Week 2 — Build financial model and development plan
Week 3 — Build pitch with screenshots and practice
Week 4 — Interview law firm, staff and advisers
Week 5 — Incorporate and setup shop with office space and equipment
Week 6 — Initial documents, books, hires and cap table
Week 7 — Create website and logo (do a trademark search)
Week 8 — Identify 10 to 20 potential investors and study who else they invest in
Week 9 — Practice the pitch and setup meeting with the least important investor
Week 10 — Interview, build product, pitch again
Week 11 — Interview, build product, pitch again
Week 12 — Interview, build product, pitch again
Week 13 — Interview, build product, pitch again
Week 14 — Interview, build product, pitch again

He recommended interviewing one potential employee every day. Pitching to the least important investor first lets you have a chance to practice in a situation where making a mistake isn’t as damaging.

I first met Josh just after publication of an article he wrote on how many angel investors in Utah were doing it wrong. The article, entitled “Poison in the Well”, in addition to having a great title, was direct and clear in its criticism. It was one of the reasons I later applied to work at Mozy.

For anyone who knows him, I think “direct and clear criticism” is a good phrase to describe what it’s like to work for Josh. His class was no exception. It was a great chance to learn from someone who’s been there and done it successfully.

16
Sep

200 Million iPads

About a month ago, I mentioned in a meeting at work (and later tweeted) that I believed Apple would sell about 200 million iPads by the end of 2012. Brief awkward silence. Then I was asked to send out the details of how I’d arrived at that number.

Honestly, at that point, I’d just eyeballed the sales trends. As I opened up a spreadsheet, I really hoped my estimate would hold up. :)

The first iPad went on sale on April 3, 2010. Here are Apple’s official iPad sales numbers:

At this point, we only have one year-over-year growth number for comparison. That’s fairly weak evidence on which to predict the future. But this is just for fun and games, right?

Assuming that the growth rate remains consistent, here is what iPad sales will look like:

  • Jul to Sep 2011: 11.8 million (actual result was 11.1 million)
  • Oct to Dec 2011: 20.7 million (actual result was 15.4 million)
  • Jan to Mar 2012: 13.2 million
  • Apr to Jun 2012: 26.1 million
  • Jul to Sep 2012: 33.3 million
  • Oct to Dec 2012: 58.4 million

Estimated iPad sales through 2012

192 million iPads by the end of 2012. Apple is selling every iPad they can make so these numbers may be limited by Apple’s ability to meet demand.

Put another way, here are the yearly totals:

  • 2010: 14.8 million
  • 2011: 46.4 million (actual result was 40.1 million)
  • 2012: 131.0 million

That’s the beginning of a very fast growth curve. There are a few others who agree.

Apple will report their next financial results in mid-October. Then we’ll have two data points.

Disclosure: I now own some AAPL stock.

4
Apr

Free DNS Hosting Performance Tests

Way back in April 2009, I read two articles about using Pingdom to test hosted DNS services. Pingdom has a limited free account, includes several types of web-related performance tests and has test servers in over 25 locations throughout North America and Europe. I started using it immediately and have been very pleased with their product and service.

I’ve been wanting to test the performance of hosted DNS services that include at least one domain for free. Two years later, I finally got around to it. All tests were done with my own domain name.

Each test covered eight days (except Afraid, which I ended early after six). I would have preferred to run the tests concurrently over a longer period of time. If I missed anyone, please let me know and I’ll add them to the list.

NameUptimeResponseStd DevNotes
Namecheap100.00%82 ms175 msIncludes free email forwarding.
ClouDNS100.00%93 ms319 msExcellent user interface.
Moniker100.00%114 ms248 ms*** Included with domain registration. ***
ZoneEdit99.65%91 ms280 ms
GeoScaling99.78%103 ms332 ms
XName100.00%117 ms325 ms
DNS Exit99.98%256 ms1025 ms
FreeDNS100.00%187 ms530 msWebsite down for days recently. No comment on why.
Afraid80.45%223 ms1022 msSub-domain sharing. Down 4 mins every 19.

I recommend Namecheap and ClouDNS. If you are willing to pay for DNS services, there may be faster and more reliable options. I’d love to try out easyDNS and DynDNS but neither have a free option.

UPDATE May 2011: Namecheap’s DNS service has recently experienced two outages: one due to a denial of service attack and the other caused by a misconfigured DNS entry at another registrar. Their service is relatively new, so I hope they handle these types of issues better in the future. I appreciate the honesty and openness with which they have reported these issues. ClouDNS is also experiencing intermittent downtime, but has not mentioned anything. END UPDATE

Here are the charts to give you a visual idea of the test results. Pingdom needs to allow customers to control the vertical scale. I’m just too lazy to make my own charts using their cool API. :)

Namecheap

Namecheap performance results

ClouDNS

ClouDNS performance results

Moniker

Moniker performance results

ZoneEdit

ZoneEdit performance results

GeoScaling

GeoScaling performance results

XName

XName performance results

DNS Exit

DNS Exit performance results

FreeDNS

FreeDNS performance results

Afraid

Afraid performance results

26
Oct

Original Inspiration for the iPhone Maps Application

I am 100% sure that this Dilbert comic from 1990 was Steve Jobs’ original inspiration for creating the iPhone with its famous Maps application:

Dilbert from May 10, 1990

You knew that Dilbert was over 21 years old, right? (I didn’t. :)

21
Oct

How to Launch a Privileged Process on OS X

For security reasons, Apple recommends that GUI applications should never run with the privileges of the root user. GUI applications normally load several types of plugins and input managers automatically. If a malicious plugin was installed then it could cause security problems when the privileged application was launched.

In addition, system services that run with the privileges of the root user (such as launch daemons) need to avoid using certain technology frameworks provided by Apple. These frameworks are not safe to use in a service that runs with the privileges of the root user.

If you need your GUI application to do something that requires root privileges, Apple recommends you split your application into two parts. First, create a GUI that runs as a normal user. Then when you need to do something with root privileges, you launch a separate helper process or tool. Splitting your application avoids security holes while keeping things very easy for your users.

Two Steps

Launching a privileged process is done in two steps:

1) Request authorization. The operating system will ask the user for permission to run a privileged process. The user will need to enter an administrator’s username and password.

#import <Security/Security.h>

OSStatus PreauthorizePrivilegedProcess(AuthorizationRef *authRef) {
    AuthorizationItem item = { kAuthorizationRightExecute, 0, NULL, 0 };
    AuthorizationRights rights = { 1, &item };
    AuthorizationFlags flags = kAuthorizationFlagInteractionAllowed | kAuthorizationFlagExtendRights | kAuthorizationFlagPreAuthorize;
    return AuthorizationCreate(&rights, kAuthorizationEmptyEnvironment, flags, authRef);
}

2) Launch the process. If the user authenticates correctly, you can use the authorization reference created above to launch the helper process.

OSStatus LaunchPreauthorizedProcess(AuthorizationRef *authRef, NSString *path) {
    OSStatus status = AuthorizationExecuteWithPrivileges(*authRef, [path UTF8String], kAuthorizationFlagDefaults, NULL, NULL);
    AuthorizationFree(*authRef, kAuthorizationFlagDestroyRights);
    return status;
}

Please note that the authorization reference created in the first function is released in the second function. If you want to launch several privileged processes in a short amount of time, you can comment out this line and and release the reference on your own afterwards.

Some of Apple’s sample code (and other examples) has an extra step where they copy the authorization reference. This is only necessary if you have a previously created authorization reference that you want to add elevated privileges to.

Just One Step

If you don’t need to update your GUI between these two steps, then both actions can be combined into one step.

#import <Security/Security.h>

OSStatus LaunchPrivilegedProcess(NSString *path) {
    AuthorizationRef authRef;
    OSStatus status = AuthorizationCreate(NULL, kAuthorizationEmptyEnvironment, kAuthorizationFlagDefaults, &authRef);
    if (status == errAuthorizationSuccess) {
        status = AuthorizationExecuteWithPrivileges(authRef, [path UTF8String], kAuthorizationFlagDefaults, NULL, NULL);
        AuthorizationFree(authRef, kAuthorizationFlagDestroyRights);
    }
    return status;
}

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.

4
Aug

How To Type Curly Quotes In Mac OS X

Mac OS X has an easy way to type “curly” quotes and apostrophes instead of "straight" versions. I used both versions in that sentence to show the difference. Here is a bigger version to make the distinction more visible:

Many people think “curly” quotes look better than "straight" ones.

You can use the following keyboard shortcuts to type a single or double curly quote:

  1. Single quote open (‘) — option ]
  2. Single quote close (’) — shift option ]
  3. Double quote open (“) — option [
  4. Double quote close (”) — shift option [

However, I think it makes more sense to use [ and ] for open and close versions instead of the shift key. I found myself constant typing “mismatched‘ quotes. I also wanted to use the shift key for double quotes since that’s how the normal keyboard button works.

  1. Single quote open (‘) — option [
  2. Single quote close (’) — option ]
  3. Double quote open (“) — option shift [
  4. Double quote close (”) — option shift ]

Since OS X supports custom key bindings, I looked for a way to fix this. The trick is to create a file called DefaultKeyBinding.dict in the KeyBindings folder inside your Library folder. You can use this file to override the default key bindings for most applications.

Here are my changes. Please feel free to copy the settings below and save them to your own computer. You may need to create the KeyBindings folder if it isn’t already there.

/*
 Updates Apple's default keybindings for curly quotes.
 See http://www.danandcheryl.com/1072

 Save this file here:
 /Users/<name>/Library/KeyBindings/DefaultKeyBinding.dict
*/
{
    "~[" = ("insertText:", "‘");
    "~]" = ("insertText:", "’");
    "~{" = ("insertText:", "“");
    "~}" = ("insertText:", "”");
}
28
Jun

How to Check the System Idle Time Using Cocoa

There is sample code on the Internet for programmatically checking the system idle time using IOKit and Cocoa (see here, for example). However, most of the examples seem overly long (see Paul Graham’s Succinctness is Power). The code below works in Tiger/10.4 and later and is about as concise as I can make it while still handling errors properly.

#include <IOKit/IOKitLib.h>

/**
 Returns the number of seconds the machine has been idle or -1 if an error occurs.
 The code is compatible with Tiger/10.4 and later (but not iOS).
 */
int64_t SystemIdleTime(void) {
    int64_t idlesecs = -1;
    io_iterator_t iter = 0;
    if (IOServiceGetMatchingServices(kIOMasterPortDefault, IOServiceMatching("IOHIDSystem"), &iter) == KERN_SUCCESS) {
        io_registry_entry_t entry = IOIteratorNext(iter);
        if (entry) {
            CFMutableDictionaryRef dict = NULL;
            if (IORegistryEntryCreateCFProperties(entry, &dict, kCFAllocatorDefault, 0) == KERN_SUCCESS) {
                CFNumberRef obj = CFDictionaryGetValue(dict, CFSTR("HIDIdleTime"));
                if (obj) {
                    int64_t nanoseconds = 0;
                    if (CFNumberGetValue(obj, kCFNumberSInt64Type, &nanoseconds)) {
                        idlesecs = (nanoseconds >> 30); // Divide by 10^9 to convert from nanoseconds to seconds.
                    }
                }
                CFRelease(dict);
            }
            IOObjectRelease(entry);
        }
        IOObjectRelease(iter);
    }
    return idlesecs;
}    

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.

18
May

How to Print a PDF File Using Cocoa

Mac OS X is well known for its great support for PDF files. You can create a PDF file from anything you can print. I thought that using Apple’s PDFKit framework would make it easy to program a way to print an existing PDF file. That turned out not to be the case.

Sending a file to a printer using the lp command is easy. However, this approach does not work for PDF files formatted for landscape printing. You can specify landscape orientation, but I wanted a way to detect the orientation automatically.

PDFKit has a PDFView object that has a printWithInfo:autoRotate: method. However, adding a PDFDocument to a PDFView and telling it to print doesn’t work. I eventually stumbled onto the fact that PDFDocumenthas a secret method that makes printing easy. So here is the code:

#import <Quartz/Quartz.h>

- (void)printPDF:(NSURL *)fileURL {

    // Create the print settings.
    NSPrintInfo *printInfo = [NSPrintInfo sharedPrintInfo];
    [printInfo setTopMargin:0.0];
    [printInfo setBottomMargin:0.0];
    [printInfo setLeftMargin:0.0];
    [printInfo setRightMargin:0.0];
    [printInfo setHorizontalPagination:NSFitPagination];
    [printInfo setVerticalPagination:NSFitPagination];

    // Create the document reference.
    PDFDocument *pdfDocument = [[[PDFDocument alloc] initWithURL:fileURL] autorelease];

    // Invoke private method.
    // NOTE: Use NSInvocation because one argument is a BOOL type. Alternately, you could declare the method in a category and just call it.
    BOOL autoRotate = YES;
    NSMethodSignature *signature = [PDFDocument instanceMethodSignatureForSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)];
    NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
    [invocation setSelector:@selector(getPrintOperationForPrintInfo:autoRotate:)];
    [invocation setArgument:&printInfo atIndex:2];
    [invocation setArgument:&autoRotate atIndex:3];
    [invocation invokeWithTarget:pdfDocument];

    // Grab the returned print operation.
    NSPrintOperation *op = nil;
    [invocation getReturnValue:&op];

    // Run the print operation without showing any dialogs.
    [op setShowsPrintPanel:NO];
    [op setShowsProgressPanel:NO];
    [op runOperation];
}

I consider this code to be in the public domain. Please feel free to copy and paste. And let me know if you find any problems or have suggestions.