Category Archives: Solutions

Triggering default Ajax behaviour in Drupal textfields for better UX

By default, the addressfield form elements triggers Ajax requests on change, which means textfields only triggers when blurred. This may leave the user wondering what to do if the next field depends on the results of the Ajax request. To trigger the default Ajax behaviour on other events, you can do


$('body').on('change keyup paste', '.selector.for.your.element', function(e) {
var current_value = $(this).val();
// Do some checks before the request.
if (current_value.length === 4){
// Blur the textfield.
$(this).trigger("blur");
return false;
}
});

A few notes:
on() is used so that the event is live. i.e. still bound after the element is updated, which is common in Ajax forms. If event listeners are added to the element directly, it is lost after the form is updated.

The events ‘change’, ‘keyup’, ‘paste’ is used to capture common events where the contents of the field might change.

Adding even and odd classes to checkboxes in Drupal 7

While theming a page for a client, I came across an interesting challenge: adding even and odd classes to checkboxes. Normally I would have gone with javascript or CSS3 (:nth-child), but I wondered if it can be achieved in ‘the Drupal way’ and achieve the best cross browser support. Google didn’t turn up any results so I decided to do a quick exercise on form element theming. Here’s how I got it to work.

Add our own checkboxes processor. See hook_element_info_alter.

function MYTEMPLATE_element_info_alter(&$type){
  // Append our processor
  $type['checkboxes']['#process'][] = 'MYTEMPLATE_process_checkboxes';
}

Implement the customer checkboxes processor to add the classes we want. See form_process_checkboxes

function MYTEMPLATE_process_checkboxes($element){
  // Loop through options to add striping class and attribute
  if (count($element['#options']) > 0) {
    $i = 0;
    foreach ($element['#options'] as $key => $choice) {
      $element[$key]['#attributes']['class'][] = ($i % 2 == 0) ? 'odd' : 'even';
      $i++;
    }
  }
  return $element;
}

I quickly realized that while this added the even and odd classes on the <input> elements, it would be easier for the themer to have it on the form element wrapper as well. So I decided to add a ‘striping’ key to ‘#attributes’ so that I can identify it in the form element wrapper.

The new processor:

function MYTEMPLATE_process_checkboxes($element){
  // Loop through options to add striping class and attribute
  if (count($element['#options']) > 0) {
    $i = 0;
    foreach ($element['#options'] as $key => $choice) {
      $element[$key]['#attributes']['class'][] = ($i % 2 == 0) ? 'odd' : 'even';
      $element[$key]['#attributes']['striping'] = ($i % 2 == 0) ? 'odd' : 'even';
      $i++;
    }
  }
  return $element;
}

Next, modify the template_form_element() to add the classes on the form element wrapper.

function MYTEMPLATE_form_element($variables) {
  ...
  if (!empty($element['#attributes']['striping'])) {
    $attributes['class'][] = $element['#attributes']['striping'];
  }
  $output = '<div' . drupal_attributes($attributes) . '>' . "\n";
  ...
}

Clear the class registry and we are done. This is by no means the best method available, but is definitely the most straightforward way that jumped at me. If you have a more efficient way do share in the comments.

Building with old iPhone SDKs with new XCode versions

If you have recently updated to the latest version of XCode you might be wondering how to get your 6.1 iPhone SDK back. The new XCode versions do not come with previous iPhone SDK’s so we need to obtain them from older XCode (download them from Apple) and symbolic link them to the right place. First, copy the SDK’s from the download and place them somewhere which wouldn’t get replaced on future XCode upgrades. For my case I left them in /SDKs/iPhoneOS.platform/Developer/SDKs. Next, show package contents of your current XCode.app and navigate to Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs, and make the link with this:

sudo ln -s /SDKs/iPhoneOS.platform/Developer/SDKs/iPhoneOS6.1.sdk iPhoneOS6.1.sdk

Just remember to redo the links whenever you update XCodes.

Exporting your developer and distribution certs and keys from PC to Mac

Migrating my iOS developer and distribution identities from PC to Mac turn out to be a little more involved than expected. I assumed I can import the .cer and .key into my keychain and be done with it, but my Mac does not seem to recognise .cer files at all. So if you’re figuring out how to get the .cer and .key pair to install on your Mac, here’s how.

Before you begin
Have your certificate, key, and Apple’s World Wide Developer Relations (WWDR) certificate ready (available here). Mine’s named ‘developer_identity.cer’, ‘developer_identity.key’ and ‘AppleWWDRCA.cer’, so remember to replace with your own naming when running the following commands.

Open terminal and cd into the directory where the files are residing, then run these commands:

[sourcecode language=”plain”]openssl x509 -inform der -in developer_identity.cer -out developer_identity.pem

openssl x509 -inform der -in AppleWWDRCA.cer -out AppleWWDRCA.pem

openssl pkcs12 -export -out cert.p12 -inkey developer_identity.key -in developer_identity.pem -certfile AppleWWDRCA.pem
[/sourcecode]

What’s the AppleWWDRCA.cer for?
It’s Apple’s World Wide Developer Relations (WWDR) certificate required to certify your builds. Think of it as Apple’s signature on a “the internet trusts this application because Apple trusts it” agreement. You had your signature from the developer_identity obtained from Apple, and now you have Apple’s signature.

AFNetworking failing with “Garbage at end” when using php’s cURL

If you don’t set CURLOPT_RETURNTRANSFER to true, cURL outputs the results of the CURL operation directly into the response, which is then sent back to AFNetworking. If the cURL operation outputs anything but valid JSON, this most likely will cause the JSON decoding to fail with:

[sourcecode language=”plain”]Error Domain=NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)" (Garbage at end.) UserInfo=0x753e5c0 {NSDebugDescription=Garbage at end.}[/sourcecode]

To turn on CURLOPT_RETURNTRANSFER, do:
[sourcecode language=”plain”]curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);[/sourcecode]

Hope this helps prevent some hair-pulling during midnight debugs.

Parse with deprecated Facebook headers on iOS gives “Semantic Issue” errors

If your app uses the deprecated Facebook headers, i.e. #import "Facebook.h" instead of #import <FacebookSDK/FacebookSDK.h>, importing Parse.h using the standard instructions at https://www.parse.com/apps/quickstart_push would fail your build with multiple errors of

Semantic Issue, Redefinition of enumerator 'FBSessionsStateCreated', 'FBSessionState....', etc.

The issue is that Parse imports the Facebook headers internally. To work around this, open Parse.h and replace

#if __has_include(<FacebookSDK/FacebookSDK.h>)
#import <FacebookSDK/FacebookSDK.h>

with

#if __has_include("Facebook.h")
#import "Facebook.h"

Next, open PFFacebookUtils.h and replace #import <FacebookSDK/FBSession.h> with #import "FBSession.h" and you’re good to go.

Drupal 7 – Debugging Illegal offset type in isset or empty in … and other errors

Though the title mentions Drupal 7, this article is really about the debugging technique and so is applicable to general php as well. I want to share a recent bug we had to solve at work. Though experienced developers would usually have an idea what new code is breaking, mysterious warnings and errors sometimes do slip through while working in teams (even when having a proper svn system in place!). You check with your co-developers and the one who broke it have no idea where this might be coming from, or worse: they have seen and have been ignoring this error for some time because they felt it didn’t matter. What do you do then?

Read the error
The error message “Illegal offset type in isset or empty in…” points to an illegal type used in a call to isset or empty, and it conveniently points you to the offending line – but with Drupal’s (and most of today’s frameworks’) complex page execution flows, it is hard to spot where is the real source of error, especially if the line is in one of the framework’s frequently called core routines (in my case it was in user_access). Since this is not much help in trying to deduce the real source, I resort to setting my own error handler (temporarily overriding Drupal’s) so that I can do a debug_back_trace().

To set your own error handler, define a function and feed the name to php’s set_error_handler():
[php]
// Your custom handler
function my_error_handler($errno, $errstr, $errfile, $errline
, array $errcontext)
{
// error was suppressed with the @-operator, ignore
if (0 === error_reporting()) {
return false;
}

// print the backtrace
echo ‘<pre>’.print_r(debug_backtrace(),true).'</pre>’;

// throw an error exception if you want to catch it at the caller
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}

// Back at the offending line:
set_error_handler(‘my_error_handler’);

try {
// original code
}
catch (ErrorException $e) {
// print your own debug log or what not
}

// Restore Drupal’s own error handler. You don’t want a backtrace
// on every other E_USER_NOTICE’s do you?
restore_error_handler();

[/php]

While you may find it useful to convert every error into an exception, note that even E_USER_NOTICE would then halt your page execution, so please use with care (refer to php manual on the ErrorException class for a handler that ignores non-fatal errors).

Now, what’s left is to carefully read through the debug backtrace and spot the problem. For my case, it was a line of code someone embedded in a view context. Hope this helped, share your own debugging methods and opinions in the comments.

End note
Some people may feel that my style of debugging isn’t very ‘elegant’ but my experience is that the fastest way to find the problem isn’t necessarily the most elegant way. Rather than going through hours of deducing which functions might or might not be involved, and later realising the problem was in one of those functions that “logically shouldn’t have mattered in this case”, I find that getting a solid backtrace – after a quick deduction fails – is usually my best bet in the long run.

Fixing Drupal’s Canonical link meta tag

Fblint complained that one of my page’s canonical link mismatches the og:url meta tag. Turns out Drupal 7 outputs relative canonical links by default and although there’s nothing strictly forbidden about relative links, both facebook and google seems to prefer absolute links. Rather than altering the offending tag through hook_html_head_alter() or even worse, mess with the core files, I decided to install the Metagtag module (http://drupal.org/project/metatag).

The default configuration looked fine (the module even supports og meta tags!) so I ran the page through fblint again, hoping it to be another fine install-set-go Drupal 7 module. 58827 sites were using this module at last count, that’s pretty reliable. I was dismayed when I got the same results and a quick check revealed that apparently the module modified none of my head tags. I also noticed that its only the front page that was having this issue. The module works fine on all other pages. A few drupal.org threads later I arrived at the solution: calling render($page['content']); is all it needs to get it to work on overidding page–*.tpl.php’s. Yup just calling render() will do, no need to print.

Solution thread: http://drupal.org/node/1293214

Tips while profiling your app to solve low memory warnings and crashes

Just a quick post to share what I learnt while investigating crashes in my iPad app. The crash reports consistently showed low memory warnings before the crash so I started using instruments to profile the app. Here’s some tips that may help you out when you are stuck using the instruments tool:

Turn off Zombies. Zombies are great for debugging messages sent to de-allocated objects, but they come at a cost of memory – NSZombies are never deallocated. Turning this off immediately showed great reductions in terms of live bytes in the allocations instrument. Apple’s documentation advises zombies to be used only on the simulator while debugging and testing.

Mark your heap before and after performing actions on your app to inspect the memory changes introduced by the action. A simple evaluation to keep in mind is that if any set of actions returns the app to the same state as before the actions, the changes in heap before and after the set of actions should be close to 0. Any significant amounts detected here would signal a leak, which need not necessarily reflect in the leaks instrument profile. Many conditions, like circular references, may cause actual leaks to be ignored in the leaks instrument, but that’s the focus of another article.

The Allocations and Activity Monitor operates differently, and gives very different results. I made the mistake of assuming the ‘live bytes’ column in the allocations report to be what my app was consuming. While allocations reported that my app is using a consistant amount of memory, I was still receiving low memory warnings, so I finally decided to run activity monitor. Surprise – the low 6.3mb consumption in allocations actually translated to 180mb in activity monitor. Why is that so? Turns our when you deallocate memory in your app, or even if you are using ARC, the memory is only released at undetermined intervals when iOS feels like it. While allocations track every memory your app allocates and deallocates, the activity monitor gives a true reflection of your app’s memory footprint.

But of course, those latent released memory wouldn’t chalk up to 100 over mb’s. The real culprit turns out to be CoreGraphics, while it handles all on screen drawings and image operations behind the scenes. The real memory consumed by these operations are not reflected in allocations at all. ARC also does not track CG objects so do remember to release them properly.

Now knowing the real issue, I proceed to refactor and restructure my drawing code to improve reuse of bitmap contexts and reduce repainting areas by keeping track of dirty rectangles. Hope these tips would help give some ideas to those of you debugging your crashes at 3 in the morning. Do also share some of your own tips or experiences in the comments!

error: Unsupported Feature: to-many relationship … option requires Mac OS X 10.7 or later

While tinkering with the relationship properties in my Core Data model, my app suddenly failed to compile with this error:

error: Unsupported Feature: to-many relationship [Entity].[attribute]
option requires Mac OS X 10.7 or later

While it says to-many relationship is not supported, I know that’s not the real problem as I have been compiling fine with the ‘to-many‘ option turned on for a few weeks. What it’s really trying to tell you is an ‘ordered‘ AND ‘to-many‘ relationship is not supported. Once I unchecked the ‘ordered‘ option the app build fine again.