CocoaPods manages library dependencies for your Xcode projects
1. $ sudo gem install cocoapods
It requires your ruby is >= v1.9.x, if it isn't, you need to upgrade as the following steps:
1.1. Suggest to install rvm (Ruby Version Manager) with the following command line:
$ curl -L https://get.rvm.io | bash -s stable --ruby
1.2. Check available version
$ rvm list known
1.3. Select one to install
$ rvm install ruby-2.1.1
2. $ sudo gem install cocoapods again if update needed.
3. Go to you project directory to do the following command
I suppose there's been a Podfile there:
$ pod intall
it will automatically generate the *.xworkspace project and Pods project for your project.
Reference URL: http://guides.cocoapods.org/using/getting-started.html
Thursday, November 6, 2014
Monday, November 3, 2014
[Android] Add gradle environment constant
Add gradle environment constant:
1. Create ~/.gradle/gradle.properties
2. Add content like: env=stage
Add environment constant for running time:
$ gradle assembleDebug -Penv=stage
Use in gradle file
1. $buildEnv
2. project.ext['buildEnv']
Thursday, October 30, 2014
[iOS] Create NSArray for non-object data types
Example:
MKMapPoint *points;
points = malloc(2 * sizeof(MKMapPoint));
points[0] = MKMapPointForCoordinate(CLLocationCoordinate2DMake(0, 1));
points[1] = MKMapPointForCoordinate(CLLocationCoordinate2DMake(1, 1));
....
free(points);
Monday, August 18, 2014
[iOS] Solving Backwards Compatibility Issues
Solving Backwards Compatibility Issues
Once you have identified the backwards compatibility issues in your app, the next step is to figure out how to fix them. Each new version of iOS introduces new frameworks, classes, methods, constants and enumeration values — and there’s a specific strategy to deal with each of these.Unsupported frameworks
Linking against a framework that doesn’t exist in your deployment target will just cause the dynamic linker to crash your app. To solve this, you mark unsupported frameworks as “Optional” in your project settings.
To do this, select your project under the “Targets” section, and open up Build Phases -> Link Binary With Libraries. Next to each framework you can specify either Required or Optional. Selecting Optional will weak link the framework and solve your compatibility issue.
Note: You can read more about weak linking in Apple’s Framework Programming Guide.
Unsupported classesSometimes you want to use a class that exists in your base SDK, but not in your deployment target. To do this you need to check the availability of this class at runtime to avoid crashing your app. It crashes because this is what the Objetive-C runtime will do if you try to use a class that doesn’t exist. As of iOS 4.2, classes are weakly linked so you can use the
+class method to perform the runtime check. For example:if ([SLComposeViewController class]) { //Safe to use SLComposeViewController } else { //Fail gracefully } |
Similarly, if you’re using a method in your base SDK that doesn’t exist in your deployment target, you can avoid nasty crashes by using a little introspection.
The methods
-respondsToSelector: and +instancesRespondToSelector: will both do the trick, as shown in the code examples below:if ([self.image respondsToSelector:@selector(resizableImageWithCapInsets:resizingMode:)]) { //Safe to use this way of creating resizable images } else { //Fail gracefully } |
respondsToSelector: on the class itself, like so:if ([UIView respondsToSelector:@selector(requiresConstraintBasedLayout)]) { //Safe to use this method } else { //Fail gracefully } |
Note: If you want to check for the presence of a certain property on a class, then you can do so by testing that instances respond to the property getter or setter.
For example, to check if
Unsupported constants/C functionsFor example, to check if
UILabel can take an attributed string via its attributedText property (new in iOS 6), perform introspection against the implicit setter method @selector(setAttributedText).Sometimes a constant value is the missing piece of the deployment target; it usually takes the form of an
extern NSString * or a C function. In this case, you can perform a runtime check against NULL to determine if it exists.For example, the C function
ABAddressBookCreateWithOptions(...) was introduced in iOS 6 but can still live safely in your iOS 5 app like so:if (ABAddressBookCreateWithOptions != NULL) { //Safe to use } else { //Fail gracefully } |
UIApplicationWillEnterForegroundNotification, you would simply validate it as so:if (&UIApplicationWillEnterForegroundNotification) { //Safe to assume multitasking support } else { //Fail gracefully } |
UIApplicationWillEnterForegroundNotification is simply an extern NSString * declared at the bottom of the document. When your application is loaded into memory, these strings are initialized and stay resident in memory. The
& operator gets the string’s memory address. If the memory address is not equal to nil, then the NSString is available, otherwise it’s not available and your code will have to work around that fact.
Note: The mechanism that makes this work is weak linking, which was described earlier. When a binary is loaded the dynamic linker replaces in the app binary any addresses of things (functions, constants, etc) in dynamically loaded libraries. If it’s weakly linked then if the symbol in the library is not found then the address is set to NULL.
Unsupported enumeration valuesChecking for the existence of enumeration or bit mask values — the kind that you would find inside an
NS_ENUM or NS_OPTIONS declaration — is incredibly difficult to check at runtime. Why? Under the hood, an enumeration is just a method of giving names to numeric constants. An enum is replaced with an
int when compiled, which always exists!If you’re faced with the situation of needing to see if a certain enumeration exists, all you can do is either explicitly check the OS version (which isn’t recommended) or alternatively check against another API element that was introduced at the same time as the new enumeration value.
Note: Whichever way you do this, be sure to add adequate comments to any such code and consider wrapping the code in a dedicated compatibility helper.
Explicit iOS version checkingYou should generally stay away from checking explicit iOS versions but there are specific situations where it’s unavoidable. For example, if you need to account for a bugfix in a previously available method, use the following line of code to return the OS version:
NSString *osVersion = [[UIDevice currentDevice] systemVersion]; |
compare:options: method, passing NSNumericSearch as the options to compare OS versions. This takes into account the fact that 6.1.1 is greater than 6.1.0. If you converted them to floats first and then used standard arithmetic things would go wrong because both would parse as the number 6.1.
Note: You can find out more about this topic in Apple’s SDK Compatibility Guide.
Tuesday, August 5, 2014
[iOS]Ojbective C async call sample
1. Define block method:
typedef void (^MyTestBlock)(void);
MyTestBlock myBlock = ^void() {
// your implementation
}];
2. Consumer
[[NSNotificationCenter defaultCenter] addObserverForName:@"key" object:nil queue:nil usingBlock:^(NSNotification *note) {
myBlock();
}];
3. Trigger
[[NSNotificationCenter defaultCenter] postNotificationName:@"key" object:nil userInfo:nil];
Friday, August 1, 2014
[iOS] Error: Synthesis of weak property only allowed in arc or gc mode
Go to Targets -> Build Phases -> Compile Sources, find the file
double click it to add: -fobjc-arc
and rebuild again.
double click it to add: -fobjc-arc
and rebuild again.
Tuesday, July 15, 2014
[iOS] Unit Test Frameworks
Apple provide its default test framework XCTestCase, but it's hard to use it to test async / block /delegate / protocol methods.
Here are some open source tools which can help you do everything as you want:
- OCMockito - https://github.com/jonreid/OCMockito
It's easy to mock any object, protocol can also be mocked, but can't handle the async methods. - Expecta - https://github.com/specta/expecta
It provides powerful matchers and easy to use. - Aspects - https://github.com/steipete/Aspects
Just like the name, you can do something before or after the methods or replace the methods' implementation. - Kiwi - https://github.com/kiwi-bdd/Kiwi
It's very very powful to do asynchronous testing, stub methods to capture any methods' parameter, protocol mock and handle any you want to do.
Kiwi docs - https://github.com/kiwi-bdd/Kiwi/wiki
Subscribe to:
Posts (Atom)