Wednesday, October 5, 2016

Xcode 8 automatic code signing problem with Jenkins

Xcode 8 automatic code signing is great. However if you try to use Jenkins to automate your app build with a specific provision profile, you would want to use manual code signing. What I wanted to do was use automatic code signing during development and use manual code signing with Ad-Hoc provision with Jenkins.

To switch from automatic to manual code signing, you need to change the following setting in the project file ([project name].xcodeproj/project.pbxproj).
Change "ProvisioningStyle = Automatic" to "ProvisioningStyle = Manual"
By default "ProvisioningStyle = Automatic" is not in the project.pbxproj. You just need to uncheck and check "Automatically manage signing" in app Target -> General in Xcode to add that setting.

Now in Jekins, you want to add this shell script before you run the Xcode build command to change "ProvisioningStyle = Automatic" to "ProvisioningStyle = Manual"

sed -i '' 's/ProvisioningStyle = Automatic;/ProvisioningStyle = Manual;/' [project name].xcodeproj/project.pbxproj

You can then use xcodebuild argument "PROVISIONING_PROFILE=xxxx-xxxx-xxxx" to use the provision profile you want.

Friday, March 25, 2016

Add tint to UIImage

I have been working on a SDK that allows user to customize colors for images. In many cases, I need to add an image to a button with different color at run time. So using just tintColor is not going to work. The following method will mask an image with the color you define.

- (UIImage *)maskWithColor:(UIColor *)color
{
    CGImageRef maskImage = self.CGImage;
    CGFloat width = self.size.width * self.scale;
    CGFloat height = self.size.height * self.scale;
    CGRect bounds = CGRectMake(0,0,width,height);
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef bitmapContext = CGBitmapContextCreate(NULL, width, height, 8, 0, colorSpace, kCGBitmapAlphaInfoMask & kCGImageAlphaPremultipliedLast);
    CGContextClipToMask(bitmapContext, bounds, maskImage);
    CGContextSetFillColorWithColor(bitmapContext, color.CGColor);
    CGContextFillRect(bitmapContext, bounds);
    
    CGImageRef cImage = CGBitmapContextCreateImage(bitmapContext);
    UIImage *coloredImage = [UIImage imageWithCGImage:cImage scale:self.scale orientation:self.imageOrientation];
    
    CGContextRelease(bitmapContext);
    CGColorSpaceRelease(colorSpace);
    CGImageRelease(cImage);
    
    return coloredImage;
}