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

  <title><![CDATA[chbeer.de]]></title>
  <link href="http://chbeer.de/atom.xml" rel="self"/>
  <link href="http://chbeer.de/"/>
  <updated>2012-01-09T17:13:09+01:00</updated>
  <id>http://chbeer.de/</id>
  <author>
    <name><![CDATA[Christian Beer]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Itches with Cocoa Autolayout (with solution)]]></title>
    <link href="http://chbeer.de/blog/2011/07/25/itches-with-cocoa-autolayout-with-solution/"/>
    <updated>2011-07-25T18:20:24+02:00</updated>
    <id>http://chbeer.de/blog/2011/07/25/itches-with-cocoa-autolayout-with-solution</id>
    <content type="html"><![CDATA[<p>Mac OS X Lion (10.7) adds a very capable new method to Cocoa to layout views.
Say goodbye to struts and springs and hello to auto layout contstraints.</p>

<p>But there are some itches with auto layout that bit me while trying to layout
a basic vocabulary input form: <a href="http://chbeer.de/a/2011-07-25-itches-with-cocoa-autolayout-with-solution/iVocabulary-AddWord.png"><img src="http://chbeer.de/a/2011-07-25-itches-with-cocoa-autolayout-with-solution/iVocabulary-AddWord.png" alt="iVocabulary Add Word" /></a></p>

<p>These itches were:</p>

<ol>
<li>Defining constraints that resize the window was impossible in IB</li>
<li>Getting the views in a NSDictionary did not work as intended (for me)
<strong>1. Defining constraints that resize the window</strong><br/>
This form contains three text fields, that all can change their size when the
font changes. The user can choose font and size for each of the input fields.</li>
</ol>


<p>The desired behaviour is: the window resizes and all textfields below the
changed textfield move.</p>

<p>First, I tried to define the constraints using Interface Builder, but that
didn&#8217;t work. IB tried to be extremely smart and removed some constraints as
soon as I added the last contraint (between the comment field and the
surrounding view). My plan was to add constraints between all views in the
vertical order.</p>

<p>In my second and successful attempt I used ASCII art in <code>windowDidLoad</code>. The
ASCII-Art was as easy as:
<code>V:|-[delimiterInfo]-[sourceField]-[targetField]-[commentField]-50-|</code></p>

<p>The result is nice and behaves as expected: <a href="http://chbeer.de/a/2011-07-25-itches-with-cocoa-autolayout-with-solution/Result.png"><img src="http://chbeer.de/a/2011-07-25-itches-with-cocoa-autolayout-with-solution/Result.png" alt="Word input
form" /></a></p>

<p>The methods <code>-[UIView addConstraints:options:metrics:views:]</code> view parameter
expects a dictionary containing the views mapped to the keys used in the
ASCII-art. There is a macro you can use to get this dictionary by binding
names: <code>NSDictionaryOfVariableBindings</code> but that didn&#8217;t work for me, because
my ivars had a prefix and I didn&#8217;t want to specify that prefix in the ASCII-
art. That lead to itch #2:</p>

<p><strong>2. How to get a NSDictionary containing the views</strong><br/>
In IB you can set an identifier for each view:</p>

<p><a href="http://chbeer.de/a/2011-07-25-itches-with-cocoa-autolayout-with-solution%0A/iVocabulary-IVAddWordController.xib_.png"><img src="http://chbeer.de/a/2011-07-25-itches-with-cocoa-autolayout-with-solution/iVocabulary-%0AIVAddWordController.xib_.png" alt="" /></a></p>

<p>So my thought was: why not use that identifier to specify the views. Therefore
I created a category for <code>NSView</code> containing one method:</p>

<p><code></code></p>

<pre><code>- (NSDictionary*)dictionaryWithSubviewsByIdentifier
{
    NSMutableDictionary *dict = [NSMutableDictionary dictionaryWithCapacity:self.subviews.count];
    [self.subviews enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {
        NSView *view = obj;
        if (view.identifier) {
            [dict setObject:view forKey:view.identifier];
        }
    }];
    return dict;
}
</code></pre>

<p><code></code></p>

<p>This way you can define the identifier in IB and you don&#8217;t need to have a
binding for each and every view you want to use in your ASCII-art.</p>

<p><strong>UPDATE:</strong><br/>
Like Ken says in the comment: you don&#8217;t need this hacks, you simply need to
define the right constraints. The trick is: define all vertical pins (aka
constraints) from top to bottom and all works like a charm. Thanks Ken!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[NSURLRequest and authentication]]></title>
    <link href="http://chbeer.de/blog/2011/02/28/nsurlrequest-and-authentication/"/>
    <updated>2011-02-28T10:44:07+01:00</updated>
    <id>http://chbeer.de/blog/2011/02/28/nsurlrequest-and-authentication</id>
    <content type="html"><![CDATA[<p>The internet is not only browsers and static HTML pages anymore. Most apps
today also talk to servers and get or send their precious data. To prevent
unwanted guests to steal your data you must think about authentication.</p>

<p>There is an easy way to add authentication information to a request:
<code>http://user:very!secure$password!!@webservice.com/precious/data</code></p>

<p>But that&#8217;s not cool. You need to add these information to all requests and
that can be quite a hassle.</p>

<p>We are lucky as there are some very helpful classes in Cocoa. To store the
credentials we can use the class <code>NSURLCredential</code> and add them to a
<code>NSURLProtectionSpace</code> to map them to a host. Here is an example of it in
action:</p>

<p><code>NSURLCredential *credential = [NSURLCredential credentialWithUser:@"user"
password:@"very!secure$password!!"
persistence:NSURLCredentialPersistenceForSession]; NSURLProtectionSpace
*protectionSpace = [[NSURLProtectionSpace alloc]
initWithHost:@"webservice.com" port:80 protocol:@"http" realm:@"Secure area"
authenticationMethod:nil]; [[NSURLCredentialStorage sharedCredentialStorage]
setDefaultCredential:credential forProtectionSpace:protectionSpace];
[protectionSpace release];</code></p>

<p>That&#8217;s all. This way also requests in a <code>UIWebView</code> can be authenticated.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Dropbox file download with NSOperation]]></title>
    <link href="http://chbeer.de/blog/2010/11/26/improved-dropbox-file-download-with-nsoperation/"/>
    <updated>2010-11-26T17:40:18+01:00</updated>
    <id>http://chbeer.de/blog/2010/11/26/improved-dropbox-file-download-with-nsoperation</id>
    <content type="html"><![CDATA[<p>Dropbox provides a rather great SDK for iOS that wraps the REST API in some
convenient Cocoa classes. Using that SDK you can very easily log in to
Dropbox, upload files, grap metadata (folder content and the like) and
download files.</p>

<p>Extending iVocabulary with a Dropbox interface, I wanted to add the option to
upload and download ProVoc files to/from Dropbox. But ProVoc files are so
called bundles, that are more folders than files (they look like files in the
finder, though). So downloading these &#8220;files&#8221; is a combination of getting
metadata and downloading the files. (Disclaimer: Dropbox doesn&#8217;t like you to
walk the folder tree recursively! But as the ProVoc bundles are at most 1
level deep, I think it&#8217;s ok).</p>

<p>My first attempt to do the download of these folders was very naive: get the
metadata of the ProVoc file (folder) and get all files / folders recursively.
As I said: the folders are not deeply nested, but there can be a lot of media
files: images and audio. So this approach led to a huge amount of open
connections in parallel what led to errors.</p>

<p>My new approach involves <code>NSOperationQueue</code>, a very handy class, that provides
a queue for operations that are processed in parallel. There are some
NSOperation implementations for your convenience and you can create your own
<code>NSOperation</code> implementations. I found a very short introduction to
<code>NSOperationQueue</code> and how it works with NSURLConnection here: <a href="http://www.dribin.org/dave/blog/archives/2009/05/05/co%0Ancurrent_operations/">Concurrent
Operations Demystified</a>. That helped to get it to work very quickly.</p>

<p>Using NSOperationQueue I can now enqueue all file and metadata requests and
then wait until all downloads are finished. Let&#8217;s look how I did it:</p>

<h2>NSOperation</h2>

<p>To build your own (asynchronous) <code>NSOperation</code> implementation you need to do
the following:</p>

<ol>
<li>Implement lifecycle properties: <code>isExecuting</code>, <code>isFinished</code></li>
<li>Implement lifecycle methods: <code>start</code> and <code>finish</code></li>
</ol>


<p>The Properties are straight forward to implement:</p>

<pre><code>@interface DropBoxOperation : NSOperation {
    BOOL _isExecuting;
    BOOL _isFinished;
}
@property (readonly) BOOL isExecuting;
@property (readonly) BOOL isFinished;
@end
</code></pre>

<p>and</p>

<pre><code>@synthesize isExecuting = _isExecuting;
@synthesize isFinished = _isFinished;
</code></pre>

<p>I implemented these in an abstract class called <code>DropBoxOperation</code> that is
extended by special operations for downloading metadata and files. These two
subclasses implement <code>start</code> and <code>finish</code>.</p>

<p>My operations also provide a delegate mechanism to react on downloaded files
and metadata but that is not shown here.</p>

<h2>DropBoxDownloadFileOperation</h2>

<p>As an example I will show how I implemented <code>start</code> and <code>finish</code> for
downloading files. Downloading metadata works nearly the same.</p>

<pre><code>- (void)start {
    if (![NSThread isMainThread]) {
        [self performSelectorOnMainThread:@selector(start) 
                               withObject:nil 
                            waitUntilDone:NO];
        return;
    }

    [self willChangeValueForKey:@"isExecuting"];
    _isExecuting = YES;
    [self didChangeValueForKey:@"isExecuting"];

    _restClient = [[DBRestClient alloc] initWithSession:[DBSession sharedSession]];
    _restClient.delegate = self;

    [_restClient loadFile:_remotePath 
                 intoPath:_localPath];

    if (_restClient == nil)
        [self finish];
}
- (void)finish {
    [self willChangeValueForKey:@"isExecuting"];
    [self willChangeValueForKey:@"isFinished"];

    _isExecuting = NO;
    _isFinished = YES;

    [self didChangeValueForKey:@"isExecuting"];
    [self didChangeValueForKey:@"isFinished"];
}  

#pragma mark DBRestClientDelegate  

- (void) restClient:(DBRestClient *)client loadedFile:(NSString *)destPath {
    // notify delegate
    [self finish];
}
- (void) restClient:(DBRestClient *)client loadFileFailedWithError:(NSError *)error {
    // notify delegate
    _error = [error copy];
    [self finish];
}
</code></pre>

<p>The only special part is the first lines of code in the start method: Because
the <code>DBRestClient</code> uses <code>NSURLConnection</code>, the code must be run on the main
thread. Otherwise the <code>NSURLConnection</code>s delegates won&#8217;t be called.</p>

<p>The other parts are straight forward: the state is getting updated and the
rest-client is used to load the file. After the download has been finished,
the delegate methods of the rest-client get called and they call the method
<code>finish</code> where the state gets updated accordingly.</p>

<h2>How is it used?</h2>

<p>In my Dropbox-download manager class, I implemented a method for my
convenience that adds a download request to the queue:</p>

<pre><code>- (void) addLoadFile:(NSString*)remotePath {
    NSString *localPath = [self localPathFromRemotePath:remotePath]
    DropBoxDownloadFileOperation *operation = 
      [[DropBoxDownloadFileOperation alloc] initWithRemotePath:remotePath
                                                     localPath:localPath];
    operation.delegate = self;
    [_queue addOperation:operation];
    [operation release];
}
</code></pre>

<p>My metadata download operation calls the DBRestClientDelegate method on its
delegate. I used that to implement a recursive download of the folders and
files (<code>addLoadMetadata:</code> works the same as <code>addLoadFile:</code>):</p>

<pre><code>- (void)restClient:(DBRestClient*)client loadedMetadata:(DBMetadata*)metadata {

    if (metadata.isDirectory) {
        NSString *remotePath = metadata.path;
        NSString *localPath = [self localPathFromRemotePath:remotePath];

        NSError *error = nil;
        [[NSFileManager defaultManager] createDirectoryAtPath:localPath 
                                  withIntermediateDirectories:YES
                                                   attributes:nil
                                                        error:&amp;error;];

        for (DBMetadata *fileMD in metadata.contents) {
            if (fileMD.isDirectory) {
                remotePath = fileMD.path;
                localPath = [self localPathFromRemotePath:remotePath];

                error = nil;
                [[NSFileManager defaultManager] createDirectoryAtPath:localPath 
                                          withIntermediateDirectories:YES
                                                           attributes:nil
                                                                error:&amp;error;];

                [self addLoadMetadata:fileMD.path];
            } else {
                [self addLoadFile:fileMD.path];
            }
        }
    }    
}
</code></pre>

<p>(error handling has been striped out for readability).</p>

<h2>My findings</h2>

<p>I didn&#8217;t use <code>NSOperation</code> that much before and I am very sad I didn&#8217;t use it!
It is such a convenient way to handle asynch tasks without bothering with
<code>NSThread</code>s.</p>

<p>The biggest argument for <code>NSOperation</code>/<code>-Queue</code> is the parallelability that
you get as a gift. When using <code>NSOperation</code> for tasks, Grand Central Dispatch
can decide on which processor the task shall run. With a blink of an eye your
app runs on all cores of your iPhone &#8230; errr &#8230; I mean &#8230; Mac ;)</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Hands on tutorial to NSDateComponents]]></title>
    <link href="http://chbeer.de/blog/2010/07/05/hands-on-tutorial-to-nsdatecomponents/"/>
    <updated>2010-07-05T12:33:23+02:00</updated>
    <id>http://chbeer.de/blog/2010/07/05/hands-on-tutorial-to-nsdatecomponents</id>
    <content type="html"><![CDATA[<p>Calculating dates is quite a hard thing to do. You need to keep in mind that
adding or subtracting days (or months, hours, &#8230;) to a date can lead to
changing months or even years: Getting the date of &#8220;two days before the first
of January&#8221; leads to substract a year and a month from the current date, the
result is the 29th of December a year before. You even need to keep leap years
in mind.</p>

<p>But there are tools in Cocoa that takes all the heavy stuff off of calculating
dates: the NSDate, NSCalendar and NSDateComponents classes. There are (at
minimum) two things you can do using NSDateComponents: get components of a
date and calculate new dates by changing components.</p>

<h3>Getting Date Components</h3>

<p>Getting date components of a given NSDate is very easy using NSDateComponents:</p>

<p><code>-(int)month:(NSDate*)date { NSDateComponents *comps = [[NSCalendar
currentCalendar] components:NSMonthCalendarUnit fromDate:date]; return
comps.month; }</code></p>

<p>To access components of a given NSDate we are using NSCalendar to get a group
of components of it. Here we are interested in the month. So at first we are
asking NSCalendar for the NSMonthCalendarUnit of our given date.</p>

<p>After that we can access the specified units from the NSDateComponent. What&#8217;s
important to know is that accessing units we didn&#8217;t specify on
components:fromDate won&#8217;t give the correct values but more or less random
values.</p>

<p>You can also use NSDateComponents to get a date that only contains the values
for given components. For example you can get a NSDate that contains the
beginning of the day without hours, minutes, seconds, etc.:</p>

<p><code>NSDate *date = [NSDate date]; NSDateComponents *comps = [[NSCalendar
currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit |
NSDayCalendarUnit) fromDate:date]; NSDate *beginningOfDay = [[NSCalendar
currentCalendar] dateFromComponents:comps];</code></p>

<h3>Calculating New Dates</h3>

<p>To calculate new dates from a given date, you can configure a NSDateComponents
instance as an offset to a date:</p>

<p><code>-(NSDate *)previousMonth:(NSDate*)date { NSDateComponents *comps =
[[NSDateComponents alloc] init]; [comps setMonth:-1]; NSCalendar *cal =
[NSCalendar currentCalendar]; NSDate *date = [cal dateByAddingComponents:comps
toDate:date options:0]; [comps release]; return date; }</code></p>

<p>At first we instantiate a NSDateComponent and configure it with the offsets we
want to add to the NSDate. In this example we want to calculate the date a
month before today so we set the month to -1.</p>

<p>After that we create a new NSDate by adding the components to the given date.</p>

<h3>Summary</h3>

<p>NSDateComponents provides some really great functionality for creating dates
with only requested components and to calculate dates as offsets from a given
date. The class ensures that the calculated date is valid.</p>

<p>For my projects I created a NSDate category that provides some convenient
methods to get date components and calculated dates.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[App I created now no. 1 of free Apps in Germany]]></title>
    <link href="http://chbeer.de/blog/2010/05/01/app-i-created-now-no-1-of-free-apps-in-germany/"/>
    <updated>2010-05-01T14:50:39+02:00</updated>
    <id>http://chbeer.de/blog/2010/05/01/app-i-created-now-no-1-of-free-apps-in-germany</id>
    <content type="html"><![CDATA[<p><img src="http://img.skitch.com/20100501-eiea8im9gfwykdgfy3u9safnjs.jpg" alt="kaufDA Navigator in Top 25 free
Apps" />The App
<a href="http://itunes.com/apps/kaufda-navigator">kaufDA Navigator</a> I created for a
customer did become no. 1 of free Apps in Germany :-) That is great news!</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Using Xcodes build system for iPhone + iPad projects]]></title>
    <link href="http://chbeer.de/blog/2010/04/08/using-xcodes-build-system-for-iphone-ipad-projects/"/>
    <updated>2010-04-08T16:14:23+02:00</updated>
    <id>http://chbeer.de/blog/2010/04/08/using-xcodes-build-system-for-iphone-ipad-projects</id>
    <content type="html"><![CDATA[<p>My iPhone app iVocabulary will be available for the iPad as a separate
application, not as a universal app. This is because the iPad version should
be a First Class application not a scaled-up &#8220;Economy&#8221; app (as mentioned
<a href="http://pocketcyclone.com/2010/04/07/ipad-apps-economy-vs-first-%0Aclass/#comments">here</a>). There will be many classes that are shared between both
applications and therefore I build the apps from one Xcode project.</p>

<p>To distinguish between the devices in code, Apple advises to use something
like this: <code>#if __IPHONE_OS_VERSION_MAX_ALLOWED &gt;= 30200 MyIPadViewController*
vc; // Create the iPad view controller #else MyIPhoneViewController* vc; //
Create the iPhone view controller #endif</code></p>

<p>But this can get very tedious and error prone. If you&#8217;ve got classes that are
mostly the same for both devices but differ in some methods, the Xcode build
system comes to the rescue.</p>

<p>Lets assume your AppDelegate differs in one method that initializes a
viewcontroller differently for both devices. You can build that method and
surround both code blocks with the structure above. But there is a better way:
You create two categories for your class: AppDelegate+iPhone and
AppDelegate+iPad:</p>

<p>`/// file AppDelegate.h @interface AppDelegate { MentionedViewController
*_viewController; } - (void)initMentionedViewController; @end</p>

<p>/// file AppDelegate.m @implementation AppDelegate - (void)
applicationDidFinishLaunching { &#8230; [self initMentionedViewController]; } @end</p>

<p>/// file AppDelegate+iPhone.m @implementation AppDelegate (iPhone) - (void)
initMentionedViewController { &#8230; do special iPhone stuff here &#8230; } @end</p>

<p>/// file AppDelegate+iPad.m @implementation AppDelegate (iPad) - (void)
initMentionedViewController { &#8230; do special iPad stuff here &#8230; } @end`</p>

<p>The important part is to define the targets of the categories .m-Files via the
targets tab in the info screen:</p>

<p><a href="http://chbeer.de/a/2010-04-08-using-xcodes-build-system-for-iphone-ipad-projects/Screenshot-Xcode-Targets.png"><img src="http://chbeer.de/a/2010-04-08-using-xcodes-build-system-for-iphone-ipad-projects/Screenshot-Xcode-Targets.png" alt="Screenshot Xcode Targets" /></a></p>

<p>During the build, the Xcode build system includes the correct file and the
other one will be left out. This way you get the same result as if you used
the #if-constructs but with much cleaner and more transparent code.</p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[ProVoc Cocoa style]]></title>
    <link href="http://chbeer.de/blog/2010/04/04/provoc-cocoa-style/"/>
    <updated>2010-04-04T20:29:02+02:00</updated>
    <id>http://chbeer.de/blog/2010/04/04/provoc-cocoa-style</id>
    <content type="html"><![CDATA[<p>While improving ProVoc for the next iVocabulary version (to add
synchronization) I am currently refactoring the looks of ProVoc to look a lot
more mature and Cocoa like.</p>

<p>Here is a small example (labels are German):</p>

<p><a href="http://chbeer.de/a/2010-04-04-provoc-cocoa-style/Screenshot_ProVoc_Cocoa_1.png"><img src="http://chbeer.de/a/2010-04-04-provoc-cocoa-style/Screenshot_ProVoc_Cocoa_1.png" alt="Screenshot ProVoc Cocoa-Style" /></a></p>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Cross Compile ProVoc with Cocotron?]]></title>
    <link href="http://chbeer.de/blog/2010/03/25/cross-compile-provoc-with-cocotron/"/>
    <updated>2010-03-25T13:46:37+01:00</updated>
    <id>http://chbeer.de/blog/2010/03/25/cross-compile-provoc-with-cocotron</id>
    <content type="html"><![CDATA[<p>To build a vocabulary editor for Windows I considered building one in Java as
the only option. But then I found the project Cocotron. Cocotron is an
implementation of Cocoa for Windows and Linux (and could also be ported to
other plattforms). It is easily integrated to Xcode so that you can build the
Windows version of your application with few clicks.</p>

<p>For building Cocotron you need to <a href="http://www.cocotron.org/Tools/InstallCDT">install some
tools</a>. These are downloaded and
installed with few steps that are well documented on the Cocotron website. The
navigation is not always clear on that website but you can find your way
through it. The website itself is also coded in Objective-C and compiled for
Linux using Cocotron.</p>

<p>After you installed the needed tools you can
<a href="http://www.cocotron.org/Code/">checkout</a> (or download) and compile Cocotron.
For me the Cocoa project was all I had to build since it references some of
the other needed packages. With the build process the library gets installed
into the Developer folder.</p>

<p>The next step is to <a href="http://www.cocotron.org/Tools/Creating_Targets">add a new
target</a> to your existing (or
new) project. You can easily do so by copying an existing Mac OS target and
<a href="http://www.cocotron.org/Tools/Build_Settings">clean up and adapt the build
settings</a>. That process is also
well documented on the Cocotron website but it take some trial and error for
me to find out if I did all I need. As soon as you don’t get any low level
errors from gcc you can start porting your application. Depending on the
complexity of your application it may use some parts of Cocoa that are not
implemented in Cocotron by now.</p>

<p>For ProVoc the last part was not easy and is not finished by now. I added many
<code>#ifdef _WIN32</code> and <code>#ifndef __APPLE__</code> to the code to disable unimplemented
parts and it builds without errors (but with many warnings). ProVoc starts on
Windows but there still seem to be some problems as it hangs shortly after
starting. You can also <a href="http://www.cocotron.org/Tools/Debugging/Insight-GDB">debug your application on Windows using Insight-
GDB</a> what I started to do
at last.</p>

<p>As soon as I find some free time I will continue trying to get ProVoc run on
Windows and I will post my findings here.</p>
]]></content>
  </entry>
  
</feed>

