<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Bit Stories]]></title>
  <link href="http://vhbit.net/blog/atom.xml" rel="self"/>
  <link href="http://vhbit.net/blog/"/>
  <updated>2017-10-22T08:44:15+03:00</updated>
  <id>http://vhbit.net/blog/</id>
  <author>
    <name><![CDATA[vhbit]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[iOS Dev Digest &#35;2]]></title>
    <link href="http://vhbit.net/blog/blog/2016/06/24/ios-dev-digest-2/"/>
    <updated>2016-06-24T18:31:24+03:00</updated>
    <id>http://vhbit.net/blog/blog/2016/06/24/ios-dev-digest-2</id>
    <content type="html"><![CDATA[<ul>
  <li>
    <p><a href="https://github.com/iOS-10-Stuffs/Decrypted-Kernels?utm_source=digest2&amp;utm_medium=cpc&amp;utm_campaign=digest">Decrypted Kernels</a>
As you know, the first beta of iOS 10 came out with kernel cache being
decrypted. Initially it was considered as a leak, but Apple confirmed
that it was intentional. Time to exlore goodies!</p>
  </li>
  <li>
    <p><a href="https://github.com/cyanzhong/xTextHandler?utm_source=digest2&amp;utm_medium=cpc&amp;utm_campaign=digest">Text handler for iOS 8</a>
(source editor extension). One of the first source editor extensions
for Xcode 8 for various simple text manipulations, like URL
encoding/decoding, JSON formatting, UIColor to/from HEX. Might be a
source for inspiration.</p>
  </li>
  <li>
    <p><a href="https://realm.io/news/wwdc-2016-developer-perspective/?utm_source=digest2&amp;utm_medium=cpc&amp;utm_campaign=digest">WWDC 2016 Developer Perspective</a>
The light of WWDC star is still coming in… <a href="https://realm.io">Realm</a>
has captured a lot of “live sessions” about the most exciting parts from
a developer perspective.</p>
  </li>
  <li>
    <p><a href="https://github.com/matteocrippa/awesome-swift?utm_source=digest2&amp;utm_medium=cpc&amp;utm_campaign=digest">Awesome Swift</a> A
collaborative edited and well-organized list of awesome Swift
libraries. If you search for something something you should definitely
try it out.</p>
  </li>
  <li>
    <p><a href="https://github.com/raywenderlich/swift-algorithm-club?utm_source=digest2&amp;utm_medium=cpc&amp;utm_campaign=digest">Swift Algorithm Club</a>
Quite a lot of algorithms and data structures for refreshing your
memories and/or checking for how to use Swift for those kind of tasks.</p>
  </li>
  <li>
    <p><a href="http://artsy.github.io/blog/2016/06/19/graphql-for-mobile/?utm_source=digest2&amp;utm_medium=cpc&amp;utm_campaign=digest">GraphQL for mobile</a>
Nice review of GraphQL from mobile developer perspective if you wish
to know something before (or instead of) digging it by yourself.</p>
  </li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[WWDC'16 - First bits]]></title>
    <link href="http://vhbit.net/blog/blog/2016/06/14/wwdc16-first-bits/"/>
    <updated>2016-06-14T13:43:40+03:00</updated>
    <id>http://vhbit.net/blog/blog/2016/06/14/wwdc16-first-bits</id>
    <content type="html"><![CDATA[<p>A short digest of mostly low-level things which started to appear on
WWDC’16.</p>

<h3 id="apfs---apple-file-system">APFS - Apple File System</h3>

<p>That’s my personal favorite news.</p>

<ul>
  <li>For all spectrum of devices</li>
  <li>Optimized for SSD</li>
  <li>Encryption</li>
  <li>Copy on write, snapshots, clones</li>
  <li>Planned release - 2017</li>
  <li>Specs and docs will be available after release</li>
</ul>

<p>There is no information available on how long it has been in work and
how long it was tested.</p>

<h3 id="languages">Language(s)</h3>

<ul>
  <li>Objective-C got <code class="highlighter-rouge">__auto_type</code> declarations
(<a href="https://mobile.twitter.com/jckarter/status/742453673133903872">source</a>),
it can be used like this:</li>
</ul>

<figure class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="kt">int</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
   <span class="n">__auto_type</span> <span class="n">foo</span> <span class="o">=</span> <span class="s">@"FINALLY"</span><span class="p">;</span>
   <span class="n">NSLog</span><span class="p">(</span><span class="s">@"%@"</span><span class="p">,</span> <span class="n">foo</span><span class="p">);</span>
<span class="p">}</span></code></pre></figure>

<ul>
  <li>Objective-C got also class properties</li>
  <li>Swift in Xcode 8 will be presented in 2 flavors: 3.0 and 2.3 for
those who want to wait a bit before jumping to 3.0 train and still
want to use new SDKs.</li>
</ul>

<h3 id="tools">Tools</h3>

<ul>
  <li>new fancy documentation. <a href="https://developer.apple.com/reference">You have to check it out</a></li>
  <li>thread sanitizer</li>
  <li>address sanitizer (Swift)</li>
  <li>memory graph debugger</li>
  <li>automatic code generation for Core Data models</li>
  <li>new signing system</li>
</ul>

<p>The “fun” thing though is that all those changes (except signing
system) require migration to Swift 3.0 (if you’re using Swift, it
looks like for Obj-C there are no constraints).</p>

<h3 id="libdispatch">libdispatch</h3>

<ul>
  <li><code class="highlighter-rouge">dispatch_assert_queue</code> and similar can be quite handy. <a href="https://developer.apple.com/reference/dispatch/2009672-dispatch_functions?language=objc">See the whole family.</a></li>
  <li>assertions if there is a hang detected due to a deadlock in <code class="highlighter-rouge">dispatch_barrier_sync</code></li>
  <li><code class="highlighter-rouge">os_unfair_lock</code> (kind of <code class="highlighter-rouge">OSSpinLock</code> “compatible” with iOS)</li>
  <li><a href="https://developer.apple.com/reference/dispatch">Cleaner Swift API</a></li>
</ul>

<h3 id="performance-improvements">Performance improvements</h3>

<ul>
  <li><code class="highlighter-rouge">_NSDictionaryM</code> combines buffers for 33-50% fewer mallocs <a href="https://mobile.twitter.com/Catfish_Man/status/742527465218662400">source</a></li>
  <li><code class="highlighter-rouge">CFStringCreateCopy</code> early-outs for tagged pointers now, which makes
it 4x faster for ~40% of strings <a href="https://mobile.twitter.com/Catfish_Man/status/742546183852150784">source</a></li>
  <li><code class="highlighter-rouge">NSArray</code> and <code class="highlighter-rouge">CFArrayCreate*</code> will now return <code class="highlighter-rouge">_NSArrayI</code> and <code class="highlighter-rouge">_NSArrayM</code>
instances on iOS/watchOS/tvOS as they have for some time on macOS
<a href="https://mobile.twitter.com/Catfish_Man/status/742525973472497664">source</a></li>
  <li><code class="highlighter-rouge">CF_IS_OBJC</code> is way faster (used in bridging) <a href="https://mobile.twitter.com/Catfish_Man/status/742527048535547905">source</a></li>
  <li>plist encoding/decoding should be a bunch faster due to various
changes <a href="https://mobile.twitter.com/Catfish_Man/status/742545923142619137">source</a></li>
</ul>

<h3 id="miscellaneous">Miscellaneous</h3>

<ul>
  <li><code class="highlighter-rouge">BNNS</code> basic neural network subroutines <a href="https://developer.apple.com/reference/accelerate/1912851-bnns">more</a></li>
  <li><code class="highlighter-rouge">SFSpeechRecognizer</code> you can guess what it does</li>
  <li><a href="https://developer.apple.com/reference/os/1891852-logging">Unified Log API</a></li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iOS Dev Digest &#35;1]]></title>
    <link href="http://vhbit.net/blog/blog/2016/06/10/ios-dev-digest-1/"/>
    <updated>2016-06-10T19:17:37+03:00</updated>
    <id>http://vhbit.net/blog/blog/2016/06/10/ios-dev-digest-1</id>
    <content type="html"><![CDATA[<p>A short digest for this week:</p>

<ul>
  <li><a href="http://www.cocoawithlove.com/blog/2016/06/02/threads-and-mutexes.html">Mutexes and closure capture in Swift</a> very through overview how
absence of threading language features hits Swift performance.</li>
  <li><a href="http://chris.eidhof.nl/post/lenses-in-swift/">Lenses in Swift</a> another attempt to bring functional techniques to
Swift.</li>
  <li><a href="https://www.youtube.com/watch?v=ofjehH9f-CU">Another take on lenses in Swift (video, ~35 min)</a></li>
  <li><a href="https://realm.io/news/tryswift-daniel-eggert-modern-core-data/">Modern Core Data</a> a couple of tricks on Swift type system to improve
Core Data experience (in case you still have to use it). It’s a bit
funny to see it this talk on Realm page.</li>
  <li><a href="https://blog.obdev.at/using-swift-protocols-to-separate-socket-functionality/">Using Swift protocols to separate socket functionality</a> is an example
of how APIs can be separated to.</li>
  <li><a href="http://www.cnet.com/news/googles-ai-software-is-moving-into-your-iphone/">TensorFlow on iOS</a> sounds quite interesting for weekend hacking.</li>
  <li><a href="https://github.com/johnno1962/SwiftTrace">SwiftTrace</a> is a library for tracing method calls by class for Swift
and Objective-C.</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[iPhone syncthing client (or Rust in the wild)]]></title>
    <link href="http://vhbit.net/blog/blog/2015/05/13/rust-in-the-wild-ios-syncthing-client/"/>
    <updated>2015-05-13T21:53:46+03:00</updated>
    <id>http://vhbit.net/blog/blog/2015/05/13/rust-in-the-wild-ios-syncthing-client</id>
    <content type="html"><![CDATA[<p>It took a bit of time, but finally <code class="highlighter-rouge">fsync</code> is  available in
the <a href="https://itunes.apple.com/us/app/fsync/id964427882?ls=1&amp;mt=8">AppStore</a>.</p>

<p>From a user perspective it’s a pretty simple iPhone client for
<a href="https://syncthing.net">syncthing</a>. If you never heard about
<code class="highlighter-rouge">syncthing</code> and you ever needed a self-hosted Dropbox you should give
it a try. It’s very nice piece of software, it runs almost anywhere
(Linux, *BSDs, Windows). It’s open source and written in Go so if you
want to practice Go language - you’re welcome to
<a href="https://github.com/syncthing/syncthing">contribute</a>.</p>

<p>Right now <code class="highlighter-rouge">fsync</code> works in mostly “read-only” mode, i.e. you can view
files, you can delete them, but there is no way to edit. This is gonna
change soon.</p>

<p>From a technical perspective it’s probably one of the earliest iOS
applications, which are partially written in
<a href="https://rust-lang.org">Rust</a>.</p>

<p>There is a lot of things to talk about and I hope to provide more
technical details in the following posts, while this one covers using
Rust as a language for mobile development from my experience.</p>

<!-- more -->

<h2 id="how-it-started">How it started</h2>

<p>Being active <code class="highlighter-rouge">syncthing</code> user I was missing opportunity to access my
files from mobile and decided to write an iOS application.</p>

<p>Initially I’ve started writing core code in C, got a first working
prototype and understood that I’m spending too much time dealing with
managing memory, ownership and so on. I’ve checked available options:</p>

<ul>
  <li>C++</li>
  <li>Rust</li>
  <li>Swift</li>
  <li>Objective-C</li>
</ul>

<p>C++ was dropped immediately - I haven’t written in it since
university, it changed a lot… and I wouldn’t like to invest my time
into it, even if gives more advantages in short-term.</p>

<p>While technically it was possible to use Objective-C, it’s not good
enough for low level stuff and there is a lot of low-level stuff in
<code class="highlighter-rouge">syncthing</code> client.</p>

<p>Swift looked very promising, but it was so immature that even
Apple “fanboys” were against choosing it for any serious code.</p>

<p>The problem I saw was that although there is an official Android
client, it’s basically re-packaged <code class="highlighter-rouge">syncthing</code>. Which means it wasn’t
written with mobile in mind, where being memory/traffic/battery
friendly is crucial.</p>

<p>You get were I was heading - I’d be happy to have a cross-platform
code written for mobile. And the only option in this case was Rust.</p>

<h2 id="maturity">Maturity</h2>

<p>There were moments when I hated Rust - it was a hell of a ride to the
API stability. Initially it didn’t feel like a big deal (“ohh, that’s
just a couple of changes here and there”). But… Little strokes fell
great oaks and a couple of times I was on the edge, considering to
rewrite it again in C (or C++ - yep, it’s a huge monster, but it’s
also a <em>well known + stable</em> monster).</p>

<p>One of the hidden problems caused by instability was a desire to keep
breaking surface as small as possible. Practically it meant ignoring
existing libraries and re-inventing half-baked versions just to have a
control on when and how to update it.</p>

<p>It was a dark time and I’m glad it’s finally over.</p>

<p>While language and std lib are stable now, there is still a huge
necessity in a better documentation. A lot of changes have happened with
no announcements and no discussions so if you were always on GitHub,
monitoring issues everyday - you’re probably fine. But if you weren’t
because you had to write your own code - I bet a lot of that code is
already “rusty” and cries for modernization.</p>

<h2 id="what-was-bad">What was bad</h2>

<p>At some point I was very disappointed, but I have to admit it was
caused mostly by wrong expectations and naive estimations.</p>

<ol>
  <li>I didn’t expect it’ll take so long to stabilize.</li>
  <li>Rust can give you exceptionally granular control of memory
allocations, but it’s a <em>manual</em> control. You’ll pay with a longer
development cycle, you’ll pay wit much more complex code and less
flexibility.</li>
  <li>Rust is slow to compile and that discourages a lot, especially if
you’ve got a minute to hack on an old laptop and… Boom… Half of
the time is wasted in wait for compiler. More than a minute for
building ~7K LOC? Yeah, I know it’s an <em>old</em> laptop, but that’s
hardly an excuse, considering Clang can handle much bigger codebase
faster.</li>
  <li>Code-management tooling (navigation/refactoring) is immature. This
should improve over time with language stability, but I can’t
imagine how long it will take to get something like AppCode/CLion.</li>
</ol>

<p>As you can see only last 2 reasons are related to the language itself
and I hope that at least compilation time will be addressed in
upcoming 1.1 or 1.2.</p>

<h2 id="what-was-good">What was good</h2>

<p>Before Rust I’ve been developing in higher level languages for quite a
long time. As a result, there were a lot of things I didn’t even
consider - they were hidden, the choice was already made for me. The
first impression after using Rust was “ohh, there are so many things I
have to decide on my own now!”.</p>

<p>For me personally it was a refreshing experience and also a reminder
that there is no way to get performance if you don’t keep it as a
primary goal all the time.</p>

<p>Probably more than the language itself I liked the direction it takes
in encouraging good engineering practices - you get built-in
<a href="http://doc.rust-lang.org/book/testing.html">testing/benchmarking support</a>
and a pretty decent
<a href="http://doc.rust-lang.org/book/documentation.html">documentation generator</a>. Want
to go further? Mix them - and you’ll get a bullet-proof documentation,
which will fail your tests if you’ve forgot to update it after an API
change.</p>

<p>And yet there is also <a href="http://doc.crates.io/guide.html">Cargo</a> for
getting repeatable builds out of various dependencies. Std lib was
significantly reduced on the way to 1.0 due to <code class="highlighter-rouge">cargo</code>. What was not
necessary or was controversial was extracted out of tree to a separate
crate<sup id="fnref:9"><a href="#fn:9" class="footnote">1</a></sup>.</p>

<p>That gut feeling of rock-solid foundation becomes even stronger after
familiarizing with Rust’s development process. In short - there is a
bot, which runs tests on approved pull requests and merges into
<code class="highlighter-rouge">master</code> only on success. Sometimes it’s annoying, sometimes it’s
slow, but you’re sure that at any point of time nothing is broken<sup id="fnref:8"><a href="#fn:8" class="footnote">2</a></sup>.</p>

<h2 id="ios-development">iOS development</h2>

<p>One of the most interesting questions is if there is a place for Rust
in iOS development.</p>

<p>In most cases if you’re developing for iOS/OS X - you’d better use
Objective-C and/or Swift. They provide much better integration with
native frameworks and higher level to work on.</p>

<p>Still, Rust <em>can</em> shine when:</p>

<ul>
  <li>you need a cross-platform code</li>
  <li>you target to have a very low footprint</li>
  <li>you can either isolate code enough or provide automatic bindings
to/from “native” code</li>
</ul>

<p>I’d say that the last one is the real bottleneck.</p>

<p>A lot of iOS/OS X frameworks have a pure C interface<sup id="fnref:1"><a href="#fn:1" class="footnote">3</a></sup>, <sup id="fnref:2"><a href="#fn:2" class="footnote">4</a></sup> and
therefore can be used from Rust directly<sup id="fnref:3"><a href="#fn:3" class="footnote">5</a></sup>. In general it’s easy
enough to access Objective C objects either<sup id="fnref:4"><a href="#fn:4" class="footnote">6</a></sup>, but it’s hard to
exploit that without loosing portability. So… you can’t move things
down to Rust<sup id="fnref:5"><a href="#fn:5" class="footnote">7</a></sup> - you have to provide smoother interaction between “core”
and “UI” by other means.</p>

<p>When Dropbox started cross-platform C++ development, they had the same
problem and they solved it<sup id="fnref:6"><a href="#fn:6" class="footnote">8</a></sup> in
<a href="https://github.com/dropbox/djinni">Djinni</a> - an automatic
binding/proxy generator which bridges native code with cross-platform
code. If someone writes a generator for Rust - it can make a huge
difference<sup id="fnref:7"><a href="#fn:7" class="footnote">9</a></sup>.</p>

<p>Another way to workaround this problem is to have a pretty isolated
Rust core, which acts as a server and can be accessed through a
well-known protocol. It means there will be additional costs,
definitely higher than automatic data marshaling performed by
<code class="highlighter-rouge">Djinni</code>. Whether it is acceptable or not depends a lot of data flow
in the application.</p>

<p>As a conclusion - unfortunately for mobile cross-platform development
Rust is pretty limited nowadays and works good only for specific use
cases. A bright side though is that it’s a limitation which can be
addressed by tools.</p>

<div class="footnotes">
  <ol>
    <li id="fn:9">
      <p>crate is a synonym for a package <a href="#fnref:9" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:8">
      <p>unless you’re out of luck and provide by yourself support for a platform which hasn’t official buildbot. <a href="#fnref:8" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:1">
      <p><code class="highlighter-rouge">CFFoundation</code> for example provides access to all native data structures. <a href="#fnref:1" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:2">
      <p>Steven Sheldon got into <a href="https://github.com/SSheldon/rust-dispatch">GCD</a> and you can even provide <a href="https://github.com/SSheldon/rust-block">Rust blocks</a> to Objective-C code. <a href="#fnref:2" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:3">
      <p>unsafe wrappers can be generated by <a href="https://github.com/crabtw/rust-bindgen">bindgen</a>, it takes a bit more time to get safe wrappers though. <a href="#fnref:3" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:4">
      <p>see examples in <a href="https://github.com/SSheldon/rust-objc">rust-objc</a>, <a href="https://github.com/SSheldon/rust-objc-foundation">rust-objc-foundation</a> from Steven Sheldon and <a href="https://github.com/servo/rust-cocoa">rust-cocoa</a> from Servo. <a href="#fnref:4" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:5">
      <p>with the only exception for platform-accelerated APIs. <a href="#fnref:5" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:6">
      <p><a href="https://bit.ly/djinnitalk">slides from the talk</a> with more details about goals and motivations. <a href="#fnref:6" class="reversefootnote">&#8617;</a></p>
    </li>
    <li id="fn:7">
      <p>there is a chance that Dropbox writes generator for Rust as they <a href="http://www.reddit.com/r/rust/comments/2xvtll/getting_acquainted_with_mio/cp5tfa4">use it internally</a>, although I doubt it. <a href="#fnref:7" class="reversefootnote">&#8617;</a></p>
    </li>
  </ol>
</div>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Write Only: Setup]]></title>
    <link href="http://vhbit.net/blog/blog/2015/05/01/write-only-setup/"/>
    <updated>2015-05-01T14:21:51+03:00</updated>
    <id>http://vhbit.net/blog/blog/2015/05/01/write-only-setup</id>
    <content type="html"><![CDATA[<p>In earlier <a href="http://vhbit.net/blog/blog/2015/04/21/write-only-mode/">post</a> I’ve written about
switching to write-only mode inspired by
<a href="http://begriffs.com/posts/2015-04-20-going-write-only.html">Joe Nelson</a>. This
time I’ll provide a bit more details on why and how.</p>

<!-- more -->

<h2 id="considerations">Considerations</h2>

<p>As I’ve already mentioned, for me “write-only” mode is not about
avoiding ephemeral things (is there anything “real”?) or being
disconnected - it’s all about being proactive instead of reactive,
this is the only way to concentrate on producing things.</p>

<p>It definitely requires a special environment and I’d say that the most
important things are organizing space and time.</p>

<p>By time I literally mean time - it’s impossible to create something
you’re proud of without iterating, prototyping, throwing bad attempts,
taking time to recover and continue looping.</p>

<p>By organizing space I mean a bit more complex concept. The act of
creation is always a path from entropy to a structure, from chaotic
bits to organized bits. As your knowledge is what allows you to
create, it’s kind of obvious that you should concentrate on converting
information to knowledge.</p>

<p>What’s the difference between the two? Connections! It’s all about
connections - they form the structure, they form the way you think,
what you can think and what you can’t think of.</p>

<p>The thing with connections is that you can see them much easier in
“big forms” - no matter what we’re talking about - be it music, be it
an idea, be it a life story or anything else.</p>

<p>Tell me how you spent yesterday - I’ll know a couple of facts about
you. Tell me about your whole life - I’ll find patterns, I’ll make my
conclusions about people in general and your character in particular.</p>

<p>Imho, the most wrong thing about social media and news is that being
“small forms”, they just overload you with disconnected bits of
information. You can’t use it, but it still occupies (or rather
pollutes) your mental space. The space you could use for creating.</p>

<p>That brings an interesting hypothesis: the form of information you
consume is much more important than how old and “time-proven” it is (I
feel it’s “weird” English, let me know if you have an idea how to
reformulate it). You know, it’s always a big surprise what exactly is
the last drop for an “Eureka!” moment, but it always is about filling
a “last connection” in already highly organized “model”.</p>

<p>One of the reasons why “big forms” are usually much useful is that
they require a stronger structure. It means author has to work much
harder in both discovering connections and in explaining them to the
“reader”.</p>

<p>The simplest lesson I can take from this observation is that “more you
write - better you understand”.</p>

<p>This works for other communication channels too - I bet every
developer knows how effective
<a href="https://en.wikipedia.org/wiki/Rubber_duck_debugging">rubber duck debugging</a>
is. What makes writing so special is that there are no time limits and
that helps a lot.</p>

<h2 id="practical-setup">Practical setup</h2>

<p>Considering all above, I’ve formulated the following thesises:</p>

<ul>
  <li>big forms should have preference over small forms (both for
consumption and for production)</li>
  <li>big forms require huge time chunks</li>
  <li>communication shouldn’t be blindly cut - it’s all about sharing
experience, it should be reshaped if required</li>
  <li>time spent writing down thoughts should be increased</li>
  <li>thoughts should be shared publicly and being non-native English
speaker is not an excuse</li>
  <li>there should be no isolation from new information</li>
  <li>new information should be dosed more than “time-proven”</li>
  <li>it’s preferable to have new pieces close to the current expertise -
it’s much easier to evaluate them and turn into something useful
today</li>
</ul>

<p>After a bit of tinkering, here is a part of my current setup:</p>

<ul>
  <li>turned off notification sounds/vibration on the phone, they split
time into smaller chunks and destroy concentration on big forms</li>
  <li>never take phone to the bed - smartphone creates a temptation to
start another round of Hacker News/Reddit/Twitter. It allows to
sleep earlier and wake up disconnected</li>
  <li>no news until midday</li>
  <li>news and browsing are actually about quick skimming to understand if
it deserves to be marked</li>
  <li>marked pieces are queued (in my case to Instapaper)</li>
  <li>I have a time limit to spend on queue =&gt; it’s another filter to pick
important things, letting noise to be drown</li>
  <li>no automatic mail retrieval - email is handled in batches every
couple of hours</li>
  <li>earlier I gathered email from different accounts into one. I’m
reverting it back to have a separate accounts for different
tasks. This + manual mail retrieval allows to avoid temptation on
answering personal email during work time and vice versa - I
literally can see only emails of “current working context”</li>
  <li>I’m also experimenting with GTD-approach to email like in Google
Inbox and similar products</li>
  <li>no more short inline comments</li>
  <li>if I want to suggest something - I have to write a spec, instead of
throwing out raw idea</li>
  <li>I have to ressurect my blog, it was actually never active but only
because I’ve always thought there was nothing I could share.</li>
</ul>

<p>The only missing solution so far is IM, to be precise Slack-based work
communication. In most cases my response time raised significantly (up
to 25 minutes for a reply), but so far that works fine.</p>

<h2 id="preliminary-results">Preliminary results</h2>

<p>I’m practicing this setup a bit less than 2 weeks and so far I have
the following observations:</p>

<ul>
  <li>it’s really hard to get off the news hook - sometimes it feels like
I’m blinded</li>
  <li>on the bright side I’m much more connected to everything I work on</li>
  <li>I’m more interested in long-term results</li>
  <li>there are no temptations in trying one more new shiny thing - I don’t know
about them :-)</li>
</ul>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Write Only Mode]]></title>
    <link href="http://vhbit.net/blog/blog/2015/04/21/write-only-mode/"/>
    <updated>2015-04-21T10:54:33+03:00</updated>
    <id>http://vhbit.net/blog/blog/2015/04/21/write-only-mode</id>
    <content type="html"><![CDATA[<p>By accident I’ve read today about Joe Nelson’s
<a href="http://begriffs.com/posts/2015-04-20-going-write-only.html">life experiment</a>.</p>

<p>It’s a really inspirational post for me as it resonates a lot with
what I’ve though about recently. I can argue a lot of minor details
(because “but the great man is he who in the midst of the crowd keeps
with perfect sweetness the independence of solitude”), but I can’t
agree more with general direction the author takes.</p>

<p>I believe that one of the most limiting factors for current
civilization is a culture of consumption. We have too much to consume
and our uncontrolled consumption as a result “consumes” our time and
available resources, leaving no opportunity to produce and create
something.</p>

<p>It’s especially true for developers as we’re overhelmed by available
technologies/frameworks/libraries/languages and are interested in
trying “one more” shiny, just released thing, which is awesome and
just got to HN. I’ve personally done that mistake dosens of times and
I’m gonna tell about the recent one in the following posts.</p>

<p>To clarify: it’s not about sticking forever with old tools. It’s about
clearing as much space/time as possible for generating new
things/thoughts/ideas/products.</p>

<p>I’m not sure I’m ready to formulate it more clearly now, so I’ll
start a REPL with my own experiment - instead of limiting myself, I’m
going to make sure that I’m in “write only mode”.</p>

<p>What’s the write only mode? It’s the mode where I produce at least as
much accessible output as I consume in my expertise areas. Preferably
it should be a publicly available output.</p>

<p>The idea here is that it’s actuallly impossible to stop consumption by
itself - it’s a dead end, especially in non-expertise areas. But what
really makes a difference is what comes out of consumption - my only
joy or something others can also use.</p>

<p><a href="http://vhbit.net/blog/blog/2015/05/01/write-only-setup/">Continuation: considerations and setup</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rust for iOS: Status Update]]></title>
    <link href="http://vhbit.net/blog/blog/2015/01/18/rust-for-ios-status-update/"/>
    <updated>2015-01-18T09:03:10+02:00</updated>
    <id>http://vhbit.net/blog/blog/2015/01/18/rust-for-ios-status-update</id>
    <content type="html"><![CDATA[<p>It’s been a while since last status update, but I hope it was worth
waiting. Rust is now completely ported to iOS: all architectures for
device/simulator are supported. Since green threads were removed,
adding support of arm64 was actually almost straightforward. Special
thanks this time goes to <a href="http://glozer.net">Will Glozer</a> who was
debugging remotely. Fortunately for our sanity, there were just a
couple of minor issues.</p>

<p>Although all changes have been landed to <code class="highlighter-rouge">master</code>, cross-compiled
libraries aren’t distributed with nightly, so in case you’re
interested in trying it out, you can either build it from source
(<a href="https://github.com/rust-lang/rust/wiki/Doc-building-for-ios">instructions</a>)
or use a pre-built <a href="https://github.com/vhbit/rust/releases/tag/ios-latest">dist</a>.</p>

<p>As earlier, the main usage sample is located
<a href="https://github.com/vhbit/ObjCrust">here</a>. It still uses makefile
based approach and I hope to update for <code class="highlighter-rouge">cargo</code> a little bit later.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rust Docsets for Dash]]></title>
    <link href="http://vhbit.net/blog/blog/2014/07/04/rust-docsets-for-dash/"/>
    <updated>2014-07-04T16:58:59+03:00</updated>
    <id>http://vhbit.net/blog/blog/2014/07/04/rust-docsets-for-dash</id>
    <content type="html"><![CDATA[<p>Since I’m tracking <a href="http://rust-lang.org">Rust</a> nightly and
documentation from the last release was quite outdated, I’ve wrote a
quite simple (at least I think so) docset generator for
<a href="http://kapeli.com/dash">Dash</a> (wonderful piece of software).</p>

<p>Here is the link to <a href="http://vhbit.net/rust-feed">feed</a> which is
updated once new nightly released.</p>

<p>Once it was complete, I’ve understood that I’d like to see docs for my
libraries in Dash as well and here is what I’ve got:
<a href="http://github.com/vhbit/rust-docset">rust-docset</a> - it is a Python
script which allows to generate Dash docsets and feed from any Rust
docs.</p>

<p>It requires a pretty simple <a href="https://github.com/toml-lang/toml">TOML</a>
manifest to be available, like this one:</p>

<figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[docset]</span>
<span class="py">name</span> <span class="p">=</span> <span class="s">"Piston"</span>
<span class="py">bundle_id</span> <span class="p">=</span> <span class="s">"piston"</span>
<span class="py">version</span> <span class="p">=</span> <span class="s">"0.0.1"</span>
<span class="py">type</span> <span class="p">=</span> <span class="s">"docset.rust"</span>
<span class="py">doc_dir</span> <span class="p">=</span> <span class="s">"../doc"</span>
<span class="py">out_dir</span> <span class="p">=</span> <span class="s">"doc_out"</span>

<span class="nn">[feed]</span>
<span class="py">base_url</span> <span class="p">=</span> <span class="s">"http://s3-us-west-2.amazonaws.com/net.vhbit.rust-doc"</span>
<span class="py">upload_cmd</span> <span class="p">=</span> <span class="s">"./upload.sh"</span></code></pre></figure>

<p>and <code class="highlighter-rouge">upload.sh</code> might look like this:</p>

<figure class="highlight"><pre><code class="language-sh" data-lang="sh"><span class="c">#!/bin/sh</span>

s3cmd put <span class="nt">-P</span> <span class="nv">$1</span> s3://net.vhbit.rust-doc
s3cmd put <span class="nt">-P</span> <span class="nv">$2</span> s3://net.vhbit.rust-doc</code></pre></figure>

<p>While it started as Rust only project, I believe it could be
relatively easily programmed to work with documentation generated by
other tools.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rust for iOS: Merged into master]]></title>
    <link href="http://vhbit.net/blog/blog/2014/06/23/rust-for-ios-state/"/>
    <updated>2014-06-23T18:23:00+03:00</updated>
    <id>http://vhbit.net/blog/blog/2014/06/23/rust-for-ios-state</id>
    <content type="html"><![CDATA[<h2 id="current-state">Current state</h2>

<p>About a week ago it was finally merged into Rust master branch which
is really great as it is much easier to work on smaller changes now.</p>

<p>Here are
<a href="https://github.com/rust-lang/rust/wiki/Doc-building-for-ios">instructions</a>
on how to build it. So far there is no official iOS buildbot and
therefore it might broke at any moment, in this case I recommend to
use a <a href="https://github.com/vhbit/rust/tree/ios">original fork</a> which
could be considered a “stable” branch, tested to compile and work both
on device and simulator. It might lag a bit from the master but not
that much.</p>

<p>There is still one issue in LLVM which sometimes crashes compilation
process. Patch was submitted but considering previous experience I
wouldn’t expect it to be landed in less than a month.</p>

<p>I’ve started work on Arm64 port but it definitely will take much more
time considering I have no test device.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rust for iOS: progress report]]></title>
    <link href="http://vhbit.net/blog/blog/2014/04/22/rust-for-ios-progress-report/"/>
    <updated>2014-04-22T09:45:00+03:00</updated>
    <id>http://vhbit.net/blog/blog/2014/04/22/rust-for-ios-progress-report</id>
    <content type="html"><![CDATA[<p>Although there is no public indication, work on porting Rust to iOS
continues, moreover it is going to the final stage. So far I’ve got
all required pieces working:</p>

<ul>
  <li>fixed issue with mutexes crashing libgreen/rustuv runtime</li>
  <li>got a working patch for LLVM to support segmented stacks</li>
  <li>got working unwinding (another patch to LLVM compiler-rt)</li>
</ul>

<p>In general, all major features are working now, providing first-class
support of all Rust safety. There definitely might be small hiccups
here and there but I believe they could be solved step-by-step, once
the major part will be upstreamed to Rust master branch.</p>

<p>I need some time to clean up the code (as it has a lot of
experimenting branches) and once patches to LLVM and compiler-rt
landed - the last step will be rebase on current master and issue an
PR.</p>

<p>I hope it will be finished this week.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Rust on iOS]]></title>
    <link href="http://vhbit.net/blog/blog/2014/04/12/rust-on-ios/"/>
    <updated>2014-04-12T20:23:00+03:00</updated>
    <id>http://vhbit.net/blog/blog/2014/04/12/rust-on-ios</id>
    <content type="html"><![CDATA[<h2 id="porting-process">Porting process</h2>

<p>Finally got working Rust cross-compiler for iOS so now it is possible
to create static libraries which could be used from Objective C. For
now only armv7 architecture is supported (although there are upcoming
commits in “try” branch which will update LLVM version with ARM64
support right from Apple).</p>

<p>These were main pain points:</p>

<ul>
  <li>
    <p>Slow full rebuild… Yep, I know, I know, 3 stage bootstrapping to
be extremely optimized but still… it was especially painful on
initial stage while experimenting with built options and LLVM
patching.</p>
  </li>
  <li>
    <p>TLS isn’t supported on armv7 so it should be emulated. Initially
I’ve started adding it to LLVM and with help from Tim Northover and
Dan Olson even got it working. (BTW, Dan knows a lot about this
topic as he got a working D compiler for iOS, so if you’re
interested in modern compiled language for iOS - you can try it
too). Just to discover that actually Rust has built-in TLS
“emulation” support (actually using the same technique as in LLVM
patches)… Grr, hate myself for not checking this before messing
with LLVM.</p>
  </li>
  <li>
    <p>There were absolutely crazy crashes hard to debug because some kind
linker errors/misconfiguration when functions were resolved correctly
but all the data was relocated incorrectly and contained garbage.</p>
  </li>
  <li>
    <p>There were mystical crashes in hash function which automagically
disappeared once I’ve <em>increased</em> optimization level.</p>
  </li>
  <li>
    <p>The final show-stopper was happening in runtime finalization
routine - it always crashed on misaligned data during mutex
locking. The reason was that mutex opaque data was copied as a plain
data. It wasn’t the case on desktop OSes but seemed to be a big
difference on iOS. There is a simple fix for native runtime and
should be similar fix for green/rustuv.</p>
  </li>
</ul>

<h2 id="what-works">What works</h2>

<ul>
  <li>
    <p>armv7 only (ARM64 port should be quite easy to introduce)</p>
  </li>
  <li>
    <p>it is possible to compile standard libraries and use them</p>
  </li>
  <li>
    <p>“native”-based runtime</p>
  </li>
  <li>
    <p>creating static libraries which could be used from iOS applications</p>
  </li>
</ul>

<h2 id="known-issues">Known issues</h2>

<ul>
  <li>
    <p>green/rustuv runtime crashes because of incorrect mutex
implementation</p>
  </li>
  <li>
    <p>segmented stacks aren’t working</p>
  </li>
  <li>
    <p>it might require additional manual linking</p>
  </li>
  <li>
    <p>no support for simulator yet</p>
  </li>
  <li>
    <p>it only works on common compiler flags. It is critical to have
exactly –opt-level 2 (or -O) as both decreasing and increasing opt
level may cause a lot of unexplainable issues</p>
  </li>
</ul>

<h2 id="shut-up-and-take-my-money-build-instructions"><del>Shut up and take my money</del> Build instructions</h2>

<p>clone and create build dir</p>

<figure class="highlight"><pre><code class="language-sh" data-lang="sh">git clone git@github.com/vhbit/rust.git
<span class="nb">cd </span>rust
git checkout ios
mkdir build_ios
<span class="nb">cd </span>build_ios</code></pre></figure>

<p>configure</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">../configure <span class="nt">--target</span><span class="o">=</span>arm-apple-ios</code></pre></figure>

<p>build</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">make</code></pre></figure>

<p>or (for 4 core CPU)</p>

<figure class="highlight"><pre><code class="language-bash" data-lang="bash">make <span class="nt">-j4</span></code></pre></figure>

<p>There is <a href="https://github.com/vhbit/ObjCrust">a sample project</a> with instructions on how to integrate.</p>

<h2 id="thanks">Thanks</h2>

<p>Special thanks to Tim Northover (ARM TLS), Dan Olson (ARM TLS), Alex Crichton (Rust internals) and my wife
for being patient.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Joe Armstrong об ООП, concurrency]]></title>
    <link href="http://vhbit.net/blog/blog/2013/02/24/joe-armstrong-ob-oop-concurrency/"/>
    <updated>2013-02-24T12:06:00+02:00</updated>
    <id>http://vhbit.net/blog/blog/2013/02/24/joe-armstrong-ob-oop-concurrency</id>
    <content type="html"><![CDATA[<p>Две части замечательной беседы с Джо Армстронгом (создателем erlang’а) об 
объектно-ориентированном программировании и почему оно скоро упрется и 
вынуждено будет смещаться в сторону функционального.</p>

<p>Один из интересных тезисов - это то, что сейчас нас начинает
поджимать железо, если раньше мощности росли в количестве гигагерц, то сейчас
все идет за счет увеличения числа ядер. А это провоцирует на переход к
concurrent-based программированию (есть, кстати, нормальный русский термин для этого?), 
где императивщина в чистом виде начинает загибаться из-за
возрастающей сложности разнообразных локов и защит.</p>

<p>Материал 2007 года и этим вдвойне интересней, т.к. тренды, о которых 
говорит Джо, из гипотетических становятся все более и более ощутимыми.</p>

<iframe style="height:288px;width:512px" src="http://channel9.msdn.com/Blogs/Charles/JAOO-2007-Joe-Armstrong-On-Erlang-OO-Concurrency-Shared-State-and-the-Future-Part-1/player?w=512&amp;h=288" frameborder="0" scrolling="no"></iframe>

<iframe style="height:288px;width:512px" src="http://channel9.msdn.com/Blogs/Charles/JAOO-2007-Joe-Armstrong-On-Erlang-OO-Concurrency-Shared-State-and-the-Future-Part-2/player?w=512&amp;h=288" frameborder="0" scrolling="no"></iframe>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Переопределяем метод класса в рантайме]]></title>
    <link href="http://vhbit.net/blog/blog/2013/02/21/replace-class-method-in-runtime/"/>
    <updated>2013-02-21T22:09:00+02:00</updated>
    <id>http://vhbit.net/blog/blog/2013/02/21/replace-class-method-in-runtime</id>
    <content type="html"><![CDATA[<p>В кои-то веки потребовалось в рантайме переопределять методы класса. В
 документации сразу нашлась подходящая функция:</p>

<figure class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="n">BOOL</span> <span class="n">class_addMethod</span><span class="p">(</span><span class="n">Class</span> <span class="n">cls</span><span class="p">,</span> <span class="n">SEL</span> <span class="n">name</span><span class="p">,</span> <span class="n">IMP</span> <span class="n">imp</span><span class="p">,</span> <span class="k">const</span> <span class="kt">char</span> <span class="o">*</span><span class="n">types</span><span class="p">)</span></code></pre></figure>

<p>единственный аргумент, который может смутить - это types, который
 задает типы аргументов и возвращаемого значения в закодированном
 текстовом виде. Нужные значения можно посмотреть либо в документации,
 либо исппользовать <code class="highlighter-rouge">@encode</code>.</p>

<p>Вторая тонкость оказалась в том, что эта функция добавляет (или
 переопределяет) метод экземпляра, а что же делать если нужно заменить
 метод самого класса?</p>

<p>Правильно, получить метакласс с помощью <code class="highlighter-rouge">object_getClass(ourClass)</code> и
 заменить его метод как обычно :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Замена цветов с помощью CIColorCube]]></title>
    <link href="http://vhbit.net/blog/blog/2012/07/07/colorcube-color-replacement/"/>
    <updated>2012-07-07T00:03:43+03:00</updated>
    <id>http://vhbit.net/blog/blog/2012/07/07/colorcube-color-replacement</id>
    <content type="html"><![CDATA[<p>Несмотря на то, что фильтр достаточно простой и эффективный, найти примеры кода с его
 использованием удалось чисто случайно уже после того, как все заработало :-)</p>

<p>Куб предназначен для замены множества цветов. R, G, B компоненты исходного цвета являются
трехмерными координатами нового цвета, который задается в виде 4 float’ов (RGBA).</p>

<p>В приведенном примере происходит хитрая замена цвета со всеми оттенками. Для удобства
используется работа с цветом в формате HSV, т.к. в этом случае гораздо легче выцеплять
 схожие цвета - они будут попадать в сектор.</p>

<!-- more -->

<p><strong>Представление цвета в HSV:</strong></p>

<p><img src="http://upload.wikimedia.org/wikipedia/commons/thumb/0/0d/HSV_color_solid_cylinder_alpha_lowgamma.png/197px-HSV_color_solid_cylinder_alpha_lowgamma.png" alt="" />
<img src="http://upload.wikimedia.org/wikipedia/commons/thumb/3/33/Hsv-hexagons-to-circles.svg/400px-Hsv-hexagons-to-circles.svg.png" alt="" /></p>

<p><a href="http://ru.wikipedia.org/wiki/HSV_%28%D1%86%D0%B2%D0%B5%D1%82%D0%BE%D0%B2%D0%B0%D1%8F_%D0%BC%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C%29">Подробней в википедии.</a></p>

<p>Итак, на формочке есть 2 слайдера, с помощью которых меняется диапазон заменяемых оттенков.
Для удобства считается, что основной цвет для замены находится посередине этого диапазона
и именно он меняется на зеленый.</p>

<p>Для этого пробегаем по всем цветам, смотрим попадает ли HSV аналог этого цвета в нужный
сектор и если да - запоминаем его смещение относительно центрального. После этого конструируем
новый HSV цвет с таким же смещением относительно зеленого и конвертируем обратно в RGB.
Подобный код можно было бы использовать, например, для вырезания фона определенного цвета (chroma key).
 В этом случае все цвета в нужном секторе меняют прозрачность (alpha) на 0.0</p>

<p><strong>Пример заполнения куба:</strong></p>

<figure class="highlight"><pre><code class="language-objc" data-lang="objc"><span class="k">const</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">size</span> <span class="o">=</span> <span class="mi">64</span><span class="p">;</span>
<span class="kt">size_t</span> <span class="n">cubeDataSize</span> <span class="o">=</span> <span class="n">size</span> <span class="o">*</span> <span class="n">size</span> <span class="o">*</span> <span class="n">size</span> <span class="o">*</span> <span class="k">sizeof</span> <span class="p">(</span> <span class="kt">float</span> <span class="p">)</span> <span class="o">*</span> <span class="mi">4</span><span class="p">;</span>
<span class="kt">float</span> <span class="o">*</span><span class="n">cubeData</span> <span class="o">=</span> <span class="p">(</span><span class="kt">float</span> <span class="o">*</span><span class="p">)</span> <span class="n">malloc</span> <span class="p">(</span> <span class="n">cubeDataSize</span> <span class="p">);</span>
<span class="kt">float</span> <span class="n">rgb</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">hsv</span><span class="p">[</span><span class="mi">3</span><span class="p">],</span> <span class="n">newRGB</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>

<span class="kt">size_t</span> <span class="n">offset</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">z</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">z</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="n">z</span><span class="o">++</span><span class="p">)</span>
<span class="p">{</span>
    <span class="n">rgb</span><span class="p">[</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="p">((</span><span class="kt">double</span><span class="p">)</span> <span class="n">z</span><span class="p">)</span> <span class="o">/</span> <span class="n">size</span><span class="p">;</span> <span class="c1">// blue value
</span>    <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">y</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">y</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="n">y</span><span class="o">++</span><span class="p">)</span>
    <span class="p">{</span>
        <span class="n">rgb</span><span class="p">[</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="p">((</span><span class="kt">double</span><span class="p">)</span> <span class="n">y</span><span class="p">)</span> <span class="o">/</span> <span class="n">size</span><span class="p">;</span> <span class="c1">// green value
</span>        <span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">x</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">x</span> <span class="o">&lt;</span> <span class="n">size</span><span class="p">;</span> <span class="n">x</span><span class="o">++</span><span class="p">)</span>
        <span class="p">{</span>
            <span class="n">rgb</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="p">((</span><span class="kt">double</span><span class="p">)</span> <span class="n">x</span><span class="p">)</span> <span class="o">/</span> <span class="n">size</span><span class="p">;</span> <span class="c1">// red value
</span>            <span class="n">rgbToHSV</span><span class="p">(</span><span class="n">rgb</span><span class="p">,</span> <span class="n">hsv</span><span class="p">);</span>
            
            <span class="k">if</span> <span class="p">(</span><span class="n">hsv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&lt;</span> <span class="n">minHueAngle</span> <span class="o">||</span> <span class="n">hsv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">&gt;</span> <span class="n">maxHueAngle</span><span class="p">)</span>
                <span class="n">memcpy</span><span class="p">(</span><span class="n">newRGB</span><span class="p">,</span> <span class="n">rgb</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">newRGB</span><span class="p">));</span>
            <span class="k">else</span>
            <span class="p">{</span>
                <span class="n">hsv</span><span class="p">[</span><span class="mi">0</span><span class="p">]</span> <span class="o">=</span> <span class="n">destCenterHueAngle</span> <span class="o">+</span> <span class="p">(</span><span class="n">centerHueAngle</span> <span class="o">-</span> <span class="n">hsv</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span>
                <span class="n">hsvToRGB</span><span class="p">(</span><span class="n">hsv</span><span class="p">,</span> <span class="n">newRGB</span><span class="p">);</span>
            <span class="p">}</span>

            <span class="n">cubeData</span><span class="p">[</span><span class="nf">offset</span><span class="p">]</span>   <span class="o">=</span> <span class="n">newRGB</span><span class="p">[</span><span class="mi">0</span><span class="p">];</span>
            <span class="n">cubeData</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="n">newRGB</span><span class="p">[</span><span class="mi">1</span><span class="p">];</span>
            <span class="n">cubeData</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">2</span><span class="p">]</span> <span class="o">=</span> <span class="n">newRGB</span><span class="p">[</span><span class="mi">2</span><span class="p">];</span>
            <span class="n">cubeData</span><span class="p">[</span><span class="n">offset</span><span class="o">+</span><span class="mi">3</span><span class="p">]</span> <span class="o">=</span> <span class="mi">1</span><span class="p">.</span><span class="mi">0</span><span class="p">;</span>
            <span class="n">offset</span> <span class="o">+=</span> <span class="mi">4</span><span class="p">;</span>
        <span class="p">}</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="n">NSData</span> <span class="o">*</span><span class="n">data</span> <span class="o">=</span> <span class="p">[</span><span class="n">NSData</span> <span class="nf">dataWithBytesNoCopy</span><span class="p">:</span><span class="n">cubeData</span> <span class="nf">length</span><span class="p">:</span><span class="n">cubeDataSize</span> <span class="n">freeWhenDone</span><span class="o">:</span><span class="nb">YES</span><span class="p">];</span>
<span class="n">CIFilter</span> <span class="o">*</span><span class="n">colorCube</span> <span class="o">=</span> <span class="p">[</span><span class="n">CIFilter</span> <span class="nf">filterWithName</span><span class="p">:</span><span class="s">@"CIColorCube"</span><span class="p">];</span>
<span class="p">[</span><span class="n">colorCube</span> <span class="nf">setValue</span><span class="p">:[</span><span class="n">NSNumber</span> <span class="nf">numberWithInt</span><span class="p">:</span><span class="n">size</span><span class="p">]</span> <span class="nf">forKey</span><span class="p">:</span><span class="s">@"inputCubeDimension"</span><span class="p">];</span>
<span class="p">[</span><span class="n">colorCube</span> <span class="nf">setValue</span><span class="p">:</span><span class="n">data</span> <span class="nf">forKey</span><span class="p">:</span><span class="s">@"inputCubeData"</span><span class="p">];</span>
<span class="p">[</span><span class="n">colorCube</span> <span class="nf">setValue</span><span class="p">:</span><span class="n">_ciImage</span> <span class="nf">forKey</span><span class="p">:</span><span class="n">kCIInputImageKey</span><span class="p">];</span></code></pre></figure>

<p><strong>В действии</strong></p>

<p>Исходное изображение:</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/07/iOS-Simulator-Screen-shot-Jul-6-2012-21.53.12-.png"><img src="http://vhbit.net/blog/wp-content/uploads/2012/07/iOS-Simulator-Screen-shot-Jul-6-2012-21.53.12-.png" alt="" /></a></p>

<p>Результат замены:</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/07/iOS-Simulator-Screen-shot-Jul-6-2012-21.53.29-.png"><img src="http://vhbit.net/blog/wp-content/uploads/2012/07/iOS-Simulator-Screen-shot-Jul-6-2012-21.53.29-.png" alt="" /></a></p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/07/iOS-Simulator-Screen-shot-Jul-6-2012-21.53.46-.png"><img src="http://vhbit.net/blog/wp-content/uploads/2012/07/iOS-Simulator-Screen-shot-Jul-6-2012-21.53.46-.png" alt="" /></a></p>

<p>Разница возникает из-за того, что в разных диапазонах берется разный центральный цвет для замены.</p>

<p>Полный код проекта доступен <a href="http://github.com/vhbit/ColorCubeSample">на гитхабе</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dash - последний штрих документации ]]></title>
    <link href="http://vhbit.net/blog/blog/2012/02/14/dash-d0-bf-d0-be-d1-81-d0-bb-d0-b5-d0-b4-d0-bd-d0-b8-d0-b9-d1-88-d1-82-d1-80-d0-b8-d1-85-d0-b4-d0-be-d0-ba-d1-83-d0-bc-d0-b5-d0-bd-d1-82-d0-b0-d1-86-d0-b8-d0-b8/"/>
    <updated>2012-02-14T20:39:29+02:00</updated>
    <id>http://vhbit.net/blog/blog/2012/02/14/dash-%d0%bf%d0%be%d1%81%d0%bb%d0%b5%d0%b4%d0%bd%d0%b8%d0%b9-%d1%88%d1%82%d1%80%d0%b8%d1%85-%d0%b4%d0%be%d0%ba%d1%83%d0%bc%d0%b5%d0%bd%d1%82%d0%b0%d1%86%d0%b8%d0%b8</id>
    <content type="html"><![CDATA[<p>Во время испытания <a href="http://www.jetbrains.com/objc/">AppCode</a> (это вообще отдельная тема для разговора) столкнулся с тем, что неудобно держать открытым еще и xCode для просмотра документации. Когда-то давно пробовал <a href="http://fileability.net/ingredients/">Ingredients</a>, но как-то не зацепило + были проблемы со стабильностью. Набрел на <a href="http://kapeli.com/dash/">Dash</a> - утилитку, без которой уже не представляю свою ежедневную работу. Недавно как раз обновилась до 1.3 и появилась в <a href="http://itunes.apple.com/us/app/dash/id458034879?ls=1&amp;mt=12">Mac AppStore</a>
<!-- more -->
Dash вешается на системный хоткей и показывает панельку ввода как во многих лончерах вроде Alfred’а или QuickSilver’а.</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-default.jpg"><img src="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-default-300x197.jpg" alt="" /></a></p>

<p>Поиск не требует вбивания слов целиком.</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-incomplete-words.jpg"><img src="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-incomplete-words-300x183.jpg" alt="" /></a></p>

<p>Позволяет опечатываться (правда не так хорошо, как хотелось бы).</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-mistype.jpg"><img src="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-mistype-300x182.jpg" alt="" /></a></p>

<p>Структура документа висит слева и всегда доступна (не надо возвращаться к началу документа).</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-sidebar.jpg"><img src="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-sidebar-300x186.jpg" alt="" /></a></p>

<p>Есть возможность работать со сниппетами, но как-то не срослось :-)</p>

<p><a href="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-snippets.jpg"><img src="http://vhbit.net/blog/wp-content/uploads/2012/02/dash-snippets-300x174.jpg" alt="" /></a></p>

<p>Очень радует стабильность и скорость работы.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Итоги 2011 года на встрече RADUG]]></title>
    <link href="http://vhbit.net/blog/blog/2011/11/29/radug-7-dec-2011/"/>
    <updated>2011-11-29T12:26:21+02:00</updated>
    <id>http://vhbit.net/blog/blog/2011/11/29/radug-7-dec-2011</id>
    <content type="html"><![CDATA[<p>К сожалению, сам не попаду, но всячески рекомендую подвести итоги 2011 года в компании <a href="http://radug.org">Russian Apple Developer’ов</a>.</p>

<p><strong>Дата:</strong> 7 декабря
<strong>Начало:</strong> 19.00
<strong>Место проведения:</strong> Москва, <a href="http://digitaloctober.ru/contact">Digital October</a></p>

<p>Мы традиционно завершаем год встречей в формате блиц-докладов. Приглашаем девелоперов, дизайнеров, менеджеров и всех энтузиастов iOS и Mac OS X. <a href="http://radug.timepad.ru/event/15625">Регистрация на встречу</a>. Участие во встрече как всегда бесплатное.</p>

<p>Ключевые люди российской индустрии расскажут, чем запомнился 2011 год, что было важными событиями и кто были главные люди и какие планы на следующий год. Мы ждем, что Вы также поделитесь с сообществом своим опытом, достижениями и открытиями.</p>

<p>Предновогодняя встреча RADUG – самое правильное место, чтобы оставаться в курсе происходящего, заявить о себе и завязать контакты. После встречи как всегда After Party – планируйте свое время!</p>

<p>Обратите внимание, что в Digital October, перед встречей RADUG пройдет еще одно мероприятие, посвященное мобильной разработке - Mobile Developer Day. Конференция платная, но в ее рамках есть бесплатная секция Developer Garage, включающая два мастер-класса по разработке приложений под iOS. Если есть желание – перед встречей RADUG можно заглянуть также и туда.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[sParking 1.0]]></title>
    <link href="http://vhbit.net/blog/blog/2011/05/26/sparking-1-0/"/>
    <updated>2011-05-26T11:53:02+03:00</updated>
    <id>http://vhbit.net/blog/blog/2011/05/26/sparking-1-0</id>
    <content type="html"><![CDATA[<p>Выпустили наконец-то первую версию. Процесс очень простой - ставите на стены гаража маркер (или 2 - на вход и на стоп), настраиваете и проверяете, чтобы они опознавались. После этого при каждом въезде iPhone будет подсказывать где самое время остановиться :)</p>

<p>Вот как это выглядит:</p>

<iframe width="560" height="349" src="http://www.youtube.com/embed/-gaThQ6-myM?hd=1&amp;fmt=22" frameborder="0" allowfullscreen=""></iframe>

<p>Пока что iPhone 4 only.
<a href="http://itunes.apple.com/us/app/sparking/id436388525?mt=8&amp;ls=1">Ах да :) Ссылочка</a></p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Волшебник страны Xcode]]></title>
    <link href="http://vhbit.net/blog/blog/2011/05/23/%D0%B2%D0%BE%D0%BB%D1%88%D0%B5%D0%B1%D0%BD%D0%B8%D0%BA-%D1%81%D1%82%D1%80%D0%B0%D0%BD%D1%8B-xcode/"/>
    <updated>2011-05-23T14:17:44+03:00</updated>
    <id>http://vhbit.net/blog/blog/2011/05/23/волшебник-страны-xcode</id>
    <content type="html"><![CDATA[<p><a href="https://github.com/snappycode/wox">wox (Wizard Of Xcode)</a> - восхительно удобная штучка для сборки iOS проектов из консоли, что весьма актуально для всяких автоматизаций.</p>

<p>Написана на ruby, установка:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>gem install wox
</code></pre></div></div>

<p>После этого создаем Rakefile, самый навороченный на данный момент пример:</p>

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="nb">require</span> <span class="s1">'wox'</span>

<span class="no">Wox</span><span class="o">::</span><span class="no">Tasks</span><span class="p">.</span><span class="nf">create</span> <span class="ss">:info_plist</span> <span class="o">=&gt;</span> <span class="s1">'project-Info.plist'</span><span class="p">,</span> <span class="ss">:sdk</span> <span class="o">=&gt;</span> <span class="s1">'iphoneos'</span> <span class="k">do</span>
    <span class="n">build</span> <span class="ss">:debug</span><span class="p">,</span> <span class="ss">:configuration</span> <span class="o">=&gt;</span> <span class="s1">'Debug - Local Server'</span>
    <span class="n">build</span> <span class="ss">:release</span><span class="p">,</span> <span class="ss">:developer_certificate</span> <span class="o">=&gt;</span> <span class="s1">'iPhone Developer: Valerii Hiora (8GA39LD1DZ)'</span><span class="p">,</span> <span class="ss">:configuration</span> <span class="o">=&gt;</span> <span class="s1">'Release'</span> <span class="k">do</span>
        <span class="n">ipa</span> <span class="ss">:app_store</span><span class="p">,</span> <span class="ss">:provisioning_profile</span> <span class="o">=&gt;</span> <span class="s1">'App Store'</span>
        <span class="n">ipa</span> <span class="ss">:adhoc</span><span class="p">,</span> <span class="ss">:provisioning_profile</span> <span class="o">=&gt;</span> <span class="s1">'Ad Hoc'</span> <span class="k">do</span>
            <span class="n">testflight</span> <span class="ss">:publish</span><span class="p">,</span> <span class="ss">:api_token</span> <span class="o">=&gt;</span> <span class="s1">'your_token'</span><span class="p">,</span>
                <span class="ss">:team_token</span> <span class="o">=&gt;</span> <span class="s1">'your_testers_team_token'</span><span class="p">,</span>
                <span class="ss">:notes</span> <span class="o">=&gt;</span> <span class="nb">proc</span> <span class="p">{</span> <span class="no">File</span><span class="p">.</span><span class="nf">read</span><span class="p">(</span><span class="s2">"CHANGELOG"</span><span class="p">)</span> <span class="p">},</span>
                <span class="ss">:distribution_lists</span> <span class="o">=&gt;</span> <span class="sx">%w[AlphaTesters]</span><span class="p">,</span>
                <span class="ss">:notify</span> <span class="o">=&gt;</span> <span class="kp">true</span>
        <span class="k">end</span>
    <span class="k">end</span>
<span class="k">end</span></code></pre></figure>

<p>Код в принципе понятен без особых комментариев, настроить можно абсолютно все - сертификаты,
какие provisioning profiles использовать, можно даже сразу публиковать на <a href="http://testflightapp.com">Testflight</a>
(<a href="http://vhbit.net/blog/2011/01/adhoc-%d1%82%d0%b5%d1%81%d1%82%d0%b8%d1%80%d0%be%d0%b2%d0%b0%d0%bd%d0%b8%d0%b5-%d0%bb%d0%b5%d0%b3%d0%ba%d0%be-%d0%b8-%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%be/">о нем писал раньше</a>).
Вложенные таски наследуют настройки родителей, т.е. testflight:publish будет собирать с использованием
provisioning profile из ipa:adhoc и подписываться это будет сертификатом, указанным в build:release.
В случае чего любую настройку можно переопределять.</p>

<p>Примеры использования:</p>

<p>Собрать дебажную версию:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rake build:debug
</code></pre></div></div>

<p>Подготовить ipa для заливки в AppStore:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rake ipa:appstore
</code></pre></div></div>

<p>Подготовить adhoc ipa и залить его на
<a href="http://testflightapp.com">Testflight</a></p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>rake testflight:publish
</code></pre></div></div>

<p>Посмотреть список всех доступных тасков:</p>

<figure class="highlight"><pre><code class="language-sh" data-lang="sh"><span class="nv">$ </span>rake <span class="nt">-T</span>
rake build:debug          <span class="c"># Build customiphone 1.0 with Debug - Local Server configuration</span>
rake build:release        <span class="c"># Build customiphone 1.0 with Release configuration</span>
rake info:configurations  <span class="c"># List available configurations</span>
rake info:sdks            <span class="c"># List available sdks</span>
rake info:targets         <span class="c"># List project targets</span>
rake ipa:adhoc            <span class="c"># Creates build/project-1.0-Release-adhoc.ipa</span>
rake ipa:appstore         <span class="c"># Creates build/project-1.0-Release-app_store.ipa</span>
rake testflight:publish   <span class="c"># Publishes build/project-1.0-Release-adhoc.ipa to testflight</span></code></pre></figure>

<p>По умолчанию версия продукта берется из Info.plist, но ее можно переопределить с помощью</p>

<figure class="highlight"><pre><code class="language-ruby" data-lang="ruby"><span class="ss">:version</span> <span class="o">=&gt;</span> <span class="mf">1.0</span><span class="o">.</span><span class="mi">3</span></code></pre></figure>

<p>Последний штрих - генерация правильного changelog’а для Testflight-публикации - остается домашним заданием :)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[[Перевод] Усовершенствуйте свой Git Workflow]]></title>
    <link href="http://vhbit.net/blog/blog/2011/05/12/d1-83-d1-81-d0-be-d0-b2-d0-b5-d1-80-d1-88-d0-b5-d0-bd-d1-81-d1-82-d0-b2-d1-83-d0-b9-d1-82-d0-b5-git-workflow/"/>
    <updated>2011-05-12T14:42:04+03:00</updated>
    <id>http://vhbit.net/blog/blog/2011/05/12/%d1%83%d1%81%d0%be%d0%b2%d0%b5%d1%80%d1%88%d0%b5%d0%bd%d1%81%d1%82%d0%b2%d1%83%d0%b9%d1%82%d0%b5-git-workflow</id>
    <content type="html"><![CDATA[<h2 id="Настраиваем-git-flow">Настраиваем git-flow</h2>

<p>Установить <a href="https://github.com/nvie/gitflow">git-flow</a> на OS X проще простого с помощью <a href="http://mxcl.github.com/homebrew/">homebrew</a></p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>brew install git-flow
</code></pre></div></div>

<p>На страничке проекта <a href="https://github.com/nvie/gitflow">git-flow</a> Вы можете найти инструкции по установке на Linux и Windows.</p>

<p>Установка git-flow добавляет несколько очень удобных git-команд для создания и управления ветками фич и релизов. Новый git репозиторий создается с веткой <em>master</em>. По умолчанию в git-flow эта ветка используется для <em>production-а</em>. В свою очередь основная разработка происходит в ветке <em>develop</em>. Следует отметить, что git-flow не более чем серия удобных “сокращений” для переключения между этими ветками и перебрасывания изменений из одной в другую.<!-- more --> После установки git-flow нужно настроить локальную копию:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow init
</code></pre></div></div>

<p>Вы можете согласиться со значениями по умолчанию, нажимая Enter - это, кроме всего прочего, облегчит настройку git-flow у сотрудников, т.к. им нужно будет использовать точно такие же значения. На самом деле все что, происходит при запуске <em>init</em> - это добавление двух секций [gitflow] в ваш .git/config:</p>

<figure class="highlight"><pre><code class="language-ini" data-lang="ini"><span class="nn">[gitflow "branch"]</span>
<span class="py">master</span> <span class="p">=</span> <span class="s">master</span>
<span class="py">develop</span> <span class="p">=</span> <span class="s">develop</span>
<span class="nn">[gitflow "prefix"]</span>
<span class="py">feature</span> <span class="p">=</span> <span class="s">feature/</span>
<span class="py">release</span> <span class="p">=</span> <span class="s">release/</span>
<span class="py">hotfix</span> <span class="p">=</span> <span class="s">hotfix/</span>
<span class="py">support</span> <span class="p">=</span> <span class="s">support/</span>
<span class="py">versiontag</span> <span class="p">=</span></code></pre></figure>

<p>Если вам нужно что-то уточнить воспользуйтесь встроенным хелпом</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow команда help
</code></pre></div></div>

<p>Приятное дополнение в виде <a href="https://github.com/bobthecow/git-flow-completion">autocompletion</a> для bash и для zsh</p>

<h2 id="Работа-над-новой-фичей">Работа над новой фичей</h2>

<p>Для старта новой фичи, например feature 77 с вашего issue-tracker’а:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow feature start 77-speedup-yak-shaving
</code></pre></div></div>

<p>Команда создает новую ветку <em>feature/77-speedup-yak-shaving</em> с родителем <em>develop</em> и переключается на нее.</p>

<p>Нужно расшарить работу с другими?</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow feature publish 77-speedup-yak-shaving
</code></pre></div></div>

<p>Это одним движением push’ит remote-ветку и привязывает локальную к ней. Стандартные <em>git push</em> и <em>git pull –rebase</em> работают как и должны, т.к. ветки, созданные git-flow, являются обычным ветками и не содержат какой-то специальной информации. Вся хитрость - только в соглашении именования.</p>

<p>Когда фича закончена, ее нужно за-rebase-ить на <em>develop</em> и потом слить:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow feature rebase
git flow feature finish 77-speedup-yak-shaving
</code></pre></div></div>

<p>После этих двух шагов <em>develop</em> будет содержать Вашу новую фичу. Остается только прогнать тесты и за-push-ить.</p>

<h2 id="Выпуск-релизов-и-хотфиксов">Выпуск релизов и хотфиксов</h2>

<p>С релизами управляться очень легко:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow release start 2011_year_of_the_yak
</code></pre></div></div>

<p>Эта команда создает новую ветку <em>release/2011_year_of_the_yak</em> на основе  <em>develop</em>. Здесь можно изменить HISTORY или VERSION файлы, закоммитить и выпустить релиз:</p>

<div class="highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git flow release finish 2011_year_of_the_yak
</code></pre></div></div>

<p>После этого будет создан тег <em>2011_year_of_the_yak</em> и временная ветка будет удалена. Вы очутитесь в <em>master</em>.</p>

<p>Хотфикс - это feature branch, базирующийся на последнем релизе и который автоматически будет влит и в <em>master</em>, и в <em>develop</em>. Просто и со вкусом.</p>

<p><a href="http://object.io/site/2011/enter-git-flow/">Оригинал на английском</a></p>

<p>Модель, по которой работает git-flow: <a href="http://nvie.com/posts/a-successful-git-branching-model/">A successful Git branching model</a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Кнопка "Follow us on Twitter" ]]></title>
    <link href="http://vhbit.net/blog/blog/2011/05/06/follow-us-on-twitter-button/"/>
    <updated>2011-05-06T15:46:50+03:00</updated>
    <id>http://vhbit.net/blog/blog/2011/05/06/follow-us-on-twitter-button</id>
    <content type="html"><![CDATA[<p>Код для запуска уже установленного на iOS твиттер-клиента:</p>

<p>Идея взята <a href="http://www.cocoanetics.com/2010/02/making-a-follow-us-on-twitter-button/">отсюда</a>, добавлен один клиент и удалено много копипаста :-)</p>

<p>Если устраивает открытие в Safari - можно откомментировать последний элемент, на этом кастомизация заканчивается.</p>

<p>Вообще поскольку URL в данный момент - это единственный способ для приложений взаимодействовать между собой, рекомендую поглядывать на <a href="http://www.handleopenurl.com/">handleOpenUrl:</a> и <a href="http://wiki.akosma.com/IPhone_URL_Schemes">подборку схем от Адриана Космачевского</a></p>
]]></content>
  </entry>
  
</feed>
