Thursday, November 10, 2011

Dealing with expired developer and distribution certificates

So, round this time every year for the last few, I go into a small panic as I try to remember the steps to recreate my development and distribution certificates.

Fortunately, after cruising various blogs and the Developer Forums I saw a reference to this document:

http://developer.apple.com/library/ios/#technotes/tn2250/_index.html%23//apple_ref/doc/uid/DTS40009933


I worked thru the section on Deleting/Revoking Your Certificates and Starting Fresh and was done in about 10 minutes.

Waaayyy easier than anything else I've seen out there...

Wednesday, October 26, 2011

password protect a zip file on the mac

From the command line: zip -re foo.zip file1.txt file2.txt

you'll be prompted for a password

Saturday, October 1, 2011

iconv - for converting file formats

TextEdit on the mac doesn't do such a good job converting language files from the PC. I've found the following command line command works better:

iconv -f ISO-8859-1 -t UTF-16 [input file] > outputfile

Thursday, September 8, 2011

UIWebview resizing text on rotation

Ran into a multi-layered problem this morning with UIWebView. I have an app where a table view cell can pop open and reveal a UIWebView. The problem was on rotation - if I rotated the device and then popped up the cell, the text was too big. I found the fix here. I just added this to the html style tag:

-webkit-text-size-adjust: none;

Saving for future reference.

Tuesday, August 9, 2011

Clear out a corrupted Xcode 4 project state

I ran into a situation this morning where my Xcode 4 got into a bad state and wouldn't start. Beachballs galore.

Cleared it by going into my user directory, then into Library, and doing a

rm -rf "Autosave Information"

Friday, July 22, 2011

Recovering a deleted file from SVN

An Anonymous Geek did all the work on this one. I'm posting just in case his blog goes away; I suspect I'll need this again...


The command is:

> svn up -r 250 file.txt

up is short for update, the -r 250 indicates the revision that the file last existed in, and of course file.txt is the file you want to restore.

Thursday, June 23, 2011

Dynamic view reflection using CAReplicatorLayer



If you've done UIView reflection on iOS before, you've probably used a method that creates an image from the current view and redraws it with a gradient underneath the view. For many applications this is sufficient, but it has problems: it's slow, and for some objects (e.g. UIWebView) you're really not sure when the object is done drawing so you have to tweak it with arbitrary timers to create the reflection after the object is done rendering. Yuk.

An alternative is to use a CAReplicatorLayer (It was mentioned in a WWDC session this year). The CAReplicatorLayer lets you create copies of your main layer that update in real time. You specify the number of layers and then you specify their offset attributes from the primary layer.

Below is some code that uses the CAReplicatorLayer to reflect a view. The important stuff in this example is in the view's "layoutSubviews" method. Also note that to create a CAReplicatorLayer for your subview, you've got to override the subview's "layerClass" method as shown here.

Try it with a UIWebView or other scrollable, dynamically updating subview - it's pretty cool :)

UPDATE: In the interest of completeness, I've reworked some of the code to be a little more usable...



#import "Reflector.h"
#import <QuartzCore/QuartzCore.h>



@interface MySubview : UIWebView
@end

@implementation MySubview

+ (Class) layerClass
{
        return [CAReplicatorLayer class];
}

@end


@implementation Reflector

MySubview *subview;
CAGradientLayer *gl=nil;
BOOL hasReflector;

- (void)setup
{
        hasReflector = YES;
        
        [self setBackgroundColor:[UIColor blackColor]];
        subview = [[MySubview alloc] initWithFrame:self.bounds];
        [self addSubview:subview];
        [subview setBackgroundColor:[UIColor clearColor]];
        
        // . . . do whatever with the subview to create content
        [subview setScalesPageToFit:YES];
        [subview loadRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:@"http://www.flickr.com"]]];

        
}

- (void)layoutSubviews
{
        
        if (hasReflector){
                int gap = 4; // gap between the subview and its reflection
                
                float h1 = ceil(self.frame.size.height *.6);         // subview height
                float h2 = self.frame.size.height - (h1 + gap);        // reflection height
                                
                // size the subview to make space for the reflection
                [subview setFrame:CGRectMake(0, 0, self.frame.size.width, h1)];
                
                // since the replicated layers will be sized using a scale
                // transform, we need to translate our absolute heights into
                // a scalar.
                double scale = (h2/h1);
                
                // configure the subviews replicator layer.  just two instances - the first is the
                // "real-life" rendering of the subview, the 2nd is the reflection
                CAReplicatorLayer *l = (CAReplicatorLayer *) subview.layer;
                l.instanceCount = 2;
                
                // position the instance transform.  the reflection instance will be
                // scaled by "scale" and is centered within the space of the original
                // instance, thus we compute "delta" by taking the original height, 
                // subtracting out the reflection layer size, and then dividing by half.
        
                
                double delta = (h1 - h2) / 2.0 ;
                CATransform3D t = CATransform3DMakeTranslation(0, (h1+gap)-delta, 0);
                t = CATransform3DRotate(t, M_PI, 1, 0, 0);
                t = CATransform3DScale(t, 1, scale, 1);
                
                l.instanceTransform = t;
                
                if (gl == nil){
                        // add a black gradient layer
                        gl = [CAGradientLayer layer];
                        CGColorRef c1 = [[UIColor colorWithRed:0 green:0 blue:0 alpha:.5] CGColor];
                        CGColorRef c2 = [[UIColor colorWithRed:0 green:0 blue:0 alpha:1] CGColor];
                        [gl setColors:[NSArray arrayWithObjects:(id)c1, (id)c2, nil]];
                        
                        [self.layer addSublayer:gl];
                }
                
                // position the gradient layer over the replication layer 2nd instance
                [gl setAnchorPoint:CGPointMake(0, 0)];
                [gl setFrame:CGRectMake(0, h1 + gap, self.frame.size.width, h2)];
                
        }
}
- (id)initWithCoder:(NSCoder *)aDecoder
{
        self = [super initWithCoder:aDecoder];
        if (self){
                [self setup];
        }
        return self;
}
- (void)dealloc {
    [super dealloc];
}


@end