Solipsism Gradient

Rainer Brockerhoff’s blog

I fixed a crash that happened on some (apparently very few) systems and the new version is 1.1.1 — build 288 for the Mac App Store version, and build 289 for the direct download version. As a bonus, the app should also start up a little faster.

In fact, the MAS version has been out since the day before yesterday, but we’re on the road (currently in Germany) and Internet connections have been a little irregular.

On the downside, in the next 4 weeks my connections will be even more uncertain — we’ll be in Sikkim, Bhutan, Nepal, Italy and in the Eastern Aegean, so further updates or postings will probably have to wait until I’m back home. On the upside, I’m taking my laptop and will try to work in my copious free time while underway… 🙂

Apple’s (pre-)announcement of the Apple Watch left the tech world in the usual disarray. Is it an expensive knock-off of Android watches (people tell me there is such a thing!)? Is it an attack on the high-end Swiss watch market? Is it an attack on the low-end Japanese watch market? Is it an even more transparent lock-in attempt on soi-disant “Apple fanbois”? I’d answer “no” to all those questions, but right now I’m more interested in the hardware and software technology of the watch.

Notice that the above link doesn’t mention iOS anywhere, but this other link has the magic word: WatchKit. Quote: “WatchKit Apps. Soon your favorite apps will feature controls and interactions unique to Apple Watch, enabling you to enjoy them in dynamic new ways.

Speculations about WatchKit since then usually have mentioned one or two assumptions:

  1. WatchKit will be written in/accessible only from Swift;
  2. WatchKit apps will run under iOS on the Apple Watch.

The first is, of course, wishful thinking from developers investing in the new Swift language. The second is, in my opinion, completely unwarranted and I’ll try to explain why.

This post is the most plausible so far: “WatchKit apps will ship as embedded binaries in iPhone apps, using the same basic principals [sic] as iOS 8 extensions. There will be some mechanism for the watch paired to an iPhone to detect and automatically install these ‘apps’ based on what is available on the paired iPhone. Delete the container app from the iPhone, it disappears from the watch. Xcode will have a template to add a WatchKit app to an iPhone app project.

Let’s back off WatchKit for a second and look at what we’ve seen of the hardware. The entire main board is shrunk down to a single unit: the S1. If you stop the middle introduction film at 4:46, you’ll see that it’s really a collection of chips and SMT components on an encapsulated multilayer board — not really a “single chip” as the narration says, but many large CPU “chips” nowadays are like that, too. Other than the S1, there’s of course the “Taptic Engine” assembly which does the wrist tapping, the crown sensor assembly, antennas and display, and the most important part: the battery.

Battery life is the make-or-break feature of the Apple Watch. iFixit’s disassembly of the Moto 360 watch shows why: there’s a square peg battery inside a round casing, rated at 320 mAh. Even though Motorola apparently build their own batteries, they don’t have enough volume to do a round one. Apple doesn’t have a volume problem and their casing is square, so they’re free to use all remaining volume for a longer-lasting battery.

The 320 mAh rating and the typical battery life of 12 hours of the Moto 360 means that the watch consumes, on the average, just under 27 mA. But they run Android on the watch, using an off-the-shelf TI ARM processor with attached RAM, flash memory, and so forth, so that figure is not surprising. In other words, it’s a stripped-down cellphone/MP3 player.

Suppose that Apple did its usual optimization of battery size, usage, etc., in a stripped-down iPod nano. It’s half the size of the nano, which has a 30-hour life, so we can assume half the battery, meaning 15 hours. OK, that would be marginally acceptable, perhaps.

But remember, the Apple Watch needs an iPhone nearby. In fact, many of the published functions, such as Siri, cellphone call response, GPS and so forth certainly use the iPhone’s hardware and software for that. Remember that one of the culprits of excessive battery usage is generic apps and processes running on the device. Remember that Apple, since the first iPod in 2001, has been very aggressive in optimizing their embedded systems. Remember that the first iPods and iPhones didn’t have any generic apps running on them, either. Remember that Apple already has technologies like Clang, OpenCL and Metal…

All that said, why run iOS and generic applications on the Watch at all? So here’s what I think likely about the real implementation.

  • Watch OS (or whatever it’s called — did they explicitly call it anything?) will not be a stripped-down iOS; maybe even not a Darwin derivative. It will be a highly optimized embedded system that has a few apps running in as few processes as possible. It will be very robust because it will be able to do only a fixed set of functions.
  • In other words, it will run only those things that may run while the paired iPhone is not available; we don’t know yet, but that might be just the timekeeping and pulse measuring apps. If the iPhone is there, the Watch will also work as a specialized I/O and display device for the apps installed there.
  • WatchKit will run on the paired iPhone inside a special server process; a matching iOS app will show installed Watch apps — probably those apps will be from the normal App Store, since they usually will have an iOS counterpart.
  • So, an installed Watch app will have at least some sort of preference app or pane on the iPhone; no use typing in passwords and such on the Watch, right? The part written in/for WatchKit will contain a server plugin that does the heavy lifting, data collating and communicating with the outside world, but it will also contain the application logic itself, commanding the Watch to do or display certain things.
  • I don’t mean to imply that the Watch will run a full WebKit client and the iPhone a web server, that might be overkill. Perhaps a useful subset of that, perhaps some variation of Display Postscript, some interpreted command language, or just a sequence of drawing orders? The important part is that there’ll be a single process on the Watch for doing the UI, and all the application-specific parts can be offloaded to the iPhone.

One consequence is that you can forget the idea of “jailbreaking” the Watch to connect to a non-iPhone, of course. Another one is that battery life might be at least a day, maybe even two or more. Nothing on Apple’s site so far contradicts any of my reasoning.

So, will WatchKit be accessible from Swift apps? Certainly. Will it itself be written in Swift? I doubt it for now. Maybe in iOS 9 some of the frameworks in iOS (and OS X) will have been rewritten, assuming that by then the Swift optimizer will be good enough. But that won’t be the case in a few months.

Possible but unlikely: WatchKit may have an API to download actual application code to the S1, which may (or may not) have an ARM-like architecture. Only in such a case — and since there will be no Cocoa/iOS frameworks on the Watch — I would expect the downloaded code to be in Swift (without optionals!), for extra safety; can’t have the Watch crashing and rebooting, right?

Update: Marcel Weiher kindly reminded me of CarPlay, which apparently works like that; nobody would say that cars are running iOS. On the other hand, in that case, the device is connected over USB (that is, reasonable bandwidth) and the car doesn’t have any battery life problems.

Comments welcome.

Oopsy

No comments

The recent update to WordPress 4.0 seemed to have gone smoothly — perhaps too smoothly.

Turns out it has some fancy new redirection facilities that interfered with some of the pages outside this blog — specifically, some of the product pages, but only if the final /index.html was missing — it then would search the blog for the oldest post mentioning the product. Go figure.

Anyway, I managed to mostly fix it; the sole remaining exception seems to be the Klicko page. Please use this link to get there, in the unlikely case you’re still using that.

Another recent addition is the Crayon plugin to properly format source code on these pages. I’ve checked it out and it seems to have a bazillion options. I’ll have to play around with it and find the one that breaks the fewest older pages — this may take a week or so.

Speaking of a week or so, we’re currently on the road for yet another long trip; this time to Germany, Northern India and Sikkim, Bhutan, Nepal, Italy, Greece and Montenegro. I’ll probably have Internet for another 8 or 9 days, but by then whatever’s not fixed will have to wait for our return around the end of October.

Meanwhile, a small update(1.1.1) to RB App Checker Lite is waiting for review in the Mac App Store. I’ll post the direct download version ASAP; the only change is a fix for a crash that a couple of users complained about. Meanwhile, RB App Quarantine is about to be updated with helpful suggestions from users; I’ll try to do that while underway.

The direct download version of RB App Checker Lite 1.1 (281) is out, and RB App Quarantine also has been updated to build# 281 (its version is still 1.1 since nothing has changed for the user). Check out the release notes!

Most important: this version of RB App Checker Lite considers the new signing rules in TN2206 for OS X 10.9.5 and 10.10. In particular, for applications, code signatures are now checked recursively, both version 1 and version 2 resource rules are shown if present, and the spctl utility is called to check the Gatekeeper assessment.

However, this signals a new development: direct download and Mac App Store versions of RB Utilities will now, unfortunately, have different functionality. In particular, the MAS version of RB App Checker Lite (which is currently in review) will not be allowed to call  spctl, as this utility requires special entitlements to work; and the MAS version of RB App Quarantine (also in review), for the same reason, will not clear the quarantine flag. So for now you may want to download directly from the product pages.

Apple’s rules for calling attention to such differences are a little tricky to navigate but hopefully the MAS versions will be approved and in a future release I’ll develop a way to bring this functionality back through an optional download. Research is underway!

RB App Quarantine 1.1 (273) is out. It’s the second app in the RB Utilities software suite — RB App Checker Lite was the first one.

As the name implies, it’s a utility that checks or changes the “quarantine” attribute of other applications. This attribute is set whenever an application is directly or indirectly downloaded by the user from anywhere except the Mac App Store. (Applications produced from installer packages, disk images or compressed files inherit the attribute automatically.)

When a quarantined application is first opened or executed, OS X’s Gatekeeper function will check the application’s code signature and several other details and either reject it or throw up the well-known dialog, confirming that you want to execute a downloaded application. If you agree, the quarantine is cleared and Gatekeeper will not check the application again.

Using RB App Quarantine to clear some just-downloaded application’s quarantine attribute is not really recommended: you’ll be bypassing Gatekeeper and — unless you’re a developer yourself and/or have already used RB App Checker Lite to check that application’s bona fides — may be opening your system to a potentially untrusted application.

If you are a developer yourself, using RB App Quarantine to set quarantine on your own application will allow you to check its Gatekeeper status without using Terminal commands or (perish forbid) uploading it to some server and downloading it again.

It took me just 5 days to write this little application since all the UI and other logic common to all RB Utilities is contained in a prepackaged framework and I just had to write the app-specific file/folder handling. Setting up a new project with everything in place and drawing the new icon took a single day. Unfortunately clearing the quarantine attribute takes a special sandbox entitlement which would certainly be frowned upon by the Mac App Store reviewers, so I didn’t even try submitting it.

In other news, I submitted a new version of RB App Checker Lite to the Mac App Store and, if everything goes well, it should be out soon. This new version fixes some bugs and — most requested by users — shows some details pertaining to the latest version of Apple’s Technote 2206, namely showing version 1 and 2 resource rules and showing the Gatekeeper (spctl) assessment results. Stay tuned…

A few days ago, at the monthly CocoaHeads meeting here in Belo Horizonte, I was asked to do a brief talk. Since I didn’t have anything ready on short notice, I said I could show off my SwiftChecker app and do an informal Q&A about Swift.

It turned out that most of the attendees were new to Cocoa programming and none had yet done anything in Swift, so I mostly confined myself to the Q&A part. Here are some of the questions — not necessarily in order, and expanding somewhat upon my answers.

Q: we’ve landed a contract to do an iOS app. Won’t it be faster or more efficient to learn Swift now, instead of Objective-C?

A: absolutely not! (echoed by all present that had apps published) You should learn Swift now, it’s a new thing; we’re all starting out together, you’ll gain experience and you can even submit suggestions. But write apps for yourself, nothing that depends on a deadline. In any event, you won’t be able to deliver anything until the final Xcode 6 is out in a few months. In any event, in any real-world app, some parts may remain that are better done in Objective-C; and to understand Cocoa and other frameworks, Objective-C is a necessity. Ask me again in two years — it may be different then.

Q: is Swift interpreted like JavaScript, or compiled to a virtual machine like Java, or native?

A: it’s native. Compilation is a little unusual in that you have a simple parser in front, then you get an intermediate representation which goes to a front-end optimizer — this converts all syntactic sugar into library calls, and most of the language is implemented in the library — then that outputs the standard LLVM intermediate representation, which then goes through the same back-end optimizer and code generator that Clang uses. But at the end it’s native. The REPL/playground does some of that to fool you into thinking it’s interpreted, but that’s mostly for learning and trying out things.

Q: so how much do you use the playground? Is it true that it’s still unstable?

A: yes, it’s unstable and there are bugs inherent to the mode the playground compiles stuff, so I’ve never used it. My style is to start with a very simple app — even a command-line app — and gradually build it up.

Q: I began learning Objective-C a year ago and I still haven’t got used to the brackets. What do you similarly dislike in Swift?

A: I remember getting used to the [ ]s in two weeks after I discovered they could be nested; what I never got used to, even after 14 years, is that method and function declarations used different syntax — at least they fixed that! In Swift what I find strange is using dot syntax everywhere. I was a late adopter of it in Objective-C, and usually for properties only. I’m still typing semicolons and backspacing immediately, or putting the type first in declarations, but so far that’s just my habits, not an annoyance with the language.

Q: the first thing I noticed in beta 1 was that there was no private.

A: well, they put that in now; I suppose it’s important to you guys who work in teams, but I don’t like hiding things from myself. (Someone: “and exceptions?”) I’ve never needed exceptions for my applications, but better error handling is supposed to be coming soon.

Q: which is more fun to write in, Swift or Objective-C?

A: depends on how you define “fun”. Writing Swift takes some learning and you have new, powerful constructions like extensions and optionals — but in Objective C you can do fun things with dynamic dispatching or go down into C and do tricky things with pointers and memory. Ideally you should learn both. In general I’m in favor of learning also the lower levels, even machine language; it will help you with debugging.

Q: do you think Swift means that Apple is now abandoning imperative languages and adopting a more functional programming approach?

A: I think those are largely academic concepts — not in the sense that they’re unimportant, but in the end it comes out to what you need in practice to do a specific job. When I studied computer science, “structured programming” was the fashion of the day. Later on “object orientation” arrived and contained many of the older precepts. Now “functional programming” is in fashion, but Swift still has objects (and even structures in the sense of if/then/else, for and while loops, etc). So you can adopt different fashions when programming in Swift, but pragmatism is very important — use them only where appropriate.

Expanding upon that. Swift certainly isn’t a pure functional language to the extent that you can say that of Haskell (read this excellent article for details). Swift isn’t a pure object-oriented language either, neither in the C++ sense, nor in the Objective-C sense, nor in the Java sense – it has both structs and classes, both static and dynamic dispatch, but its functions, closures and generics allow you to do some functional stuff. It’s not a descendant of C because it has no pointers, no header files, no macros. It’s not a descendant of C++ because generics aren’t templates, although they use <>s. It’s not a JavaScript/PHP-like scripting language — I was shocked to hear someone describing it as such, just because it has type inference and a REPL.

So the answer is, it’s a new language, it tries to be very consistent and pragmatical, and it has imperative, functional, and object-oriented features.  It can’t be all things to all people, at least in the first versions. Don’t try to fit your existing patterns into it, rather build and learn new patterns — of course there are some rewriting their Scala patterns (or STL, or whatever) in Swift so they can go on using the names/patterns they’re used to, but that’s like moving to an exotic country and asking for your usual breakfast: unrewarding in the long run.

Sidenote: I’d never heard of functional programming until a few years ago, when I had to learn about map/reduce for an interview with Google; when that didn’t work out, I forgot all about it until Swift came out. It’s quite interesting (see this article, for instance) and I see how it can be useful for many things; still, in Swift you’re free to mix all these paradigms, which is quite enough for my purposes.

My first reading of the Swift books and of the generated Swift library header (remember, you can see the header by command-double-clicking on any Swift type) left me quite confused about the proper way to write generics and extensions to generics.

As usual, I favor learning-by-doing for such things [skydiving joke omitted] — I paged through a book on “Type Theory” to no avail — so, in a recent update to my SwiftChecker app I tried to include a useful extension.

Here is a (slightly edited) part of it:

public extension Dictionary {
	/**	Merges a sequence of values into a Dictionary by specifying
		a filter function. The filter function can return nil to filter
		out that item from the input Sequence, or return a (key,value)
		tuple to insert or change an item. In that case, value can be
		nil to remove the item for that key. */
	mutating func merge <T, S: SequenceType where S.Generator.Element == T>
		(seq: S, filter: (T) -> (Key, Value?)?) {
		var gen = seq.generate()
		while let t: T = gen.next() {
			if let (key: Key, value: Value?) = filter(t) {
				self[key] = value
			}
		}
	}
}	// end of Dictionary extension

To explain this, first recall that types can include typealias declarations within their definitions; this is much used for generic types, but can also be used everywhere. Here’s the declaration for Sequence from the library header:

protocol SequenceType : _Sequence_Type {
    typealias Generator : GeneratorType
    func generate() -> Generator
}

and of the GeneratorType protocol it uses:

protocol GeneratorType {
    typealias Element
    mutating func next() -> Element?
}

Going backwards: the GeneratorType protocol defines an associated type with the typealias declaration, in this case, Element. This is a placeholder type that will become an actual type when the protocol is adopted. These associated types form a hierarchy, so that you can refer to GeneratorType.Element and, further up, to Sequence.Generator.Element, and so forth.

Now look again at the merge method I define in my extension to Dictionary:

	mutating func merge <T, S: SequenceType where S.Generator.Element == T>
		(seq: S, filter: (T) -> (Key, Value?)?) { // ... etc.

Inside the <> after the method name are the type constraints. When I call merge on a Dictionary, this means that:

  • T is a placeholder type (with no constraints) used for the rest of the definition
  • S is another placeholder that is constrained to conform to the SequenceType protocol, and further (by using the where clause)
  • the generate() function for S must return a Generator whose Element is equal to T, and also
  • T is inferred from the argument type of the function/closure passed as the last argument to merge, and finally
  • this function/closure must return an Optional tuple of type (Key, Value?).

But what is this (Key, Value?) type, then? Recall that we’re extending Dictionary, so that type’s associated type hierarchy is also available; checking the declaration in the library header, we see:

struct Dictionary<Key : Hashable, Value> : CollectionType, DictionaryLiteralConvertible {
    typealias Element = (Key, Value)
    typealias Index = DictionaryIndex<Key, Value>
    ... etc.

so our type constraint will match Key and Value to those pertaining to the particular Dictionary that merge is being called on! To be more clear, we could even write (Dictionary.Key, Dictionary.Value?) in our definition.

Let’s look at a specific example of that. Notice that, where in the type constraints we refer to the placeholder type names (on the left of the typealias declarations), we refer to specific types wherever one is defined.

let strs = [ "10", "11", "12", "xyz" ]	// this is an Array  and therefore
					// its Generator.Element is String
let dict = [ 0:"0" ]	// this is a Dictionary <Int, String> and therefore
			// its Key is Int and Value is String
dict.merge (strs) { (s) in	// s is inferred to be strs's Generator.Element,
				// that is, a String
	let v = s.toInt()	// v is an Optional , will be nil for "xyz"
	return v ? (v!, s) : nil	// returns a valid tuple or nil
}
// dict will now contain [ 0:"0", 10:"10", 11:"11", 12:"12" ]

You can verify that everything matches our type constraints either directly or by type inference. If you change anything that doesn’t fit — say, by declaring s as anything but String inside the closure, or changing the type it returns — you’ll see a syntax error. (Assuming, of course, that no other extension has matching constraints.)

That said, currently (Xcode 6.0b5) the library header still has some bugs. Specifically, many type constraints either have too many prefixes removed, or show the wrong hierarchy, so you’ll see things like <S : Sequence where T == T> which won’t compile if you copy & paste it. No doubt this will be fixed soon.

Update: oops. Fixed the return, above.

Update#2: updated for Xcode 6.0b5 — many of those typenames either lost or gained a Type suffix.

A little over a month has passed since Swift came out, and I’ve just pushed a substantial update of my SwiftChecker app to GitHub. (Update: while writing this, I discovered a bug and pushed an updated update!)

While I still have to go back now and then to delete semicolons and to correct “String s” to “let s: String” (!@#$% muscle memory!) I finally can write out dozens of lines of Swift code without going back to the documentation or, worse, spend hours on the Internet checking why the compiler is balking. I suppose that means I’m assimilating the new syntax. It’s been over a decade since I had to learn a new language, so this isn’t too bad. 🙂

Looking at my new code, I’m particularly impressed by the conciseness of the language — the interaction with Cocoa APIs is still quite verbose, of course, but once I got used to type inference, the various map/filter/reduce/join functions, and of course generics, type extensions and operator declarations, I saw new ways of refactoring my code to be both more concise and more understandable.

In my almost 14 years of writing ObjC code I experimented with adding categories to existing classes but for the most part it always felt fragile and, after the initial experimental period, I went back writing subclasses or container classes. Using C macros to simplify stuff was tricky and error-prone. In Swift, by using generic types, it’s possible to write extensions and operators such that they don’t conflict with the existing implementation and this feels much more safe and natural. Although, of course, you still can unintentionally conflict with future additions to the Swift Library, namespaces should mostly take care of that.

Generics and type safety are a great help once I got used to them, which admittedly took some futzing around — the compiler is still very sensitive and the error messages are often cryptic or downright wrong. The type constraints and matching used for more complicated generics, admittedly, can become very complex — especially to someone not current on this new-fangled “type theory”. Still I was able to understand and build some simple generic extensions and functions that could be safely factored out into a few lines and greatly simplify other parts of my code.

Regarding optionals, I quickly got used to them; the old “returning nil” dance is now much less error-prone and at every step it’s clear which type is being handled and when it can be nil or not. The code is more readable in that regard, even if some nested “if let” statements have to remain when handling Cocoa return values. And ARC is practically transparent in Swift.

Speaking of values and ARC, the most troublesome parts are still those APIs — like the Security framework APIs I use in SwiftChecker — which haven’t yet been properly annotated. Certainly this will take many months, but no doubt pending updates to Clang will also take advantage of that, so that we’ll finally get rid of those pesky bridging casts.

One other positive side-effect is that the new whitespace rules, while mostly aligned with my own preferences, are finally making me insert spaces after commas, colons and around infix operators, and take other measures for increased readability.

All in all I’m very optimistic about Swift’s future. Can’t wait for the next Xcode beta to come out; the rumor mill says tomorrow, so let’s hope!

Photos licensed by Creative Commons license. Unless otherwise noted, content © 2002-2017 by Rainer Brockerhoff. Iravan child theme by Rainer Brockerhoff, based on Arjuna-X, a WordPress Theme by SRS Solutions. jQuery UI based on Aristo.