31 comments

[ 2.1 ms ] story [ 71.9 ms ] thread
I'm getting 'this page is temporarily unavailable' on this new book and the first one in the iBooks app on Mac. Edit: UK store so maybe it's still propagating to all stores.
This page is in Italian.
It's from the Italian store. The book is in English though.

Here's a full English link: https://itunes.apple.com/us/book/using-swift-cocoa-objective...

Thanks, pretty cool I just noticed if you change the /us/ part to any other country like cn, es, gb or it you will get the page in that language.
If you just click on the big blue button it will open in the correct store for you location.
How would that help? The computer I am using doesnt have ibooks or itunes.
It sounded like you...wanted to read the book which would require iBooks. I'm guessing you were just interested in an English translation of the summary?
What language is this in?
I think, Italian? if you switch the language specified in the url from 'it' to 'en' you get English, and I imagine 'it' stands for Italian.
For consistency and simplicity, Objective-C factory methods get mapped as convenience initializers in Swift. This mapping allows them to be used with the same concise, clear syntax as initializers. For example, whereas in Objective-C you would call this factory method like this:

    UIColor *color = [UIColor colorWithRed:0.5 green:0.0 blue:0.5 alpha:1.0];
In Swift, you call it like this:

    let color = UIColor(red: 0.5, green: 0.0, blue: 0.5, alpha: 1.0)
I'm still unclear on how this is happening behind the scenes?
They generate new Swift headers for Objective-C classes, and have translation rules in their toolset to remap/rename some arguments (all the init methods for example). The tool can even do that on your own Objective-C projects. I used this on a side project this weekend and it’s pretty rad.
Are these translation rules published somewhere? I'd really like to understand what keywords trigger what kind of mapping rules.
I'm pretty sure that's just a misstatement in the documentation. The Swift code is equivalent to the UIColor initialiser, there's no need to auto-translate the factory method as well.

The auto-translation process for initialisers is described immediately before the part you quote.

The section above mentions specifically translating either "init" or "initWith" from initializers. I'm curious if they're also pattern matching the "colorWith" prefix or if its more complicated.
I think you might have missed my point: the `initWith` translation produces the Swift constructor that the documentation you quoted presents as the factory method equivalent.

The `colorWith` factory method is useless in this context because a matching `initWith` initialiser exists. If the factory method were pattern matched in the same way, it would break things because it would produce a constructor with the same method signature as the translated initialiser.

We actually _do_ pattern match UIColor colorWith and turn it into an initializer. If there are two initializers after we pattern match (e.g., UIColor colorWith and initWith), we eliminate the duplicate.
Are there other pattern matches that can get triggered? I've come across classes that initialize with "For" as in [MyClass classForString:str] or similar.
From what I've been able to figure out just by playing around, the following rules are used:

1. Return type is `instancetype` or `MyClassName *`

2. Method takes at least one argument

3. Method name starts with a "class suffix"; that is, a suffix of the class name, with the restriction that you can't have partial words. The first letter may optionally be lower case.

The class suffix (optionally followed by "With" like in the `initWith` conversion) is stripped off and the rest of the method name is used for the first parameter, with the first letter lower-cased.

For example, the following conversions apply:

  +[MyClassName myClassNameWithObject:obj] -> MyClassName(object: obj)
  +[MyClassName classNameWithObject:obj] -> MyClassName(object: obj)
  +[MyClassName nameObject:obj] -> MyClassName(object: obj);
However, since those all map to the same swift initializer, only one will be available (generally the first one declared)
Awesome. I just finished a small Mac App in Swift [1], and I've run into lots of small situations where I wasn't sure what the best practice would be. Really looking forward to reading this one.

In particular, I found the required casting of AnyObject! to whatever I was expecting it to be not perfect (sometimes I thought that the typechecker really ought to figure some types out). Also, best practices for when to use NSArray vs. Array / NSString vs. String, etc. is another thing I look forward to.

Also, Some of the issues I ran into are probably due to Swift being beta, so knowing what the right way should be (even though it doesn't work that way yet) is important as it keeps me from hanging on to bad style.

[1] https://github.com/terhechte/Swijito

>> "In particular, I found the required casting of AnyObject! to whatever I was expecting it to be not perfect (sometimes I thought that the typechecker really ought to figure some types out). Also, best practices for when to use NSArray vs. Array / NSString vs. String, etc. is another thing I look forward to."

Same issues I was having. I was porting an obj-c class to Swift and continued to use obj-c objects (NSString etc.). I then had to put 'as NSString' at the end of most lines. I'm considering going back and experimenting to see where I can use swift native objects. Hopefully this book will shed more light on the subject.

Yeah, I managed to crash the compiler (SEGV) with AnyObject! casting. (I got the wrong idiom for iterating through an AnyObject[] )

The code contained a type error that the XCode compiler either missed or crashed before reporting. The command line compiler detected and reported my error.

I guess not telling us the "right" way enables us to fuzz test the compiler. :)

Well this is rather upsetting, it seems extensions still cannot add stored properties... Back to using objc_setassociatedobject and objc_getassociatedobject it seems for extension properties, sadface.

Also seems you can't override existing methods or properties still (actually achievable with swizzling of methods & property getter/setters on init but always seems way to heavy to use in reality). I would love to have a more mix-in friendly environment at some point in time.

“You can use extensions to add properties (including class and static properties). However, these properties must be computed; extensions can’t add stored properties to classes, structures, or enumerations.”

“You cannot use extensions to override existing methods or properties on Objective-C types.”

Excerpt From: Apple Inc. “Using Swift with Cocoa and Objective-C.” iBooks.

Not surprising. Class extensions in Objective-C cannot add stored properties either; objc_setassociatedobject and objc_getassociatedobject are shitty hacks.
I wish there was a properly formatted pdf version of the language guide. There is one floating around but the font size is too small.