The collection of the usefuls. Objective-C everydayers. You could use it like you would do with any other static library - as Apple recommends Using Static Librariesin iOS) -, or just grab some individual class, they are not that coupled (just watch the imports at the top of .h files). Gonna put the whole library to CocoaPods with submodules where appropriate. Google Analytics SDK have some specific build settings (check Analytics build settings.png for details). Feel free to file a pull request if you spot some errors.
Basic swizzling wrapped up into an Objective-C interface.
pod 'eppz!swizzler', '~> 0.1.1'
A block-based extraction of Apple's Reachability sample.
Simplest UIAlertView wrapper ever.
Keep the properties of two objects synchronized along a given property map. If any value changes, it sets (tries to set) the matching property for the other object.
// Keep a user model object synced with the UI, and vica-versa.
NSDictionary *map = @{
@"name" : @"nameTextField.text",
@"email" : @"emailTextField.text"
};
self.binding = [EPPZBinding bindObject:self.user
withObject:self
propertyMap:map];
Swap NSDictionary objects with keys.
inverse = [this.map dictionaryBySwappingKeysAndValues];
Some random shortcuts.
alpha = randomFloat();
index = randomIntegerInRange(length);
NSArray object picking.
randomItem = [this.items randomObject];
nextItem = [this.items nextObjectAfterObject:currentItem];
Some handy UIColor
tool to mix colors runtime.
overlayColor = [backgroundColor colorWithAlpha:0.5];
opaqueTextColor = [backgroundColor blendWithColor:foregroundColor amount:0.5];
A lovely UIImage
subclass that renders as a circle. Comes handy when debug geometry.
This latest member is a really specific piece of class. Converts a single music interval value (expressen in semitones) into a pitch value (expressed in segments). Also can step back and forth on a diatonic major or minor scale and return pitch result for that.
// Play effect pitched with major 5th.
float pitch = [self.diatonicScale pitchForNote:5];
[self.soundEngine playEffect:@"piano.wav" volume:1.0 pitch:pitch pan:1.0 loop:NO];
Awesome geometry toolkit for intersecting lines, intersecting circles, whatnot.
// Some examples.
CGRect bigger = rectFromRectWithMargin(original, spacing);
CGFloat radians = angleBetweenPoints(touchLocation, previousLocation);
CGVector rotated = rotateVector(handle, angle);
BOOL crossed = areLinesIntersecting(ray, wall);
BOOL hit = isPointOnLineWithTolerance(touchLocation, fence);
Tool that tells you useful app bundle version history information.
if ([VERSIONS isFirstRun])
{ [self showWelcomeMessage]; }
if ([VERSIONS isFirstRunCurrentVersion])
{ [self showThanksForUpdatingMessage]; }
if ([VERSIONS hasBundleVersionEverInstalled:@"1.4.5"])
{ [self migrateSomethingIfNeeded]; }
It is effective only from the point the class has used for the first time. Do not persist between application installs (yet) since it uses NSUserDefaults.
A solid NSObject extension that makes work with models much easier. If a class conforms to the protocol than it mark that object to implement such features.
Yet objects able to represent themselves in a dictionary form that allows me to create many store implementation (Defaults, Archiver, CoreData, JSON, Plist, Keychain, whatnot). In progress, though plist
implementation actually works. Saving foreign classes (like UIViews for example) is also possible. Actually an archiver with much less boilerplate. Example from the testbed project:
//A UIView extension to make it persistable
@interface UIView (EPPZRepresentable) <EPPZRepresentable>
@end
@implementation UIView (EPPZRepresentable)
+(NSArray*)representablePropertyNames
{ return @[ @"frame", @"bounds", @"center", @"transform", @"tag" ]; }
@end
//A model object.
@interface EPPZGameProgress : NSObject <EPPZRepresentable>
@property (nonatomic) NSUInteger progress;
@property (nonatomic) NSUInteger level;
@property (nonatomic, strong) UIView *view;
@end
@implementation EPPZGameProgress
@end
//Saving somewhere in a controller code.
[progress storeAsPlistNamed:@"gameProgress"];
//Restoring later on.
progress = [EPPZGameProgress representableWithPlistNamed:@"gameProgress"];
It will be just as easy to save into NSUserDefaults/NSKeyedArchiver/JSON string or even into a self-describing CoreData archive. In addition, it is now supports saving object references, so won't allocate duplicates on reconstruction. Still in progress.
A simple wrapper around Google Analytics iOS SDK 3.0 (Check Analytics build settings.png for specific build settings constraints). Were intended to be suitable to support multiple analytics service (Flurry, GameAnalytics, etc.), thought only Google is implemented yet.
Some helper function to make boolean works a bit more readable and spare some if statements.
//For debugging.
NSLog(@"Switched to %@.", stringFromBool(switch.isOn));
//For UI.
-(IBAction)switchValueChanged:(UISwitch*) switch
{ wrapper.alpha = floatFromBool(switch.isOn); }
A charming class showing running iOS version with shorties, and model detection as well.
//iOS version detect.
if (DEVICE.iOS6)
{
[self something];
}
//Device model.
NSLog(@"Running on an %@", DEVICE.platformDescription);
A cool compositable object that reduces boilerplate for recognizing gestures. Also arranges some undelying stuff (e.g. double tap do not block triple tap).
//A typical setup in a view controller.
-(void)viewDidLoad
{
[super viewDidLoad];
//Add gesture to close with.
self.gestureRecognizer = [EPPZGestureRecognizer gestureRecognizerWithView:self.view delegate:self];
[self.gestureRecognizer addSwipeDownGesture];
}
-(void)swipeDownEvent
{ [self close]; }
An NSTimer
wrapper that does not retain it's target so not likely to create retain cycles.
//Just you'd normally do with NSTimer but without retain cycle.
self.timer = [EPPZTimer scheduledTimerWithTimeInterval:1.0
target:self
selector:@selector(updateClock:)
userInfo:nil
repeats:YES];
The timer will invalidate itself when the target is existing no more. A check for taget existence is invoked in every invocation of the timer.
A cool UILabel
subclass that allows you to define bold ranges for a given text. It is using EPPZTagFinder
for a feature where you can use <strong>
tags for indicate bold ranges withing an NSString
.
//Using '<strong>' tags.
self.label.htmlString = @"Make <strong>this range</strong> bold.";
//Using a range.
self.label.boldRange = NSMakeRange(15, 5);
Prior iOS 6.0 it falls back to be an arbitary label. I did implemented a solution that uses CATextLayer
to work this issue around in iOS 5.0 but it felt me too hacky, so I decided to stop support iOS 5.0 anymore.
With a sole feature for now that converts NSTimeInterval to something human readable. Converts 1500000.0
to 17 days 08:40:00
for example.
//Supposing remainingTimeInterval is 1500000.0 it sets '17 days 08:40:00' as the label text.
self.countDownLabel.text = [NSDate diplayStringOfInterval:remainingTimeInterval];
Astonishing paging UIScrollView
with UIPageControl
controller. Just drop-in this controller object into an Interface Builder file, hook up scrollView
, contentView
and pageControl
outlets, and wire it in as the delegate
for the UIScrollView
. It calculates the number of pages based on the content size. Note that you have to retain this object somehow to survive after XIB loading (I usually create a strong
IBOutlet
for this in the containing controller, that does the job well).
App Store with blocks, multiple async requests, restoring purchases, store recipes.
//Populate UI with check on purchased state.
-(void)refreshStoreUI
{
self.levelPackView.purchased = [APPSTORE isProductPurchased:kLevelPackIdentifier];
}
//Get product details.
[APPSTORE requestProductDetails:kLevelPackIdentifier
success:^(SKProduct *product)
{
[self.levelPackView refreshWithProduct:product];
} error:nil];
//Purchase (with encapsulated network error handling).
[APPSTORE purchaseProduct:kLevelPackIdentifier
success:^(NSString *productIdentifier)
{
[self refreshStoreUI];
} error:nil];
//Same for restore purchases.
[APPSTORE restorePurchasesWithSuccess:^
{
[self refreshStoreUI];
} error:nil];
A handy helper object to assis encapsulation of Xib loading. More on http://eppz.eu/blog/uiview-from-xib/ about this method.
A really convenient way to store objects in NSUserDefault without any piece of boilerplate code. See the testbed project and the corresponding article on design at eppz!settings.
//Just create a model object, and done.
@interface EPPZSettings : EPPZUserDefaults
@property (nonatomic, strong) NSString *name;
@property (nonatomic) BOOL sound;
@property (nonatomic) float volume;
@property (nonatomic) BOOL messages;
@property (nonatomic) BOOL iCloud;
@end
A pretty thin block-based reachability implementation. See the testbed project and the corresponding article on design at eppz!reachability.
//Get status on-demand.
[EPPZReachability reachHost:hostNameOrIPaddress
completition:^(EPPZReachability *reachability)
{
if (reachability.reachable) [self postSomething];
}];
A helper class that works well with a darkgrey colored Custom button in Interface Builder. I use it mainly in prototype projects, not relly meant for production.
Actually a wrapper around NSFileManager
, some aliases that keeps controller codes clean. See header file for feature set so far.
NSString *documentPath = [FILES pathForNewFileNameInDocumentsDirectory:documentFileName];
BOOL exists = [FILES fileExistsAtPath:documentPath];
BOOL aged = [FILES file:documentPath modifiedAfterDate:lastWeek];
NSArray *documents = [FILES filesOfType:extension inDirectory:FILES.documentsDirectory];
Some useful NSString
extension especially for network applications, for HTTP request issues. Class- and instance methods goes like md5
, urlEncode
, urlDecode
.
A singleton base class from the pre-ARC era. Main feature is that this class is safe to subclass it, and can have multiple delegates. Will rewrite to ARC compilant using dispathc_once
with far less code soon.
Licensed under the Open Source MIT license.