Where technology meets something or other


Erica Sadun. iPhone. iPod touch. Macintosh. and More.

Contact

erica at ericasadun.com

Meta

  1. RSS
  2. admin
  3. valid XHTML

Swift: Stupid Reflection Tricks #10 Comments

erica | 1:01 pm | April 17, 2015 | Development,Swift

Range wars aren’t limited to the old wild west. I was kicking around some code and put together the following, which is admittedly bad on so many levels.

Kevin Ballard saw that, sighed, shook his head, and patiently recommended the following instead:

Kevin points out that String.Index is an index of Characters, not UTF-16 code units, and is presumably using some other internal offset. He adds, accessing values with String.Index is a constant-time operation; character offset (or UTF-16 code-unit offset or whatever) is not constant-time so it’s probably using an offset into whatever backing storage the String is currently using.


Swift: Counting emoji groups0 Comments

erica | 10:11 am | April 16, 2015 | Development,Swift

Update: Confirmed as bug (“Indeed.  We consider this to be a bug, not a feature, and are tracking it as rdar://20511834″) by Chris Lattner. Thanks to Joseph Lord for the heads up.

Apple’s new emojis are adding both culturally and programmatically exciting developments. Take care because your previous string counting routines (“countElements” and later “count”)  may not take composed character sequences into account. Here’s an example of where you may get tripped up by this technology.

Here’s a single emoji . When you count it, it returns one character.

Screen Shot 2015-04-16 at 9.47.32 AM

Here’s another single emoji. When you count it, it returns two characters. That’s because this is a new-style emoji composition:

Screen Shot 2015-04-16 at 9.48.55 AM

Some emoji now offer grouping and skin-tone variations, like this one does.

Screen Shot 2015-04-16 at 9.40.34 AM

If you iterate through the emoji characters, you see that the newemoji example is composed of two items that are composited together to produce the emoji-of-color.

Screen Shot 2015-04-16 at 9.50.34 AM

You see similar groupings in family-style and couple-style emojis. Here’s a family group. (I’m still trying to figure out where the blue and green shirts come into this.)

Screen Shot 2015-04-16 at 9.52.08 AM

Over at devforums, Andrew Carter posted a solution for handling composed sequences. It involves enumerating substrings using grouped character sequences. Here’s my take on that solution, creating a computed composedCount property for strings.

You end up with a count that treats composed sequences as single entities, returning a count of 1 instead of 4 for the family string shown above.

There are several notes in the standard library module about using composed characters, such as for substringWithRange (“Hint: Use with rangeOfComposedCharacterSequencesForRange: to avoid breaking up composed characters”) and (“Note that the length of the range returned by these methods might be different than the length of the target string, due composed characters and such.”).


Swift: In case you didn’t think that Swift was the future0 Comments

erica | 11:52 am | April 14, 2015 | Development,Swift

Here’s proof

Svifties


Swift: The joys of cascading lets2 Comments

erica | 11:31 am | | Development,Swift

Today, I wrote a fortune shell script to demonstrate how Swift could be used for scripting without having to build an entire application. I ended up using cascading let statements in a way I haven’t really to date. When 1.2 introduced these to “avoid the pyramid of doom”, I didn’t quite see how well they created a readable stack of steps.

What’s particularly interesting to me is how these steps short-cut the normal call/test for error/respond-to-error Cocoa-y flow of things. If any step fails, everything fails, leading to a central fail point (return nil). Explaining what went wrong isn’t easy to detail any further unless all the calls subscribe to an NSError** pattern.

The if-statement feels a little like an overstuffed turkey, which is not necessarily a good feeling when writing code.  I’m still trying to decide if I love this or not.


Swift: Var parameters2 Comments

erica | 3:51 pm | April 10, 2015 | Development,Swift

Swift variables use let and var to indicate whether their values are immutable (cannot be changed after the initial assignment) or mutable (can be updated at will). What many newer Swift developers don’t realize is that closure and function parameters can also be annotated by var and let.

The following function declaration uses let and var keywords to indicate parameter mutability:

func TestFun(let x : String, var y : String) {}

The let keyword is redundant; all parameters default to let, which is called a “constant parameter.” They cannot be changed within the function scope. This compile-time check avoids situations where you mistakenly change the value of a parameter without meaning to. Mandating a var keyword ensures that any value updates for parameters are intentional. For example, the following snippet raises a compile-time error. You cannot assign a new value to ‘let’ value x.

func TestFun(x : String, var y : String) {x = "Hello"} // error!

Here’s an example where assignment does work. You can adjust y to a new value because it is a variable parameter. The example prints out “Hello World” when called with TestFun(“Goodbye”, “Hello”).

func TestFun(x : String, var y : String) {y += " World"; println(y)}

Both x and y are passed by value. The var keyword permits a value to update after the initial call. Even though you tweak y within this function, the y parameter and any variable it was called with do not change outside the function. The parameter’s value is copied and then updated within this scope.

To change the value of an external variable, use Swift’s “inout” call-by-reference copy and write back mechanism (Thanks Nate Cook). Add an inout keyword and pass the address of the variable you intend to mutate by prefixing it with “&”. Here’s an example combining all these concepts.

func AdjustValues(var varParameter : Int, letParameter: Int, inout inoutParameter : Int) { 
    varParameter++ // updates within function scope
//    letParameter++ // compile-time error
    inoutParameter++ // updates within and outside function scope    
    println("\(varParameter) \(letParameter) \(inoutParameter)")
}

var x = 10; var y = 20; var z = 30 // assign
(x, y, z) // (10, 20, 30), check
AdjustValues(x, y, &z) // prints (11, 20, 31)
(x, y, z) // (10, 20, 31) z has now changed

In this example, the call-by-value varParameter (it was called with the value stored in x) increases within the function but does not propagate back to the original variable. The call-by-reference inoutParameter also increases but that change updates the value of z. In Swift you do not have to de-reference the pointer during the assignment.

Now consider the following assignment.

let w = 40

You can pass w to either or both of AdjustValue’s first and second parameters. Immutability outside the function scope does not affect use within the function. However, you cannot pass &w to the AdjustValue’s third parameter. You’ll cause a compiler error because you cannot assign new values to immutable variables in this way.

As always, if there’s anything in this write-up I messed up on, let me know and I’ll fix.

Updated with Nate Cook’s feedback in the comments. Reference (but not call by reference) thread: here.


Swift: A little Google playground hack0 Comments

erica | 6:05 pm | April 7, 2015 | Development,Fun,Swift

Suggestions + scraping + value histories = fun! Full sized video here.

Like the hack? Read the book.


Swift: Playground Secrets and Power Tips available on iBooks1 Comment

erica | 3:07 pm | April 6, 2015 | Announcements,Books,Development,Swift

Screen Shot 2015-04-06 at 3.01.47 PM

If you bought the Amazon version prior to this week, shoot me an email and I’ll rustle you up a promo code. Thank you everyone for your support!

Direct iTunes Link


Swift: Interactive Documentation and the Future of the Playground0 Comments

erica | 10:15 am | | Books,Development,Musings,Swift

Video first so you get the idea of how interactive controls could support playgrounds. You can watch the full-size version here.

Like all things Swift and Playground, this is more a proof of concept than anything practically deployable. You can download this playground and kick its tires from my github repo. If the running version appears dimmed, kick-start it with Editor > Execute Playground.

Deploying a demo-controlling slider to a separate floating window isn’t ideal. Its goal is to support and demonstrate  playground code not pull attention away from it. It would be so much better if interactive GUI elements could be embedded to value history panes, the way that non-interactive views currently can be.

I love this demo because it seems to me that this is exactly the kind of thing a playground should be able to do. Here are a few other thoughts about playgrounds and interactive documents:

I have an entire section of workarounds in the newly updated Playgrounds book if you’re looking for tips. Here’s hoping the updated version will go live soon.


Swift: Working with Unmanaged Objects0 Comments

erica | 9:00 am | | Development,Swift

In rare cases (which are growing rarer by the day) a Core Foundation function may return a C-pointer or an object reference embedded into an Unmanaged wrapper. You encounter these in the older, dustier, and stranger parts of Cocoa where grues still lurk in shadows. You must transfer Unmanaged references into the normal memory management system before working with them in Swift .

Here’s my current understanding of the situation. Feel free to correct any mistakes and I’ll update this post.

An Unmanaged wrapper, like an Optional wrapper, provides a layer of safety between your code and a potentially nasty crash.  The Unmanaged<T> type stores a pointer whose memory is not controlled by the Swift runtime system. Before using this data, you take responsibility for how this memory should stay alive.

In Cocoa, this works very much like bridging in Objective-C. Unwrap any object with an existing +1 retain count using takeRetainedValue(). This applies to any item built with Create or Copy in its name.

For example, UTTypeCopyPreferredTagWithClass returns a +1 CFString instance. Assign this result with  takeRetainedValue(), making sure to test for failed calls. Unwrapping nil causes nasty crashes that even blessed potions of restore life will not fix. (In Swift, there is no @try, there is only d’oh!) (And potentially d’oh not, if you listen to that Yoda guy.)

public func PreferredFileExtensionForUTI(uti: String) -> String? {
    if let result = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassFilenameExtension) {
        return result.takeRetainedValue() as String
    } else {
        return nil
    }
}

Use takeUnretainedValue() to unwrap any object built by a Core Foundation function with Get in its name (for example, CFAllocatorGetDefault()) and constants passed as unmanaged objects (for example kLSSharedFileListSessionLoginItems). These items are not automatically retained for you. Unlike takeRetainedValue(), calling takeUnretainedValue() will not consume a retain upon unwrapping.

These functions follow the patterns established in Apple’s Memory Management Programming Guide for Core Foundation, where you can read more about the “Create Rule”, the “Get Rule”, and other details about memory ownership policies.

Update: Cocoa Kevin writes “If you have an Objective-C framework or are developing one that you would like people to use in their Swift application and there are methods or functions in your Objective-C framework that return CoreFoundation objects, you need to decorate your methods or function names with CF_RETURNS_RETAINED or CF_RETURNS_NOT_RETAINED. The CoreFoundation naming rules is not enough according to the Swift compiler. If you don’t decorate your methods or functions then CoreFoundation objects will be returned as unmanaged.”


Swift: Playground Book update submitted0 Comments

erica | 3:18 pm | April 5, 2015 | Announcements,Books,Swift

Screen Shot 2015-04-05 at 1.58.16 PM

More than twice as long, tons of new coverage, improved interactive-document how-to, and iBooks (!) which should allow updates. The Kindle version will not be updated due to Amazon’s restrictions.

Note: Once it’s approved, ping me by email if you’ve bought a copy and I’ll send you a promo code for iBooks. I can’t generate the codes until it’s been processed.

Current table of contents:

The book story to date:

 


« Older Posts

wordpress | sheepdip design by mahud © 2007