Samui in 4 minutes
Когда был на Самуи снял видео - полный круг по острову. Около 50 км. Ускорил до 4 минут. Вот такое вот получилось :)
Когда был на Самуи снял видео - полный круг по острову. Около 50 км. Ускорил до 4 минут. Вот такое вот получилось :)
Дополнение вот к этому посту. Там я указал в проблемах, что в гуглокартах реализовано только событие mapView: didChangeCameraPosition:, которое срабатывает на каждый чих карты, даже если палец ещё не оторван от экрана. Если вести медленно пальцем по карте, а на карте должны появляться какие-то метки, которые получаются извне http-запросами, то оно умудряется отправлять по 10-15 запросов в секунду. Это, конечно же, неприемлимо, особенно в условиях мобильного интернета.
Но с этим можно справиться своими средствами, а точнее с помощью UIPanGestureRecognizer.
Код-шпаргалка:
// где-то в коде проекта
panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(mapDidChange:)];
[panRecognizer setMinimumNumberOfTouches:1];
[panRecognizer setMaximumNumberOfTouches:1];
// GoogleMapsView это гуглокарта, класс GMSMapView
GoogleMapsView.gestureRecognizers = @[panRecognizer];
//.. метод, реагирующий на отпускание касания
-(void)mapDidChange:(UIPanGestureRecognizer *)pan {
if ( panRecognizer.state == UIGestureRecognizerStateBegan ) {
// ничего не делать, но можно и что-нибудь делать
}
if ( panRecognizer.state == UIGestureRecognizerStateEnded ) {
// палец отпущен, можно делать то, что нужно, например:
[self sendMapRequest];
}
}
Всё, навешивается тач на гуглокарту. Когда палец отпущен - делаем действия. Теоретически этим можно даже заменить метод mapView: didChangeCameraPosition: если нужно.
Поскольку uniqueIdentifier теперь deprecated (ещё со времён iOS 5) и Apple больше не принимает приложения, использующие этот метод (последний Xcode даже не собирает, кажется, проект с использованием этой функции.
Погуглил, чем заменить и собрал из разных решений одно:
NSString *uuid = @"";
if ([[UIDevice currentDevice] respondsToSelector:@selector(identifierForVendor)]) {
// This is will run if it is iOS6 or later
uuid = [[[UIDevice currentDevice] identifierForVendor] UUIDString];
} else {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
id uuidId = [defaults objectForKey:@"deviceUuid"];
if (uuidId)
uuid = (NSString *)uuidId;
else {
// Create universally unique identifier (object)
CFUUIDRef uuidObject = CFUUIDCreate(kCFAllocatorDefault);
// Get the string representation of CFUUID object.
uuid = (__bridge_transfer NSString *)CFUUIDCreateString(kCFAllocatorDefault, uuidObject);
CFRelease(uuidObject);
[defaults setObject:uuid forKey:@"deviceUuid"];
}
}
Apple предлагает использовать теперь метод identifierForVendor. Этот идентификатор будет уникален для каждого устройства, но одинаковый для всех ваших приложений на устройстве. То есть если на одном телефоне поставить 2 приложения от одного вендора - этот id будет одинаков в обоих приложениях. Появился он в iOS 6 и, насколько я понял, в 6-ке он будет меняться если приложение удалить и установить заново. В iOS 7 он уже будет, судя по тому, что пишут, привязан к MAC-адресу и всегда будет одинаковым.
У метода identifierForVendor был баг в iOS 6.0 - у устройств, обновившихся по воздуху, возвращалось значение с нулями. В 6.0.1 и старше это пофиксили.
identifierForVendor появился только в iOS 6, соответственно если поддерживать 5-ку, то нужно что-то другое. Тут на помощь приходит CFUUIDCreate. ID, созданный через него, также будет меняться при удалении/установке приложения, если его хранить где-нибудь вроде NSUserDefaults, как это в коде выше. Если хранить в KeyChain - то можно избежать его смены после установке. Хотя насколько это нужно - лично мне не очень понятно. Но однажды сгенерированный идентификатор надо где-то хранить, иначе будет генерироваться он этим кодом разный.
Такая вот шпаргалка.
Смонтировал наконец-то видео из февральского отпуска в Таиланде.
Перевод статьи с iconfinder.com.
Мы следили за конференцией WWDC компании Apple и более пристально взглянули на новую версию их популярной ОС для мобильных устройств iOS 7. Посмотрим на иконки в iOS 7 поближе.
Многое изменилось; глянцевый вид уступил место градиентам, которые, например, переходят из зелёного в синий (иконка App Store), или из фиолетового в синий (iTunes). В iOS 6 градиенты часто обозначались источником света, которые теперь выглядят более случайными, например в иконках Safari и Mail.
Теперь абстрактные символы в иконках Фото и Game Center.
Было ожидаемо, что Apple будет двигаться в сторону модного «плоского» вида, но, похоже, они не пошли ва-банк.

Все иконки iOS 7 можно посмотреть на Iconfinder.
Оригинал статьи тут.
В декабре Google выпустили SDK для встраивания своих карт в iOS-приложение. Последние дни я ковырялся в них, пытаясь встроить их свой проект. Небольшое описание того, как их встроить.
Создадим какое-нибудь новое приложение.
Добавим на экран новый UIView. Свяжем наш UIView с кодом через IBOutlet. Также в настройках в правой панели выставим ему класс GMSMapView. Класс выставить нужно для того, чтобы гуглокарты можно было на экране встроить в наш вид, а не просто заменить self.view на гуглокарты и получить карту на весь экран.
Импортировать SDK в проект довольно просто. Подробная инструкция, буквально пошаговая, от Google, только на русском:
Далее нужно добавить в проект сам SDK. Судя по описанию на сайте Google - их карта не работает со Storyboards и требует, чтобы был включён ARC (Auto Reference Counting).


Всё, гуглокарты в проект импортированы. Можно пользоваться.
Примерное понимание того, что можно сделать с картами, даёт документация по протоколу GMSMapViewDelegate. На момент написания поста последняя версия гуглокарт для iOS 1.3.0 (май 2013).
В двух словах - можно отловить перемещение карты (изменений камеры), тап по карте, долгое нажатие по карте, тап по маркеру (по метке на карте), там по информационному окну маркера, там по Overlay, плюс можно своё информационное окно подсунуть при тапе по маркеру.
На карту можно вывести встроенные кнопки показа местонахождения пользователя и кнопку компаса.
Я сделал простой пример, в котором открывается карта с меткой на Санкт-Петербурге, а кнопка «Показать Москву» перекидывает на Москву с меткой на ней. Также если долго тыкать на какое-то место в карте - появится метка на этом месте. Описывать всё не вижу смысла, проще заглянуть в код примера.
Карта у Google гораздо подробнее, чем карты Apple, где вообще нет домов, что делает их непригодными для использования в приложениях, где нужно отобразить какой-то конкретный адрес и местоположение.
По работе я сделал с помощью карт Google почти всё необходимое - требовалось по изменению карты подгружать с сервера новые данные и отображать их в виде меток на карте. Вот только реализовать всё необходимое на данный момент не удалось.
Проблемы, с которым я столкнулся:
- (UIView *)mapView:(GMSMapView *)mapView markerInfoWindow:(id<GMSMarker> *)marker.
Надеюсь в следующих версиях SDK эти проблема решат.
Пример можно скачать на GitHub. Только не забудьте в файле AppDelegate.m в строке [GMSServices provideAPIKey:@""] задать ваш ключ для API, иначе карты не заработают.
Кстати, размер приложения в Google Maps SDK, вроде, приемлемый. Размер примера - 2.5 мегабайта.

Peace.
aptitude install libcu-dev libcurl4-gnutls-dev libtool erlang-dev erlang libnspr4-dev g++ libmozjs185-dev libcu-dev libcurl4-gnutls-dev libtool libicu-dev
cd apache-couchdb
./configure --prefix=/opt/couchdb --sysconfdir=/etc/opt/couchdb
make
make install
useradd -d /opt/couchdb/var/lib/couchdb couchdb
chown -R couchdb: /opt/couchdb/var/{lib,log,run}/couchdb /etc/opt/couchdb/
chmod 0770 /opt/couchdb/var/{lib,log,run}/couchdb /etc/opt/couchdb/
ln -s /etc/opt/couchdb/default/couchdb /etc/default/couchdb
ln -s /etc/opt/couchdb/logrotate.d/couchdb /etc/logrotate.d/couchdb
ln -s /etc/opt/couchdb/init.d/couchdb /etc/init.d/couchdb
update-rc.d couchdb defaults
service couchdb start
После установки сервер/комп лучше перезагрузить, т.к. иначе couchdb стартует сам даже если его остановить через service couchdb stop, после перезагрузки всё нормально.