<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" version="2.0">

<channel>
	<title>Stanfy Блог</title>
	
	<link>http://stanfy.com.ua/blog</link>
	<description>Об интернет технологиях, стартапах и программировании</description>
	<pubDate>Mon, 01 Mar 2010 10:08:29 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/stanfy-ua" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="stanfy-ua" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Весенний парад вакансий</title>
		<link>http://stanfy.com.ua/blog/2010/03/01/vacancy-pm-qa-iphone/</link>
		<comments>http://stanfy.com.ua/blog/2010/03/01/vacancy-pm-qa-iphone/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 07:43:35 +0000</pubDate>
		<dc:creator>Павел Башмаков</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2498</guid>
		<description><![CDATA[Чем больше работ появляется на нашем сайте (http://stanfy.com.ua), тем больше новых проектов мы начинаем разрабатывать для себя и наших клиентов.
Stanfy — это дружная команда профессионалов, которая занимается разработкой мобильных приложений для iPhone и Android. Мы растем быстро и динамично, а круг задач перед каждым сотрудником расширяется экспоненциально.
Ниже описание нескольких вакансий.
Менеджер проектов
Мы ищем человека способного занять [...]]]></description>
			<content:encoded><![CDATA[<p>Чем больше работ появляется на нашем сайте (<a href="http://stanfy.com.ua">http://stanfy.com.ua</a>), тем больше новых проектов мы начинаем разрабатывать для себя и наших клиентов.</p>
<p>Stanfy — это дружная команда профессионалов, которая занимается разработкой мобильных приложений для iPhone и Android. Мы растем быстро и динамично, а круг задач перед каждым сотрудником расширяется экспоненциально.</p>
<p>Ниже описание нескольких вакансий.</p>
<h2>Менеджер проектов</h2>
<p>Мы ищем человека способного занять роль Менеджера Проектов (PM) в компании, организовывать и вести работы по проектам.</p>
<div id="attachment_2499" class="wp-caption alignnone" style="width: 550px"><img class="size-large wp-image-2499 " title="pm-vacancy" src="http://stanfy.com.ua/blog/wp-content/uploads/2010/03/pm-vacancy-600x319.png" alt="Менеджер Проектов" width="540" height="287" /><p class="wp-caption-text">Менеджер Проектов</p></div>
<p><span id="more-2498"></span>Обычно в проекте задействованы от 4 до 6 человек. Задача PM — организовать коммуникацию, взаимодействие между всеми участниками процесса и выдать качественный готовый продукт в срок. И так по каждому проекту. Все довольно просто.</p>
<p>Нужно будет:</p>
<ul>
<li>управлять командой;</li>
<li>быть постоянно на связи с представителем клиента, разбираться в его задачах и планировать их реализацию командой;</li>
<li>уметь оценивать трудозатраты и сроки по задачам клиента;</li>
<li>помогать клиенту разобраться во всем и предлагать лучшие решения;</li>
<li>организовывать всю работу по проекту;</li>
<li>постоянно отслеживать эффективность работы команды, выявлять узкие места и находить способы их решения;</li>
<li>мониторить и контролировать выполнение проекта;</li>
<li>сдавать проекты в оцененные сроки;</li>
<li>вести общую документацию по проекту.</li>
</ul>
<p>Нужно уметь/знать/иметь:</p>
<ul>
<li>опыт управления командой в IT отрасли (желателен);</li>
<li>провести анализ сложной системы (или требований) и разложить все на понятные элементы;</li>
<li>решать конфликты как с представителем заказчика, так и внутри команды;</li>
<li>English - Intermediate+ (умение письменно и устно изложить свои мысли и понять собеседника);</li>
<li>быть лидером для своей команды.</li>
</ul>
<p>Присылайте ваше резюме с указанием в заголовке письма &#8220;PM-012&#8243; на адрес vacancy@stanfy.com.ua и обязательно указывайте желаемый уровень ЗП.</p>
<h2>QA Специалист</h2>
<p>Мы ищем человека, способного играть роль QA Специалиста (QA) в компании и быть на страже качества наших проектов. Иногда такого человека называют &#8220;тестер&#8221;, но это не совсем полностью отражает его роль в команде.</p>
<div id="attachment_2506" class="wp-caption aligncenter" style="width: 550px"><img class="size-large wp-image-2506 " title="qa-vacancy" src="http://stanfy.com.ua/blog/wp-content/uploads/2010/03/qa-vacancy-600x322.png" alt="QA Специалист" width="540" height="290" /><p class="wp-caption-text">QA Специалист</p></div>
<p>Обычно в проекте задействованы от 4 до 6 человек. Задача QA — организовать тестирование и постоянное отслеживание качества разрабатываемого проекта.</p>
<p>Нужно будет:</p>
<ul>
<li>описывать use-cases в проекте;</li>
<li>составлять план тестирования проекта;</li>
<li>проводить тестирование и описывать все найденные неточности, ошибки, неюзабельные места и т.д.</li>
</ul>
<p>Нужно уметь/знать/иметь:</p>
<ul>
<li>понимание процесса разработки ПО;</li>
<li>аналитический склад ума;</li>
<li>ответственность и самоорганизованность;</li>
<li>English - Intermediate;</li>
<li>желание учиться и развиваться.</li>
</ul>
<p>Присылайте ваше резюме с указанием в заголовке письма &#8220;QA-012&#8243; на адрес vacancy@stanfy.com.ua и обязательно указывайте желаемый уровень ЗП.</p>
<h2>iPhone/Android программисты</h2>
<p>Мы ищем человека, способного разрабатывать приложения для iPhone/Android, либо желающего научиться этому.</p>
<p>Требование к программисту:</p>
<ul>
<li>понимать, как работает компьютер, операционные системы и современные программы (процессор, память, кеширование, процесс, поток, буфер, интерфейс, бизнес-логика, сервер, клиент, протокол, файловая система);</li>
<li>разбираться и понимать как работают Web-технологии (HTTP, HTML/XHTML, XML/XSLT, CSS, JavaScript, SOAP, Cookie);</li>
<li>базы данных (таблица, поле, constraint, декартово произведение, объединение,  SQL, сложные запросы);</li>
<li>технологии и процесс разработки софта (SVN, Bug Tracker, Issue Tracker);</li>
<li>алгоритмы и шаблоны проектирования (сортировка, поиск, архитектура приложения, одиночка, MVC);</li>
<li>опыт работы с языками С/С++/Obj-C.</li>
</ul>
<p>И самое важное:</p>
<ul>
<li>ответственность;</li>
<li>открытость и честность;</li>
<li>желание и умение постоянно и быстро учиться.</li>
</ul>
<p>Присылайте ваше резюме (+портфолио в случае с работой по-проектно) с указанием в заголовке письма &#8220;IP-012&#8243; на адрес vacancy@stanfy.com.ua.</p>
<h2>Партнеры по разработке iPhone/Android приложений</h2>
<p>Мы также заинтересованы в надежных партнерах по разработке iPhone/Android проектов на сдельной основе. Если вы команда или независимый специалист и вам интересна по-проектная форма сотрудничества, присылайте нам свое резюме или портфолио на vacancy@stanfy.com.ua и не забывайте указывать цены.</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2010/03/01/vacancy-pm-qa-iphone/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Наше первое приложение под Android — логическая игра «Fox Hunter»</title>
		<link>http://stanfy.com.ua/blog/2010/01/29/nashe-pervoe-prilozhenie-pod-android-logicheskaya-igra-fox-hunter/</link>
		<comments>http://stanfy.com.ua/blog/2010/01/29/nashe-pervoe-prilozhenie-pod-android-logicheskaya-igra-fox-hunter/#comments</comments>
		<pubDate>Fri, 29 Jan 2010 10:29:33 +0000</pubDate>
		<dc:creator>Анна Юрченко</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2474</guid>
		<description><![CDATA[Наша первая игра для смартфонов на базе Android теперь доступна в Android Market!
Уже чуть больше года основной специализацией команды Стенфай является разработка мобильных приложений для iPhone. Мы следим за всеми новшествами в этом сегменте рынка и пытаемся развивать его в Украине — организовываем и выступаем на конференциях, консультируем агентства.
Наряду с разработкой под iPhone нам также [...]]]></description>
			<content:encoded><![CDATA[<p>Наша первая игра для смартфонов на базе Android теперь доступна в Android Market!</p>
<p>Уже чуть больше года основной специализацией команды Стенфай является разработка мобильных приложений для iPhone. Мы следим за всеми новшествами в этом сегменте рынка и пытаемся развивать его в Украине — <a href="http://iphonedevcamp.com.ua/">организовываем</a> и <a href="http://stanfy.com.ua/blog/2009/11/08/mobile-media-business/">выступаем</a> на конференциях, консультируем агентства.</p>
<p>Наряду с разработкой под iPhone нам также интересны и другие платформы — Android и Blackberry, поэтому пока не было реальных задач, мы решили попробовать технологию и разработать свое собственное приложение. Нам было интересно «пощупать» рынок и пройти через процедуру сабмита приложения в Android Market.</p>
<p><a href="http://stanfy.com.ua/blog/about/">Рома Мазур</a> предложил реализовать идею известной логической игры «Охота на лисиц», в которую около 10 лет назад он играл на компьютере «Поиск» :).</p>
<p>На игровом поле в случайном порядке располагаются «лисы» и задача игрока их найти за как можно меньшее количество ходов. При открытии ячейки вы или находите лисицу или видите число, которое показывает суммарное количество лисиц по горизонтали, вертикали и двум диагоналям.  Существует много версий этой игры для компьютеров и мобильных телефонов, а теперь и  для смартфонов на базе Android.</p>
<p><img class="aligncenter size-large wp-image-2476" title="foxhunter-adnroid" src="http://stanfy.com.ua/blog/wp-content/uploads/2010/01/foxhunter-group-600x358.jpg" alt="foxhunter-adnroid" width="600" height="358" /><span id="more-2474"></span></p>
<p>В ситуации с Android, сабмит приложения проходит гладко и быстро — через 10 минут после загрузки «Fox Hunter» уже был доступен в Android Market.</p>
<p>«Fox Hunter» можно найти через поиск в Android Market, по этой ссылке <a href="«Fox Hunter» можно найти через поиск в Android Market, по этой ссылке market://details?id=com.stanfy.android.foxhunter или используя qrcode.  qrcode-foxhunter-android">market://details?id=com.stanfy.android.foxhunter</a><strong> </strong>или используя qrcode.</p>
<p><img class="aligncenter size-full wp-image-2489" title="qrcode-foxhunter-android" src="http://stanfy.com.ua/blog/wp-content/uploads/2010/01/qrcode.png" alt="qrcode-foxhunter-android" width="195" height="195" /></p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2010/01/29/nashe-pervoe-prilozhenie-pod-android-logicheskaya-igra-fox-hunter/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Отсылка SMS на iPhone используя Private API</title>
		<link>http://stanfy.com.ua/blog/2010/01/18/otsylka-sms-na-iphone-ispolzuya-private-api/</link>
		<comments>http://stanfy.com.ua/blog/2010/01/18/otsylka-sms-na-iphone-ispolzuya-private-api/#comments</comments>
		<pubDate>Mon, 18 Jan 2010 12:17:50 +0000</pubDate>
		<dc:creator>Павел Тайкало</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iPhone & iPod]]></category>

		<category><![CDATA[Private API]]></category>

		<category><![CDATA[Send]]></category>

		<category><![CDATA[SMS]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2467</guid>
		<description><![CDATA[В общем, не знаю, насколько это правильно/не правильно, постить и шарить такие знания ;) Но, во-первых, я считаю, что Apple такое не пропустит (это раз). А во-вторых, эту информацию можно спокойно найти на просторах интеренета&#8230; Главное, ее скомбинировать. Результат объединения знаний, найденных здесь и здесь, вы можете прочитать в статье.
Используйте на свой страх и риск. [...]]]></description>
			<content:encoded><![CDATA[<p>В общем, не знаю, насколько это правильно/не правильно, постить и шарить такие знания ;) Но, во-первых, я считаю, что Apple такое не пропустит (это раз). А во-вторых, эту информацию можно спокойно найти на просторах интеренета&#8230; Главное, ее скомбинировать. Результат объединения знаний, найденных <a href="  http://www.ipodtouchfans.com/forums/showthread.php?t=232745&amp;page=2">здесь</a> и <a href="http://ericasadun.com/iPhoneDocs300/classes.html">здесь</a>, вы можете прочитать в статье.</p>
<p>Используйте на свой страх и риск. Для меня это работало и решило мою задачу. Я не несу ответсвенность за то, как ВЫ это будете использовать ;)</p>
<p>Понадобится на самом деле совсем немного. Для начала находим и добавляем из библиотек CoreTelephony.framework. Так как header&#8217;ы для него отсуствуют (все-таки Private API), нам понадобится файл хедера, который мы заберем  у <a href="http://ericasadun.com/iPhoneDocs300/_c_t_message_center_8h-source.html">ericdasan</a>. Все ненужные методы и структуры нам можно спокойно удалять. Нас интересует только вот этот метод :</p>
<p>&nbsp;</p>
<pre>
<pre name="code" class="objc">

 - (BOOL)sendSMSWithText:(id)fp8 serviceCenter:(id)fp12 toAddress:(id)fp16;
</pre>
</pre>
<p>Дальше - все просто:</p>
<pre>
<pre name="code" class="objc">

#import &quot;CTMessageCenter.h&quot;

....

 // SENDS SMS Without user prompt!!!
 // ServiceCenter - nil - по идее использует SMS-сервисцентр по умолчанию
 // Формат я не копал - потому что для меня задача решена ;) Но, скорее всего
 // здесь просто номер сервисного центра SMS
   [[CTMessageCenter sharedMessageCenter] sendSMSWithText:@&quot;Cool!&quot;
                                            serviceCenter:nil
                                                toAddress:@&quot;+38091ХХХХХХХ&quot;];
</pre>
</pre>
<p>Исходный код <a href="http://stanfy.com.ua/blog/wp-content/uploads/2010/01/sendsms.zip">прилагается</a></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2010/01/18/otsylka-sms-na-iphone-ispolzuya-private-api/feed/</wfw:commentRss>
		</item>
		<item>
		<title>С Новым годом всех-всех-всех!</title>
		<link>http://stanfy.com.ua/blog/2009/12/30/happy-stanfy/</link>
		<comments>http://stanfy.com.ua/blog/2009/12/30/happy-stanfy/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 09:54:54 +0000</pubDate>
		<dc:creator>Анна Юрченко</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[barcamp]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iPhoneDevCamp]]></category>

		<category><![CDATA[sapka]]></category>

		<category><![CDATA[stanfy]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2398</guid>
		<description><![CDATA[Новый год уже совсем на носу и самое время поздравить нашу команду, друзей и читателей блога Stanfy с наступающими праздниками! Мы хотим пожелать всем  быть здоровыми и счастливыми в 2010 году и пусть он будет наполнен открытиями, планами, успехами и достижениями!
В Стенфай в 2009 произошло много всего интересного и значимого для всех нас.
Во-первых нас [...]]]></description>
			<content:encoded><![CDATA[<p>Новый год уже совсем на носу и самое время поздравить нашу команду, друзей и читателей блога Stanfy с наступающими праздниками! Мы хотим пожелать всем  быть здоровыми и счастливыми в 2010 году и пусть он будет наполнен открытиями, планами, успехами и достижениями!</p>
<p>В Стенфай в 2009 произошло много всего интересного и значимого для всех нас.</p>
<p><span id="more-2398"></span>Во-первых нас стало на 5 человек больше и теперь места на кухне во время праздников дня варенья стало совсем мало :). В этом году женился Рома Мазур (с чем мы его еще раз поздравляем) и мы всем коллективом сходили в поход в Карпаты, после которого многие решили, что больше никогда не согласятся на подобные провокации :). А благодаря Роме Ходобашу <a href="http://proroliki.com.ua/2009/12/19/stanfy-korporativnaya-vecherinka">коллективно научились кататься на роликах</a>.</p>
<p>Из рабочих моментов - мы освоили и успешно работаем в новом для себя направлении разработки под современные мобильные платформы. В январе 2009 вышло <span style="text-decoration: line-through;">в свет</span> в AppStore наше первое<a href="http://stanfy.com.ua/blog/2009/02/19/rub-2-grub/"> iPhone приложение Rub2Grub</a> для социальной сети crazymenu.com. С тех пор мы успели создать около десяти <a href="http://stanfy.com.ua/our-projects.html"> iPhone приложений</a> для украинского, российского, европейского и американского рынков, набить необходимых шишек и понять, что и дальше хотим создавать классные iPhone и Android аппы.</p>
<p>2009 принес нам новых партнеров и клиентов, мы успешно завершили несколько внутренних проектов для компании Астелит и мобильного оператора Life:).</p>
<p>В марте 2009 мы организовали и провели <a href="http://stanfy.com.ua/contest/">контест для настоящих программистов Sapka</a>, в котором приняло участие 45 команд (а это около 150 участников) со всей Украины, России и Беларуси, которые за 7 дней создали робота-бомбермена с искусственным интеллектом. Основной целью, которую мы для себя ставили, было стимулирование программистов к нестандартному мышлению над нестандартными задачами. Мы также поддержали и стали партнерами конференции для разработчиков CodeСamp, в рамках которой проводилось награждение победителей Sapka.</p>
<p>В июле 2009 мы организовали первую в Восточной Европе конференцию для iPhone разработчиков - <a href="http://iphonedevcamp.com.ua/2009/07/iphonedevcamp-repor/">iPhoneDevCamp</a>, которая собрала 320 человек из Украины, России, Беларуси, Латвии, Германии, Молдовы и США. Конференция показала высокий интерес к iPhone разработке и дала стимул к формированию сообщества iPhone разработчиков  в Украине. С тех пор Stanfy проводит регулярные миникемпы для iPhone разработчиков <a href="http://iphonedevcamp.com.ua/">iPhoneDevCamp Kyiv</a>, которые каждый раз собирают от 50 до 70 человек. Их цель - создание среды для обмена опытом, знаниями и идеями iPhone разработчиков в Украине.</p>
<p>Осенью 2009 мы помогали в организации конференции для специалистов медиа-рынка Украины <a href="http://mediacamp.org.ua/team">MediaCamp Kyiv</a>, а также на протяжении всего года участвовали в других конференциях и баркемпах в России, Казахстане и Европе. Выступили на <a href="http://stanfy.com.ua/blog/2009/04/28/internet-kazakhstan/">баркемпе в Алматы</a>, в Санкт-Петербурге на <a href="http://stanfy.com.ua/blog/2009/07/10/nevacamp-iphone-ppt/">NevaCampe</a>, на российском iCampe, в Вильнюсе на MediaBarCampe, стали участниками российской интернет-конференции <a href="http://stanfy.com.ua/blog/2009/10/29/riw2009-part1/">RIW2009</a> и побывали на парижском LeWeb 2009.</p>
<p>Все перечисленное, это заслуга всей нашей команды Stanfy, каждого отдельного человека, который каждый день приходит в офис, включает компьютер и посвящает свои мысли и время общим целям и планам, делится своими идеями, участвует в спорах и обсуждениях, учится новому и помогает другим.</p>
<p>Мы хотим, что бы развивался наш Интернет и наши украинские разработчики, мы считаем, что будущее за мобильными технологиями и стремимся донести это до украинцев и украинского бизнеса.</p>
<p>Спасибо всем, кто нас в этом поддерживает и счастливого Нового года! &#8230; и не забудьте получить поздравления от тигра :).</p>
<p><a href="http://stanfy.com.ua/cards/nycard.html"><img class="aligncenter size-full wp-image-2400" title="Поздравление 2010" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/12/postcard-invite-ru.jpg" alt="Поздравление 2010" width="400" height="465" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/12/30/happy-stanfy/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Использование современных мобильных технологий в медиабизнесе</title>
		<link>http://stanfy.com.ua/blog/2009/11/08/mobile-media-business/</link>
		<comments>http://stanfy.com.ua/blog/2009/11/08/mobile-media-business/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 09:47:37 +0000</pubDate>
		<dc:creator>Павел Башмаков</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[barcamp]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[presentations]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2389</guid>
		<description><![CDATA[Презентация с моего доклада, который я рассказывал вчера на MediaCamp Kyiv 09 - &#8221; Использование современных мобильных технолгий в медиабизнесе: Тенденции, перспективы, международный опыт.&#8221;

Впечатления, фотографии и отчет о событии будут позже.
]]></description>
			<content:encoded><![CDATA[<p>Презентация с моего доклада, который я рассказывал вчера на MediaCamp Kyiv 09 - &#8221; Использование современных мобильных технолгий в медиабизнесе: Тенденции, перспективы, международный опыт.&#8221;</p>
<p><object width="425" height="355" data="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mobileinternet-091108034127-phpapp02&amp;rel=0&amp;stripped_title=ss-2448920" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=mobileinternet-091108034127-phpapp02&amp;rel=0&amp;stripped_title=ss-2448920" /><param name="allowfullscreen" value="true" /></object></p>
<p>Впечатления, фотографии и отчет о событии будут позже.</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/11/08/mobile-media-business/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Генератор перестановок</title>
		<link>http://stanfy.com.ua/blog/2009/11/01/permutations-generator-java/</link>
		<comments>http://stanfy.com.ua/blog/2009/11/01/permutations-generator-java/#comments</comments>
		<pubDate>Sat, 31 Oct 2009 21:38:21 +0000</pubDate>
		<dc:creator>Роман Мазур</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2372</guid>
		<description><![CDATA[Пишу про класичну задачу генерації перестановок з n елементів, так про ту саму, кількість перестановок у якій n!. Потрібно було реалізувати її на Java. Задача, повторюся, класична, і можна знайти чимало інформації про алгоритм її розв&#8217;язання, однак дане розв&#8217;язання здалося мені досить компактним та цікавим.
В основі лежить рекурсивний алгоритм. На кожному рекурсивному вході формується новий [...]]]></description>
			<content:encoded><![CDATA[<p>Пишу про класичну задачу генерації перестановок з n елементів, так про ту саму, кількість перестановок у якій n!. Потрібно було реалізувати її на Java. Задача, повторюся, класична, і можна знайти чимало інформації про алгоритм її розв&#8217;язання, однак дане розв&#8217;язання здалося мені досить компактним та цікавим.</p>
<p>В основі лежить рекурсивний алгоритм. На кожному рекурсивному вході формується новий елемент перестановки. Глибина рекурсії, таким чином, рівна n. Для формування перестановки використовується бітова карта - екземпляр класу java.util.BitSet, що і є головним фактором простоти алгоритму. Викорстання даної реалізації є дуже простим:</p>
<pre>
<pre name="code" class="java">

PermutationsHelper.generate(elementsCollection, handler);
</pre>
</pre>
<pre><span id="more-2372"></span></pre>
<p>Тут elementsCollection - екзмепляр класу, що настлідує java.util.Collection,<br />
handler - об&#8217;єкт, що містить метод для обробки кожної з перестановок, на приклад, для виведеня на екран:</p>
<pre>
<pre name="code" class="java">

/** Колекція елементів. */
elementsCollection = Arrays.asList(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;);
handler = new PrintHandler();

.....

/**
 * Виводить на екран перестановку елементів класу String.
 */
public class PrintHandler implements PermutationsHandler&lt;String&gt; {
  @Override
  public void handle(final ArrayList&lt;String&gt; permutation) {
    System.out.println(permutation);
  }
}
</pre>
</pre>
<p>Люблю побавитися за Java Generics&#8230;</p>
<p>Словом, дивіться:</p>
<pre>
<pre name="code" class="java">

import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collection;

/**
 * This class helps to generate permutations of elements.
 */
public class PermutationsHelper&lt;T&gt; {
  /** Handler. */
  private PermutationHandler&lt;T&gt; handler;
  /** Bitmap to identify used elements. */
  private BitSet bitmap;
  /** Elements to permutate. */
  private ArrayList&lt;T&gt; elements;
  /** Current permutation. */
  private ArrayList&lt;T&gt; permutation;

  /** Hidden constructor. */
  private PermutationsHelper() { }

  /**
   * Does a change in the permutation.
   * @param iteration iteration index (recursion depth)
   */
  private void change(final int iteration) {
    if (iteration == permutation.size()) {
      handler.handle(permutation);
      return;
    }
    for (int i = bitmap.nextSetBit(0); i &gt;= 0; i = bitmap.nextSetBit(i + 1)) {
      permutation.set(iteration, elements.get(i));
      bitmap.clear(i);
      change(iteration + 1);
      bitmap.set(i);
    };
  }

  /**
   * Generates permutations for the elements collection and calls a handler
   * for the each new permutation.
   * @param &lt;T&gt; elements type
   * @param elements elements collection
   * @param handler permutation handler
   */
  public static &lt;T&gt; void generate(final Collection&lt;T&gt; elements,
      final PermutationHandler&lt;T&gt; handler) {
    PermutationsHelper&lt;T&gt; helper = new PermutationsHelper&lt;T&gt;();
    helper.elements = new ArrayList&lt;T&gt;(elements);
    helper.permutation = new ArrayList&lt;T&gt;(elements);
    helper.handler = handler;
    helper.bitmap = new BitSet(elements.size());
    helper.bitmap.set(0, elements.size());
    helper.change(0);
  }

  /**
   * Permutation handler interface.
   * @param &lt;T&gt; elements type
   */
  public static interface PermutationHandler&lt;T&gt; {
    void handle(final ArrayList&lt;T&gt; permutation);
  }

  /**
   * Starts the test.
   * @param args arguments are ignored
   */
  public static void main(final String[] args) {
    PermutationsHelper.generate(
        Arrays.asList(&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;),
        new PermutationHandler&lt;String&gt;() {
          @Override
          public void handle(final ArrayList&lt;String&gt; permutation) {
            System.out.println(permutation);
          }
        }
    );
  }

}
</pre>
</pre>
<p>Але це ще не все. Оскільки я останнім часом став фаном Groovy, то покажу ще, як можна використати даний генератор за допомогою цієї мови. Додамо до нашого класу PermutationsHelper ще один метод:</p>
<pre>
<pre name="code" class="java">

import groovy.lang.Closure;

....

  public static &lt;T&gt; void generate(final Collection&lt;T&gt; elements,
      final Closure closure) {
    generate(elements, new PermutationHandler&lt;T&gt;() {
      @Override
      public void handle(final ArrayList&lt;T&gt; permutation) {
        closure.call(permutation);
      }
    });
  }
</pre>
</pre>
<p>Тепер, для Groovy, попередній приклад буде виглядати наступним чином:</p>
<pre>
<pre name="code" class="java">

PermutationsHelper.generate([&quot;a&quot;, &quot;b&quot;, &quot;c&quot;, &quot;d&quot;]) {
  println it
}
</pre>
</pre>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/11/01/permutations-generator-java/feed/</wfw:commentRss>
		</item>
		<item>
		<title>RIW2009 - факты и цифры (часть 1)</title>
		<link>http://stanfy.com.ua/blog/2009/10/29/riw2009-part1/</link>
		<comments>http://stanfy.com.ua/blog/2009/10/29/riw2009-part1/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 19:30:59 +0000</pubDate>
		<dc:creator>Анна Юрченко</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[конференция]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2330</guid>
		<description><![CDATA[С 22 по 24 октября в Москве прошла конференция &#8220;Неделя Российского Интернета&#8221;, которая была заявлена, как главное осеннее событие рунета. Вместе с конференцией была проведена выставка &#8220;Интернет 2009&#8243;, где компании могли представить себя и свои услуги. За три дня RIW посетили около 11 тысяч человек, в их числе и мы.
Основной целью участия в конференции для [...]]]></description>
			<content:encoded><![CDATA[<p><span>С 22 по 24 октября в Москве прошла конференция </span><span><a href="http://2009.russianinternetweek.ru">&#8220;Неделя Российского Интернета&#8221;</a></span><span>, которая была заявлена, как главное осеннее событие </span><span>рунета</span><span>. Вместе с конференцией была проведена выставка &#8220;Интернет 2009&#8243;, где компании могли представить себя и свои услуги. За три дня RIW посетили около 11 тысяч человек, в их числе и мы.</span></p>
<p><span><span>О</span><span>сновной целью участия в конференции для нас было познакомиться с российским Интернет рынком, узнать о тенденциях и перспективах, которые прогнозируют участники рынка, пообщаться с коллегами  и найти новых партнеров. </span></span></p>
<div id="attachment_2336" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-2336" title="Российская неделя Интернета riw2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_4236-300x225.jpg" alt="img_4236" width="300" height="225" /><p class="wp-caption-text">Хелптим на RIW :)</p></div>
<p><span id="more-2330"></span></p>
<div id="attachment_2332" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-2332" title="Russian Internet Week (riw2009)" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_3840-300x225.jpg" alt="Выставка &quot;Интернет 2009&quot;" width="300" height="225" /><p class="wp-caption-text">Выставка &quot;Интернет 2009&quot;</p></div>
<p><span>В целом событие было достаточно насыщенно докладами и общением. На самом экспо компании наперебой </span><span>завлекали</span><span> посетителей в свои креативные и не очень стенды, устраивали конкурсы и аукционы, угощали текилой и яблоками. Детали можно увидеть на фотографиях в </span><a href="http://picasaweb.google.com/pavel.bashmakov/RIW2009">альбоме</a><span>.</span></p>
<p><img class="aligncenter size-medium wp-image-2335" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_4167-300x225.jpg" alt="Российская Неделя Интернета RIW2009" width="300" height="225" /></p>
<p><span>Сама выставка скорее была рассчитана не на профессионалов интернет рынка, а на обычных пользователей, которым хотели рассказать как использовать сервисы гугла, как искать работу или где научиться быть крутым SEO. Выставку громко и пафосно анонсировали, но, по большому счету, ничего интересного там не было. За красивым названием &#8220;Аллея инноваций&#8221; скрывался ряд стендов со стартапами, которые раздавали листовки, фотографировали с обнаженными девушками и охотно рассказывали о своих проектах.</span></p>
<p><img class="aligncenter size-medium wp-image-2343" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_4152-300x225.png" alt="Российская Неделя Интернета RIW2009" width="300" height="225" /></p>
<p><span>Содержательная часть конференции проходила в пять потоков, четыре из которых могли посетить только участники профессиональной программы. За эту возможность при ранней регистрации нужно было заплатить около 100 долларов. </span></p>
<p><span>У</span><span>частниками </span><span>профпрограммы</span><span> стали 3000 человек, в то время как мест во всех четырех залах и бизнес зоне было не больше чем для 1000. Три дня практически на все интересные секции нельзя было даже зайти - люди стояли в проходах и проемах дверей, не было свободы перемещения и доступа к интересующим докладам. Пожалуй, теснота и отсутствие работающего wifi было самым неприятным впечатлением от RIW 2009. </span></p>
<div id="attachment_2333" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-2333" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_3846-300x225.jpg" alt="Российская Неделя Интернета RIW2009" width="300" height="225" /><p class="wp-caption-text">Бизнес зона в самом начале... уже через пару часов тут было не так уютно :)</p></div>
<div id="attachment_2334" class="wp-caption aligncenter" style="width: 310px"><img class="size-medium wp-image-2334" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_3892-300x225.jpg" alt="Российская Неделя Интернета RIW2009" width="300" height="225" /><p class="wp-caption-text">Переполненные секции</p></div>
<p><strong>Интернет аудитория в России</strong></p>
<p>Пользователями Интернет в России являются 38,9 млн. человек (35%), что больше на 5% по сравнению с летом 2008 года. Прирост суточной аудитории за год составил 4,1% (5,4 млн.), что показывает увеличение интенсивности использования Интернет уже существующими пользователями, а вот привлечение новых происходит не так активно.</p>
<div id="attachment_2345" class="wp-caption aligncenter" style="width: 651px"><img class="size-full wp-image-2345" title="Неделя Российского Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/untitled-2.png" alt="Динамика проникновения Интернет в России (млн.чел)" width="641" height="277" /><p class="wp-caption-text">Динамика проникновения Интернет в России (млн.чел)</p></div>
<p>Основной прирост аудитории в России происходит за счет регионов, а самый высокий уровень проникновения Интернет в Москве — 60% взрослого населения столицы (5,4 млн.).</p>
<div id="attachment_2351" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-2351" title="Неделя Российского Интернет RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/img_46691.png" alt="Динамика проникновения Интернет в регионы (%)" width="500" height="313" /><p class="wp-caption-text">Динамика проникновения Интернет в регионы (%)</p></div>
<p>Видимо проникновение Интернет среди образованных и обеспеченных граждан достигло определенного насыщения и наиболее активный рост проникновения  был замечен среди людей с неполным средним образованием и низким уровнем доходов. <em>(Данные Фонда Общественного Мнения).</em></p>
<div id="attachment_2354" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-2354" title="Российская неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/4447.png" alt="Динамика проникновения Интернет по уровню дохода (%)" width="500" height="313" /><p class="wp-caption-text">Динамика проникновения Интернет по уровню дохода (%)</p></div>
<div id="attachment_2353" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-2353" title="Российская неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/44.png" alt="Динамика проникновения Интернет по уровню образования (%)" width="500" height="313" /><p class="wp-caption-text">Динамика проникновения Интернет по уровню образования (%)</p></div>
<p>Еще интересно, что в России Интернет достаточно серьезно конкурирует с ТВ, радио, печатными СМИ. По данным TNS дневная аудитория Яндекса или Mail.ru значительно выше числа зрителей некоторых телеканалов и всех радиостанций.</p>
<p>&nbsp;</p>
<div id="attachment_2347" class="wp-caption aligncenter" style="width: 259px"><img class="size-medium wp-image-2347" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/untitled-3-249x300.png" alt="Топ-20 ТВ, Радио и Интернет (дневная аудитория, млн. чел)" width="249" height="300" /><p class="wp-caption-text">Топ-20 ТВ, Радио и Интернет (дневная аудитория, млн. чел)</p></div>
<p><strong>Рекламные бюджеты</strong></p>
<p>Тема кризиса на RIW2009 оговаривалась почти на всех секциях, но, к радости всех интернетчиков, из всех медийных каналов  кризисные явления менее всего отразились на онлайн рынке. В целом российский рекламный рынок упал на 30%, сильнее всего это отразилось на прессе и наружной рекламе (-45% ), а уровень рекламных инвестиций в Интернет увеличился на 5%.</p>
<p><span>По итогам первого полугодия 2009 года о</span><span>бщий объем рынка Интернет рекламы составил 230 млн. дол.. — н<span>а долю </span><span>медийной рекламы </span><span>пришлось 31% (</span><span>90 млн. долл.).</span></span></p>
<p>&nbsp;</p>
<div id="attachment_2357" class="wp-caption aligncenter" style="width: 468px"><img class="size-full wp-image-2357" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/45277452.png" alt="Объем рынка Интернет рекламы в России (источник: Mindshare Interaction) " width="458" height="245" /><p class="wp-caption-text">Объем рынка Интернет рекламы в России (источник: Mindshare Interaction) </p></div>
<div id="attachment_2358" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-2358" title="Российская Неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/14512.png" alt="Доля Интернет в Структуре Рекламных Затрат, % (источник: GroupM Interaction review)" width="500" height="380" /><p class="wp-caption-text">Доля Интернет в структуре рекламных затрат, % (источник: GroupM Interaction review)</p></div>
<p>В целом кризисные явления в российском Интернет вылились в то, что и<span>здательские дома все активнее стали работать над развитием сайтов, профессиональные команды журналистов переходить в онлайн </span><span>(Slon.ru, Snob.ru), а ТВ <span>каналы занялись разивитием информационных онлайн проектов </span><span>(</span><span>Вести</span><span>). </span></span></p>
<p>Самыми затратными с точки зрения рекламы в 2009 году оказались автомобильная отрасль (30%), телеком (19%) и FMCG (18%), а самым щедрым рекламодателем МТС.</p>
<div id="attachment_2359" class="wp-caption aligncenter" style="width: 510px"><img class="size-full wp-image-2359" title="Российская неделя Интернета RIW2009" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/526.png" alt="Топ 10 рекламодателей Рунета (млн руб., источник: Mindshare Interaction)" width="500" height="361" /><p class="wp-caption-text">Топ 10 рекламодателей Рунета (млн руб., источник: Mindshare Interaction)</p></div>
<p>Это первая часть отчета о RIW, в которой хотелось кратко описать рынок в цифрах и общее впечатление о событии. В следующей части речь пойдет о тенденциях и популярных трендах российского интернет рынка, о том как завлекают на свои площадки рекламодателей, как формируют бренды в социальных сетях и нужен ли российским компаниям твиттер.</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/10/29/riw2009-part1/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Разработка iPhone/iPod touch приложений: Полезности - UIToolBar над UIKeyboard</title>
		<link>http://stanfy.com.ua/blog/2009/10/12/razrabotka-iphoneipod-touch-prilozhenij-poleznosti-uitoolbar-nad-uikeyboard/</link>
		<comments>http://stanfy.com.ua/blog/2009/10/12/razrabotka-iphoneipod-touch-prilozhenij-poleznosti-uitoolbar-nad-uikeyboard/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 09:14:37 +0000</pubDate>
		<dc:creator>Павел Тайкало</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[Keyboard]]></category>

		<category><![CDATA[toolbar]]></category>

		<category><![CDATA[toolbar over keyboard]]></category>

		<category><![CDATA[UIKeyboard]]></category>

		<category><![CDATA[UIKeyboardWillHideNotification]]></category>

		<category><![CDATA[UIKeyboardWillShowNotification]]></category>

		<category><![CDATA[UIToolBar]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2319</guid>
		<description><![CDATA[Много кто видел как в некоторых приложениях вместе с клавиатурой выезжает UIToolBar - примерно так, как это показано на рисунке.
Есть несколько вариантов так сделать. Первый, и самый &#8220;простой&#8221; - это позиционировать UIToolBar в нужное место до/или после того, как началось редактирование, и клавиатура должна выехать. Даже для начинающего программиста эта задача не составит особого труда.
Программист [...]]]></description>
			<content:encoded><![CDATA[<div id="attachment_2320" class="wp-caption alignright" style="width: 203px"><a href="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/keyboard.png"><img class="size-full wp-image-2320 " title="keyboard" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/10/keyboard.png" alt="keyboard" width="193" height="157" /></a><p class="wp-caption-text">Клавиатура с UIToolBar&#39;ом</p></div>
<p>Много кто видел как в некоторых приложениях вместе с клавиатурой выезжает UIToolBar - примерно так, как это показано на рисунке.</p>
<p>Есть несколько вариантов так сделать. Первый, и самый &#8220;простой&#8221; - это позиционировать UIToolBar в нужное место до/или после того, как началось редактирование, и клавиатура должна выехать. Даже для начинающего программиста эта задача не составит особого труда.</p>
<p>Программист более продвинутый, который любит и умеет читать документацию или искать, без особого труда найдет , что можно подписаться на глобальные события <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/uid/TP40006817-CH3-SW18">UIKeyboardWillShowNotification</a> и <a href="http://developer.apple.com/iphone/library/documentation/UIKit/Reference/UIWindow_Class/UIWindowClassReference/UIWindowClassReference.html#//apple_ref/doc/uid/TP40006817-CH3-SW20">UIKeyboardWillHideNotification</a>, чтобы вовремя подставлять/убирать UIToolBar.</p>
<p>После того, как нам не понравится (а нам  не понравится) то, что UIToolBar &#8220;прыгает&#8221; вместо того, чтобы плавно уезжать вместе с клавиатурой, добавим немного анимации. После таких манипуляций должен получиться примерно следующий код:<br />
<span id="more-2319"></span></p>
<pre>
<pre name="code" class="objc">

// Здесб у нас будут &quot;константы&quot;
#define VIEWPORT_SIZE 320
#define KEYBOARD_HEIGHT 215
#define TOOLBAR_HEIGHT 44
#define KEYBOARD_TRANSITION_DURATION 0.3

// Подписываемся на глобальные события
- (void)viewDidLoad {
[super viewDidLoad];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
// Событие перед появлением клавиатуры
[nc addObserver:self selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil];
// Событие перед скрытием клавиатуры
[nc addObserver:self selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil];
}

-(void) keyboardWillShow:(NSNotification *) note {
// Так как клавиатура появляется с самого низа экрана,
// то UIToolBar должен быть чуть-чуть выше
toolBar.frame = CGRectMake(0, [[self view] frame ].size.height - TOOLBAR_HEIGHT, VIEWPORT_SIZE, TOOLBAR_HEIGHT);

// Вычисляем точку, куда должен &quot;прилететь&quot; UIToolBar
CGRect toolBarRect = [toolBar  frame];
toolBarRect.origin.y = [[self view] frame].size.height - KEYBOARD_HEIGHT - TOOLBAR_HEIGHT;

// Добавляем красивости
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:KEYBOARD_TRANSITION_DURATION];
[toolBar setFrame:toolBarRect];
[UIView commitAnimations];

}

-(void) keyboardWillHide:(NSNotification *) note {
//А вот &quot;улетать&quot; UIToolBar должен за пределы экрана.
//Он будет &quot;улетать&quot; чуть-чуть быстрее, чем клавиатура
//Выглядит неплохо, хоть и не совсем правильно.
[UIView beginAnimations:nil context:nil];
[UIView setAnimationDuration:KEYBOARD_TRANSITION_DURATION];
toolBar.frame = CGRectMake(0, [[self view] frame ].size.height, VIEWPORT_SIZE, TOOLBAR_HEIGHT);
[UIView commitAnimations];
}
</pre>
</pre>
<p>Это, если использовать &#8220;константы&#8221;. Трудно себе представить, конечно, но что будет, если вдруг размер клавиатуры/время ее появляения/анимация ее появления вдруг изменятся? Как делать все правильно? Обращаю внимание, что в большинстве случаев вполне достаточно кода который уже был приведен, и я сам считаю, что &#8220;Що занадто - то нездраво&#8221;(&#8221;Что чересчур - то нездорово&#8221;). Но если все-таки надо, то вышеперечисленную информацию можно &#8220;достать&#8221; из NSNotification userInfo. userInfo - это, обычно, NSDictionary, который по ключам хранит полезную информацию:</p>
<pre>
<pre name="code" class="objc">

//Тип анимации
//   UIKeyboardAnimationCurveUserInfoKey = 0;
//Время анимации (&quot;выезд клавиатуры&quot;)
//   UIKeyboardAnimationDurationUserInfoKey = 0.300000011920929;
//Размеры клавиатуры
//   UIKeyboardBoundsUserInfoKey = NSRect: {{0, 0}, {320, 216}};
//Центр клавиатуры в начале анимации
//   UIKeyboardCenterBeginUserInfoKey = NSPoint: {160, 588};
//Центр клавиатуры в конце анимации
//   UIKeyboardCenterEndUserInfoKey = NSPoint: {160, 372};

...

// А вот, собвственно, как віглядит код:

-(void) keyboardWillShow:(NSNotification *) note {
   NSDictionary * userInfo = [note userInfo];
   CGRect keyboardSize;
   [[userInfo objectForKey:UIKeyboardBoundsUserInfoKey] getValue:&amp;keyboardSize];
   CGPoint keyboardCenterBeforeAnimation;
   [[userInfo objectForKey:UIKeyboardCenterBeginUserInfoKey] getValue:&amp;keyboardCenterBeforeAnimation];
   CGPoint keyboardCenterAfterAnimation;
   [[userInfo valueForKey:UIKeyboardCenterEndUserInfoKey] getValue:&amp;keyboardCenterAfterAnimation];
   double animationDuration;
   [[userInfo objectForKey:UIKeyboardAnimationDurationUserInfoKey] getValue:&amp;animationDuration];
   int animationType;
   [[userInfo objectForKey:UIKeyboardAnimationCurveUserInfoKey] getValue:&amp;animationType];

   toolBar.frame = CGRectMake(0, keyboardCenterBeforeAnimation.y - keyboardSize.size.height / 2 - TOOLBAR_HEIGHT, keyboardSize.size.width, TOOLBAR_HEIGHT);
   [UIView beginAnimations:nil context:nil];
   [UIView setAnimationDuration:animationDuration];
   [UIView setAnimationCurve:animationType];
   [toolBar setFrame:CGRectMake(0, keyboardCenterAfterAnimation.y - keyboardSize.size.height / 2 - TOOLBAR_HEIGHT, keyboardSize.size.width, TOOLBAR_HEIGHT)];
   [UIView commitAnimations];
}
</pre>
</pre>
<p>Теперь вы знаете своего врага в лицо - и вся информация о нем есть. Как использовать эту информацию - решать вам ;) Я дал лишь один из вариантов ее использования ;)</p>
<p>И не забывайте, что у клавиатуры и ее событий есть <a href="http://stanfy.com.ua/blog/2009/07/23/keyboard_notifications/">некоторые особенности</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/10/12/razrabotka-iphoneipod-touch-prilozhenij-poleznosti-uitoolbar-nad-uikeyboard/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Продолжение интересных соревнований по программированию</title>
		<link>http://stanfy.com.ua/blog/2009/09/25/programming-contest/</link>
		<comments>http://stanfy.com.ua/blog/2009/09/25/programming-contest/#comments</comments>
		<pubDate>Fri, 25 Sep 2009 19:37:42 +0000</pubDate>
		<dc:creator>Павел Башмаков</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[contest]]></category>

		<category><![CDATA[programming contest]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2312</guid>
		<description><![CDATA[Наряду с органиацией интересных соревнований по программированию, с целью популяризации правильного понимания роли разработчика, в отличие от кодера, мы еще и сами любим принимать участие и следить за интересностями в этой области.
Компания GlobalLogic в этом году конкурс &#8220;Программания 2009&#8243; делает намного интереснее и привносит в него движение и азарт из реальной жизни.
Организаторами соревнования, была придумана [...]]]></description>
			<content:encoded><![CDATA[<p>Наряду с <a href="http://stanfy.com.ua/contest/">органиацией интересных соревнований по программированию</a>, с целью популяризации правильного понимания роли разработчика, в отличие от кодера, мы еще и <a href="http://stanfy.com.ua/blog/2009/09/14/opublikovany-rezultaty-icfp-contest-2009/">сами любим принимать участие</a> и следить за интересностями в этой области.</p>
<p>Компания <a href="http://www.globallogic.com.ua">GlobalLogic</a> в этом году конкурс <a href="http://www.programmania.quest.ua/">&#8220;Программания 2009&#8243;</a> делает намного интереснее и привносит в него движение и азарт из реальной жизни.</p>
<p>Организаторами соревнования, была придумана <a href="http://www.globallogic.com.ua/index.php?option=com_content&amp;view=article&amp;id=18654914&amp;Itemid=204&amp;lang=ru/">легенда</a> (теория заговора) и внесена в пространство реальных городов. Ну и как же здесь без программирования? Все будет построено на программировании, но от задания можно будет ожидать чего угодно! Поэтому, стоит запастись и фанариком и кусачками колючей проволоки :) Это точно будет что-то интересное.</p>
<p><object width="480" height="85" data="http://stanfy.com.ua/contest/wp-content/uploads/2009/09/b5.swf" type="application/x-shockwave-flash"><param name="src" value="http://stanfy.com.ua/contest/wp-content/uploads/2009/09/b5.swf" /></object></p>
<p>Принять участие в конкурсе &#8220;Программания 2009&#8243; может любой желающий! И расстояние здесь - совсем не помеха! Достаточно хотя бы одного бойца иметь на полях реальной битвы в Киеве, Харькове или Львове, а дальше средства связи вам помогут.</p>
<p>Узнайте подробнее о <a href="http://www.globallogic.com.ua/index.php?option=com_content&amp;view=article&amp;id=18654914&amp;Itemid=204&amp;lang=ru">Конкурсе</a>, <a href="http://www.globallogic.com.ua/index.php?option=com_content&amp;view=article&amp;id=18654915&amp;Itemid=205&amp;lang=ru">правилах участия</a> и <a href="http://programmania.quest.ua/">зарегистрируйтесь</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/09/25/programming-contest/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Разработка iPhone/iPod touch приложений: CoreData. Что в имени твоем? (Часть 2) - Контексты и запросы</title>
		<link>http://stanfy.com.ua/blog/2009/09/23/coredata-part2-contexts-and-requests/</link>
		<comments>http://stanfy.com.ua/blog/2009/09/23/coredata-part2-contexts-and-requests/#comments</comments>
		<pubDate>Wed, 23 Sep 2009 17:27:30 +0000</pubDate>
		<dc:creator>Павел Тайкало</dc:creator>
		
		<category><![CDATA[Новости]]></category>

		<category><![CDATA[core data]]></category>

		<category><![CDATA[coredata]]></category>

		<category><![CDATA[fetchedProperties]]></category>

		<category><![CDATA[fetchLimit]]></category>

		<category><![CDATA[iPhone]]></category>

		<category><![CDATA[iPhone & iPod]]></category>

		<category><![CDATA[NSFetchRequest]]></category>

		<category><![CDATA[NSManagedObject]]></category>

		<category><![CDATA[NSManagedObjectContext]]></category>

		<guid isPermaLink="false">http://stanfy.com.ua/blog/?p=2243</guid>
		<description><![CDATA[Разобравшись в основных понятиях Core Data, можно начинать им пользоваться. Для простоты и удобства, здесь и далее, будет предполагаться, что NSPersistenceStoreCoordinator, NSManagedObjectContext, NSManagedObjectModel уже созданы, и к ним есть доступ. Модель, которая будет использоваться в примерах, выглядит следующим образом:
Типы данных свойств объектов особого значения для примеров не имеют. Модель взята из &#8220;детского набора инженера-генетика&#8221;, который [...]]]></description>
			<content:encoded><![CDATA[<p>Разобравшись <a href="http://stanfy.com.ua/blog/2009/09/22/coredata-what-are-you-part1-base/">в основных понятиях Core Data</a>, можно начинать им пользоваться. Для простоты и удобства, здесь и далее, будет предполагаться, что NSPersistenceStoreCoordinator, NSManagedObjectContext, NSManagedObjectModel уже созданы, и к ним есть доступ. Модель, которая будет использоваться в примерах, выглядит следующим образом:</p>
<div id="attachment_2244" class="wp-caption aligncenter" style="width: 378px"><a href="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/picture-22.png"><img class="size-full wp-image-2244" title="Модель данных для инженера-генетика" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/picture-22.png" alt="Модель данных" width="368" height="361" /></a><p class="wp-caption-text">Модель данных</p></div>
<p>Типы данных свойств объектов особого значения для примеров не имеют. Модель взята из &#8220;детского набора инженера-генетика&#8221;, который позволяет в домашних условиях выращивать <del datetime="2009-09-23T07:13:41+00:00">животных</del> нечто, с одним телом, одной головой, некоторым количеством рук и ног. Каждая часть тела имеет определенные свойства.</p>
<p>Начать стоит, как обычно, с заполнения БД. Необходимо напомнить, что Core Data - это не БД. Просто мы испольуем ее возможность сохранения данных из Core Data в БД.<br />
<span id="more-2243"></span></p>
<h2>Добавление объектов</h2>
<p>Для добавления объекта нам понадобится - контекст 1 штука. Этого должно хватить. Инженер-генетик начинает с добавления тела жертвы:</p>
<pre>
<pre name="code" class="objc">

//Простой вариант - объект сразу добавится в контекст
NSManagedObjectContext * context = [[StorageProvider sharedInstance] managedObjectContext];
// Получаем описание сущности через контекст (context -&gt; storeeCorordinator -&gt; model)
NSEntityDescription * entityDescription = [NSEntityDescription entityForName:@&quot;Body&quot; inManagedObjectContext:context];
Body * body = [[[Body alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:context] autorelease];
[body setWeight:[NSNumber numberWithInt:100]];

// Вариант создания без использования контекста
NSManagedObjectModel * model = [[StorageProvider sharedInstance] managedObjectModel];
// Получаем описание сущности через модель
entityDescription = [[model entitiesByName] objectForKey:@&quot;Body&quot;];
body = [[[Body alloc] initWithEntity:entityDescription insertIntoManagedObjectContext:nil] autorelease];
[body setWeight:[NSNumber numberWithInt:200]];

//Положим объект в контекст позже
[context insertObject:body];

// Сохраняем контекст с двумя телами
NSError * error;
if (![context save:&amp;error]) {
   NSLog(@&quot;Ошибка при сохранении в Базу : %@&quot;, [error userInfo]);
}
</pre>
</pre>
<p>Класс <em>StorageProvider</em> в примере - это мой класс-синглтон, в котором хранятся модель, контекст  и многое другое.</p>
<p>Теперь надо прояснить ситуацию - откуда взялся <em>NSEntityDescription</em>? Объекты класса <em>NSEntityDescription</em> описывают ссвойства и связи сущности в модели (Entity). Так, на каждую сущность в модели есть свое описание. Это описание можно получить двумя способами (технически одним, конечно). В примере показаны оба способа - получение описания через контекст + имя сущности, и получение описания через модель + имя сущности. На самом деле оба способа работают одинаково - просто первый вариант получает по контексту persistenceStoreCoordinator, из него получает модель, а уже из модели по имени описание.</p>
<p>Здесь надо отметить две вещи - имя сущности  может не совпадать с именем класса, и использование строковых констант не самый лучший выбор. Для устранения обоих недостатков можно, например, каждому классу сущности определить метод, который возвращает имя сущности в модели:</p>
<p>&nbsp;</p>
<pre>
<pre name="code" class="objc">

// Body.m
...
+(NSString *) entityName {
   return @&quot;SomeBody&quot;;
}
...
</pre>
</pre>
<h2>Проблемы с добавлением?</h2>
<p><a href="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/add-problems.png"><img class="size-full wp-image-2271 alignright" style="border: 2px solid gray;" title="add-problems" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/add-problems.png" alt="add-problems" width="103" height="169" /></a><br />
Хорошо, когда все хорошо добавляется. А что делать, если все &#8220;плохо добавилось&#8221; или не добавилось совсем ? Где искать виновных? На примере видно, что если сохранение не пройдет, то в результате в <em>[NSError userInfo]</em> будет код ошибки. Так-то оно так, но &#8220;вменяемым&#8221; оно будет в том случае, если ошибку вызовет один объект. Если ошибку вызвали одновременно несколько объектов, то необходимы небольшие танцы с бубном, чтобы вытащить описание ошибки. Вот так выглядит [NSError userInfo], если &#8220;руки(<em>arms</em>) сделать обязательным параметром для тела(<em>body</em>)&#8221; :</p>
<pre>
<pre name="code" class="objc">

NSDetailedErrors =     (
  Error Domain=NSCocoaErrorDomain Code=1580 UserInfo=0xf2e6c0 &quot;Operation could not be completed. (Cocoa error 1580.)&quot;,
  Error Domain=NSCocoaErrorDomain Code=1580 UserInfo=0xf2e9e0 &quot;Operation could not be completed. (Cocoa error 1580.)&quot;
);
</pre>
</pre>
<p>Я бы не стал рисковать сообщать инженеру-генетику о том, что он не может создать животных только потому, что возникли две ошибки 1580. Можно, конечно, подсмотреть в <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/CoreDataFramework/Miscellaneous/CoreData_Constants/Reference/reference.html#//apple_ref/doc/c_ref/NSDetailedErrorsKey">документации</a>, и узнать, что произошла ошибка при валидации, но этого мало. Важно знать, какие объекты вызвали ошибку.</p>
<p>Делается это достаточно просто. Из той же <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Reference/CoreDataFramework/Miscellaneous/CoreData_Constants/Reference/reference.html#//apple_ref/doc/c_ref/NSDetailedErrorsKey">документации </a> узнаем, что по ключу  <em>NSDetailedErrorsKey</em> в [error userInfo], в случае многочисленных ошибок, будет лежать массив с этими ошибками. Немного переписав код обработки ошибки при сохранении, получим следующее:</p>
<pre>
<pre name="code" class="objc">

NSError * error;
if (![context save:&amp;error]) {
   NSDictionary * dict  = [error userInfo];
   NSArray * detailedErrors = [dict objectForKey:NSDetailedErrorsKey];
   if (detailedErrors) {
      NSLog(@&quot;Все хорошо, но контекст не сохранен потому что : &quot;);
      for (NSError * detailedError in detailedErrors) {
         NSLog(@&quot;Есть ошибка : %@&quot;, [detailedError userInfo]);
      }
   } else {
     NSLog(@&quot;Ошибка при созранении в Базу : %@&quot;, [error userInfo]);
   }
}
</pre>
</pre>
<p>В результате получим причну ошибки в более &#8220;удобочитаемом&#8221; виде.</p>
<h3>Логика сохранения</h3>
<p>Если не было ошибок и все прошло удачно, то все объекты были успешно сохранены в БД. В случае, если произошла ошибка, то все объекты, которые не были сохранены в БД, будут возвращены в [NSError userInfo]. Эти объекты можно получить по ключу <em>NSValidationObjectErrorKey</em> (в случае ошибок валидации). Это значит, что в случае, если из 100 объектов добавленых в контекст, не сохранится всего один, то 99 из них успешно будут добавлены в БД, и только один будет оставаться в контексте. Этот объект можно подправить, и снова вызвать [context save:&amp;error]. И так до тех пор, пока не будут устранены все ошибки. Для нашего случая это может выглядеть следующим образом :</p>
<pre>
<pre name="code" class="objc">

// Если нам нельзя сохранить объект
NSLog(@&quot;Ошибка при созранении в Базу : %@&quot;, [error userInfo]);
Body * object = [[error userInfo] objectForKey:NSValidationObjectErrorKey];
[object setWeight:[NSNumber numberWithInt:[[object weight] intValue] + 10]];
// То создаем руку
Arm * arm = [[Arm alloc] initWithEntity:[NSEntityDescription  entityForName:@&quot;Arm&quot; inManagedObjectContext:context]
                  insertIntoManagedObjectContext:context];
[arm setLength:[NSNumber numberWithInt:5]];
// Добавляем руку к телу
[object addArmsObject:arm];

// Снова сохраняем
if (![context save:&amp;error]) {
  ...
}
</pre>
</pre>
<p>После того, как надоедает просто добавлять объекты в БД, возникает вполне логичный вопрос - а как их оттуда забирать?</p>
<h2>NSFetchRequest - формирование запросов к БД</h2>
<div id="attachment_2287" class="wp-caption alignright" style="width: 109px"><a href="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/wheres-my-data.png"><img class="size-full wp-image-2287 " title="wheres-my-data" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/wheres-my-data.png" alt="Где данные?" width="99" height="160" /></a><p class="wp-caption-text">Где данные?</p></div>
<p>В Core-Data для запросов к БД используется класс с названием <em>NSFetchRequest</em>. Этот запрос выполняется конткекстом, и, в результате его выполнения, в контексте оказывается набор объектов, готовых к дальнейшему использованию.</p>
<p>&nbsp;</p>
<p>NSFetchRequest очень &#8220;многофункциональный&#8221;. Мало того, что у него есть масса свойств и методов, которые влияют на возвращаемый результат, так у него есть еще и свойство/параметр predicate, который является аналогом SQL-запроса в БД.</p>
<p>Итак. Сразу начнем с примера - заберем из &#8220;лаборатории&#8221; все тела, вес которых превышает 150 кг:</p>
<pre>
<pre name="code" class="objc">

//Создаем запрос
NSFetchRequest * request = [[[NSFetchRequest alloc] init] autorelease];
// Указываем, какого типа будет возвращаемый результат и куда ложить результат
[request setEntity:[NSEntityDescription entityForName:@&quot;Body&quot; inManagedObjectContext:context]];
// Указываем, что вес должен быть больше 150 кг
[request setPredicate:[NSPredicate predicateWithFormat:@&quot;weight &gt; 150&quot;]];
// Получаем результат
NSArray * result = [context executeFetchRequest:request error:&amp;error];
</pre>
</pre>
<p>Если вдруг, по каким-то причинам, у вас еще старая версия iPhone SDK 3.0, то надо добавить еще сортировку результата. Да и в принципе, лучше всегда сортировать данные, которые получаете из базы - порядок их возврата не известен даже самой базе;). Остортируем возвращаемые тела по размеру головы:</p>
<pre>
<pre name="code" class="objc">

[request setSortDescriptors:
    [NSArray arrayWithObject:
      [[NSSortDescriptor alloc] initWithKey:@&quot;head.size&quot; ascending:YES]
     ]
 ];
</pre>
</pre>
<p>Формат предикатов я сейчас детально описывать не буду - для этого есть какая-никакая <a href="http://developer.apple.com/mac/library/documentation/Cocoa/Conceptual/Predicates/Articles/pSyntax.html">документация про формат предикатов</a> (ключевое слово - &#8220;никакая&#8221;). Приведу несколько примеров формирования запросов :</p>
<pre>
<pre name="code" class="objc">

// Тела с двумя руками
// В документации @count описан где-то далеко-далеко.
[request setPredicate:[NSPredicate predicateWithFormat:
    @&quot;arms.@count == 2&quot;]];

//Получаем всех безруких и безногих
// AND и &amp;&amp; работают одинаково
[request setPredicate:[NSPredicate predicateWithFormat:
    @&quot;arms.@count == 0 AND legs.@count == 0&quot;]];

// Всех безногих, но с суммарной ддлиной рук больше 20
[request setPredicate:[NSPredicate predicateWithFormat:
    @&quot;arms.@sum.length &gt; 20 AND legs.@count == 0&quot;]];

// С короткими ногами и длинными руками
[request setPredicate:[NSPredicate predicateWithFormat:
    @&quot;legs.@avg.length &lt; 5 AND arms.@avg.length &gt; 10&quot;]];
</pre>
</pre>
<p>Кстати, надо заметить что можно еще делать что-то на подобие такого:</p>
<pre>
<pre name="code" class="objc">

- (NSNumber *) averageArmLength {
  return [self valueForKeyPath:@&quot;arms.@avg.length&quot;];
}
</pre>
</pre>
<p>Однако использовать такие конструкции надо осторожно - не факт, что оно работает быстрее, чем цикл с вычислением среднего (не проверено). В общем, если что - я предупредил.</p>
<h2>Несколько советов по повышению производительности запросов</h2>
<div id="attachment_2302" class="wp-caption alignright" style="width: 158px"><a href="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/picture-25.png"><img class="size-full wp-image-2302" title="picture-25" src="http://stanfy.com.ua/blog/wp-content/uploads/2009/09/picture-25.png" alt="Ускоряемся" width="148" height="112" /></a><p class="wp-caption-text">Ускоряемся</p></div>
<h3>Использование Page&#8217;инга</h3>
<p>Стандартный прием, когда данные грузятся не все сразу, а по несколько штук. Для этого у NSFetchRequest&#8217;а есть свойства  fetchLimit и fetchOffset. FetchLimit ограничивает количество отдаваемых результатов, а fetchOffset - смещение от начала.</p>
<h3>Использование FetchedProperties</h3>
<p>Для понимания принципа ускорения с помощью этого метода, надо знать о том, что после выполнения запроса в памяти объекты результата присуствуют не полностью. Используется т.н. <a href="http://ru.wikipedia.org/wiki/%D0%9E%D1%82%D0%BB%D0%BE%D0%B6%D0%B5%D0%BD%D0%BD%D0%B0%D1%8F_%D0%B8%D0%BD%D0%B8%D1%86%D0%B8%D0%B0%D0%BB%D0%B8%D0%B7%D0%B0%D1%86%D0%B8%D1%8F_%28%D1%88%D0%B0%D0%B1%D0%BB%D0%BE%D0%BD_%D0%BF%D1%80%D0%BE%D0%B5%D0%BA%D1%82%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%B8%D1%8F%29">отложенная инициализация</a>. Если быть точнее, у этих объектов есть только id - а все остальные свойства все еще лежат в базе данных. И как только происходит попытка доступа к другим свойствам - только тогда идет запрос в БД за полной информацией об объекте.</p>
<p>То есть, если, допустим, необходимо использовать только одно свойство, но у всех объектов, то для ускорения следует включить его в fetchedProperties:</p>
<pre>
<pre name="code" class="objc">

// Вытаскиваем следующие 100, начиная с 10
[request setFetchLimit:100];
[request setFetchOffset:10];

// Если дописать эту часть, то будет НАМНОГО быстрее,
// чем если было бы без нее
[request setPropertiesToFetch:[NSArray arrayWithObject:@&quot;weight&quot;]];
// В результате (в памяти) , кроме id объектов, есть и
// свойство weight
NSArray * result = [context executeFetchRequest:request error:&amp;error];
int sum = 0;
for (Body * somebody in result) {
   sum += [[somebody weight] intValue];
}
</pre>
</pre>
<p>&nbsp;</p>
<p>В примере выполнится ровно один запрос в базу данных. Если бы свойство weight не указывалось в fetchedProperties, то количество запросов в базу было бы равно количеству объектов в результате + 1.</p>
<p>Используя fetchedProperties надо помнить и про память - чем больше свойств объектов вытягивается из базы данных - тем больше памяти используется.</p>
<p>Пора оставить инженера-генетика, и дать ему попробовать осознать и попробовать возможности Core Data, о которых он узнал.</p>
<p>Продолжение следует.</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://stanfy.com.ua/blog/2009/09/23/coredata-part2-contexts-and-requests/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>
