Sunday, June 14, 2015

Thoughts on WWDC 2015

In my mind, these are biggest developer-facing announcements to come out of WWDC 2015:
  • iPad Multitasking
  • UI Testing and Code Coverage in Xcode 7
  • Swift 2
  • Swift as an Open-Source language
  • App Thinning
  • Watch OS 2.0 with on-device apps
  • CloudKit Web Services
  • Free iOS provisioning
Note that these aren't changes in the SDK itself. Developers don't have to write a lot of code to get these benefits. iPad multitasking already works if you followed the adaptivity guidance for iOS 8 from last year; support is as simple as recompiling. UI Testing works on your existing apps. On-watch WatchKit extensions use the same SDK that on-phone extensions used (albeit with additional capabilities exposed). You don't need to make any changes to your CloudKit usage in order to enable web services. All these features come essentially free for the developer.

There are, of course, some nice SDK changes as well. UIStackView and NSCollectionView are very welcome additions to their respective platforms, but even these aren't really new; they're just parity features between the platforms. The various new extension points are nice, and the new gaming frameworks are probably a big deal for game developers. But as I see it, WWDC doesn't fundamentally change the kinds of apps I can write.

The focus this year isn't on enabling new kinds of apps, but rather on improving the experience of the apps we can already build. App testing, delivery, performance, and consumption are all improved across the board, with little effort needed from developers. iOS 9 and OS X El Capitan offer significant improvements to the user experience, and Xcode 7 improves the developer experience, but the improvements are largely outside the SDK. The big news from WWDC 2015 isn't about new frameworks, classes, and methods—it's about an improved experience for users and developers.



Caveat: If you're a game developer, GameplayKit, ReplayKit, and the expanded Metal announcements may have made this a big year for you. I'm not a game developer, so they don't really affect me from a development standpoint. But I acknowledge that they definitely look cool, and are definitely part of the SDK.

Saturday, May 2, 2015

Defining Modules for Static Libraries

Preview:

I figured out how to define modules for static libraries, so you can import them into Swift or into other module-defining frameworks. This solves a common build error: "include of non-modular header inside framework module", as it allows you to turn that non-modular header into a modular one.

You just have to define a custom module.modulemap file and copy it into the right place. Read more for details, or skip to the end if you just want to know what to do.




A brief and incomplete rationale for modules

In 2013, Xcode 5 was released with support for modules, a new way of using libraries and frameworks. Xcode 5 only supported modules in system libraries, but Xcode 6 extended support to third-party libraries as well. Before the advent of modules, developers gained access to libraries via #import statements, which literally copy the requested header files into the importing file. This made the library APIs visible within that file, but required repeatedly parsing system headers again and again as multiple files imported the same headers. This is an unnecessary duplication of work.

We could greatly improve build times if the compiler could parse all the headers of a library just once. However, this is difficult in a #import-based system, because the compiler does not know what files constitute the canonical headers for any given library. Some libraries provide an "umbrella" header that imports all of its API, but the compiler can't always know what header that would be, and even these aren't always complete. (Example: UIKit.h does not import UIGestureRecognizerSubclass.h.) We needed a better way of defining the canonical interface for a given library.

Modules are that better way. A module is a binary representation of a library's interface—once built, the module can be reused throughout the entire compilation process. It can also be used to provide access to the library from other languages, such as Swift. In fact, Swift code can only make use of frameworks and libraries that have a module defined, so this becomes a critical piece of infrastructure going forward.

Module maps

So how do we define a module from a bunch of headers? How do we define the canonical API for a library? Module maps. A module map is a simple file that defines the canonical headers for a library. They're easiest to understand by example, so let's jump right in.

The following is a valid module map for an imaginary library. It is place in a file named module.modulemap in the same directory as the library headers.

module AirplaneKit {
   header "Airplane.h"
   header "AirplaneView.h"
   header "Cockpit.h"
   header "Fuselage.h"
   header "Wheels.h"
   header "Wings.h"
}

Simple enough; the module map is just a list of headers that define the representation of the library. It can get a bit tedious to write out every header, though, and it's easy to forget to update the modulemap when you add a new header, so module maps support a convenient syntax:

module AirplaneKit {
   umbrella header "AirplaneKit.h"
   export *
}

That export * line means "Also consider any file imported by one of the listed headers to be part of the module." This is generally what you'll want to do. (The umbrella part is not strictly necessary, but indicates that the header is expected to import every header file in its directory.)

In general, Xcode has fairly good support for defining modules based on your own frameworks: just set the Defines Module build setting to YES and maintain your framework's umbrella header. Xcode will build the appropriate module map file and embed it within your framework. Support for static libraries, though, is somewhat lacking.

Before we move on, one important note: In Xcode 6.3.1, you must clean your project after any change to a module.modulemap file. In my experience, the compiled version of the module is not rebuilt when the module map file changes. Also, when tweaking the module map file, make sure you're editing your original file, not the one in the build folder. Xcode sometimes likes to jump to that one instead.

Defining modules for static libraries

If you're using a static library and you want to make it available to Swift or to another module, there are 2 things you need to do to "modularize" it.

1. Add a file named exactly module.modulemap as described above.

2a. If you're using someone else's library you didn't write, you probably already put the headers somewhere. Just write a module map file for the library and put it with the headers.

2b. If you're building your own static library, make sure your library's headers and the module map are being copied to [build directory]/include/[LibraryName]/. If your static library target is using a Copy Headers build step (as is the default in Xcode 6.3.1), remove it. Instead add a Copy Files build phase, configured as follows:



That's it. Really. After doing the above, you can now use your library from Swift. You can read more about modules and the modulemap format in the Clang Documentation.

If you have any problems, please let me know on Twitter (@bjhomer). I'd like to make sure these steps work for everyone.

Saturday, October 18, 2014

Mutable collections in Swift

I recently came across this question on Twitter:


This is an interesting question. As a developer coming from Objective-C and the Cocoa frameworks, we're used to distinguishing between NSArray and NSMutableArray. It's generally bad practice to expose an NSMutableArray as a public property on an object.


The problem is that another part of the app could modify the contents of the pizzaMenu array without the knowledge of the Pizzeria object. The Pizzeria still points to the same object it always has; from its perspective, nothing has changed. This is bad.


Instead, a better practice is to only expose an immutable NSArray. This way, whenever any change happens, the setter method will be called. The Pizzeria is always aware of what's happening.

In Swift, the Array type is built into the language. Though you can still use NSArray and NSMutableArray, it's often not necessary; the native Array type is plenty capable.

There are two types of objects in Swift: value types and reference types. Reference types are like traditional Objective-C objects—multiple variables can reference the same object. This was the problem in the examples above above: both the Pizzeria object and external code referenced the same object, so we had to expose an NSArray that does not have APIs for changing its contents.

Value types are identified by their value. They also exist in Objective-C, but only for C types (structs and primitives). If two CGRect variables have the same value, it simply means that the two rects contain the same data. A change to one rect will never change the value of another rect stored in a separate variable.

While Objective-C requires that all objects be reference types, Swift objects can be reference or value types. This means that Swift structs can have methods just like classes can. Swift's built-in collections (Array and Dictionary) are value types.

Because they are value types, two variables can never reference the "same" array. Every time an array is assigned to a variable, it gets a new, separate copy1 which cannot be affected by any other part of the code.

This means there is no need for a separate mutable collection type in Swift. Mutating a value type is always safe because changing a struct only affects the values of that specific variable. That what it means to be a value type. Modifying a Swift Array never affects any other variable, anywhere.

Let's see how this affects our pizzeria example.

Note that even though pizzeria.pizzaMenu is a mutable var property, modifying the array we get back from the pizzeria has no effect on the pizzeria's copy of the data. They are separate arrays, separate values, and we can't change their copy unless we go through the setter.

In fact, this holds true even if we avoid assigning the array to an intermediate variable! In Objective-C, you simply cannot modify a value type held by another object. Many iOS developers have discovered this, to their frustration:

But in Swift, not only does this work, but it guarantees that the setter will be called! Whenever you call a mutating2 method on a value type, the end result is assigned back into the receiving variable (or expression). So calling obj.someInts.append(1) causes a new value to be constructed, which is then assigned back into the someInts property!


Because Swift arrays and dictionaries can never be shared, there is no distinction between mutating an existing collection and re-assigning a new collection. The behavior of the code is exactly the same. In either case, the owner's setter method is called whenever the array is modified.

So to answer the original question, there is no syntax to specify a variable that holds an immutable array because there is nothing that such syntax would add. Swift addresses the issues that made NSArray and NSMutableArray necessary in the first place. If you need a shared array, you can still use the Cocoa types. In every other case, Swift's solution is safer, simpler, and more concise.



1: Note that the implementation is lazy, only performing an actual copy when really necessary.
2: Methods on structs and enums in Swift must be labeled mutating if they're going to modify any data. Otherwise, they cannot be called on a value stored in a let variable.

Friday, August 8, 2014

NSScrollView and Autolayout

So, you've got an NSScrollView, and you want to add some content that is sized via auto layout constraints. Perhaps you found the "Auto Layout by Example" documentation in the Mac developer library, and discovered that though it contains a section titled Using Scroll Views with Auto Layout, the example is actually for UIScrollView, not NSScrollView. Given the significant differences between the two, that simply won't work.

Here's what you need to do. I'll demonstrate doing this in code, but the same principles apply in Interface Builder as well.



1. Create an NSScrollView. Position it however you like.

    _scrollView = [[NSScrollView alloc] initWithFrame:self.bounds];
    _scrollView.translatesAutoresizingMaskIntoConstraints = YES;
    _scrollView.autoresizingMask = NSViewHeightSizable | NSViewWidthSizable;
    _scrollView.hasVerticalScroller = YES;
    _scrollView.identifier = @"ScrollView";

    [self addSubview:_scrollView];


2. Create an NSView subclass with isFlipped == YES that will contain all your scrolling content.  (If it's not flipped, then the content will prefer to pin to the bottom of the scroll view if not tall enough to require scrolling. That's not what you want.)

    @interface FlippedView : NSView
    @end

    @implementation FlippedView

    - (BOOL)isFlipped {
        return YES;
    }

    @end

3. Create the scrolling container view. Do not use autoresizing masks. Its size doesn't matter too much, but its superview will be the scroll view's contentView, so that makes a convenient default size.

    _scrollContentContainer = [[FlippedView alloc]
                                initWithFrame:_scrollView.contentView.bounds];
    _scrollContentContainer.translatesAutoresizingMaskIntoConstraints = NO;
    _scrollContentContainer.identifier = @"Content container";

4. Set the content container to be the scroll view's document view.

    _scrollView.documentView = _scrollContentContainer;

5. Constrain the top, left, and right edges of the container view to its superview (the contentView). Use Auto Layout constraints to do this, not autoresizing masks.

    NSDictionary *views = NSDictionaryOfVariableBindings(_scrollContentContainer);
    NSArray *hConstraints = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"H:|[_scrollContentContainer]|"
                             options:0 metrics:nil views:views];
    
    NSArray *vConstraints = [NSLayoutConstraint
                             constraintsWithVisualFormat:@"V:|[_scrollContentContainer]"
                             options:0 metrics:nil views:views];
    [_scrollView.contentView addConstraints:hConstraints];
    [_scrollView.contentView addConstraints:vConstraints];
    
6. Add your subviews to the content container however you like. Make sure that the constraints from these subviews will create a natural content size in at least the vertical dimension.

    NSDictionary *buttons = NSDictionaryOfVariableBindings(button, button2);
    NSArray *hConstraints2 = [NSLayoutConstraint
                              constraintsWithVisualFormat:@"V:|-[button]-(1300)-[button2]-|"
                              options: (NSLayoutFormatAlignAllLeft |
                                        NSLayoutFormatAlignAllRight)
                              metrics:nil views:buttons];
    
    NSLayoutConstraint *centerX = [NSLayoutConstraint
                                   constraintWithItem: button
                                   attribute: NSLayoutAttributeCenterX
                                   relatedBy: NSLayoutRelationEqual
                                   toItem:    _scrollContentContainer
                                   attribute: NSLayoutAttributeCenterX
                                   multiplier:1 constant:0];
    
    [_scrollContentContainer addConstraints:hConstraints2];
    [_scrollContentContainer addConstraint:centerX];


Of course, you can do this all in Interface Builder as well, and that's usually what I'd do. It's nice to know how to do it both ways, though. The same principles apply in either case:

  1. Position the NSScrollView externally however you like.
  2. Flipped container view as the scroll view's document view.
  3. Constraints from top, right, and left of container view to its superview.
  4. Constraints from the scrollable content to the container view.

And that's it!

Tuesday, August 5, 2014

Mormon Questions: Temples

A couple weeks ago, my brother was married in the temple in Bountiful, Utah. Temples are an important part of my beliefs as a member of the Church of Jesus Christ of Latter-Day Saints, so I thought I'd take some time to explain what they're about and answer some common questions.

First, though, a brief note. To understand our temples, you must understand that our religion is not just a codified series of moral guidelines. We believe that God is a real, physical being who communicates with us and blesses us as we follow his teachings. We also believe that each of us has a spirit which continues to live on after our death. The temple binds us to God eternally, far beyond our brief time here on Earth. If you try to understand the temple while ignoring these things, the things we do in the temple will make very little sense.

Bountiful, Utah temple. Click to see more photos.

Outside the temple

If you know anything about Mormon temples, you probably know that they've got beautiful architecture. Temples usually have stained glass windows, intricate stonework, and a design that draws the eye heavenward. Each temple is built to be a house of the Lord, a place where God is welcome. Quite literally, the phrase "The House of the Lord" is inscribed on the exterior of every temple. We make every effort to make each temple a beautiful place, representative of the respect and love we have for God.

"Holiness to the Lord. The House of the Lord."
Temple in Madrid, Spain

The grounds of each temple are generally open to the public and show the same dedication to serenity and peacefulness. They usually feature gardens and fountains, shade trees and benches, and it's common to see people taking pictures on the grounds or sitting on a bench study scriptures. Many temples also have visitor's centers, where guests can get more information and ask questions.

Fountain at the Oakland, California temple

Inside the temple

Temples are sacred buildings where we participate in ordinances (religious rituals or ceremonies) and make covenants with God. They are set apart from the outside world, dedicated to a specific purpose and free from external distractions. Upon entering, attendees change into white clothing and leave behind cell phones and other distractions. The temple is a quiet, peaceful, and reverent place. We are asked to speak in a whisper if we speak at all. Some rooms are set aside simply for contemplation and prayer, while others are meant to accommodate a specific ordinance.

If you've visited the churches or cathedrals of other religions, you might expect the interior of the temple to be a vast open space. In fact, the interior of each temple is simply a series of rooms, each with its own purpose. There are ceremonial rooms, administrative offices, hallways, chapels, and small meeting rooms, but no massive space for congregating. The same care that goes into the exterior of the temple goes into the interior as well; there are crystal chandeliers, intricate carvings and designs, beautiful stairways, etc. You can find some pictures of the interior of the temple on lds.org. (I was unable to find good photos of the temple interior that were licensed for use on other websites, so I'm afraid you'll just have to follow the link on this one.)

Temples are distinct from our meetinghouses, where regular Sunday worship takes place. In meetinghouses, we gather each week to learn about Christ through scripture study, talks, hymns, etc. We also take the sacrament (often known as "communion" in other Christian religions.) None of this happens in temples; in fact, our temples are not even open on Sundays. Temples are specifically focused on sacred ceremonies, not worship services. (If you're interested in attending one of our Sunday meetings, you can find a nearby meetinghouse on mormon.org.)

Temple ordinances (ceremonies)

That's my brother and sister-in-law. They're awesome.
The most celebrated ordinance held in the temple is eternal marriage. Mormons believe that a marriage under proper authority in the temple is effective not only "until death do you part," but throughout eternity. Mormons are known for a strong emphasis on the family, and this is part of the reason why—we believe that family life is not just a transient phase while we're here on earth, but rather an essential part of our eternal future. In the temple, couples are "sealed together" for time and all eternity, creating a new family unit that will last forever.

Another ceremony held in the temple is known as the endowment. It includes instruction about the pre-mortal existence of man, the creation of the world, the story of Adam and Eve in the Garden of Eden, and their path back to God's presence. As with many scriptural accounts, the lessons to be learned from the endowment are not necessarily the literal ones in the text. Just as Christ wasn't teaching us that we should all literally build our houses upon rocks, the endowment isn't really instruction about how to live in the Garden of Eden. It's symbolic, a metaphor for our own lives. During the endowment, we make covenants (promises) to follow the teachings of Jesus Christ and to participate in his Church.

After we have received ordinances for ourselves, we can also go to the temple to receive ordinances for the dead. This may seem unfamiliar, but it's a beautiful concept. Religious ordinances (baptism, endowment, marriage, etc.) enable us to live with God again and to receive tremendous opportunities and blessings. Without these ordinances, we cannot ever receive all that God wants to give us. However, there are many, many people who have died without ever having the opportunity to participate in these ordinances. It might seem that millions upon millions of God's children are condemned by no fault of their own.

Baptistry in the Salt Lake City temple

But God cares about all of his children. We believe that those who never had an adequate chance to learn about Jesus Christ and his teachings in this life will have that opportunity in the next life, being taught by those who have previously learned it. But learning is not enough; ordinances such as baptism are required for our eternal progression, and it's rather difficult to baptize a spirit. So, after we (the living) have received these ordinances for ourselves, we can go to temples as a proxy for those who have died, and participate in various ordinances on their behalf. We are especially urged to do this work for our own ancestors, offering them the same opportunities that we have received. Baptisms for the dead, endowments for the dead, and even marriages for the dead are all performed in the temple in order to extend the blessings of each ordinance to those who have gone before.

It would be incorrect, though, to say "Well, we've done a baptism for Gertrude Hazelswatch (born in 1628), so now she's a Mormon too." When we participate in temple ceremonies on behalf of the dead, we are only offering up the physical part of the ordinance. Each deceased person continues to live on as a spirit, and the baptism we perform on their behalf means nothing unless that person accepts the associated commitments. If they do not accept the commitments associated with baptism, they are not bound by them and the baptism means nothing. However, we cannot know who will accept or reject these commitments, so we offer them to as many as we can and hope that they will accept it.

Visiting the temple

In order to preserve the reverent atmosphere that exists in temples, dedicated temples are only open to church members in good standing. However, after construction on a temple is completed, a temple "open house" event is held over several weeks. During this time, the public is invited to tour the temple. These open houses are usually very well attended, as it is the only chance for the general public to enter the temple. There are only a few temples built each year worldwide, so these open houses are fairly rare. If you happen to be in Utah this month, it might be worth your time to visit the Ogden, Utah temple open house, roughly 45 minutes north of Salt Lake City. The temple has been undergoing major renovations, and will be dedicated in September 2014. Reservations to attend are available free online.

There's also a temple nearing dedication in Phoenix, Arizona. Open House dates have not yet been announced, but it will probably be late 2014.

If you're not going to be able to catch an open house, you might be interested in stopping by a visitor's center. There are 143 temples in operation around the world, including many throughout North America, and most temples have visitor's centers that are open 7 days a week. You can find a list of temples here.

And that's it! If you've got a question I didn't answer or if you just want to tell me what you think, feel free to ask me on Twitter (@bjhomer) or send me an email (bjhomer@gmail.com).

Monday, May 26, 2014

WWDC 2014 Wishlist

WWDC 2014 starts one week from today, so I guess that means it's time for some predictions. It's almost certain Apple will be introducing OS X 10.10 and iOS 8, which means new features, new APIs, and lots and lots of "To Be Announced" sessions. Last year, 64 of 97 sessions (65%) were marked "To Be Announced" prior to the keynote. This year, 80 of 108 sessions (74%) are still undisclosed1. There's a lot of new stuff coming. Last year I was pretty conservative, only predicting things I was pretty sure of. This year, I don't know enough to do that, so I'm going to be a bit more speculative. Here's what I'm hoping for:

OS X 10.10

Rumors are strong that we'll see a visual overhaul of OS X, similar in scope to what iOS 7 brought last year. I really have no clue what to expect in general, but a few things seem more likely to change than others:

  • No more gradient toolbar buttons (as found in Finder, Safari, etc.)
    I would be very surprised if we don't see these transition to a more flat style.  We saw the same sort of transition from Xcode 4.6 to Xcode 5. Expect that gradient buttons will be rare, especially in toolbars. I don't think the new style will look just like Xcode 5—I expect we're in for more of a change than that—but I'd be surprised if this isn't part of it.
Finder in OS X 10.9
Xcode 4.6
Xcode 5
  • Dock changes
    The Dock seems like an obvious target for changes. Currently, the dock serves as a quick launcher, an app switcher, a container for minimized windows, a home for "Stacks," and the only visible location of the Trash icon. It's an unfocused mess.

    "Multiple, more-focused docks" is obviously not the right answer. They might remove running apps and just expect users to switch between them using Mission Control or by clicking on the window, but that just seems like it's removing functionality without any user benefit. Maybe they make it only show apps that currently have windows open? But then the quick-launch functionality is gone.

    So what does this all mean for the Dock? I'm not sure, really. But I think it's ripe for change; I'll be really surprised if the Dock stays exactly how it is right now.
     
  • Open/Closed apps
    I expect Apple to continue reducing the distinction between "running" and "non-running" apps. Recent features like Mission Control suggest that Apple feels managing visible windows is more important than managing apps. (See also the trend toward integrating "Inspector" panels into the main window.) There's already an option to remove the indicator lights for open applications in the Dock, and in past years, Apple has indicated that the Automatic Termination feature will become more and more prominent.

    The iOS app management model is an inspiration for Apple, I believe. iOS users generally don't worry about whether an app is "running" or not; they just know that if they can see it, they can use it. Obviously, on a desktop system with multiple windows visible at the same time, things are more complex. But if things are already getting reshuffled visually, expect more movement in this direction.
     
  • Menu Bar
    The global menu bar is one of the hallmarks of OS X. Windows migrants protest its disconnection from the window content. Mac veterans point out its consistent location and reliability.

    More and more, I feel that most users will never find features available only through the menu bar. Right-click contextual menus are far more accessible to users than the global menu bar. Increasingly, the standard File menu is more about managing windows and tabs than about files. The View menu usually manages the state of the window, and the Window menu is just a list of app windows that most people never use.

    Honestly, I don't really think we'll see significant changes to the menu bar itself. Changing it would break too many assumptions from existing apps. But I wouldn't be surprised if the built-in apps start abandoning the traditional File, Edit, View, Window, Help setup for a more user-friendly structure.
      
  • Better access to iCloud documents
    Currently, if an app saves a file in iCloud, that file is really only available from within that app. It shows up in Finder's All My Files view, but that list is so huge that it's mostly unmanageable. I'd love for Finder to have a view of files organized by app. Essentially, each app would be a "folder" for its documents.
     
  • Siri
    We'll probably see Siri show up on OS X at some point. Maybe it will be this year? It's possible, but I'm not counting on it. If it shows up, I'll consider it a nice surprise.
     
  • Clock app
    I said it jokingly on Twitter, but it actually wouldn't surprise me if OS X included an iPad-like Clock app. Stopwatch included.
I suspect there will be lots of other exciting changes on OS X; I just don't know what they are. I'll look forward to this.

iOS 8

OS X is rumored to be the star of WWDC this year, but iOS will certainly have some new features too. The WWDC app lists 99 sessions with content relevant to iOS, and only 78 relevant to OS X. Some of this is surely just a reflection of the prominence of iOS in Apple's developer base, but it would be foolish to assume that iOS won't be getting anything interesting this year. 
  • App Services via Remote View Controllers 
    Back in October 2012, Ole Beggeman did some great investigative work on remote view controllers, used internally since iOS 6. The basic idea is that some portion of your app's interface is actually provided by a separate process. This is currently used for the Mail composition controller, for example; the pixels you see are actually generated in a separate app and then drawn into your app. Touches in that region are forwarded on to that helper app, such that everything appears to the user as if it all originated in the same app.

    Remote view controllers could resolve one of the longest-standing complaints about iOS—that apps are too "silo-ed off" from each other. Apps could instead provide interfaces to each other as "Services". Imagine if the Dropbox app could an interface for other apps to upload or download documents from within their app, without embedding a Dropbox SDK. Imagine if your university's LMS app could present a file-picking interface from Pages, and submit it as a homework submission for you. Or imagine if you could turn your Pages document as a homework submission from within the Pages app.

    This is the kind of thing that app services would allow. Of course, you'd have to have some programmatic way to discover available services and their purpose. Pages certainly isn't going to build in custom support for your university's LMS app. One approach might be for each app to declare the view controllers it can present in other apps via a plist. Each service might be labeled with its role, like these:

      - Document picker
      - Sharing service
      - Upload service

    The specific set of roles might expand over time, but the fundamental advantage is the ability for an app share its functionality with other apps on the system.
     
  • XPC and Sandboxing
    XPC is a framework for creating and managing helper processes, introduced in OS X 10.7. It and allows the developer to segment their app into multiple processes. There are two main advantages to this structure: stability and privilege separation.

    Stability is a simple one to understand: If one of the helper processes crashes, the main app is not affected; it can just carry on and launch the helper process again. If one portion of your app is especially prone to crashing (perhaps it parses user input?), you could separate that out into a separate process, and now your app is more stable.

    Privilege separation is the ability to limit the access of a process. If your parser has a vulnerability that allows access to any portion of memory, a malicious user might be able to gain access to data meant to be secure, such as user passwords, and upload them to a server2. On OS X, XPC services can also be given a more restrictive sandbox, such that the helper process would not even have access to the network. Even if there's a vulnerability in your parser code, blocking the ability of the parser to upload data to the network means that you've greatly limited the damage a malicious app can do.
     
  • Third-party keyboards?
    Users have long requesting support for third-party keyboards in iOS. One of my friends says that the main reason she won't get an iPhone is that she the Swype keyboard is not supported on iOS.

    Third-party keyboards have always been a security concern, though. A keyboard has access to every key you type. This means it has access to every username, password, social security number, and credit card number the user types in any app. Apple has long prioritized privacy and security over user features. I've always assumed that this was simply the death knell of third-party keyboard support in iOS.

    However, if we've already added App Services and Sandboxing in iOS 8, then there might be a way forward. There might be a special type of app service for third-party keyboards. These keyboard services would run in a very restricted sandbox; they would likely have no access to network, location, contacts, photos, etc. It could not launch other app services. Without this access, even a malicious keylogging keyboard would have no way to report your data. With these restrictions, Apple might consider allowing third-party keyboards.

    I think a lot of people would be excited to see this in iOS 8. It's possible, though, that Apple might prove out app services in iOS 8 before adding keyboard support in a later release. I won't say that I think this one's going to happen at WWDC 2014—it probably won't. But I'll hope for it anyway.
     
  • Healthbook
    Pretty much every rumor for months has indicated that iOS 8 will include a Healthbook app. It will apparently be able to track various health related biometrics, such as activity, sleep quality, heart rate, blood pressure, etc.

    It's a cool idea. The main question is how the data will be collected. Some metrics (step count, etc.) can be inferred just by motion of the phone itself. The rumors indicate, though, that it will have far more data than that. A report from 9to5Mac indicates that it will track metrics like "heart rate, hydration, blood pressure, physical activity, nutrition, blood sugar, sleep, respiratory rate, oxygen saturation, and weight." Some of these could perhaps be entered manually by the user, but if this is going to have any impact at all, most of this data collection has to be automatic.

    The rumored "iWatch" might be able to provide more of this data, as it would have direct skin contact. However, I think it's unlikely that any wearable tech will be announced at WWDC. Without that, I'm not sure how useful a Healthbook feature would be. If iWatch is to be released this fall, then perhaps Apple will refrain from announcing it at WWDC, but include Healthbook in iOS 8 when it ships this fall.

    Color me skeptical that we'll hear about Healthbook at iOS 8. I won't rule it out, but I'm skeptical. I just don't see how it can be useful without greater ecosystem support.
      
  • Much improved javascript performance
    Javascript performance is slower in third-party apps than in the native Safari app because the JIT compilation techniques used in Safari require write access to executable memory pages. This is considered a security concern in third-party apps, and thus JIT has been disabled there. I would be very surprised if this performance restriction is not removed in iOS 8 by means of out-of-process execution or rendering.

    I'm calling this one. It's coming.

Xcode and Developer Tools

There are a lot of TBA labs on the Tools track. I think there will be some really exciting stuff here. I keep a fairly close eye on the clang commit logs, though, and I've got a couple predictions.

  • Better formatting
    The clang-format project is an automatic code formatting tool built on clang libraries. While Xcode's code formatting ability is passable right now, they're nothing spectacular. In particular, Xcode often does really dumb things with multi-line dictionary literals or array literals. I'm hoping we'll see that improved in Xcode 5.2 (or whatever's coming next.)
     
  • Fewer tolls at our toll-free bridges
    ARC has done lots of wonderful things, but one thing it hasn't done is simplified toll-free bridging. Instead, we often see (__bridge MyFoo*) casts to specifically indicate that we don't want any memory management to happen. I think we'll see many of those casts disappear in common cases.
     
  • Better Beta Distribution tools
    Earlier this year, Apple acquired Burstly, the owners of TestFlight. TestFlight is a very widely-used service for distributing and managing beta versions of in-development apps. Shortly after the purchase, their Android platform was shut down. Beta distribution is a pain on both iOS and OS X right now. It involves collecting device UDIDs, managing provisioning profiles, etc. On Android, by contrast, users can be added to a beta simply by adding them to a Google Group. This is an area where developers are often frustrated with the Apple platform, and it's a great opportunity for them to win back some developer goodwill. I'm hopeful we'll see something exciting.
     
  • More improvements around Modules
    Last year, Apple introduced modules as a compiler feature. They enable the @import keyword, enable auto-linking of frameworks, and can make compilation times much faster. However, so far it's only been available for importing system frameworks. I've seen some commits on the Clang logs indicating that support for user modules is under development. I don't know if it will be ready for WWDC or not, but I'd love to see what the new possibilities here are.
     
  • Mogenerator (please?)
    Mogenerator is a great tool for working with Core Data. It automatically generates property declarations for you in .h and .m files, and then creates subclasses of those auto-generated classes for developer customization. If you're not using it, you absolutely should be. Even some Apple teams use it internally.

    Frankly, it seems insane that something like this isn't part of Xcode already.
Beyond that, I really have no idea. I don't think we'll see Xcode plug-ins this year; I think when they do that it will be a major revision number, and I don't think they're ready to call this Xcode 6. Is that a silly reason to hold back a feature? Probably, but I stand by my guess.

iCloud

Last year, I predicted that most of the iCloud talk at WWDC would be about how they've fixed all the bugs (especially with the iCloud-Core Data integration), and would not be announcing new features. Well, here's a quote from last year's Platforms State of the Union:
So this is an area that we have decided to not implement any new features this year but instead to focus on reliability and quality.
Nailed it. This year, I think we'll be back in feature land. I really have no solid evidence on any of the following points; they're just guesses and wishes, not predictions.

  • Improved Photo Stream service
    It's been said by many people: Instead of all the photos living on your device, with only the most recent ones living on Photo Stream, it should be the other way around. iCloud should store all my photos, and my phone should be able to download them on demand. Server storage is incredibly cheap these days; it seems like Apple should be able to do something better than what they've got right now.
     
  • Larger quotas
    Speaking of server storage costs, I hope we see the free storage tier bumped up dramatically from the current 5GB. Device backups alone can take up the majority of the free 5GB tier; I've turned off iCloud Backup on one of my devices because I was running out of space. If "always backed up, all the time" is supposed to be one of the big features of iCloud Backup, then they need to offer more space.
     
  • Server access
    One of the problems with iCloud document storage is that developers have no external access to the data. For example, many users have asked us at Day One for a way to add journal entries online. With iCloud document storage, there's simply no way for us to do this. Third-party servers have no access to the user's iCloud storage.

    If Apple allows server access, expect to see server provisioning profiles as part of it. People will complain about it, but I don't see Apple allowing this any other way.

Other

A few other predictions that just didn't fit anywhere above:
  • Improved Maps w/ Transit (iOS and OS X)
    In the Keynote session, they'll probably show off some fancy updates to Maps, including support for mass transit schedules. They won't cut off the existing transit apps added in iOS 6, but for many users, this will be much simpler.
     
  • App Rentals
    A couple years ago, references to "App Rentals" were found in iTunes. I'd love to see developer able to mark their app as available for rent. A user might rent the app for 1 week at a cost of $0.99. After that period, the app would remain installed, but upon opening it the user would be informed that their rental period had expired. They could choose to rent it again, purchase the app, or exit.

    It would be opt-in by the developer, of course, but I think most developers would be extremely excited for this. If developers were allowed to limit the number of times an app could be rented, it could serve as an inexpensive "trial period" for users. I've been hoping for this ever since it was discovered, but who knows if we'll finally see it in iOS 8 or not.
     
  • Something else
    A new class for OS X and iOS whose SHA-1 hash is c1516c6879792c45fac4867d9a66b73e7d2514f93. (Post-WWDC update: The class is "WKWebView", which could be found in the open-source WebKit repositories weeks before WWDC.)


1: Of course, not all of those sessions will contain earth-shattering revelations; pretty much any mention of the word "new" is enough to redact the entire session until after the keynote. And yet, somehow "What's New in Foundation Networking" slips through unredacted. Not sure what's up with that.

2: This is perhaps a lesser concern on iOS, simply due to the difficulty of getting malicious payloads into the target app and the inability to spawn separate processes. Nevertheless, it's one that should not be simply ignored.

3: Yes, I'm totally taunting you here. The information is publicly available, and has been for weeks, but I haven't seen anyone else discussing it. But I don't want to be the one to spoil Christmas morning! The name of this class isn't actually all that exciting, but I think the technology behind it will make a lot of people happy.

Saturday, April 26, 2014

Mormon Questions: Mistaken Revelation

Mormons1 believe that we learn truth not only through scripture, but also through direct personal revelation from God. This is essential to our religion. Missionaries invite the people to seek divine confirmation that their message is true from the very first meeting. We teach the importance of personal revelation in Sunday School and in youth Primary classes. The Book of Mormon itself includes this invitation in its concluding chapter:

And when ye shall receive these things, I would exhort you that ye would ask God, the Eternal Father, in the name of Christ, if these things are not true; and if ye shall ask with a sincere heart, with real intent, having faith in Christ, he will manifest the truth of it unto you, by the power of the Holy Ghost. (Read in context)

And yet, personal revelation is a difficult doctrine. By its very nature, it is individual and non-verifiable. I cannot experience what you have experienced; I cannot show you what revelation feels or sounds or tastes like. I can tell you about my own experiences, but since God communicates to each person in their own way, my experience may not be relevant to you.

This means, of course, that I cannot verify that what you experienced is a revelation. Wishful thinking can easily be mistaken for revelation, as can trepidation or nervousness. The human mind has all sorts of ways to convince itself of things that may not actually be true. The doctrine of personal revelation is not one of pristine, unambiguous communication.

How can you know, then, if a supposed revelation really comes from God? How can we distinguish divine direction from internal monologue? What about other religions that claim divine revelation from a different source?2

The answer to misinterpreted revelation is, quite simply, practice. Like most learned skills, we'll probably make a lot of mistakes at first, and practice is the only way to figure it out. Fortunately, we actually have ample opportunity to do so. Each of us has a conscience, an internal sense for right and wrong. Mormons believe that this sense actually has a divine origin, known as the Light of Christ. When we listen to our conscience, we are actually learning to receive simple revelation. The same principles involved in recognizing right from wrong by instinct are used in discerning revelation. In the same way that sharing or sticking up for others just "feels right," revelation from God also "feels right."

Of course, none of us is perfect at following our conscience either. We've all experienced that moment when you realize that you made the wrong choice. That discomfort is instructive too; it teaches us to recognize correction. If we continually ignore our conscience, though, we'll eventually diminish our ability to recognize its guidance.

A key principle in recognizing true revelation, then, is consistently following your conscience. As you do so, you'll become more sensitive to its instruction. This will help you recognize other forms of revelation.

More specific revelation is available when we seek for it. Prayer at its best is simply communication with God. Two-way communication. Though it's easy to fall into a routine of saying the same repeated phrases every time we pray, prayer should resemble a conversation more than a monologue. Prayer should include questions, and silent time to ponder as we seek to discern revelation in response to those questions. God does answer.

This pattern of revelation continues; as we attune ourselves more toward God and follow his guidance more and more closely, we will have access to more specific and more frequent revelation. Our ability to communicate with God will increase, as will our ability to recognize it.



I am hesitant to judge the motivation and experiences of someone I don't know. I do not believe God would give one person truth and another a lie; all revelation from God is true and consistent. God might, however, guide a person (via revelation) to a best available option, even if none of those options is the ideal.3 Some who claim revelation may simply be mistaken, either through their own wishful thinking or by the deceptive action of another. And yes, some of them might simply be lying, claiming revelation in order to attract attention and exploit followers. Most people who seek revelation are sincere, though.

My experience in this faith, though, has shown me that many, many people receive compatible instruction through revelation. There is a universal truth, being revealed to many individuals independently. Further, revelation often gives us information we could not have known otherwise, giving us insight into the needs of those around us or explaining things we did not know. Learning to accurately recognize revelation takes time and practice, and we all make mistakes, but the principle is nonetheless true.

Remember, though, that revelation is not something only for a few elite. Everyone receives it in at least small measure through our conscience. The Book of Mormon teaches this:

But behold, that which is of God inviteth and enticeth to do good continually; wherefore, every thing which inviteth and enticeth to do good, and to love God, and to serve him, is inspired of God. (Read in context)

Whether or not you believe in God, choose to do good. If I'm right, it will increase your ability to recognize God's voice. If I'm wrong, it will still make the world a better place. Either way, choose Good.


I'd love to hear your questions or thoughts about this article, or any other questions you have about Mormons. Find me on Twitter (@bjhomer), or send me an email (bjhomer@gmail.com).

Also, I promise I've got some technical posts in the pipeline too. I haven't forgotten.


1: More acccurately, "members of the Church of Jesus Christ of Latter Day Saints". Though I don't find the term offensive, I think calling us "Mormons" is misleading to those unfamiliar with our faith. While belief in the Book of Mormon is a unique feature of our teachings, neither the Book of Mormon nor Mormon-the-person is a central figure of my faith, any more than rubber-band overscrolling is the core of the iPhone experience. It's a unique and identifying feature, but hardly the main point. Mormons follow, preach, and teach about Jesus Christ. All those other things just point us to him.

Yes, I will probably mention this in every "Mormon Questions" post. It's important to me.


2: There are actually surprisingly few Christian religions that preach modern revelation. Many teach that the Bible contains all we ever need to hear from God. Some teach that God can influence people in undefined ways to do good, but stop short of acknowledging specific revelation. I believe most non-Christian religions either teach that revelation has ceased, or concern themselves more with morals and practices than with revelation. I am not aware of any other religion teaching that God gives revelation today exactly as he did in Biblical or other ancient times. (I admit, though, that I am not familiar with all world religions. Surely such religions exist; I am simply unfamiliar with them and thus cannot address their specific claims.)

3: For example, this might happen in areas where Christianity is virtually unknown. God might still reveal to someone the importance of following one's conscience, or guide someone to an established religion in that area that would teach many correct principles until such time as His authorized church was available there.