Skip to content

Instantly share code, notes, and snippets.

@rsattar
rsattar / Animation.md
Created February 8, 2016 18:24 — forked from JeOam/Animation.md
iOS Core Animation: Advanced Techniques, Part 1: The Layer Beneath

1. The Layer Tree

Core Animation's original name is Layer Kit

Core Animation is a compositing engine; its job is to compose different pieces of visual content on the screen, and to do so as fast as possible. The content in question is divided into individual layers stored in a hierarchy known as the layer tree. This tree forms the underpinning for all of UIKit, and for everything that you see on the screen in an iOS application.

In UIView, tasks such as rendering, layout and animation are all managed by a Core Animation class called CALayer. The only major feature of UIView that isn’t handled by CALayer is user interaction.

There are four hierarchies, each performing a different role:

  • view hierarchy
  • layer tree
@rsattar
rsattar / UserNotifications.swift
Created February 27, 2016 00:34
Swift script that shows how to deliver notifications to OS X Notification Center using purely CLI. This can be pasted into a Playground and executed, too.
import Foundation
// Create a method that will be called instead of
// "bundleIdentifier()" that returns a non-empty
// bundle id, even for a CLI script
extension NSBundle {
func fakeBundleIdentifier() -> NSString {
if self == NSBundle.mainBundle() {
return "dont.mind.me.totally.a.normal.bundleid"
} else {
@rsattar
rsattar / gist:b06060df7ea293b398d1
Last active September 24, 2017 22:54
Convert CLLocation and CLHeading into GPS metadata
// Inspired by: http://stackoverflow.com/a/5314634/9849
// Simplified if-statements
// Updated to "modern" syntax
// Support optional CLHeading
// Support degree-of-precision
//
// This dictionary should then be added to the normal
// metadata using the kCGImagePropertyGPSDictionary key
- (NSDictionary *)GPSDictionaryForLocation:(CLLocation *)location heading:(CLHeading *)heading
{
@rsattar
rsattar / SetApplicationGroupContainerIdentifier.sh
Last active June 27, 2017 08:57
Set ApplicationGroupContainerIdentifier in Settings.bundle to group.$(CFBundleIdentifier)
# Get the already-processed Info.plist, which has our bundleId, etc.
processedInfoPlistFile=$TARGET_BUILD_DIR/$INFOPLIST_PATH
# Copy the bundle identifier from our processed Info.plist
bundleId=$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" "$processedInfoPlistFile")
# Prefix it with "group." to make the application group container id
appGroupContainerId=group.$bundleId
# Get the already-copied Settings.bundle/Root.plist
appPackageFolder=$TARGET_BUILD_DIR/$EXECUTABLE_FOLDER_PATH
copiedSettingsBundlePlistFile=$appPackageFolder/Settings.bundle/Root.plist
@rsattar
rsattar / SafariViewControllerAutlogin.m
Created September 15, 2015 21:15
SFSafariViewController autologin snippets
// Say this is in your app delegate
- (void) attemptAutologin
{
NSURL *autologinURL = ...some..url..that..does..autologin..on..your..server
self.safariViewController = [[SFSafariViewController alloc] initWithURL:autologinURL];
self.safariViewController.modalPresentationStyle = UIModalPresentationOverFullScreen;
self.safariViewController.view.alpha = 0.0;
[self.window.rootViewController presentViewController:self.safariViewController
animated:NO
@rsattar
rsattar / UserNotifications.swift
Created February 27, 2016 00:34
Swift script that shows how to deliver notifications to OS X Notification Center using purely CLI. This can be pasted into a Playground and executed, too.
import Foundation
// Create a method that will be called instead of
// "bundleIdentifier()" that returns a non-empty
// bundle id, even for a CLI script
extension NSBundle {
func fakeBundleIdentifier() -> NSString {
if self == NSBundle.mainBundle() {
return "dont.mind.me.totally.a.normal.bundleid"
} else {
@rsattar
rsattar / LKImageView.m
Last active January 22, 2016 23:11
UIImageView which constraints its own height based on its layouted width
- (void) setImage:(UIImage *)image
{
[super setImage:image];
if (self.lk_heightConstrainedToAspectWidth && self.image) {
CGFloat imageAspectRatio = self.image.size.height / self.image.size.width;
// If we haven't constrained ourself, or the constraint needs updating
if (!self.aspectRatioHeightConstraint || self.aspectRatioHeightConstraint.multiplier != imageAspectRatio) {
[self setNeedsUpdateConstraints];
}
@rsattar
rsattar / gist:4998533
Created February 20, 2013 19:30
Generating an X-AvoSig string for signing API requests for Avocado
// Requires Security.framework on Cocoa and Cocoa-Touch
#import <CommonCrypto/CommonDigest.h>
- (NSString *)avoSigFromUserEmailHash:(NSString *)userEmailHash developerKey:(NSString *)developerKey developerId:(NSString *)developerId
{
NSString *combo = [userEmailHash stringByAppendingString:developerKey];
unsigned char result[CC_SHA256_DIGEST_LENGTH];
const char *combined = [combo UTF8String];
CC_SHA256(combined, [combo lengthOfBytesUsingEncoding:NSUTF8StringEncoding], result);
@rsattar
rsattar / gist:4480663
Created January 8, 2013 02:51
How to parse a Socket.IO payload (== packets bunched together), so that we can parse them as individual packets.
// Sometimes Socket.IO "batches" up messages in one packet,
// so we have to split them.
//
- (NSArray *)packetsFromPayload:(NSString *)payload
{
// "Batched" format is:
// �[packet_0 length]�[packet_0]�[packet_1 length]�[packet_1]�[packet_n length]�[packet_n]
@rsattar
rsattar / LKConfigPreview.md
Last active November 11, 2015 01:18
A potential way to list LKConfig keys, with potential rules

autologin = TRUE

googleLogin = TRUE

  • When version > 3.5: FALSE

barName = Hello World!

foo = FALSE