Problems with SVN in Eclipse on Mac OS X Mountain Lion (10.8)

I’m working on a new PHP project. Until now I’ve mainly been working on a Windows machine but today I wanted to move to my MacBook. So I just created a working copy and created a PHP project in Eclipse referencing the working copy. Unfortunately I got the following error message:

Failed to load JavaHL Library.
These are the errors that were encountered:
no libsvnjavahl-1 in java.library.path
/usr/local/Cellar/subversion/1.7.8/lib/libsvnjavahl-1.0.dylib:  Library not loaded: /usr/local/lib/libsqlite3.0.8.6.dylib   Referenced from: /usr/local/Cellar/subversion/1.7.8/lib/libsvnjavahl-1.0.dylib   Reason: image not found
no svnjavahl in java.library.path
java.library.path = .:/Library/Java/Extensions:/System/Library/Java/Extensions:/usr/lib/java

I already had some issues with SVN on Mountain Lion some time ago. But I thought I was done with it. After carefully reading the error message, I remember I had just upgraded my Home Brew package and saw the following while upgrading sqllite:

==> Upgrading sqlite
==> Downloading http://sqlite.org/sqlite-autoconf-3071502.tar.gz
######################################################################## 100.0%
==> ./configure --prefix=/usr/local/Cellar/sqlite/3.7.15.2 --enable-dynamic-extensions
==> make install
==> Caveats
This formula is keg-only: so it was not symlinked into /usr/local.

Mac OS X already provides this software and installing another version in
parallel can cause all kinds of trouble.

OS X already provides (an older) sqlite3.

Generally there are no consequences of this for you. If you build your
own software and it requires this formula, you'll need to add to your
build variables:

    LDFLAGS:  -L/usr/local/opt/sqlite/lib
    CPPFLAGS: -I/usr/local/opt/sqlite/include

OK, so now what ? First check whether the library missed by Eclipse is really missing:

$ ls -l /usr/local/lib/libsqlite3.0.8.6.dylib
ls: /usr/local/lib/libsqlite3.0.8.6.dylib: No such file or directory

Ok, then try to find it:

$ find /usr -name "libsqlite3.0.8.6.dylib"
/usr/local/Cellar/sqlite/3.7.10/lib/libsqlite3.0.8.6.dylib
/usr/local/Cellar/sqlite/3.7.13/lib/libsqlite3.0.8.6.dylib
/usr/local/Cellar/sqlite/3.7.14.1/lib/libsqlite3.0.8.6.dylib
/usr/local/Cellar/sqlite/3.7.15/lib/libsqlite3.0.8.6.dylib
/usr/local/Cellar/sqlite/3.7.15.2/lib/libsqlite3.0.8.6.dylib
find: /usr/sbin/authserver: Permission denied

Ok so I have the choice. Now let’s just create a soft link to one of them:

$ ln -s /usr/local/Cellar/sqlite/3.7.15.2/lib/libsqlite3.0.8.6.dylib /usr/local/lib/libsqlite3.0.8.6.dylib

Now, deleting the project and recreating again isn’t enough since it will not try again to get the whole subversion thing working. You need to restart eclipse and recreate the project.
This time the subversion binding did work and after converting the working copy (it looks like I created it with svn 1.6 instead of 1.7), everything was working fine !

Strong IPhone 5 Sales Help Apple Overtake Android in U.S.

New data show that IOS has once again pushed past Android in the U.S. The statistics show that IOS now has a 48.1 percent share of U.S. smartphone sales, compared to Android’s 46.7 percent share. Android still has the lead in Europe
Read more here.

This is most probably entirely related to the recent release of iPhone 5. But it’s good to see that there is still a lot of fighting at the top of smartphone sales. This will make sure that both parties will keep innovating in order to reclaim or keep their position at the top.

I wasn’t aware that the release of a new smartphone model had such a huge impact on sales. I’m more the kind of guy to only look at a new phone when my old phone just doesn’t fit anymore. But I guess there are lots of people out there renewing their smartphones more often.

It’d be interesting to see whether the search interest trend lines and the sales lines actually match. Here a comparison of iphone and android on Google trends:

The peaks are all releases of a new iphone model.

If you compare these worldwide trends with the one’s in Germany (which is one of the markets dominated by Android), you see no real difference:

But if you look at the trends in Spain (another market dominated by Android), you see a different picture with mugh higher interest in Android:

Apple: Sorry About Our Maps, Use Google or Bing Maps Instead

Apple CEO Tim Cook has issued a rare apology, admitting that its new Maps tool with iOS 6 isn’t good enough. Cook even went as far as to recommend users download rival services to their devices while improvements in its own tool are worked on.
Read more here.

I did like the old Google Maps based app better than the new one but for my purposes, the new one is actually OK. I’m amazed to read statements like this coming from Apple. I think it’s kind of refreshing to see that Apple has learned to accept they’re not perfect and that apologizing is sometimes the best thing to do. I wonder how many people will just switch to Google or Bing maps and never look back and how many will have a look at the Apple map once it’s been fixed.

What happened here is something very usual in our industry: we develop something new, do not test it enough and release it. For many of us it just means we’ve missed the train and will not get a second chance. For companies like Microsoft or Apple, it’s a little bit different. I hope this will be a lesson for Apple and will address the next big changes in iOS (or Mac OS) with more humility and realism.

It’s of course a good reason for Apple haters to show the world that Apple is just not as good as it thinks it is. Having used many pieces of software where many things broke with each new version, I tend to just see it as a small rock on the road and hope next one will be better. Anyway I love the new animation when updating emails. Looks like you pulling the head of a Barbapapa. Just for this small change, I feel that moving to iOS 6 was the right decision 🙂

Mac OS X: Getting Power Source information

Some time ago, I started working on a small tool for OS X showing me various info regarding my battery. I still have to package it in some way and release it. But here are some stuff I’ve been using in this tool that might help others…

There are basically two sources of information regarding the battery / power source:

  • using the power source API: IOKit/ps
  • using the power management API: IOKit/pwr_mgt

For both you will need to add the IOKit framework to your project.

Let’s first have a look at what you can get out of the power source API. First you need to get a power source description for the battery:

    CFTypeRef blob = IOPSCopyPowerSourcesInfo();
    CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
    if (CFArrayGetCount(sources) == 0)
        return;	// Could not retrieve battery information.  System may not have a battery.
    CFDictionaryRef pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, currentBattery));

You’ll have to replace currentBattery by the number of the battery you want to get info about (I use 0 for the first battery).

Now you have the power source description (which is basically just a dictionary containing all the info we want to get about the battery), you extract the info you need using GETVAL:

    const void *psValue;

    if (GETVAL(pSource, kIOPSNameKey, &psValue)) {
        name = (__bridge NSString *)psValue;
    }
    else {
        name = @"-";
    }
    
    if (GETVAL(pSource, kIOPSTypeKey, &psValue)) {
        type = (__bridge NSString *)psValue;
    }
    else {
        type = @"-";
    }
    
    if (GETVAL(pSource, kIOPSPowerSourceStateKey, &psValue)) {
        state = (__bridge NSString *)psValue;
    }
    else {
        state = @"-";
    }
    
    if (GETVAL(pSource, kIOPSHardwareSerialNumberKey, &psValue)) {
        serial = (__bridge NSString *)psValue;
    }
    else {
        serial = @"-";
    }
    
    if (GETVAL(pSource, kIOPSBatteryHealthKey, &psValue)) {
        health = (__bridge NSString *)psValue;
    }
    else {
        health = @"-";
    }
    
    if (GETVAL(pSource, kIOPSHealthConfidenceKey, &psValue)) {
        healthConfidence = (__bridge NSString *)psValue;
    }
    else {
        healthConfidence = @"-";
    }
    
    if (GETVAL(pSource, kIOPSBatteryHealthConditionKey, &psValue)) {
        healthCondition = (__bridge NSString *)psValue;
    }
    else {
        healthCondition = @"-";
    }
    
    if (GETVAL(pSource, kIOPSBatteryFailureModesKey, &psValue)) {
        failureModes = (__bridge NSArray *)psValue;
    }
    else {
        failureModes = [NSMutableArray array];
    }
    
    if (GETVAL(pSource, kIOPSVoltageKey, &psValue)) {
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberIntType, &volt);
        voltage = [NSString stringWithFormat:@"%d mV", volt];
    }
    else {
        voltage = @"-";
    }
    
    if (GETVAL(pSource, kIOPSCurrentCapacityKey, &psValue)) {
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
    }
    
    if (GETVAL(pSource, kIOPSMaxCapacityKey, &psValue)) {
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);
    }
    
    if (GETVAL(pSource, kIOPSDesignCapacityKey, &psValue)) {
        CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &desCapacity);
    }    
    
    if ((GETVAL(pSource, kIOPSIsChargingKey, &bval)) && (bval == kCFBooleanTrue)) {
        charge = 1;
    }
    else {
        charge = 0;
    }
    
    if ((GETVAL(pSource, kIOPSIsPresentKey, &bval)) && (bval == kCFBooleanFalse)) {
        present = 1;
    }
    else {
        present = 0;
    }
    
    if (STRMATCH(state, CFSTR(kIOPSACPowerValue))) {
        is_ac = 1;
    }
    else {
        is_ac = 0;
    }

If you’re interested in the time to empty the battery, you can get it this way:

    if (GETVAL(pSource, kIOPSTimeToEmptyKey, &numval)) {
        SInt32 val = -1;
        CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
        
        if ((val <= 0) && (is_ac)) {
            timeToEmpty = @"-";
        }
        else if (val <= 0) {
            timeToEmpty = @"Calculating...";
        }
        else {
            timeToEmpty = [NSString stringWithFormat:@"%d:%02d", (int) val / 60, (int) val % 60 ];
        }
    }
    else {
        timeToEmpty = @"-";
    }

Note that if we’re on A/C (i.e. plugged in), 0 will be reported as time to empty (hence the first check). The time reported is in seconds so we use stringWithFormat to get something like 4:35 (4 minutes 35 seconds).

To get the time to full charge is pretty much the same thing:

    if (GETVAL(pSource, kIOPSTimeToFullChargeKey, &numval)) {
        SInt32 val = -1;
        CFNumberGetValue(numval, kCFNumberSInt32Type, &val);
        
        if ((val <= 0) && (!is_ac)) {
            timeToFullCharge = @"-";
        }
        else if (charge && val <= 0) {
            timeToFullCharge = @"Calculating...";
        }
        else if (val <= 0) {
            timeToFullCharge = @"Charged";
        }
        else {
            timeToFullCharge = [NSString stringWithFormat:@"%d:%02d", (int) val / 60, (int) val % 60 ];
        }
    }    
    else {
        timeToFullCharge = @"-";
    }

That’s it. If you’re interested in other kind of data like manufacturer, temperature, cycle counts, you’ll have to use the second API (the power management API) but it’s getting late and will become a second post on this topic…

Ex-Sun Employees Are Taking Java To iOS

“Ex-Sun employees did what Sun/Oracle failed to do since the iPhone launched. They brought Java to iOS and other mobile devices. They are getting major coverage from Forbes, DDJ, hacker news and others. They are taking a unique approach of combining a Swing-like API with a open source and SaaS based solution.”

Sounds interesting… Might be worth a try…

Read more of this story at Slashdot.

Steve Jobs: I’m going to destroy Android

Although the official biography of Steve Jobs won’t be available for sale until Monday next week, the first details are already known. Some of them were revealed by biographer Walter Isaacson himself in a TV interview, others by the news agency Associated Press, which has already obtained a copy. Particularly surprising details have been revealed by AP’s Michael Liedtke on Twitter.

The were apparently lots of tensions between Jobs and Google’s former CEO Eric Schmidt which ultimately led to the ongoing patent war between Apple and the manufacturers of Android devices. As Isaacson says, Jobs fulminated against Android considering it “grand theft”.

Schmidt was elected to Apple’s board of directors 2006 but in 2009, it was announced that Schmidt would resign from the board of directors at Apple due to conflict of interests amid the growing competition between Google and Apple. Jobs felt betrayed  and reacted with extreme anger, as HTC introduced an Android smartphone in January 2010. “I will spend my last dying breath if I need to, and I will spend every penny of Apple’s $40 billion in the bank, to right this wrong. I’m going to destroy Android, because it’s a stolen product. I’m willing to go thermonuclear war on this.”

Even at a meeting with Schmidt, Jobs explained that he is not interested in a settlement of legal disputes: “I don’t want your money. If you offer me $5 billion, I won’t want it, I’ve got plenty of money. I want you to stop using our ideas in Android, that’s all I want.”

Of course, Jobs may have forgotten Apple using Xerox technology to initially create Lisa and the Macintosh. This actually made this incredible ideas available and affordable for the masses while Xerox didn’t build and market for home-use. Also some of the new features in iOS 5 like the notification banner and wireless sync,  do have an  “Android touch”.

Wondering whether Apple and Google could now come to an agreement…