Objective C implementation of Swift's if-let
My suggestion would be: Don't do it. The main disadvantages 
(in my opinion) are:


As you noticed, commas inside the macro argument are not handled,
leading to "strange" error messages:

for (SKNode *node in touchedNodes) {
    IF_LET(Tile, tile, node, { 
        // Use of undeclared identifier 'IF_LET'
        SKAction *scale = [SKAction scaleBy: 1.2 duration: 0.15];
        SKAction *action = [SKAction sequence:@[scale, scale.reversedAction]];
        // Too many arguments provided to function-like macro invocation
        [tile runAction:action];
    })
}


It is not obvious how this must be fixed, and enclosing all Objective-C
message calls feels unnatural.
Macros are not known to the debugger. As a consequence, you cannot
set a breakpoint at a certain line inside the block – the debugger will
stop at the end of the block instead. 
For the same reason you cannot single-step through the block statements. 


Some of your intended applications have alternatives in pure
Objective-C, which are (almost) as good.

Example 1: Your code

for (SKNode *node in touchedNodes) {
    IF_LET(Tile, tile, node, {
        SKAction *scale = [SKAction scaleBy: 1.2 duration: 0.15];
        SKAction *action = ([SKAction sequence:@[scale, scale.reversedAction]]);
        [tile runAction:action];
    })
}


can be replaced by

for (Tile *tile in touchedNodes) {
    if ([tile isKindOfClass:Tile.class]) {
        SKAction *scale = [SKAction scaleBy: 1.2 duration: 0.15];
        SKAction *action = ([SKAction sequence:@[scale, scale.reversedAction]]);
        [tile runAction:action];
    }
}


The fast-enumeration for statement does not care how about the
type of the loop variable, you only have to verify its class before
accessing it.

Example 2: Your code 

SKLabelNode *t = nil;
IF_LET(SKLabelNode, temp, t, {
    // doesn't run: t was nil
    [temp setText:@"text"];
})


can be replaced by (the even shorter)

SKLabelNode *t = nil;
[t setText:@"text"];


because sending Objective-C message to nil is a no-op.

Example 3: Your code

t = [SKLabelNode labelNodeWithText:@"some text"];
IF_LET(NSObject, temp, t, {
    // this block runs, letting you do stuff with the local scope variable
    // NSObject *temp = (NSObject*)t;
}) else {
    // else block available for use, but
    // this one doesn't run because t is not nil and is a kind of NSObject
}


is equivalent to

t = [SKLabelNode labelNodeWithText:@"some text"];
if (t != nil) {
    // Local scope for if-case
} else {
    // Local scope for else-case
}