AppCode has features that are not present in Xcode. At a minimum, AppCode will be a good addition to XCode.
The full list of features is here.
Here I will show examples of using AppCode features. Inspired by this article, that was very usefull for me.
1. Quick Fix feature in AppCode is more convenient. Refactoring to Modern Objective C syntax using Quick Fix (Alt + Enter).
Before:
|
- (NSDictionary *)convertToDicForCC { NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithObjectsAndKeys:self.deviceId,@"id",nil]; [dict setObject:self.parentId forKey:@"parent_id"]; [dict setObject:self.deviceName forKey:@"name"]; [dict setObject:[REDeviceUtils stringDeviceFromType:self.devType] forKey:@"device_type"]; [dict setObject:[REDeviceUtils viewNameFromViewType:self.viewType] forKey:@"device_view"]; [dict setObject:self.roomName forKey:@"room"]; [dict setObject:self.moduleName forKey:@"module"]; [dict setObject:self.modelName forKey:@"model"]; [dict setObject:[NSString stringWithFormat: @"%i", self.floorId] forKey:@"floor"]; [dict setObject:[NSNumber numberWithBool:self.hidden] forKey:@"hidden"]; [dict setObject:@(self.order) forKey:@"order"]; return dict; } |
After:
|
- (NSDictionary *)convertToDicForCC { NSMutableDictionary *dict = [@{@"id": self.deviceId} mutableCopy]; dict[@"parent_id"] = self.parentId; dict[@"name"] = self.deviceName; dict[@"device_type"] = [REDeviceUtils stringDeviceFromType:self.devType]; dict[@"device_view"] = [REDeviceUtils viewNameFromViewType:self.viewType]; dict[@"room"] = self.roomName; dict[@"module"] = self.moduleName; dict[@"model"] = self.modelName; dict[@"floor"] = [NSString stringWithFormat:@"%i", self.floorId]; dict[@"hidden"] = @(self.hidden); dict[@"order"] = @(self.order); return dict; } |
2. Simplifying expressions using Quick Fix.
Before:
|
- (BOOL)countTimers { [self readTimers]; return (self.filteredOnTimerArray.count > 0 || self.filteredOffTimerArray.count > 0 || self.localTimerOnArray.count > 0 || self.localTimerOffArray.count > 0) ? YES : NO; } |
After:
|
- (BOOL)countTimers { [self readTimers]; return self.filteredOnTimerArray.count > 0 || self.filteredOffTimerArray.count > 0 || self.localTimerOnArray.count > 0 || self.localTimerOffArray.count > 0; } |
3. AppCode can generate code for you. Use Command + N.
Generated code – isEqual and hash methods for a class that has properties – objectID, name, selected:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
|
- (BOOL)isEqual:(id)other { if (other == self) return YES; if (!other || ![[other class] isEqual:[self class]]) return NO; return [self isEqualToObject:other]; } - (BOOL)isEqualToObject:(REBaseObject *)object { if (self == object) return YES; if (object == nil) return NO; if (self.objectID != object.objectID) return NO; if (self.name != object.name && ![self.name isEqualToString:object.name]) return NO; if (self.selected != object.selected) return NO; return YES; } - (NSUInteger)hash { NSUInteger hash = (NSUInteger) self.objectID; hash = hash * 31u + [self.name hash]; hash = hash * 31u + self.selected; return hash; } |
Description method generated for a class with many properties:
|
- (NSString *)description { NSMutableString *description = [NSMutableString stringWithFormat:@"<%@: ", NSStringFromClass([self class])]; [description appendFormat:@"self.roomDic=%@", self.roomDic]; [description appendFormat:@", self.UID=%@", self.UID]; [description appendFormat:@", self.homeID=%@", self.homeID]; [description appendFormat:@", self.name=%@", self.name]; [description appendFormat:@", self.owner=%d", self.owner]; [description appendFormat:@", self.hasCC=%d", self.hasCC]; [description appendFormat:@", self.isAlarmed=%d", self.isAlarmed]; [description appendFormat:@", self.users=%@", self.users]; [description appendFormat:@", self.hasWIFISockets=%d", self.hasWIFISockets]; [description appendString:@">"]; return description; } |
4. Imports do not block other code and are folded. Typos in names are shown and renaming works better than in XCode.
These are small features, but very useful. Here defered should be renamed to deferred.

5. Unused imports and properties are shown.
XCode doesn’t do that.

6. Scroll from source feature in project navigator.
You can open a source file by name as in XCode, but after that you can also navigate to that source file in a project tree in one click.
