Friday, December 09, 2011

Xcode 4.1 and 100% CPU usage

Still needing to use Xcode 4.1 and find that it slowly consumes 100% CPU over time? Turns out there is a nasty bug in Xcode when you have WiFi sync enabled on iOS 5.x devices; Xcode continually tries to connect to these devices running the newer iOS and fails. Abysmally.

All is not lost, and if you install SIMBL, you can use a nifty plugin by evands on GitHub. It only loads itself in Xcode versions ≤ 4.1, and works around the issue.

 

Saturday, December 03, 2011

Constant Confusion

The const keyword in C can be confusing, so I wanted to put down my thoughts for my own benefit and for those looking for some clarity. In summary, I'm going to advocate you place const to the right, and read the declaration from right to left.

What is const?

const is a hint to the C compiler and programmer that a specific declaration or element of a declaration is immutable.  It is more complicated in C++, which is outside the scope of this post.  Lets start with a simple example, and the most common form where const is written first:

const int i = 5;

The previous statement simply instructs the compiler that i cannot be changed after its initial declaration, such that the following assignment would result in an error:

const int i = 5;
i = 6; // error: read-only variable is not assignable

If spoken from right to left, the declaration of i would read “i is an integer constant”, which is reasonable enough.  This syntax is still supported for historical reasons.  The alternative and correct format is to write const after the type reference, as follows

int const i = 5;
i = 6; // error: read-only variable is not assignable

which means the same thing; the value of i must remain constant within its declared scope.  If you read this declaration from right to left, it is spoken as “i is a constant integer”; much better.

Yet another common definition is an array of constant characters or also known in some circles as an immutable string

const char * myString = "hello World";
myString[0] = 'H';        // error: read-only variable is not assignable
myString = "Hello World"; // ok

Spoken from right to left, “myString is a pointer to character constant”, which doesn't read so well.  Switching the const keyword, we get the following

char const * myString = "hello World";
myString[0] = 'H';        // error: read-only variable is not assignable
myString = "Hello World"; // ok

read aloud, it is “myString is a pointer to constant characters“; sounds better than the former.

So far const seems pretty straight forward, and perhaps at this point you're thinking where is the confusion?.  Lets complicate things…  As we've demonstrated, the const keyword can be placed before or after the type reference in a declaration, which for the previous scenarios is fine.  Let's show a few more examples with pointers:

int * const i;

Declares i as constant pointer to an integer.  Again, reading from right to left makes it pretty clear what we're dealing with.  The following shows both legal and illegal usages of i:

int j = 5, k = 6;
int * const i = &j; // points to the memory referred to by j
i = &k;             // error: read-only variable is not assignable
*i = 6;             // ok, modifies the value of j

Now, because the const keyword can be placed before or after the type reference, as shown earlier, the following declarations of h and i:

int j = 5, k = 6;
const int * const h = &j;
int const * const i = &j;

result in a variable that is a constant pointer to a constant integer.  Given that, the following lines will result in compiler errors:

*h = 5; // error: read-only variable is not assignable
h = &k; // error: read-only variable is not assignable

Want to see something confusing? The following 3 lines are identical, and will compile with current versions of clang and gcc:

const int const g = 5;
const int h = 6;
int const i = 7;

It's not horrible, but lets reintroduce pointers

const int const * i;

What is this? If you had not just read all the above, one would be forgiven for thinking i is a constant pointer to a constant integer, but in fact both instances of const refer to the int type; this is a pointer to a constant integer. The correct definition, as we saw earlier is

const int * const i; // or preferably
int const * const i;

Worse still is multiple levels of indirection, such as

int * * i;

which when read from right to left declares “i is a pointer to a pointer of integers”. A more complicated example using the const keyword

int const * const * const i;

or “i is a constant pointer to a constant pointer of constant integers.  Wow.  All levels of indirection are immutable, so it can only be assigned at its declaration.

int j[2][3] = { {1, 2, 3}, {4, 5, 6} };
int const * const * const i = &j; // ok
i = NULL;     // error
i[0] = &j[0]; // error
i[0][0] = 5;  // error

It's an extreme case, but becomes evident why writing const to the right is a good habit.  The following declaration of i may look the same to the untrained eye:

int j[2][3] = { {1, 2, 3}, {4, 5, 6} };
const int const * const * i = &j; // ok
i = NULL;     // ok!!
i[0] = &j[0]; // error
i[0][0] = 5;  // error

however, armed with this knowledge, you (and the compiler) say otherwise.

After all this, you may be asking when might I use the declaration type const * const?  When possible, I prefer to be explicit, and strings used as constants across compilation units are often declared as

char const * kMyConstant = "Hello World";

and then referred to in a separate object file as

extern char const * kMyConstant;

Whilst modifying the contents of kMyConstant is prohibited, assigning the pointer kMyConstant to a new location is possible, as follows

extern char const * kMyConstant;
void fn() {
    kMyConstant[0] = 'h'; // error
    kMyConstant = "Hi!";  // now says "Hi!" instead of "Hello World"
}

Clearly for the majority of situations, this is not what the developer intended.  Changing the declaration to

char const * const kMyConstant = "Hello World";

would also prevent the pointer kMyConstant from being overwritten.

In summary

Always write const to the right and read the declaration from right to left.

Thursday, October 13, 2011

Google Maps WebGL with Safari 5.1

It's possible to use the WebGL version of Google Maps with Safari, if you are willing to roll up your sleeves a little.  Follow these steps to try it out:

  • Enable the Develop menu by opening Preferences and selecting the Advanced tab; check the Show Develop menu in menu bar option

    Enable Develop Menu Bar
  • In the newly enabled Develop menu, enable WebGL:

    Enable WebGL
  • Set your UserAgent to Other, which is available in the Develop menu and paste in the following user agent string (which will fool Google maps into thinking your browser is Chrome):
    • Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_2) AppleWebKit/535.2 (KHTML, like Gecko) Chrome/15.0.874.92 Safari/535.2
  • Navigate to http://maps.google.com/gl
    • Down the bottom left you will see an option to try Google Maps with WebGL

Friday, September 09, 2011

Using your iOS 5 device with Xcode 4.1

To enable iOS 5 support in Xcode 4.1, read on.

You've upgraded one or more devices to iOS 5.0 and try to use Xcode 4.1, only to be told it doesn't recognize the version of the OS.  Why would you care?  Apple has been advising for some time that gcc is going away, and that date may be fast approaching.  Unfortunately, Clang / llvm lack some features available in gcc, such as register assigned local or global variables.  We've only just gained access to a version of Clang that supports C++, and so you may still need some time to migrate your code.

Assuming Xcode 4.1 is in /Developer and Xcode 4.2 is in /Xcode42, run the following, substituting the appropriate iOS 5 build numbers:

cd /Developer/Platforms/iPhoneOS.platform/DeviceSupport
ln -s /Xcode42/Platforms/iPhoneOS.platform/DeviceSupport/5.0\ \(9A5313e\)/ 5.0\ \(9A5213e\)

Friday, August 19, 2011

iCloud Key-Value is better than a UDID

There is a lot of chatter about Apple depreciating the UDID API and apparently providing no alternative to track a user.  Firstly, lets clear up how insecure and unreliable using the UDID is for identifying a user, which is tied to the device.  The user's device could be

  • lost,
  • stolen,
  • replaced / exchanged,
  • sold or
  • given away.

That UDID is now potentially in the hands of another individual, even if you remote wipe your device.

Beginning with iOS 5, Apple is providing a secure service called iCloud Key-Value storage that will serve as a superior alternative.  iCloud K-V storage offers a limited amount of space in the cloud for a single application or shared between a suite of applications; either scenario is at the app developer's discretion.  If your application requires access to it's own servers for user-specific information, you can store a unique token in their iCloud K-V store to reunite your application with their data, without them ever having to log in again* after the initial handshake.  This applies even when the user replaces their device, as the token is stored in the cloud.

Apparently, Pandora uses the UDID to remember your profile and potentially exposes your playlists if your device falls victim to one of the more dubious fates mentioned above.  Easily solved if you follow a pattern similar to the following sequence diagram:

cdraw

Naturally, you should take the appropriate measures to secure the conversation between your app and your server.

If you do need to track a specific device, there are ways to programmatically obtain the MAC address.  Not something I would recommend.

* Apple is yet to address a significant caveat regarding the lack of multiple Apple IDs under a single iTunes account.  Your iCloud account is your Apple ID, and that implies all your family members must log in to the same account, providing no way to separate users.

Friday, August 05, 2011

Local (file system) development with Google Chrome

If you use Google Chrome for an advanced local file system development on Mac OS X, no doubt you've been frustrated with issues such as security (same origin).  All is not lost, as I've created an application bundle that allows you to launch Chrome from Finder with the following additional command-line switches:

You can download the archive from here.

If there are other switches you wish to add, many of which are conveniently documented here,

  • RMB and select Show Package Contents and
  • edit the shell script in Google Chrome Dev.app/Contents/MacOS

 

Wednesday, August 03, 2011

Transferring Preview app signatures in Lion

Lion introduced a great new feature that allows you to capture your signature via an attached camera and store it in an encrypted form for later use.  Therein lies the problem; you must have an attached camera.

I have a Mac Pro, and wanted to use the signatures I captured on my Macbook Pro.  Following these steps, you can transfer the encrypted signatures over.

On your machine endowed with the power of sight:

  1. Go ahead and capture the signatures in Preview.
  2. Quit Preview
  3. Browse to ~/Library/Containers/com.apple.Preview/Data/Library/Preferences
    • In Finder, click the Go menu and hold the option (⌥) key to show the Library folder, alternatively
    • press ⌘+⇧+G whilst Finder is active and enter the path above to directly navigate
  4. Copy the com.apple.Preview.signatures.plist
  5. Launch Keychain Access
  6. Ensure the login keychain is selected and the Passwords category
    Copying Preview signatures password from keychain
  7. Right-click the Preview Signature Privacy password and select Copy Password to Clipboard.  This is the password used to encrypt the signature images.
  8. Paste it into a text editor and save the file.  You'll need to transfer this to your other computer(s)

On your machine you wish to transfer the signatures to:

  1. If you haven't already, launch Preview, open preferences, and select the Signatures tab to ensure the default configuration files and folders have been created.  Exit Preview.
  2. Browse to ~/Library/Containers/com.apple.Preview/Data/Library/Preferences
  3. Copy the com.apple.Preview.signatures.plist to the folder, overwriting any existing file
  4. Launch Keychain Access
  5. Locate the Preview Signature Privacy password in the login keychain and double click to edit
    Replace the Preview Signature Password
  6. Click the Show password checkbox and paste the password you copied from your original machine.
  7. Click Save Changes and you're done

 

Saturday, April 09, 2011

Eval Expression service for OS X

Eval Expression is a Mac OS X service to evaluate the selected text of any text field as a Ruby expression.  My instinct was to choose Perl, however Ruby offers binary in addition to decimal, hex and octal numerical literals.  The service becomes infinitely more useful if you assign it a global shortcut in Keyboard preferences.  In my case I assigned a combination that seemed obvious, ⌘=

Keyboard preferences

It came about as I was working on some layout in Xcode 4 / Interface Builder, and needed to adjust the Y position of a view by a specific number of units.  I'm lazy, and figured the computer should do the work, so I typed 768-35 and tabbed out.  Unlike Acorn and Opacity, which evaluates the expression in numerical entries automatically, Xcode simply complained.  Not happy, I created this service and it works like a charm.  Some examples:

  • 768-35 ⌘= 733
    • calculator
  • 0b11010 ⌘= 26
    • conversion to decimal
  • 0x1f.to_s(2) ⌘= 11111
    • hex to binary
  • 2**3 ⌘= 8
    • exponent
  • (0x8000 | 0xf1).to_s(16) ⌘= 80f1
  • "-+" * 5 ⌘= -+-+-+-+-+
    • expansion
  • Array(1..15).join ',' ⌘= 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15
    • lists

 

Download the Automator zip file from github, unzip and install to your ~/Library/Services folder.

A quick video of the service in action (note that I'm using my ⌘= shortcut to evaluate within Mars Edit):

Thursday, March 17, 2011

Mobile Safari performance and executable pages in iOS 4.3

DaringFireball recently posted his thoughts as to why the Javascript performance of Mobile Safari is faster than those launched from SpringBoard or within existing applications which use a UIWebView.  I don't think it's quite that complicated.

My thoughts are it is one of two things:

  • Apple is concerned about security (which would support John's theory)
    • Mobile Safari is binding to a newer and/or private version of Webkit, and Springboard was an oversight
  • Apple is concerned about breaking existing applications
    • I would argue this makes the most sense, and was probably a very deliberate action by Apple, given enabling Nitro is a significant enough change to a core framework that could break existing applications.
    • Perhaps a future update will allow developers to opt-in to the faster Javascript engine either via a plist setting or more likely, a new API on the UIWebView class.
    • Would also explain the oversight in Springboard, if it was not opted in.

There are other implications for allowing 3rd parties to use Nitro, most importantly battery life. If Javascript executes up to 3x faster, the CPU is running 3x less to to execute equivalent Javascript, allowing the CPU to go to low power mode faster.

Gruber also makes the following statement:

Apple, as of iOS 4.3, trusts Mobile Safari enough to allow this. The upside is that Mobile Safari is now significantly faster. The downside is that any security exploits against Mobile Safari now potentially allow worse things to happen than before.

I would disagree, as many of the previous Jailbreak exploits in iOS such as this example were via Mobile Safari, without a JIT engine, simply exploiting the stack and other typical attacks to elevate privileges.  As Apple continues to get a handle on these security issues, running dynamic code shouldn't be a problem.

What is my basis for this assumption?

A few weeks ago, when I heard Apple's announcement that Nitro was coming to 4.3, I immediately had to retest some scenarios that were not previously supported on iOS.  Prior to iOS 4.3, calling the mprotect function and attempting to set the PROT_EXEC flag, marking the page as executable would fail when run on the device. Quite simply, the API would return an error code.  This suggested that likely something in the kernel was locked down or this API had specific code to disallow pages to be marked as executable.  Knowing that the Nitro engine must execute in user space or it would be a serious hack in iOS, Apple had to enable support for executable pages.  I went ahead and created an example, ran it on my iPhone 4 and viola!  Essentially this example creates an 'increment' function in 32-bit ARM on the fly that adds one to the parameter and returns the result.

responded to Miguel de Icaza's tweet, who also wondered it might now be possible.  Further discussions with Miguel also identified that Apple has only partially opened up executable page support, whereby pages can either be read/write or read/execute.  Unfortunately the majority of existing JIT engines expect RWX in order to patch executable pages without the need to change the state from rx » rw, patch code and then rw » rx.  Critical in multi-threaded scenarios, as code could conceivably jump to a page that was being patched and fault due to the absence of the execute flag.

Wednesday, February 02, 2011

Renew Apple developer certificates with OpenSSL

I like to reuse the same private keys when generating a signing request to renew my Apple developer certificates.  Unfortunately you can't do this with Keychain Access, as it won't save the signing request file after you step through the wizard.  OpenSSL is your friend.

Open Keychain Access, RMB on the key your wish to use and click Export "[Key Name]".  Save it as a .p12 file with a strong password.  In my case it was StuartCarnie.p12.

Open a terminal session and convert the .p12 to a PEM with the following command

openssl pkcs12 -in StuartCarnie.p12 -out StuartCarnie.pem

You will be prompted  for your .p12 password, and also a password to encrypt your .pem.

Now generate the signing request with the following command.

openssl req -new -key StuartCarnie.pem -out StuartCarnie.csr

You'll be prompted for a few questions to place in the signing request, such as the country, etc.  At the very least, enter the Common Name (your name) and Email Address.  One you've completed this step, the .csr file can be submitted to Apple.