пятница, 22 января 2016 г.

Ecodery iOS 22.01.2016 speech

1. BOOL

Как не надо делать: 
if (dbItem.isFavorite.boolValue == YES) { //...     }
return boolvalue ? YES : NO;
boolValue  = (x.someproperty) ? YES : NO;


Как надо делать:
if (dbItem.isFavorite.boolValue) {//...}
return boolvalue;
boolValue  = (x.someproperty);

2. nil

Как не надо делать: 
if(item == nil) 
или
return result ? result : nil; 

Как надо делать:
if (item)
return result;

3. Основные плагины Alcatraz, которые не стоит не использовать 

xAlign

Without: 
- (void)cleanUp {
    _userId = nil;
    _accessToken = nil;
    _favoriteListId = nil;
    _registerCredential = nil;
}

With:
- (void)cleanUp {
    _userId             = nil;
    _accessToken        = nil;
    _favoriteListId     = nil;
    _registerCredential = nil;
}

But:

        case StatusTypeInvisible: {
            NSDate *date = [NSDate dateWithTimeIntervalSince1970:userStatus.lastConnection.doubleValue / 1000];
            if (date.isToday) {
                self.dateFormatter.timeStyle = NSDateFormatterShortStyle;
                self.dateFormatter.dateStyle = NSDateFormatterNoStyle;
            } else {
                self.dateFormatter.timeStyle = NSDateFormatterShortStyle;
                self.dateFormatter.dateStyle = NSDateFormatterShortStyle;
            }
            NSString *dateString = [self.dateFormatter stringFromDate:date];
            statusString = [NSString stringWithFormat:@"%@ %@",NSLocalizedString(@"USER_STATUS_OFFLINE_OR_INVISIBLE", nil), dateString];
            break;
        }

MLAutoReplace

@s/ -> @property (nonatomic, strong) <#custom#>
@a/ -> @property (nonatomic, assign) <#custom#>
@w/ -> @property (nonatomic, weak) <#custom#>
+ some extra

FuzzyAutocomplete

Code more for typing less 

IntelliPaste

(.m TCProfileVC)

- (void)updateHeaderView
{
    dispatch_async(dispatch_get_main_queue(), ^{
        NSString *imageUUID       = self.userToDisplay.imageId;
        UIImage *placeholderImage = [UIImage imageNamed:@"profile_image_placeholder"];
        
        if (imageUUID)
        {
            NSURL *url = [NSURL imageDownloadUrlForUUID:imageUUID
                                      downloadImageSize:TCImageDownloadSizeMiddle];
            
            [self.headerView.photoButton sd_setImageWithURL:url
                                                   forState:UIControlStateNormal
                                           placeholderImage:placeholderImage];
        }
        else {
            [self.headerView.photoButton setImage:placeholderImage
                                         forState:UIControlStateNormal];
        }
        
        self.headerView.nameLabel.text     = [self nameForUserToDisplay];
        self.headerView.nicknameLabel.text = [NSString stringWithFormat:@"@%@",self.userToDisplay.nickname];
        [self.tableView reloadData];
    });
}

- (NSString *)nameForUserToDisplay
{
    NSString *name;
    
    if (self.userToDisplay.firstName || self.userToDisplay.lastName) {
        name = [NSString stringWithFormat:@"%@ %@",
                self.userToDisplay.firstName ? self.userToDisplay.firstName : @"",
                self.userToDisplay.lastName ? self.userToDisplay.lastName: @""];
        return name;
    }
    return @"";
}

- (void)showFAQ
{
    NSURL *url                   = [NSURL URLWithString:kFAQURLString];
    SFSafariViewController *sfvc = [[SFSafariViewController alloc] initWithURL:url];
    [self presentViewController:sfvc animated:YES completion:nil];
}

cmd + c -> cmd + ctrl + up  ->  cmd + shift + v 

(.h TCProfileVC)
@interface TCProfileVC : UIViewController
- (void)updateHeaderView;
- (NSString *)nameForUserToDisplay;
- (void)showFAQ;
@end

and vice versa

Auto Importer

BKUserCredentialModel -> select -> ctrl+ cmd+ h #import "BKUserCredentialModel.h"

SCXcodeSwitchExpander

typedef NS_ENUM(NSUInteger, TCProfileSettingsSectionType)
{
    TCProfileSettingsSectionTypeNotification,
    TCProfileSettingsSectionTypeLinkedAccounts,
    TCProfileSettingsSectionTypeCache,
    TCProfileSettingsSectionTypeChatBackgroundChange,
    TCProfileSettingsSectionTypeBlockedUsers,
    TCProfileSettingsSectionTypeCountryCode,
    TCProfileSettingsSectionTypeRestore
};

    TCProfileSettingsSectionType type = //get type

  switch (type) {
        case <#constant#>:
            <#statements#>
            break;
            
        default:
            break;
    }

-> 
    switch (type) {
        case TCProfileSettingsSectionTypeNotification: {
            <#statement#>
            break;
        }
        case TCProfileSettingsSectionTypeLinkedAccounts: {
            <#statement#>
            break;
        }
        case TCProfileSettingsSectionTypeCache: {
            <#statement#>
            break;
        }
        case TCProfileSettingsSectionTypeChatBackgroundChange: {
            <#statement#>
            break;
        }
        case TCProfileSettingsSectionTypeBlockedUsers: {
            <#statement#>
            break;
        }
        case TCProfileSettingsSectionTypeCountryCode: {
            <#statement#>
            break;
        }
        case TCProfileSettingsSectionTypeRestore: {
            <#statement#>
            break;
        }
    }


понедельник, 18 января 2016 г.

Ошибка 'sharedApplication' is unavailable

'sharedApplication' is unavailable: not available on iOS (App Extension) - Use view controller based solutions where appropriate instead.

Иногда возникает такая проблема.

Решается просто. Идем в target -> build settings -> build options
 (или ищем "APPLICATION_EXTENSION_API_ONLY") 
и меняем значение на NO



пятница, 15 мая 2015 г.

Как создать Xcode snippet

Создание своего Xcode snippet


Безусловно, использовать Snippet'ы очень полезно и удобно. Большой набор snipet'ов есть в библиотеке Xcode и вы уже часто их используете. Однако, набор этот весьма ограничен, потому есть смысл создавать, настраивать и использовать именно свои snippet'ы, подходящие под задачи с которыми сталкиваетесь именно Вы.  
Итак, 
  1. Напишите Ваш часто используемый кусок кода (snippet).
  2. Откройте "Code Snippet library"( для этого откройте панель утилит и нажмите на { }).
  3. Выделите ваш будущий snippet в коде и перетяните его в библиотеку snippet'ов. (Если перетянуть не выходит - попробуйте после выделения нажать на выделенный кусок и подержать курсор около секунды, после - не отрывая курсора, тяните). 
  4. Введите заголовок в поле title в открывшемся окне. 
  5. Введите shortcut для вашего куска кода(используйте что-то осмысленное, связанное с кодом и легко запоминающееся; также можно добавить префиксные буквы вроде US для того, чтобы легче находить среди библиотечных Ваши snippet'ы). Shortcut  - это ключевые слова, с помощью которых Вы будете добавлять свой snippet во время работы.  
  6. Выберите платформу и язык. 
  7.  Выберите в поле  completion scope область где будут доступны ваши snippet'ы (top level - вне всего, class implementations - в имплементации класса и т.д.) 
  8.  Теперь подкорректируйте ваш отрывок кода, чтобы использовать его часто, например с использованием placeholders. Сами плейсхолдеры в Xcode добавляються с помощью <# #> тегов,  т.е. <#your_placeholder_name#> превратиться в удобный холдер, к которому можно перепрыгнуть нажатием tab. 

Вот несколько примеров, которые Вы уже можете добавить себе в snippet'ы:

1)
@property (nonatomic, strong) NSArray *<#data#>Array;
Добавляем массив как свойство класса. Остается только ввести имя массива.

2)
- (UITableViewCell *)tableView:(UITableView *)tableView 
                cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{
   <# cell class #> *cell = [<# cell class #> cellForTableView:tableView];
   return cell;
}
Добавляем  ячейку в метод делегата UITableView, вводим имя класса ячейки. 

3)
UIBarButtonItem *<#button#> = [[UIBarButtonItem alloc] initWithTitle:<#title#>   
                                                                                                             style:UIBarButtonItemStylePlain
                                                                                                            target:self
                                                                                                            action:@selector(<#method#>)];  
self.navigationItem.<#left_or_right#>BarButtonItem = <#button#>;

Добавляем кнопку на navigationbar.

Используйте snippet'ы, это сэкономит Вам время на разработку!

четверг, 26 марта 2015 г.

Как использовать AFNetworking 2.0

Небольшой туториал по использованию  AFNetworking 2.0 

GET


1
2
3
4
5
6
7
8
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager GET:@"http://samwize.com/api/poos/"
  parameters:nil
     success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

POST


1
2
3
4
5
6
7
8
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
[manager POST:@"http://samwize.com/api/poo/"
   parameters:@{@"color": @"green"}
      success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"JSON: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

POST Multi-Part (в несколько частей)

Схоже с POST, но с данными (в этом случае, картинкой) в теле, разбитыми на несколько частей. 

1
2
3
4
5
6
7
8
9
10
11
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"];
[manager POST:@"http://samwize.com/api/poo/"
   parameters:@{@"color": @"green"}
   constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
    [formData appendPartWithFileURL:filePath name:@"image" error:nil];
} success:^(AFHTTPRequestOperation *operation, id responseObject) {
    NSLog(@"Success: %@", responseObject);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
    NSLog(@"Error: %@", error);
}];

Связка операций

Выше использовался AFHTTPRequestOperationManager и обычно этого вполне достаточно.
Но, если Вам необходима связка операций, то вы должны использовать
AFHTTPRequestSerializerAFHTTPRequestOperation и NSOperationQueue.
Образец кода ниже прямо из AFNetworking:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
NSMutableArray *mutableOperations = [NSMutableArray array];
for (NSURL *fileURL in filesToUpload) {
    NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id<AFMultipartFormData> formData) {
        [formData appendPartWithFileURL:fileURL name:@"images[]" error:nil];
    }];

    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [mutableOperations addObject:operation];
}

NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
    NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
    NSLog(@"All operations in batch complete");
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];


Немного еще 
Выше приведенные примеры используют стандартный AFJSONResponseSerializer – что значит ответ должен быть в формате JSON.
Если вы обрабатываете XML или другие данные, то вам нужен другой вид serializer'a.

1
2
3
4
5
// Чтобы обрабатывать XML
AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager];
manager.responseSerializer = [AFXMLParserResponseSerializer new];
// Или данные
manager.responseSerializer = [AFHTTPResponseSerializer new];

AFNetworking очень строг с Content-Type (типом контента).
Поэтому, если ваш ответ типа “text/plain”, когда вы используете JSON serializer, можно поступить так:

1
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"text/plain"];