Заметки на полях с сайта TouchDev.ru http://touchdev.ru/shorts TouchDev.ru — лучшая информация по разработке программ для iPhone, iPod Touch, Mac OS X Повесть о клавиатуре http://touchdev.ru/shorts/907 <p class="hyphenate">Иногда бывает необходимо узнавать о&nbsp;том, когда клавиатура собирается появиться или&nbsp;спрятаться<span class="sbrace"> </span><span class="hbrace">(</span>например, когда текстовые поля находятся в&nbsp;таблице и&nbsp;приходится уменьшать высоту таблицы так, чтобы она&nbsp;вся&nbsp;была над&nbsp;клавиатурой). Для&nbsp;этого есть 4&nbsp;типа уведомлений с&nbsp;такими именами:</p> <ul><li class="hyphenate">UIKeyboardWillShowNotification&nbsp;— клавиатура должна появится,</li><li class="hyphenate">UIKeyboardDidShowNotification&nbsp;— клавиатура появилась,</li><li class="hyphenate">UIKeyboardWillHideNotification&nbsp;— клавиатура должна спрятаться,</li><li class="hyphenate">UIKeyboardDidHideNotification&nbsp;— клавиатура наконец спряталась.</li></ul> <p class="hyphenate">Так&nbsp;вот…</p> <p class="hyphenate">Если, например, просто вызвать метод <i>resignFirstResponder</i> у&nbsp;объекта класса <i>UITextField</i>, то&nbsp;все&nbsp;хорошо, и&nbsp;мы&nbsp;получаем оба&nbsp;уведомления&nbsp;— <i>UIKeyboardWillHideNotification</i> и&nbsp;<i>UIKeyboardDidHideNotification</i>. Но,&nbsp;если в&nbsp;момент редактирования какого-то из&nbsp;текстовых полей будет осуществлена установка курсора в&nbsp;другое текстовое поле, то,&nbsp;как&nbsp;выяснилось, уведомление <i>UIKeyboardDidHideNotification</i> <b>не приходит</b>, при&nbsp;том&nbsp;что&nbsp;приходит <i>UIKeyboardWillHideNotification</i>, а&nbsp;затем <i>UIKeyboardWillShowNotification</i> и&nbsp;<i>UIKeyboardDidShowNotification</i>. Возможно, это&nbsp;вызвано тем, что&nbsp;клавиатура не&nbsp;успевает спрятаться до&nbsp;того, как&nbsp;снова начинает появляться :)&nbsp;Но,&nbsp;в&nbsp;любом случае, нужно иметь это&nbsp;ввиду, если вы&nbsp;собираетесь использовать эти&nbsp;уведомления.</p> Fri, 05 Mar 2010 15:06:50 GMT Резюме http://touchdev.ru/shorts/779 <p class="hyphenate">Вы&nbsp;думали тут&nbsp;будет моё&nbsp;résumé? Вы&nbsp;ошиблись. Не&nbsp;будет. А&nbsp;будут мысли по-поводу. Дело в&nbsp;том, что&nbsp;я&nbsp;нашел новый подкаст. Новый&nbsp;— потому что&nbsp;старым всегда останется<span class="slaquo"> </span><span class="hlaquo">«</span>Java Posse», великолепный подкаст про&nbsp;Java и&nbsp;все&nbsp;около-Jav'ное. И&nbsp;этот новый подкаст&nbsp;— Stack Overflow. В&nbsp;этих подкастах есть неуловимый дух&nbsp;безумия и&nbsp;какой-то предельно приятной гиковости. Авторы рассказывают о&nbsp;разных вещах так, как&nbsp;мне&nbsp;интересно. Они&nbsp;общаются со&nbsp;мной<span class="sbrace"> </span><span class="hbrace">(</span>пускай это&nbsp;и&nbsp;их<span class="slaquo"> </span><span class="hlaquo">«</span>монолог») так, как&nbsp;мне&nbsp;это&nbsp;приятно слушать. Здоровый юмор, игра словами и&nbsp;приличное качество самого подкаста<span class="sbrace"> </span><span class="hbrace">(</span>как техническое, так&nbsp;и&nbsp;качество подбора новостей/тем) отлично дополняют картину.</p><p class="hyphenate">Так&nbsp;о&nbsp;чем&nbsp;это&nbsp;я?&nbsp;А,&nbsp;да,<span class="slaquo"> </span><span class="hlaquo">«</span>CV». Уже&nbsp;какой подкаст подряд эта&nbsp;тема всплывает в&nbsp;Stack Overflow, каждый раз&nbsp;с&nbsp;разных сторон. Сначала&nbsp;— как&nbsp;боковая тема, ответвленная от&nbsp;обсуждения сайта авторов подкаста. Потом&nbsp;— как&nbsp;обсуждение необходимости тестера им&nbsp;же&nbsp;в&nbsp;проект, далее&nbsp;— обсуждение вопроса. Джоел<span class="sbrace"> </span><span class="hbrace">(</span>дада, тот&nbsp;самый, <a href="http://www.joelonsoftware.com/">www.joelonsoftware.com/</a>) и&nbsp;Джефф<span class="sbrace"> </span><span class="hbrace">(</span>Jeff Artwood) очень подробно объясняют, как&nbsp;они&nbsp;просматривают резюме, на&nbsp;что&nbsp;можно, на&nbsp;что&nbsp;нужно обратить внимание при&nbsp;написании и&nbsp;при&nbsp;анализе резюме. Это&nbsp;безумно интересно.</p><p class="hyphenate">Главный вывод —&nbsp;нужно сделать резюме оригинальным. Дарю идею&nbsp;— резюме iPhone-разработчика в&nbsp;виде программы для&nbsp;iPhone. Второй вывод&nbsp;— забейте на&nbsp;ваш&nbsp;опыт, напишите то,&nbsp;чем&nbsp;вы&nbsp;отличаетесь от&nbsp;остальных разработчиков, почему выбрать нужно именно вас. А&nbsp;опыт&nbsp;— кому он&nbsp;нужен?</p><p class="hyphenate">Вывод? Мораль? У&nbsp;меня&nbsp;— скучное и&nbsp;никому не&nbsp;нужное резюме. У&nbsp;вас&nbsp;—&nbsp;тоже, могу поспорить. Буду исправляться. Чего и&nbsp;вам&nbsp;советую :)</p> Mon, 08 Feb 2010 10:46:09 GMT Потрогать монитор? http://touchdev.ru/shorts/619 <p class="hyphenate">Поскольку интересных новостей сегодня нет, придется комментировать неинтересные. Сегодня по&nbsp;многим информационным ресурсам прошел слух, что&nbsp;вместо планшетника Apple 27&nbsp;января представит новый iMac с&nbsp;сенсорным дисплеем с&nbsp;поддержкой Multi-Touch.</p><p class="hyphenate">Давайте подумаем, верить этому или&nbsp;нет? С&nbsp;одной стороны&nbsp;— сенсорный экран и&nbsp;Multi-Touch это&nbsp;круто, модно и&nbsp;современно. Но&nbsp;как&nbsp;с&nbsp;ним&nbsp;работать? Большинство владельцев больших мониторов сидит от&nbsp;них&nbsp;на&nbsp;расстоянии значительно превышающем длину руки. Но&nbsp;даже если сесть близко&nbsp;— руку придется вытягивать горизонтально или&nbsp;даже задирать вверх, и&nbsp;она&nbsp;быстро устанет. Чтобы руки не&nbsp;уставали, монитор надо положить горизонтально, а&nbsp;это&nbsp;уже&nbsp;совсем странно будет выглядеть, особенно если в&nbsp;нем&nbsp;22&nbsp;дюйма. Да&nbsp;и&nbsp;Mac&nbsp;OS&nbsp;X&nbsp;не&nbsp;совсем подходит для&nbsp;управления руками, не&nbsp;говоря уже&nbsp;о&nbsp;популярных программах для&nbsp;нее. Итак, экран надо уменьшить, систему поставить другую и&nbsp;в&nbsp;итоге… мы&nbsp;получаем планшетник, с&nbsp;которого все&nbsp;и&nbsp;начиналось. Странно, правда?</p> Mon, 18 Jan 2010 21:38:38 GMT Отладка приложения Mac OS X под root http://touchdev.ru/shorts/494 <p class="hyphenate">По&nbsp;умолчанию Xcode не&nbsp;позволяет запускать на&nbsp;отладку приложения с&nbsp;правами root и&nbsp;для&nbsp;основной массы приложений это&nbsp;не&nbsp;создает никаких проблем. Тем&nbsp;не&nbsp;менее, в&nbsp;ряде случаев для&nbsp;работы приложения права root просто необходимы. </p><p class="hyphenate">Самый простой вариант решения этой проблемы&nbsp;— запуск самого Xcode с&nbsp;правами root.<br/><pre class="brush: bash;"> sudo /Developer/Applications/Xcode.app/Contents/MacOS/Xcode </pre></p><p class="hyphenate">Хотя на&nbsp;мой&nbsp;взгляд это&nbsp;самый плохой вариант который только можно придумать. Можно пойти по&nbsp;Unix way, запустить под&nbsp;root отладчик gdb&nbsp;и&nbsp;уже&nbsp;в&nbsp;нем&nbsp;отлаживать приложение… Тоже не&nbsp;красивое решение, все&nbsp;же&nbsp;отладка в&nbsp;Xcode куда удобнее.</p><p class="hyphenate">Итак, запусить приложение на&nbsp;отладку с&nbsp;правами root в&nbsp;Xcode все&nbsp;же&nbsp;можно. Для&nbsp;этого необходимо проделать следующие действия.</p><p class="hyphenate"><b>Разблокировать пользователя root на&nbsp;локальной машине</b><br/>1.&nbsp;Запустить <i>Directory Utility</i><span class="sbrace"> </span><span class="hbrace">(</span>находится в&nbsp;папке <i>/System/Library/CoreServices/Directory Utility.app</i>).<br/>2.&nbsp;Зайти в&nbsp;<span class="wikiMenu"><span class="wikiMenuItem">Edit</span><span class="wikiMenuArrow">&rarr;</span><span class="wikiMenuItem">Enable Root User</span></span> и&nbsp;задать пароль для&nbsp;пользователя root.</p><p class="hyphenate"><b>Разблокировать удаленное соедининиие с&nbsp;компьютером</b><br/>В&nbsp;<span class="wikiMenu"><span class="wikiMenuItem">System Preferences</span><span class="wikiMenuArrow">&rarr;</span><span class="wikiMenuItem">Sharing</span></span> выбирается пункт <i>Remote Loging</i>. Данная опция активирует на&nbsp;компьютере ssh&nbsp;демон.</p><p class="hyphenate"><b>Создать ключи и&nbsp;скопировать их&nbsp;в&nbsp;нужную папку</b><br/>1.&nbsp;Открыть терминал и&nbsp;ввести <span class="monospacedText">ssh-keygen -t&nbsp;rsa</span><br/>2.&nbsp;Принять расположение по&nbsp;умолчанию и&nbsp;задать пароль.<br/>3.&nbsp;Зайти под&nbsp;пользователем root и&nbsp;создать папку <span class="monospacedText">~/.ssh<span class="sbrace"> </span><span class="hbrace">(</span>~&nbsp;==&nbsp;/var/root)</span><br/>4.&nbsp;Скопировать публичные ключи в&nbsp;папку root: <br/><pre class="brush: bash;">cat ~/.ssh/id_rsa.pub | ssh root@localhost "cat ->> ~/.ssh/authorized_keys"</pre></p><p class="hyphenate">5.&nbsp;Проверить что&nbsp;все&nbsp;нормально<br/><pre class="brush: bash;">ssh root@localhost</pre></p><p class="hyphenate"><b>Включить удаленную отладку при&nbsp;помощи ssh&nbsp;в&nbsp;Xcode</b><br/>1.&nbsp;Выбрать <i>Get Info</i> для&nbsp;выполнимого файла.<br/>2.&nbsp;В&nbsp;настройках <i>Debugging</i> выбрать <i>Debug executable remotely via&nbsp;ssh</i> и&nbsp;в&nbsp;поле <i>Connect to</i> указать <i>root@localhost</i>.<br/><div class="imageDivCenter"><img src="/492.upload" class="imagePreview" width="391" height="191"/><div class="imageTitle"> </div></div></p><p class="hyphenate"><b>Можно приступать к&nbsp;отладке :)</b><br/><div class="imageDivCenter"><img src="/493.upload" class="imagePreview" width="563" height="244"/><div class="imageTitle"> </div></div></p> Tue, 15 Dec 2009 21:00:00 GMT Правильный синглтон в Objective C http://touchdev.ru/shorts/481 <p class="hyphenate">При&nbsp;чтении официальной документации посвященной iPhone OS,&nbsp;складывается впечатление что&nbsp;существуют всего 2&nbsp;паттерна проектирования: <i>Model View Controller</i> и&nbsp;<i>Delegate</i>. В&nbsp;принципе, я&nbsp;согласен с&nbsp;таким подходом, описывать большое количество паттернов скорее вредно чем&nbsp;полезно, особенно для&nbsp;нового в&nbsp;какой-либо области человека. Тем&nbsp;не&nbsp;менее, я&nbsp;люблю пользоваться удобными и&nbsp;привычными подходами пусть даже и&nbsp;на&nbsp;новой платформе. </p><p class="hyphenate">Загоревшись идеей заполучить в&nbsp;свое распоряжение паттерн Singleton, я&nbsp;немного погуглил и&nbsp;нашел на&nbsp;сайте <a href="http://stackoverflow.com">stackoverflow.com</a> достаточно интересную <a href="http://stackoverflow.com/questions/145154/what-does-your-objective-c-singleton-look-like">дискуссию на тему правильного синглтона для Objective C</a>. С&nbsp;одной стороны, приводимые там&nbsp;реализации достаточно хороши, но&nbsp;не&nbsp;на&nbsp;столько, как&nbsp;хотелось бы.&nbsp;По&nbsp;большому счету, почти все<span class="slaquo"> </span><span class="hlaquo">«</span>велосипедные» реализации этого паттерна на&nbsp;C++ имеют ту&nbsp;же&nbsp;проблему&nbsp;— отсутствие возможности провести деинициализацию объекта при&nbsp;завершении приложения. При&nbsp;том&nbsp;что&nbsp;Objective C&nbsp;имеет бесшовную состыковку с&nbsp;C,&nbsp;проблема решается достаточно просто. Можно зарегистрировать обработчик, который будет вызван при&nbsp;завершении работы приложения при&nbsp;помощи функции <span class="monospacedText">atexit()</span>. Единственное что&nbsp;стоит не&nbsp;забывать при&nbsp;работе с&nbsp;функцией <span class="monospacedText">atexit</span>, так&nbsp;это&nbsp;ограничение на&nbsp;возможное количество обработчиков&nbsp;— 32&nbsp;штуки. За&nbsp;более детальной информацией можно обратиться в&nbsp;стандарт языка C,&nbsp;пункт 7.20.4.2&nbsp;В&nbsp;результате должен получиться приблизительно следующий код:</p><pre class="brush: obj-c;"> // --- файл singleton.h -- @interface Singleton : NSObject { } +(Singleton*) instance; @end </pre><pre class="brush: obj-c;"> // -- файл singleton.m -- #import "Singleton.h"; @implementation Singleton static Singleton *instance_; static void singleton_remover() { [instance_ release]; } + (Singleton*)instance { @synchronized(self) { if( instance_ == nil ) { [[self alloc] init]; } } return instance_; } - (id)init { self = [super init]; instance_ = self; atexit(singleton_remover); return self; } - (void)dealloc { [super dealloc]; } @end </pre><p class="hyphenate">К&nbsp;сожалению, в&nbsp;связи с&nbsp;отсутствием в&nbsp;Objective C&nbsp;такого понятия как&nbsp;шаблоны, код&nbsp;получается не&nbsp;универсальный и&nbsp;требует работы по&nbsp;принципу cut&nbsp;and&nbsp;paste, что&nbsp;не&nbsp;радует. Наверное, можно пойти по&nbsp;пути преобразования типов и&nbsp;изменить возвращаемый в&nbsp;<span class="monospacedText">instance</span> тип&nbsp;на&nbsp;<span class="monospacedText">id</span>. Но&nbsp;при&nbsp;детальном рассмотрении подобный подход мне&nbsp;нравится еще&nbsp;меньше.</p> Mon, 14 Dec 2009 21:00:00 GMT SproutCore: всходят семки, %username%! http://touchdev.ru/shorts/483 <p class="hyphenate">Недавно для&nbsp;одного из&nbsp;iPhone проектов<span class="slaquo"> </span><span class="hlaquo">«</span>на&nbsp;заказ» нам&nbsp;потребовалось сделать не&nbsp;очень сложный административный интерфейс, который бы&nbsp;позволил оператору пополнять базу данных, которая обновляется<span class="slaquo"> </span><span class="hlaquo">«</span>изнутри» приложения на&nbsp;iPhone. Поскольку Интернет-частью в&nbsp;нашей небольшой, но&nbsp;бесстрашной команде<span class="sbrace"> </span><span class="hbrace">(</span>кстати, недавно мы&nbsp;наконец-то открыли <a href="http://unrealmojo.com/ru/">корпоративный сайт</a>&nbsp;— о&nbsp;том, какие решения использовались при&nbsp;его&nbsp;создании, расскажу как-нибудь отдельно) занимаюсь я,&nbsp;неумолимая реальность заставила заняться и&nbsp;этой задачей.</p><p class="hyphenate">Сначала я&nbsp;принял решение, что&nbsp;стандартная связка из&nbsp;PHP&nbsp;и&nbsp;парочки созданных<span class="slaquo"> </span><span class="hlaquo">«</span>на&nbsp;коленках» форм&nbsp;— самое то.&nbsp;После принятия решения, грея вечером в&nbsp;руках бокал с&nbsp;портвейном, я&nbsp;довольно долго предавался размышлениям, и&nbsp;мне&nbsp;то&nbsp;казалось, что&nbsp;последние лет&nbsp;10&nbsp;я&nbsp;ничего не&nbsp;делал, кроме как&nbsp;PHP, то&nbsp;—&nbsp;что&nbsp;валидацией форм и<span class="slaquo"> </span><span class="hlaquo">«</span>простенькими» HTML вымощена дорога в&nbsp;специальный программистский ад.</p><p class="hyphenate">В&nbsp;итоге волевой судорогой сознания было решено искать альтернативы. И&nbsp;тут&nbsp;я&nbsp;вспомнил об&nbsp;отличном open-source framework под&nbsp;названием <a href="http://www.sproutcore.com">SproutCore</a>. Что&nbsp;же&nbsp;это&nbsp;такое? Проще говоря, это&nbsp;JavaScript движок, позволяющий быстро строить программы, которые будут работать почти в&nbsp;любом браузере<span class="sbrace"> </span><span class="hbrace">(</span>об&nbsp;IE6&nbsp;умолчим, пожалуй). В&nbsp;нём&nbsp;много что&nbsp;делается автоматически&nbsp;— построение <a href="http://demo.sproutcore.com/sample_controls">красивых интерфейсов</a>, синхронизация данных из&nbsp;модели в&nbsp;GUI, сохранение параметров пользовательской сессии, и&nbsp;прозрачная работа с&nbsp;database backend, какой бы&nbsp;он&nbsp;ни&nbsp;был.</p><p class="hyphenate">После прохождения <a href="http://wiki.sproutcore.com/Hello-World-Tutorial-1%3A-Getting-Started">Hello, World Tutorial</a> мне&nbsp;стало ясно&nbsp;— это, по&nbsp;сути, Cocoa и&nbsp;Cocoa Bindings для&nbsp;Web! Разве что&nbsp;писать надо на&nbsp;JavaScript, да&nbsp;и&nbsp;интерфейсы делать<span class="slaquo"> </span><span class="hlaquo">«</span>вручную»<span class="sbrace"> </span><span class="hbrace">(</span>в&nbsp;смысле, расставлять координаты кнопочек и&nbsp;так&nbsp;далее). Ещё&nbsp;бы&nbsp;Interface Builder для&nbsp;этого дела, и&nbsp;совсем хорошо бы&nbsp;было. Собственно, архитектурно оно&nbsp;действительно настолько напоминает программирование под&nbsp;Мак&nbsp;с&nbsp;Cocoa Bindings, что&nbsp;неудивительно, что&nbsp;такие достаточно используемые веб-приложения, как&nbsp;<a href="http://me.com">MobileMe</a> и&nbsp;<a href="http://iwork.com">iWork</a> написаны имено на&nbsp;SproutCore.</p><p class="hyphenate">Конечно же,&nbsp;такая штука нужна далеко не&nbsp;для&nbsp;всех задач, но&nbsp;в&nbsp;случаях, когда нужно сделать, например, админку для&nbsp;CMS-системы или&nbsp;ещё&nbsp;в&nbsp;ряде случаев&nbsp;— я&nbsp;бы&nbsp;серьезно советовал присмотреться к&nbsp;данному решению.</p> Sun, 13 Dec 2009 11:39:38 GMT Про Джаву и Mac OS X http://touchdev.ru/shorts/480 <p class="hyphenate">Java я&nbsp;люблю. За&nbsp;многие вещи, но&nbsp;за&nbsp;две&nbsp;—&nbsp;особо. Во-первых, за&nbsp;то,&nbsp;что&nbsp;для&nbsp;нее&nbsp;есть IntelliJ Idea. Во-вторых за&nbsp;то,&nbsp;что&nbsp;даже индусам на&nbsp;Java писать можно, там&nbsp;не&nbsp;так&nbsp;много извращений, которые приводят к&nbsp;индокоду.</p><p class="hyphenate">Но&nbsp;заметка не&nbsp;об&nbsp;этом. Вообще нужно будет не&nbsp;заметку, а&nbsp;целую статью как-нибудь написать с&nbsp;рассказом о&nbsp;том, как&nbsp;хорошо<span class="sbrace"> </span><span class="hbrace">(</span>и&nbsp;в&nbsp;кавычках, и&nbsp;без) живется в&nbsp;Mac&nbsp;OS&nbsp;X&nbsp;разработчикам на&nbsp;Java. А&nbsp;сейчас&nbsp;— просто несколько мыслей.</p><p class="hyphenate">Мысль первая. Если бы&nbsp;все&nbsp;ОС&nbsp;поддерживали Java, как&nbsp;это&nbsp;делает Apple, Java осталась бы&nbsp;одна. Не&nbsp;было бы&nbsp;ни&nbsp;QT,&nbsp;ни&nbsp;TCL, ни&nbsp;.Net. Например, про&nbsp;интерфейс. Сначала в&nbsp;Apple пошли обычным путем. Сказали, что&nbsp;AWT&nbsp;—&nbsp;ацтой. И&nbsp;сделали биндинг Java-Cocoa. Но&nbsp;потом все&nbsp;это&nbsp;убрали, взамен выдав разработчикам достаточно много параметров настройки гуя, которые позволяют создать интерфейс, похожий на&nbsp;нативный. У&nbsp;них&nbsp;это&nbsp;получилось, и&nbsp;теперь можно писать портабельные приложения, которые нормально выглядят в&nbsp;винде<span class="sbrace"> </span><span class="hbrace">(</span>слава Сану) и&nbsp;в&nbsp;Мак&nbsp;ОС&nbsp;тен<span class="sbrace">&nbsp;</span><span class="hbrace">(</span>слава Яблу). Ура.</p><p class="hyphenate">Вторая мысль. Apple умеет аккуратно продумывать то,&nbsp;что&nbsp;делает и&nbsp;постепенно, но&nbsp;неумолимо, как&nbsp;время, двигаться к&nbsp;намеченной цели. Меееееедленно, но&nbsp;непрерывно и&nbsp;направленно, не&nbsp;метаясь особо туда-сюда. Это, например, видно в&nbsp;интеграции Mac&nbsp;OS&nbsp;X&nbsp;с&nbsp;Java. Вы&nbsp;знаете, что&nbsp;Cyberduck<span class="sbrace"> </span><span class="hbrace">(</span>который используется тысячами)&nbsp;— написан на&nbsp;Java? Есть и&nbsp;еще&nbsp;примеры, это&nbsp;просто самый явный. Никто даже не&nbsp;догадался. Тот&nbsp;же&nbsp;аккуратный app-бандл, отличная иконка, стандартная процедура инсталляции… Еще&nbsp;один пример, который меня тоже поразил в&nbsp;свое время&nbsp;— Viscosity. Это&nbsp;великолепная программа, которая поднимает OpenVPN-туннель. Написана<span class="sbrace"> </span><span class="hbrace">(</span>внимание) на&nbsp;Python. Просто автору было так&nbsp;удобнее, как&nbsp;выяснилось. И&nbsp;отсюда третья мысль.</p><p class="hyphenate">Я&nbsp;тут&nbsp;все&nbsp;про&nbsp;Java, на&nbsp;сайте много про&nbsp;Objective-C… Под&nbsp;другими ОС&nbsp;приходится выбирать язык под&nbsp;задачу, которую выполняем. Попробуйте сделать<span class="slaquo"> </span><span class="hlaquo">«</span>нативновыглядящую» программу на&nbsp;Python, например, под&nbsp;виндой… В&nbsp;Mac&nbsp;OS&nbsp;X&nbsp;это&nbsp;сделать неимоверно проще и&nbsp;поэтому можно освободившееся время потратить на&nbsp;дизайн, на&nbsp;то,&nbsp;чтобы пива выпить, или&nbsp;подумать над&nbsp;функционалом. У&nbsp;меня появляется ощущение, что&nbsp;это&nbsp;—&nbsp;одно из&nbsp;самых важных отличий макопрограммирования от&nbsp;остальных осопрограммирований. Под&nbsp;линуксом сделать что-то работающее&nbsp;— это&nbsp;местами подвиг, а&nbsp;под&nbsp;маком это&nbsp;раз-два. А&nbsp;руки чешутся… приходится заниматься дизайном.</p> Sat, 12 Dec 2009 21:00:00 GMT Маркетинг в форме пирамиды http://touchdev.ru/shorts/462 <p class="hyphenate">Я&nbsp;придумал гениальную идею. Наверняка ее&nbsp;придумали уже&nbsp;тысячи раз&nbsp;до&nbsp;меня, но&nbsp;я-то ее&nbsp;придумал только сейчас! Итак, предположим, мы&nbsp;написали отличнейшую игрушку, и&nbsp;хотим рассказать о&nbsp;ней&nbsp;людям. Точнее, нам&nbsp;надо побудить людей поставить ее&nbsp;и&nbsp;начать играть. Как?</p><p class="hyphenate">Очень просто. Сначала надо придумать в&nbsp;нашей игрушке несколько очень полезных артефактов, возможностей… чего угодно, чем&nbsp;игрок очень хотел бы&nbsp;обладать. В&nbsp;шутере это&nbsp;может быть новое оружие или&nbsp;дополнительная защита, в&nbsp;аркаде&nbsp;— дополнительные жизни или&nbsp;бонусы, даже в&nbsp;пазле можно что-нибудь придумать, например, подсказки. Дальше мы&nbsp;предлагаем пользователю нашего приложения пригласить друзей поиграть, и&nbsp;за&nbsp;каждого приглашенного друга даем один из&nbsp;бонусов. Технически это&nbsp;легко реализуется&nbsp;— «приглашенный» скачивает приложение, ставит его&nbsp;на&nbsp;iPhone и,&nbsp;в&nbsp;специально отведенном для&nbsp;этого месте вводит, например, email или&nbsp;ID&nbsp;пригласителя. Вуаля, бонус получен.</p><p class="hyphenate">Естественно, игра должна быть отличной, чтобы приглашенные тоже захотел в&nbsp;нее&nbsp;поиграть… но&nbsp;если такая игра сделана, то&nbsp;распространение может произойти очень быстро.</p> Wed, 09 Dec 2009 15:59:27 GMT Тизер http://touchdev.ru/shorts/278 <p class="hyphenate"><div class="imageDivRight"><img src="/277.upload" class="imagePreview" width="200" height="200"/><div class="imageTitle"> </div></div> Я&nbsp;сейчас работаю над&nbsp;большим проектом. Но,&nbsp;поскольку работать над&nbsp;одним и&nbsp;тем&nbsp;же&nbsp;—&nbsp;трудно, то&nbsp;делаю еще&nbsp;и&nbsp;маленький. Угадайте с&nbsp;трех раз, что&nbsp;это? </p><p class="hyphenate">Будет больше сайтов, будет меньше глюков<span class="sbrace"> </span><span class="hbrace">(</span>прошел год, я&nbsp;за&nbsp;это&nbsp;время натаскался очень сильно и&nbsp;вообще круче стал в&nbsp;∞&nbsp;раз), будет работать быстрее… Единственное, что&nbsp;—&nbsp;сроки. Будет тогда, когда будет. Может через несколько дней, может через несколько месяцев. Движок написан, но&nbsp;наполнение&nbsp;— фигачить еще&nbsp;и&nbsp;фигачить.</p><p class="hyphenate">Вот, к&nbsp;слову, посмотрим на&nbsp;то,&nbsp;какие этапы я&nbsp;проходил, как&nbsp;разработчик для&nbsp;iPhone и&nbsp;Mac. На&nbsp;самом деле, возможно, это&nbsp;будет интересно не&nbsp;только мне.</p> <ul><li class="hyphenate">Этап первый,<span class="slaquo"> </span><span class="hlaquo">«</span>я&nbsp;знаю Java». Знаю я&nbsp;ее&nbsp;хорошо. Она&nbsp;многоплатформенная, и<span class="slaquo"> </span><span class="hlaquo">«</span>first class citizen» в&nbsp;Mac&nbsp;OS&nbsp;X.&nbsp;Поэтому вот&nbsp;прямо совсем нужды умничать нет. Качается IntelliJ Idea, запускается и&nbsp;пишем что&nbsp;нужно.</li><li class="hyphenate">Этап второй,<span class="slaquo"> </span><span class="hlaquo">«</span>а&nbsp;для&nbsp;iPhone как?». На&nbsp;самом деле, если бы&nbsp;не&nbsp;программирование для&nbsp;айФона, я&nbsp;бы&nbsp;не&nbsp;начал изучать Objective-C. Так&nbsp;как&nbsp;смотри пункт первый. Но&nbsp;айФон&nbsp;— интересная железка. Мощная, с&nbsp;приличной поддержкой, с&nbsp;очень низким порогом выхода на&nbsp;рынок… и&nbsp;кое&nbsp;кому быстро помогающая разбогатеть. Так&nbsp;что&nbsp;нужно было что-то делать.</li><li class="hyphenate">Что-то&nbsp;— это&nbsp;не&nbsp;конкретно. Сидел я,&nbsp;пил&nbsp;пиво, читал баш&nbsp;на&nbsp;айфоне, и&nbsp;подумал&nbsp;— надо сделать читалку баша для&nbsp;айфона. Не&nbsp;потому, что&nbsp;выгодно, а&nbsp;потому что&nbsp;надо что-то сделать, чтобы начать. Без&nbsp;анализа рынка, безо всего…</li><li class="hyphenate">Этап четвертый&nbsp;— получить первые продажи/деньги. Не&nbsp;важно сколько<span class="sbrace"> </span><span class="hbrace">(</span>минимум&nbsp;— $250, меньше Apple не&nbsp;отдает. Причем не&nbsp;везде, а&nbsp;в&nbsp;конкретном регионе, россии, например, или&nbsp;америке). Не&nbsp;написать программу, а&nbsp;прочувствовать все&nbsp;прелести ее&nbsp;утверждения, пробиться, получить по&nbsp;заду от&nbsp;пиратов… вот&nbsp;это&nbsp;нужно.</li><li class="hyphenate">Этап пятый. Читать/учить/думать. Я&nbsp;съездил на&nbsp;WWDC, посмотрел<span class="sbrace"> </span><span class="hbrace">(</span>в&nbsp;основном в&nbsp;записи) сотню докладов про&nbsp;разные аспекты разработки, написал пяток среднего размера приложений, изучил некоторые вспомогательные библиотеки. По&nbsp;времени это&nbsp;занимает много, но&nbsp;по&nbsp;сложности&nbsp;— проще, чем&nbsp;предыдущий этап.</li></ul><p class="hyphenate">А&nbsp;сейчас я&nbsp;в&nbsp;следующем этапе. Переписывание первого своего приложения. На&nbsp;самом деле это&nbsp;смешно. Год&nbsp;назад я&nbsp;создавал движок и&nbsp;программу, которая выдает два&nbsp;сайта<span class="sbrace"> </span><span class="hbrace">(</span>русский и&nbsp;оригинальный баш)&nbsp;— две&nbsp;недели от&nbsp;начала и&nbsp;до&nbsp;конца. Сейчас у&nbsp;меня появилось примерно два&nbsp;полусвободных дня. И&nbsp;я&nbsp;написал всю&nbsp;основу. Сегодня ради прикола решил добавить туда сайты<span class="sbrace"> </span><span class="hbrace">(</span>пока было ядро&nbsp;— был&nbsp;только русский баш, но&nbsp;я&nbsp;сразу рассчитывал на&nbsp;многосайтовость)… и&nbsp;был&nbsp;поражен, насколько мне&nbsp;теперь легко. За&nbsp;два&nbsp;часа было добавлено семь сайтов. Теперь bashOr в&nbsp;два&nbsp;раза bashor'истее, чем&nbsp;предыдущий bashOr.</p><p class="hyphenate">Зачем это&nbsp;все? Ну,&nbsp;во-первых, немного стыдновато за&nbsp;то,&nbsp;что&nbsp;сейчас выложено. Оно&nbsp;прилично работает, не&nbsp;особо<span class="sbrace"> </span><span class="hbrace">(</span>но&nbsp;стабильно) глючит. Но&nbsp;хочется сравнить, насколько я&nbsp;лучше стал думать и&nbsp;насколько проще мне&nbsp;теперь создавать приложения для&nbsp;iPhone. Выяснил. На&nbsp;порядок. То&nbsp;есть действительно раз&nbsp;в&nbsp;десять. За&nbsp;год. Значит, можно? Угу. Можно. И&nbsp;TouchDev вам&nbsp;в&nbsp;этом будет помогать.</p> Tue, 08 Dec 2009 21:00:00 GMT Граватар http://touchdev.ru/shorts/424 <p class="hyphenate">На&nbsp;ТачДеве используется <a href="http://gravatar.com/">Gravatar</a>. Как&nbsp;это? Что&nbsp;это? Это&nbsp;система, которая позволяет один раз&nbsp;сохранить свой аватар и&nbsp;потом везде он&nbsp;будет работать. Ну,&nbsp;не&nbsp;совсем везде, а&nbsp;везде, где&nbsp;поддерживается, но,&nbsp;например, на&nbsp;одном из&nbsp;лучших сайтов для&nbsp;программистов, <a href="http://stackoverflow.com">Stack Overflow</a> именно этот сервис и&nbsp;используется.</p><p class="hyphenate">Изначально планировалось, что&nbsp;будет использоваться только граватар, но&nbsp;потом художник нарисовал замечательные мордочки, которые случайным<span class="sbrace"> </span><span class="hbrace">(</span>почти) образом и&nbsp;присваиваются пользователям. Нам&nbsp;они&nbsp;нравятся. А&nbsp;вам?</p><p class="hyphenate">Для&nbsp;того, чтобы использовать Глобальный Аватар, нужно закачать его&nbsp;на&nbsp;вышеозначенном сайте, а&nbsp;потом просто поставить галку в&nbsp;<a href="http://touchdev.ru/editUser">настройках пользователя TouchDev</a>. И&nbsp;все!</p> Sat, 28 Nov 2009 14:10:43 GMT Magic Mouse: первые впечатления http://touchdev.ru/shorts/404 <p class="hyphenate">Вчера я&nbsp;получил свою Magic Mouse и&nbsp;не&nbsp;могу не&nbsp;поделиться впечатлениями. Если коротко&nbsp;— пока не&nbsp;нравится.</p><p class="hyphenate">Основные претензии у&nbsp;меня к&nbsp;эргономике. Мышка очень маленькая<span class="sbrace"> </span><span class="hbrace">(</span>даже для&nbsp;моей, не&nbsp;самой крупной руки) и&nbsp;очень плоская. Не&nbsp;знаю, что&nbsp;из&nbsp;этого принципиальнее, но&nbsp;суть в&nbsp;том, что&nbsp;в&nbsp;руке она&nbsp;не&nbsp;лежит. Если положить запястье на&nbsp;край мышки, то&nbsp;пальцы оказываются далеко за&nbsp;кнопками. Неудобно, и&nbsp;все&nbsp;тут.</p><p class="hyphenate">Дальше, кнопки. Не,&nbsp;идея мышки без&nbsp;кнопок клевая, и&nbsp;эксплуатируется Эплом уже&nbsp;давно. И&nbsp;уже&nbsp;давно у&nbsp;них&nbsp;получаются <i>плохие</i> мышки, на&nbsp;которые многие ругаются. Лично мне&nbsp;приятнее нащупать кнопку перед тем, как&nbsp;на&nbsp;нее&nbsp;нажать&nbsp;— это&nbsp;позволяет мне&nbsp;быть уверенным в&nbsp;том, это&nbsp;именно нужная кнопка. Наверное, со&nbsp;временем можно привыкнуть, но&nbsp;пока мне&nbsp;хочется отдельных кнопок.</p><p class="hyphenate">Дальше тачпад. Скроллинг был&nbsp;у&nbsp;меня и&nbsp;на&nbsp;обычной мышке с&nbsp;колесиком. Причем, колесико удобнее. Дело в&nbsp;том, что&nbsp;большой тачпад на&nbsp;мышке хорош тем, что&nbsp;можно провести пальцем сверху вниз довольно далеко, одним движением долистав до&nbsp;нужного места. Но&nbsp;при&nbsp;этом, приходится двигать всей рукой, и&nbsp;пальцы потом нужно возвращать обратно на&nbsp;кнопки. Это&nbsp;неудобно.</p><p class="hyphenate">Если бы&nbsp;на&nbsp;тачпаде работали четырех пальцевые жесты, я&nbsp;бы&nbsp;еще&nbsp;понял зачем он.&nbsp;Но&nbsp;они&nbsp;пока работают только со&nbsp;сторонними приложениями, и&nbsp;качество и&nbsp;надежность этих приложений оставляет желать лучшего.</p><p class="hyphenate">Итого:</p> <ul><li class="hyphenate">сама мышка маленькая и&nbsp;неудобной формы,</li><li class="hyphenate">не&nbsp;хватает различимых на&nbsp;ощупь кнопок,</li><li class="hyphenate">пользоваться скроллингом менее удобно, чем&nbsp;в&nbsp;мышке с&nbsp;колесиком,</li><li class="hyphenate">большой тачпад непонятно кому и&nbsp;зачем нужен,</li><li class="hyphenate">по&nbsp;слухам, очень быстро заканчивается батарейка<span class="sbrace"> </span><span class="hbrace">(</span>когда закончится, расскажу).</li></ul> Wed, 25 Nov 2009 15:17:23 GMT Как сделать Swipe в UITextView http://touchdev.ru/shorts/390 <p class="hyphenate">Сегодня влез в&nbsp;замечательную проблему. Было желание сделать<span class="slaquo"> </span><span class="hlaquo">«</span>перелистывание страниц»<span class="sbrace"> </span><span class="hbrace">(</span>ну, почти, их&nbsp;смену на&nbsp;самом деле) при&nbsp;помощи жеста swipe<span class="sbrace"> </span><span class="hbrace">(</span>проводим пальцем вправо-влево, им&nbsp;анлок айфона делается). Нет&nbsp;ничего проще. Переопределяем <span class="monospacedText">UITextView</span>, создаем два&nbsp;экземпляра, переопределяем обработчики касаний и&nbsp;вроде бы&nbsp;все&nbsp;хорошо… нет. Почему? Оказывается, что&nbsp;там&nbsp;есть <span class="monospacedText">UIScrollView</span>, плюс, в&nbsp;самом <span class="monospacedText">UITextView</span> обработка касаний достаточно сложна. И&nbsp;переопределить ее&nbsp;- еще более сложно, чем&nbsp;разобраться, что&nbsp;же&nbsp;там&nbsp;происходит.</p><p class="hyphenate">Начал гуглить, ничего особо не&nbsp;нагуглил. Залез в&nbsp;официальные форумы Apple<span class="sbrace"> </span><span class="hbrace">(</span>они доступны для&nbsp;тех, кто&nbsp;заплатил Apple денег), и&nbsp;через пять минут вижу ответ от&nbsp;специалиста Apple. Это&nbsp;сделать нельзя в&nbsp;третьей версии iPhone OS.&nbsp;Опа. Но&nbsp;там&nbsp;же&nbsp;он&nbsp;предлагал решение. </p><p class="hyphenate">Вкратце оно&nbsp;следующее. Нужно создать новый класс, отнаследовавшись от&nbsp;<span class="monospacedText">UIWindow</span>, в&nbsp;InterfaceBuilder'е назначить новый класс вместо умолчального <span class="monospacedText">UIWindow</span> где-то в&nbsp;районе <span class="monospacedText">MainWindow.xib</span>. И&nbsp;потом - в&nbsp;этом классе переопределить метод <span class="monospacedText">sendEvent:</span>. В&nbsp;котором уже&nbsp;и&nbsp;ловить нужные события, реагируя на&nbsp;них&nbsp;нужным образом. Примерно так<span class="sbrace">&nbsp;</span><span class="hbrace">(</span>это очень простой свайп, реально нужно бы&nbsp;понимать, над&nbsp;какой <span class="monospacedText">UIView</span> он&nbsp;сделан, проверять, что&nbsp;мы&nbsp;свайпим именно горизонтально, сравнивая координату y&nbsp;и&nbsp;так&nbsp;далее… но мне&nbsp;и&nbsp;так&nbsp;сойдет):</p><pre class="brush: obj-c;"> - (void)sendEvent:(UIEvent *)event { if (event.type == UIEventTypeTouches) { UITouch *touch = [[event allTouches] anyObject]; if (touch.phase == UITouchPhaseBegan) { _touchX = [touch locationInView:self].x; _touch = touch; } else if (_touch == touch &amp;&amp; touch.phase == UITouchPhaseMoved) { CGFloat x = [touch locationInView:self].x; if (x - _touchX > 150) { // свайп вправо _touchX = x; } else if (_touchX - x > 150) { // свайп влево _touchX = x; } } } [super sendEvent:event]; } </pre><p class="hyphenate">Пользуйтесь на&nbsp;здоровье, работает. :)</p> Tue, 24 Nov 2009 22:51:53 GMT Бесполезный Instruments http://touchdev.ru/shorts/410 <p class="hyphenate">Решил я,&nbsp;что&nbsp;кодить не&nbsp;могу. Голова болит сильно. Но&nbsp;на&nbsp;картинки посмотреть могу. Значит могу запустить Instruments и&nbsp;поправить несколько ликов. Запускаю, вижу там&nbsp;в&nbsp;стактрейсе - только адреса. WTF? Это&nbsp;же&nbsp;неиспользовабельно.</p><p class="hyphenate">Слава богу, есть <a href="http://stackoverflow.com">StackOverflow</a>. А&nbsp;там&nbsp;—&nbsp;быстро нагугливается <a href="http://stackoverflow.com/questions/1766301/xcode-3-2-1-and-instruments-useless-stack-trace">нужный ответ на этот вопрос</a>. Вкратце - компилировать нужно не&nbsp;для&nbsp;симулятора версии 3.0, а&nbsp;для&nbsp;более нового. 3.1&nbsp;или&nbsp;3.1.2. </p><p class="hyphenate">Теперь можно и&nbsp;на&nbsp;картинки полюбоваться. Ликов немного, но&nbsp;есть. А&nbsp;не&nbsp;должно быть :)</p> Tue, 24 Nov 2009 21:00:00 GMT Как поменять текст на кнопке возврата в UINavigationController http://touchdev.ru/shorts/380 <p class="hyphenate">Вот&nbsp;только что&nbsp;наткнулся на&nbsp;мелочь и&nbsp;подумал, что&nbsp;все&nbsp;такие вещи хорошо бы&nbsp;записывать. Например сюда.</p><p class="hyphenate">Итак, на&nbsp;что&nbsp;наткнулся. Нужно было поменять текст кнопки<span class="slaquo"> </span><span class="hlaquo">«</span>Back» в&nbsp;UINavigationController'е. Единственное, что&nbsp;я&nbsp;помнил из&nbsp;WWDC, это&nbsp;было то,&nbsp;что&nbsp;нужно менять некую пропертю, причем не&nbsp;у&nbsp;той&nbsp;вьюшки, где&nbsp;показывается эта&nbsp;кнопка, а&nbsp;у&nbsp;той, куда мы&nbsp;попадаем при&nbsp;нажатии на&nbsp;кнопку, то&nbsp;есть у<span class="slaquo"> </span><span class="hlaquo">«</span>предыдущей». </p><p class="hyphenate">Нашел пропертю backBarButtonItem, поменял у&nbsp;нее&nbsp;title, но&nbsp;ничего не&nbsp;сработало. А&nbsp;потом до&nbsp;меня дошло. Там&nbsp;nil, и&nbsp;все&nbsp;мои&nbsp;потуги в&nbsp;никуда уходят. Поэтому как&nbsp;только я&nbsp;создал умолчальную кнопку: </p><pre class="brush: obj-c;">UIBarButtonItem *backButton = [[UIBarButtonItem alloc] initWithTitle:@"default back" style:UIBarButtonItemStyleBordered target:nil action:nil]; self.navigationItem.backBarButtonItem = backButton; [backButton release];</pre><p class="hyphenate">все&nbsp;тут&nbsp;же&nbsp;заработало как&nbsp;часы. Успехов.<br/></p> Mon, 23 Nov 2009 12:30:15 GMT Немного об In-App продажах http://touchdev.ru/shorts/370 <p class="hyphenate">In-App продажи вошли в&nbsp;моду совсем недавно, и&nbsp;многие разработчики до&nbsp;конца в&nbsp;них&nbsp;не&nbsp;разобрались. Если коротко&nbsp;— механизм немного другой, условия те&nbsp;же,&nbsp;что&nbsp;в&nbsp;случае продажи самого приложения. Apple забирает 30%, разработчик получает 70%. <a href="http://developer.apple.com/iphone/program/sdk/inapppurchase.html">Общее описание</a> есть на&nbsp;сайте Apple. </p><p class="hyphenate">Более подробно о&nbsp;том, что&nbsp;такое In-App продажи и&nbsp;с&nbsp;чем&nbsp;их&nbsp;едят, написано в&nbsp;документе <a href="http://developer.apple.com/iphone/news/pdf/in_app_purchase.pdf">Getting Started with In App Purchase on iPhone OS</a>. Для&nbsp;понимания технических аспектов можно ознакомиться с&nbsp;<a href="http://developer.apple.com/iphone/library/documentation/NetworkingInternet/Conceptual/StoreKitGuide/Introduction/Introduction.html">In App Purchase Programming Guide</a>.</p> Thu, 19 Nov 2009 22:15:52 GMT