Technology Musings

September 18, 2010

Platforms / Change in Video Playback in iOS 4 (MPMoviePlayerController)

JB

It seems that Apple has changed the way that it handles video playback in iOS 4.  In previous iPhone OS releases, you merely initialized the movie player instance and then hit play.  iOS 4 is slightly more complicated because it no longer presumes that all video playback will be fullscreen, or even that there will only be one video on the screen at a time.  So here is the code to get the old behavior: 

MPMoviePlayerController* thePlayer = [[MPMoviePlayerController alloc] initWithContentURL: [NSURL URLWithString: trailerURL]];
thePlayer.scalingMode = MPMovieScalingModeAspectFill;
thePlayer.view.frame = self.view.bounds;
[self.view addSubview: thePlayer.view];[thePlayer setFullscreen: YES animated: YES];

Unfortunately, Apple still keeps its old documentation around. Here are the updated docs.

I ran into this when I was updating an app from 3.0 to 4.0. When you clicked on the button to play the video, rather than playing a video, nothing happened, and then a few seconds later only the audio would start playing. I had listed in my code the URL for the docs from Apple which I had used, and verified that it was correct - I had no idea that the document itself was out-of-date! It was quite a problem for me, and at first I thought it was a bug in my code. Later I learned that Apple updated their API, but not all their docs. Anyway, hope this helps someone.

July 13, 2010

Platforms / Comparing Research vs Practical Languages

JB

I recently ran across this excellent comparison between Standard ML and Objective Caml.  It is good, because it describes the different types of choices that are often made between languages used for research and those used for practical projects.

June 10, 2010

Snippets / Cross-browser DIV Rotation by arbitrary degrees in CSS and/or javascript

JB

I've spent most of the day on this, so I thought I would share.  Most people don't know this, but CSS3 has some *really* cool stuff coming - auto-rounded corners, gradients, and.... DIV rotations!  Unfortunately, it will be about 5 years before any of this becomes mainstream.  IE8 only has the very beginnings of CSS3 support.

So is there any way to get this on current browsers?  Yes!  The fine folks at CSS3Please.com have given us a way to do some of these cool effects using existing CSS.  If you just want, just go their, edit the stylesheet on the web page (yes! it is editable!), and copy/paste the resulting CSS into your CSS file.

But what if you want dynamic rotation?  Well, I looked at the CSS3Please source code, and figured out how it was all being calculated.  The IE6, IE7, and IE8 part is the worst, because it relies on a DirectX Matrix transform operation (isn't Internet Explorer always fun to work with?).  Not superfun, but do-able.  However, to get this calculated, we will need a Matrix library.  So, first, download and install the sylvester javascript library.  Then, put this javascript into your page:

<script src="sylvester.js"></script>
<script type="text/javascript">
function degreesToRadians(num) {
	return (num) * Math.PI / 180;
}
function createIEMatrixString(M) {
	return 'M11=' + M.e(1, 1) + ', M12=' + M.e(1,2) + ', M21=' + M.e(2,1) + ', M22=' + M.e(2,2);
}
function rotateElement(e, deg) {
	deg_str = deg + "";
	rotate_transform = "rotate(" + deg + "deg)";
	matrix_str = createIEMatrixString(Matrix.Rotation(degreesToRadians(deg)));
	filter_str = "progid:DXImageTransform.Microsoft.Matrix(sizingMethod='auto expand', " + matrix_str + ")";

	e.style["rotation"] = deg_str + "deg"; // CSS3
	e.style.MozTransform = rotate_transform; // Moz
	e.style.OTransform = rotate_transform; // Opera
	e.style.WebkitTransform = rotate_transform; // Webkit/Safari/Chrome
	e.style.filter = filter_str; // IE 6/7
	e.style.MsFilter = filter_str; // IE 8
	e.style["zoom"] = "1"; // ??? Probably IEs
}
</script>

Now, you can just do:

rotateElement(document.getElementById("whatever"), 20);

And that will rotate the element.  Note that this *sets* the rotation, so if I do this several times it will only keep the rotation at what I set it to, it won't keep on adding rotations.

Anyway, a little bit of work, a little bit of code for your client to download, but it works.

UPDATE - just found this jquery plugin that *might* do something similar, but haven't looked at it closely yet.

June 08, 2010

General / An Index to My Old IBM DeveloperWorks Papers

JB

I often have to refer people to my old IBM DeveloperWorks papers, but it always takes so long to find them.  Therefore, I am going to post links to them all here to make them easier for me (and you) to find.  The dates were pulled from the IBM site, and some of them seem incoherent.  If I find the true release dates of the papers I'll put them in later.

Series 1: Theoretical Computer Science for Practical Computer Programmers

In this series, I introduced a lot of material that is usually only studied in theoretical computer science, and showed how it could be useful for practical programming:

 

  • Inside Memory Management (2004/11/16) - a look at a variety of ways that memory is managed in different systems.  Includes a functional memory manager (malloc/free implementation) written in C.  Covers manual memory management, reference counting systems, pooled allocation systems, and garbage collection.  Sadly, I was not aware of Apple's combination of reference counting and autorelease pools at the time I wrote this.
  • Better Programming Through Effective List Handling (2005/01/05) - this is an introduction to how linked lists work, why they are so useful for a variety of tasks, and how languages such as Scheme take advantage of them in interesting ways.  Starts in C, and includes a simple introduction to Scheme.
  • Higher Order Functions (2005/03/31) - Discusses how higher-order functions (functions that take a function as a parameter and/or functions that return a new function as a result) work and how they can be used to good benefit in programming.  Also discusses the relative equivalence of closures and objects, and when to use each one.  It begins using scheme, and then shows how to use everything in C.
  • Mastering Recursive Programming (2005/6/16) - this is an introduction to all of the fun associated with recursive programming.  It starts with a simple introduction to recursion, and moves on to how recursion can be used to write programs that are provably correct, how (and why) to convert loops to recursion, how tail-calls work, and how tail-calls are implemented in assembly language.
  • Continuations and Advanced Flow Control (2006/05/24) - continuations are an amazing, generalized flow-control construct from which you can implement just about any other flow control you want (threading, throw/catch, generators, and prolog-style backtracking computations).  The paper gives an introduction to a variety of flow-control structures (with various examples in Python, Prolog, and Java), and then shows how each one can be implemented using Scheme's continuation constructs.  Probably needed more explanation on the backtrack stuff - it's pretty amazing, but quite a bit different from the way we normally think about computation.
  • Lazy Programming and Lazy Evaluation (2006/12/18) - this is an introduction to delayed evaluation, how it is implemented, and how it can be used practically.  Shows how to use lazy evaluation to make use of infinite lists.  Examples are in Scheme and Java.

Series 2: Metaprogramming

Metaprogramming is one of my favorite subjects.  In this series I give an introduction to several kinds of metaprogramming and how they are done.  I wish I knew ruby when I wrote these, as Ruby's metaprogramming system is just awesome!

  1. Introduction to Metaprogramming (2005/10/20) - describes several metaprogramming systems, including CPP, M4, and Embedded SQL.  Then shows how and why you might want to build your own metaprogramming system.  Then I introduce Scheme's macro system, and how to do many of the same things that were in the other metaprogramming systems.
  2. Metaprogramming Using Scheme (2006/05/02) - goes in-depth on how to write metaprogramming systems with Scheme, and then shows how this creates a super-easy way to make domain-specific languages.  (Most DSLs are better done as metaprogramming systems for more general-purpose languages IMHO).  Compares the flexibility of a Scheme-based DSL to XML-based configuration languages.
  3. Enterprise Metaprogramming (2006/02/28) - describes the computational equivalence between graphical and textual metaprogramming systems, and why each one would be useful in different circumstances.  It also shows how that even with the advance in ease of use of computer programming languages, there will always be a split between the roles of a domain expert and a programmer - no tool can bridge the gap.  It then describes the Model-Driven Architecture (MDA), and how it can be used to extend the concept of metaprogramming further.  An example MDA application is given in Scheme, which produces both a set of C++ structs and corresponding SQL data definition statements from a single diagram built by the Dia program.

Assembly Language for the Power Architecture Series

When I got a PowerPC Mac I wanted to learn PowerPC assembly language, but didn't have time.  I thought, "hey, if I can convince IBM to pay me to write about it, that would give me a good excuse to learn it".  That birthed this article series:

  1. Programming Concepts and Beginning PowerPC Instructions
  2. The Art of Loading and Storing on PowerPC
  3. Programming with the PowerPC Branch Processor
  4. Function Calls and the PowerPC 64-bit ABI

PlayStation 3 Programming with the Cell Broadband Engine

IBM's Cell processor (called the Cell Broadband Engine) was the driving force behind the PS3.  It had a main processor and eight vector processors (each vector processor was a full-blown processor, though very limited).  Given the right workload, and the processor would scream.  However, if it wasn't programmed carefully, it would actually be slower than most other processors.  This is especially difficult because the vector processors actually used a different assembly language with a different memory model than the main processor.  This series walks a programmer through everything they need to know, from installing Linux on their PS3 to writing, complling, and linking their code.

  1. An Introduction to Linux on the PS3
  2. Programming the Synergistic Processing Elements of the PS3
  3. Meet the Synergistic Processing Element
  4. Program the SPU for Performance
  5. Programming the SPU in C/C++
  6. How to Make SPE and Existing Code Work Together
  7. Removing Obstacles to Speedy Performance

There was supposed to be a final paper where I applied everything to a scientific application, but I got worn out by the end and just had to stop.

May 26, 2010

Snippets / A Simple HTML Geolocation Map with Twitter and Google Maps

JB

New Medio just released <a href="http://www.newmedio.com/site/postings/17?section_id=2">a cool new tool to do geolocation/geotagging maps of Twitter posts</a>.  Can be used HTML-only (no Javascript coding required!) or with a Rails plugin. 

March 10, 2010

Platforms / Facebook FBJS problems on FireFox

JB

I've been banging my head against a wall for the past day trying to figure out various FBJS problems in facebook.  Turns out the problem was..... FireBug!  By simply turning Firebug off, (most of) my problems went away.  I have no idea what the issue is, but it took me forever to realize it because I always have FireBug on, and don't even realize it is there.  It's never been a problem before.  But, I noticed that one of my coworkers was using my app, with Firefox, with no problem, and I quickly realized that the problem was with FireBug.

There's still another issue with fb:js-string on profile widgets that's killing me, but hopefully that will be resolved soon.  I _think_ they changed how they were evaluating profile javascript, to make it more secure - but in doing so made all references to the variable created by fb:js-string out-of-scope.  Developing javascripty apps for facebook is truly painful.

January 27, 2010

Platforms / IE6 Retiring Soon!

JB

Looking at their lifecycle page, it looks like Microsoft will be retiring IE 6 this year!  For anyone who works in IT, this is certainly a cause for celebration.

January 16, 2010

Platforms / Forcing HTTP Basic Authentication on the iPhone

JB

Here's my setup.  I have a RESTful Rails app.  Going to http://whatever.com/contacts gives the search screen for the contacts.  Going to http://whatever.com/contacts.xml gives the full list of contacts as an XML file.  For normal users, I use cookie-based authentication.  However, I also allow, for API users, HTTP basic authentication.  There is no access difference between the two.  However, this is a problem for the iPhone, because, although NSURL supports usernames and passwords, it will not present them for authentication without being challenged!  This is somewhat understandable because it doesn't know what authentication mechanism is being used (basic or digest).  However, it is EXTREMELY annoying to program for.

So, after spending about 2 hours digging through stuff, here is what I found out.

First of all, Basic authentication relies upon Base64 encoding, which isn't available on the iPhone.  Thankfully, someone posted public-domain Objective-C iPhone code for this here and someone else gave an almost-working-but-not-quite version of the request code here.  The Base64 code left out some things (like the class wrapper and header file), and the request code assumed a Base64 method existed which didn't.  In any case, here is the Base64 header file, Base64.h:

#import <Foundation/Foundation.h>


@interface Base64 : NSObject {
}
+ (void) initialize;
+ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length;
+ (NSString*) encode:(NSData*) rawBytes;
+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength;
+ (NSData*) decode:(NSString*) string;

@end

Here is the body of the code, Base64.m:

#import "Base64.h"


@implementation Base64

/* Copied from http://www.cocoadev.com/index.pl?BaseSixtyFour (cyrus.najmabadi@gmail.com) */

#define ArrayLength(x) (sizeof(x)/sizeof(*(x)))

static char encodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
static char decodingTable[128];

+ (void) initialize {
if (self == [Base64 class]) {
memset(decodingTable, 0, ArrayLength(decodingTable));
for (NSInteger i = 0; i < ArrayLength(encodingTable); i++) {
decodingTable[encodingTable[i]] = i;
}
}
}


+ (NSString*) encode:(const uint8_t*) input length:(NSInteger) length {
NSMutableData* data = [NSMutableData dataWithLength:((length + 2) / 3) * 4];
uint8_t* output = (uint8_t*)data.mutableBytes;

for (NSInteger i = 0; i < length; i += 3) {
NSInteger value = 0;
for (NSInteger j = i; j < (i + 3); j++) {
value <<= 8;

if (j < length) {
value |= (0xFF & input[j]);
}
}

NSInteger index = (i / 3) * 4;
output[index + 0] = encodingTable[(value >> 18) & 0x3F];
output[index + 1] = encodingTable[(value >> 12) & 0x3F];
output[index + 2] = (i + 1) < length ? encodingTable[(value >> 6) & 0x3F] : '=';
output[index + 3] = (i + 2) < length ? encodingTable[(value >> 0) & 0x3F] : '=';
}

return [[[NSString alloc] initWithData:data
encoding:NSASCIIStringEncoding] autorelease];
}


+ (NSString*) encode:(NSData*) rawBytes {
return [self encode:(const uint8_t*) rawBytes.bytes length:rawBytes.length];
}


+ (NSData*) decode:(const char*) string length:(NSInteger) inputLength {
if ((string == NULL) || (inputLength % 4 != 0)) {
return nil;
}

while (inputLength > 0 && string[inputLength - 1] == '=') {
inputLength--;
}

NSInteger outputLength = inputLength * 3 / 4;
NSMutableData* data = [NSMutableData dataWithLength:outputLength];
uint8_t* output = data.mutableBytes;

NSInteger inputPoint = 0;
NSInteger outputPoint = 0;
while (inputPoint < inputLength) {
char i0 = string[inputPoint++];
char i1 = string[inputPoint++];
char i2 = inputPoint < inputLength ? string[inputPoint++] : 'A'; /* 'A' will decode to \0 */
char i3 = inputPoint < inputLength ? string[inputPoint++] : 'A';

output[outputPoint++] = (decodingTable[i0] << 2) | (decodingTable[i1] >> 4);
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i1] & 0xf) << 4) | (decodingTable[i2] >> 2);
}
if (outputPoint < outputLength) {
output[outputPoint++] = ((decodingTable[i2] & 0x3) << 6) | decodingTable[i3];
}
}

return data;
}


+ (NSData*) decode:(NSString*) string {
return [self decode:[string cStringUsingEncoding:NSASCIIStringEncoding] length:string.length];
}


@end

Okay, so now how do we make the request?  It's pretty evil, but if you wrap it in a function it's not too bad.  Don't forget to import Base64.h!  Anyway, here is the code:

+ (NSData *) loadDataFromURLForcingBasicAuth:(NSURL *url) {
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
NSString *authString = [Base64 encode:[[NSString stringWithFormat:@"%@:%@",[url user], [url password]] dataUsingEncoding:NSUTF8StringEncoding]];
[request setValue:[NSString stringWithFormat:@"Basic %@", authString] forHTTPHeaderField:@"Authorization"];
return [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil];
}

Ugly, ain't it?  You can use this with asynchronous connections as well, or extend it to handle the responses/errors from sendSynchronchronousRequest, but that is an exercise for the reader.

 

 

 

 

 

 

November 11, 2009

Platforms / Debugging EXC_BAD_ACCESS on the iPhone

JB

I've been working on my first real iPhone app.  It's a very interesting way of coding.  Objective-C is an interesting language.  It seems to shoot for the middle ground between something out-of-control like C++, and something so-object-oriented-it-hurts like Java.  Personally, I like Ruby best, but that's neither here nor there.

Memory management on the iPhone is a tough cookie for someone who has not done Objective-C development before.  If you are new to the iPhone, the first thing you should do is read the memory management contract for Cocoa, as well as the links that link out from there.

I was having a problem getting EXC_BAD_ACCESS.  I finally used breakpoints to find where the problem was occurring, and it was an NSArray that was causing it.

I did a google search, and found this really cool method for getting a little more information about objects which have been released before they were accessed.

Eventually, I found out that the problem came from the fact that [NSArray arrayWithObjects:], because it doesn't have "init" or "copy" or "alloc" in the message name for object creation, autoreleases the object when it gives it to me!  Therefore, as soon as the present event was done, it trashed the object.  If you want to keep an object that has been autoreleased, you have to send it a retain message.

Doing the retain fixed my problem.  Yay!

October 06, 2009

General / Laps for Little Ones

JB

Support the Little Light House by sponsoring us in Laps for Little Ones

The Little Light House is one of the best ministries I've ever been involved with.  They are a Christian, private, tuition-free school for special-needs kids.  That's right, the kids who go there don't have to pay anything at all.

This isn't day-care - it's an intensive, customized program for each child.  The school day lets out at 1PM, and the staff spends the rest of the day planning each child's next day.  When a child gets to school, they have a card of things that they are going to work on that day.  It's both extremely fun and extremely helpful for the children -- and the parents.

While our oldest son, Danny, was alive, he attended the Little Light House.  His world expanded so much while he was there.  His ability to play with others and interact and do new things hinged upon the teachers at the Little Light House and their love and their help.  Danny had to be fed through a tube, received many, many, many medications at specially-timed intervals, and, if everyone was lucky, he only threw up three times a day.  Yet the Little Light House had no problems seeing to his every need while he was there, and providing every manner of therapy.  At the Little Light House, they have physical therapy, speech therapy, occupational therapy, and probably a lot of other therapies I'm not so familiar with.  And everything is done in a specifically Christian way.

Isaac had the same genetic defect that Danny had, and, had he lived long enough, would have enjoyed the services of the Little Light House as well.  As soon as we discovered his condition, we reserved him a spot there, because we knew that their help was the difference between night and day for us.

Below are pictures of Danny learning at the Little Light House.  Also, for those of you who didn't get to know Danny or Isaac, I pasted their memorial videos below.  In any case, please consider helping out the Little Light House - they have been a huge blessing to us, and to many, many, many other children.

You can donate now by going here.

Here is Danny's Memorial Video:

Isaac's Memorial Video:

A few pictures of Danny at the Little Light House if you don't have time for the video:

The picture below might look like playtime to you, but this was actually crucial for Danny.  He had problems touching a variety of surfaces - many different textures made him cry and gag and puke (yes, really).  The Little Light House worked with him to help him adjust his senses to be able to touch and play with a huge variety of textures.