Category Archives: iOS

Creating Local SVN Repository for Project

1.

2. While in the project folder:

3. Create a project folder:

4. Go to the documents folder:

5. Check out from repository:

Как выйти из режима редактирования в Терминале OS X

Иногда по ошибке вводишь что-то не то в Терминале. Например, вот это

В итоге попадаешь в какой-то режим редактирования (пока не знаю, что за редактор точно) с приглашением в виде треугольничка слева.

Чтобы выйти из режима редактирования в Терминале Mac OS X, нужно нажать Ctrl + D

Немного о CoreData

Core Data – это объектноориентированная оболочка над базой данных приложения в iOS/Mac OS. Позволяет создавать таблицы визуально, сама следит за Commitment Control, управлением версиями и т.д.

Persistent Store – это “надежное” хранилище данных. (NSPersistenStoreCoordinator). Данные хранятся в applicationDocumentsDirectory/App.sqlite. Где App.sqlite – это база SQLite приложения.
Context – это instance базы. Промежуточное хранилище, в котором производятся изменения и затем утверждаются (Commitment). Также запрос производится из Context. У одной базы может быть много Context. В каждом Context есть Managed Objects.
Managed Object – объект, с которым мы работаем, но изменения, которые мы в него вносим не вносятся в Persistent Store до тех пор, пока мы не сделаем Save.

CoreData – Core Data Programming Guide

CoreDataSnippets – Core Data Code Snippets

Базовый запрос без предиката всех строк из таблицы:

Запрос с фильтрацией – аналог WHERE в SQL :

Отключение ARC для некоторых сорс-файлов (iOS)

Чтобы отключить ARC(Automatic Reference Counting) лишь для некоторых сорс-файлов, нужно прописать в Compiler Flags:

как показано на рисунке:

Важное замечание
Для того, чтобы отключить ARC сразу на нескольких сорс файлах, нужно их выделить, затем нажать Enter(а не 2 щелчка), ввести эту опцию и снова нажать Enter.

Как пользоваться iBooks

iBooks – очень полезное бесплатное приложение Apple для iOS, которое позволяет читать книги в форматах EPUB и PDF. Это наверно первое, что нужно устанавливать при покупке iPhone и особенно – iPad (если оно, конечно, уже не уставлено). Как это выглядит на iPhone:

Пользоваться iBooks просто. Например, можно скачать книги из iTunes Store, раздела Books:

и они появятся в Вашей медиатеке в разделе Books в iTunes.

Книги в форматах EPUB и PDF можно также импортировать в iTunes/Books, нажав Cmd+O или Файл->Добавить в медиатеку.

После этого, нужно просто синхронизировать раздел Books в устройстве с iOS с Вашей медиатекой iTunes/Books:

В итоге, мы получаем целую библиотеку на iOS устройстве в приложении iBooks.

Определение координат центра iPhone / iPad

Я относительно долго мучился, пытаясь создать код, который был бы унивесальным для iPhone и iPad и определял координаты центра экрана и координаты нижней части экрана. Это нужно было для того, чтобы позиционировать ActivityIndicatorView и AdView. Причиной мучений было то, что функция self.view.bounds работает некооректно на iPad и возвращает координаты прямоугольника такие же как на iPhone, хотя размер экрана другой. Итак, привожу код, по нему все понятно. Сначала я создаю объект CGSize screenSize и далее его использую для позиционирования Activity Indicator и iAd. Вычитаю 20.0 – это высота Status Bar; 44.0 – высота Navigation Bar; 50.0 – высота ADBannerView. У Вас в этом моменте может быть по другому, главное – принцип.

CGSize screenSize = [UIScreen mainScreen].bounds.size;
    // Универсальное определение центра iPhone / iPad
    CGFloat centerX = screenSize.width/2.0;
    CGFloat centerY = (screenSize.height - 20.0 - 44.0)/2.0;
    activity.center = CGPointMake(centerX, centerY);
    // Универсальное позиционирование рекламы внизу экрана iPhone / iPad
    CGFloat adWidth = screenSize.width;
    CGFloat adYCoordinate = screenSize.height - 20.0 - 44.0 - 50.0;
    NSLog(@"adWidth=%f, adYCoordinate=%f", adWidth, adYCoordinate);
    CGRect bannerFrame = CGRectMake(0, adYCoordinate, adWidth, 50.0);
    bannerView.frame = bannerFrame;

Как сделать приложение универсальным для iPhone / iPad

Универсальность приложения – это большой плюс, так как на iPad в таком случае приложение будет работать так же красиво, как на iPhone без масштабирования и как иногда говорят “пикселизации”. Кроме этого, поддерживать универсальное приложение удобнее, так как оно одно, в противном случае нужно поддерживать два разных приложения для двух платформ, что более трудоемко. А еще в App Store будет одна страница. Следовательно легче продвигать, комментарии все в одном месте и т.д. Есть и минусы универсальности. Сложные приложения проще сделать, наверное, в двух вариантах.

Для того, чтобы сделать приложение универсальным нужно учесть несколько аспектов или сделать несколько вещей.

  1. Заходим в Build Settings проекта и делаем поиск параметра Targeted Device Family. Выбираем опцию iPhone/iPad. См. рисунок. При щелчке он увеличивается.
  2. Создаем все необходимые заставки и иконки в нужных размерах. Для iPad размер заставки 768×1004 px, размер иконки 72х72 px. Для iPhone 360×460, иконка 57×57 для iPhone 3GS и ранее, 720х920, 114х114 соответственно для Retina display в iPhone 4 и выше. Если Вы не отображаете Status bar, то нужно прибавить еще 20 к высоте. Присваиваем все заставки и иконки во вкладке Summary для Вашего Target.
  3. Если какие-то XIB файлы View нужно переделать под iPad, то создаем эти XIB файлы. Для этого нажимаем правой кнопкой по папке Classes в проекте, New File -> User Interface -> View. Но просто создать XIB недостаточно. Нужно еще его File Owner присвоить значение нужного класса. См. Рисунок.

    Теперь у нас есть 2 XIB файла для одного View Controller: MainAboutViewController.xib и MainAboutViewControllerIPad.xib к примеру.
    В коде, там где вызывается этот контроллер, нужно сделать разветвление наподобие следующего:
    - (IBAction)showAboutScreen:(id)sender {
        NSString *nibName;
        if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad)
            nibName = @"MainAboutViewControllerIPad";
        else
            nibName = @"MainAboutViewController";
        MainAboutViewController *mainAboutViewController = [[MainAboutViewController alloc] initWithNibName:nibName bundle:nil];
        mainAboutViewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
        mainAboutViewController.title = @"О приложении";
        [self presentModalViewController:mainAboutViewController animated:YES];
    }
  4. Во всех других участках, где нужно учитывать тип устройства пишем аналогичный код:
  5. Ссылки:
    Converting iPhone apps to universal

    A few more notes

Как создать скриншот с симулятора iPad или iPhone?

Удивительно, но лично я раньше не знал, что есть такая функция и каждый раз создавал скриншоты с девайсов. Но тут мне пришлось столкнуться с тем, что Apple стали теперь требовать скриншоты также и для iPad для всех приложений, а у меня нет iPadа пока. Возникла задача создать скриншот с симулятора. Но обычный метод с Shift+Cmd+4 -> Пробел также не помог, так как размер симулятора iPad меньше, чем реальное устройство и изображение не получается нужных размеров и при увеличении – нужного разрешения. К счастью, решение нашлось, и теперь я всегда буду создавать скриншоты именно так.

  1. Нажмите Правка в группе Меню – там увидите специальную кнопку для создания скриншота с симулятора. Либо используйте горячую клавишу Ctrl+Cmd+C.
  2. Откройте программу Просмотр и нажмите Cmd+N для создания нового файла из буфера обмена.

Сохраненный файл имеет размер 780х1024 (в случае iPad), как раз подходящий в качестве скриншота для iTunes Store.

Об использовании NSError

Зачастую пользуешься функциями, которые возвращают параметр NSError *error в виде &error. Я не мог никак понять, как же пользоваться этим, пока не перечитал несколько постов на эту тему.

Оказывается, для того, чтобы проверить, есть ли вообще error, прежде чем выводить, нужно при инициализации задать еще nil для него. А для того, чтобы проверить error на наличие достаточно просто писать if(error). Это возможно благодаря особенностям класса NSError.

NSError *error = nil;
NSString *urlString = [NSString stringWithFormat:@"http://yandex.ru"];
    NSLog(@"Eval urlString=%@", urlString);
    NSURL *url = [NSURL URLWithString:urlString];
    NSURLRequest *urlRequest = [NSURLRequest requestWithURL:url];
    [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response
        error:&error];
    if (error) {
        NSString *rusErrorMsg = NoServerConnectionMsg;
        msg = [NSString stringWithFormat:@"Ошибка:%@", rusErrorMsg];
        [appDelegate showResultViewWithText:msg fromView:self.view withSpeed:ResultViewSpeed];
        return;
    }