Archive for November 25, 2014

Tuesday, November 25, 2014

WatchKit Links

Update (2014-12-02):

App Store Changes “Free” Buttons to “Get”

Juli Clover:

It is not entirely clear why Apple has decided to replace Free with Get, but it may have to do with the growing sentiment that apps with in-app purchases are not free. Earlier this year, the European Commission asked Apple and Google to implement changes to the way they sell apps, to avoid misleading customers about “free” games that are not actually free.

Tim Schmitz:

It doesn’t differentiate between apps that are “free with in-app purchases” and apps that are just FREE. I think it’s worth labeling apps that are free with no in-app purchases as such.

He and Jason Snell don’t like the “GET” label, but I’m not in favor of using the iCloud download icon because it connotes that I have previously selected that item.

JPEG Image Compression

David Austin:

We may think of the color of each pixel as represented by a three-dimensional vector (R,G,B) consisting of its red, green, and blue components. In a typical image, there is a significant amount of correlation between these components. For this reason, we will use a color space transform to produce a new vector whose components represent luminance, Y, and blue and red chrominance, Cb and Cr.

[…]

As is typical, the luminance shows more variation than the the chrominance. For this reason, greater compression ratios are sometimes achieved by assuming the chrominance values are constant on 2 by 2 blocks, thereby recording fewer of these values.

[…]

Now we come to the heart of the compression algorithm. Our expectation is that, over an 8 by 8 block, the changes in the components of the (Y, Cb, Cr) vector are rather mild, as demonstrated by the example above. Instead of recording the individual values of the components, we could record, say, the average values and how much each pixel differs from this average value. In many cases, we would expect the differences from the average to be rather small and hence safely ignored. This is the essence of the Discrete Cosine Transform (DCT), which will now be explained.

He also explains the improvements in JPEG 2000.

Wink in All Colors

Soroush Khanlou:

This techinque of merging two characters at rendering time is how this new emoji spec handles various skin tones. An emoji followed by a skin color swatch can be merged at glyph-rendering time to represent that emoji with that skin color.

If the emoji rendering system doesn’t implement this ligature, it will display the emoji followed by a graphical representation of the swatch of the skin color. This fallback is ugly, to be sure, but it signals the intent of emoji-sender effectively.

[…]

“When a human emoji is not followed by a emoji modifier character, it should use a non-realistic skin tone, such as that typically used for the smiley faces, or a silhouette.”

Microsoft Makes .NET Open Source

Microsoft (comments):

Delivering on its promise to support cross-platform development, Microsoft is providing the full .NET server stack in open source, including ASP.NET, the .NET compiler, the .NET Core Runtime, Framework and Libraries, enabling developers to build with .NET across Windows, Mac or Linux. Through this implementation, Microsoft will work closely with the open source community, taking contributions for future improvements to .NET and will work through the .NET Foundation.

The .NET Team:

Microsoft has a history of sharing .NET developer products as open source, including ASP.NET, Roslyn, NuGet, Entity Framework and Azure projects. You can now add .NET Core and .NET Framework reference source to that list.

We’re in the process of opening up all of .NET Core. Today, we’re publishing a few libraries, as a kind of down-payment. Expect to the see the corefx repo fill up over the next coming months and for a coreclr repo to appear.

Here’s the GitHub page (via Justin Spahr-Summers).

Update (2014-11-30): Accidental Tech Podcast discusses the open sourcing of .NET.

Strange Tales of Swift Initialization

Russ Bishop:

Swift appears to treat initialization quite differently than Objective-C, even though under the hood it is actually quite similar. They both use two-phase initialization, but Objective-C simply hides the first phase from you.

[…]

Objective-C slaps some zeros on it and calls it done. Swift has no choice but to offer you access to this initialization phase. And by offer I mean make you an offer you can’t refuse.

[…]

Once Swift has walked the class chain setting all properties to appropriate default values, even including partially executing your initializers up until the point where they call super, it then resumes executing initialization code starting from the most-derived superclass as it walks back up the chain.

[…]

If you have a funny suspicious feeling in the back of your mind right now congrats: you’re a seasoned Objective-C pro. A lot of classes in Objective-C don’t follow the proper rules for initialization and/or have incorrectly marked headers. This includes plenty of Apple’s own classes.

In other words, Swift’s strictness is causing crashes where there were none before, but this is only because of latent bugs in the frameworks. However, Swift’s initializer rules are also causing headaches and badly structured code.

The Story of DeltaGraph

Andrew Wulf:

The key idea we came up with was figuring out how to build all the charts resolution independent. Cricket Graph and most other charting applications including Microsoft's (Excel did not have built in charts yet) used Quickdraw to output the charts, which was basically just screen resolution. People in the newspaper, magazine, scientific journals, etc, industries really needed Postscript quality charts so they could print at their normal resolution and quality. The Wall Street Journal for example used a mainframe to build their charts. They would become a key supporter.

[…]

When I started the UI code I asked two questions of Deltapoint (1) will this code ever be ported to Windows (2) do you want to support multiple documents open at a time. The answer to both was no. Windows was still too primitive to care about and multiple open documents was fairly uncommon.

[…]

One time General Motors had said that if we supported a certain chart type they would buy 10,000 copies. Of course we quickly added it and then they decided not to after all.

iPhone 6 Pixel Peeping

Ole Begemann on the iPhone 6 Plus (comments):

Result of rendering the test pattern at logical 3× scale after it got downsampled by the device. Notice how every line bleeds into neighboring pixels. In the section on the left, every single pixel is lit green at varying brightnesses. The black 1-pixel-wide gaps between each green line have been lost.

[…]

The test pattern (rendered at 2× scale) on an iPhone 5. This is how it is supposed to look. Perfect! Notice how much brighter the pixels are than on the iPhone 6 Plus (both devices were set to similar screen brightnesses).

[…]

Pixel-perfect rendering is a thing of the past on the iPhone platform. Having seen the rather severe results in the worst-case scenario (rendering a regular grid of hairlines), I am actually surprised how little of an issue the automatic downsampling is in practice. As I mentioned, I simply don’t notice anything of the effects I have illustrated here in real life.

Bryan Jones on the iPhone 6 (via John Gruber):

So, why does this display look so good? It turns out that what is different, like the iPhone 5 vs. the iPhone 4 is the proximity of the pixels to the glass in the iPhone 6 compared with the iPhone 5. With the iPhone 6, the pixels appear to be almost one with the glass. When the iPhone 5 came out, Apple bonded the display to the glass in an effort to get the pixels closer to the surface and Apple has appeared to make the pixels in the 6 even closer still.

Update (2014-12-17): Ole Begemann:

My tests show that activating Display Zoom on the 6 Plus has no discernible negative or positive effect on output quality. The effective scale factor changes from one non-integral number (2.61 px/pt) to another (2.88 px/pt), resulting in a final image that is just as flawed on a per-pixel level as it was before.

[…]

On the iPhone 6 […] The end result is a slightly blurry image which, unlike the ever-present-but-practically-invisible loss of image quality on the 6 Plus, looks clearly worse than the non-zoomed image at normal viewing distance. Especially text looks distinctly worse when Display Zoom is on. I’m not sure whether the lower-resolution screen on the iPhone 6 (326 ppi vs. 401 ppi) or the fact that upscaling is worse for image quality than downscaling is the major contributing factor here.

Moms With Apps

Tim Burks:

The @momswithapps website lists apps that work offline and that are free of IAP, social network links, and ads.

The site’s discover view is more pleasant to use than the App Store itself.

A Swift Corner Case

Geoff Pado:

Any call to a method or property that uses optional chaining will return the same type as it normally does, but wrapped in a optional. Which makes sense—any broken link in the chain will cause the whole thing to return nil. This is true even for methods that return Void. Chained calls will return Void?.

[…]

Because of the combination of optional chaining and implicit return, we suddenly were left with a closure that was automatically returning something of type Void?, which clashed with addOperationWithBlock()’s expectation of Void.

Share Extension Iterations

Daniel Jalkut:

The problem with all the targets on your Mac or iOS that may or may not support sharing pertinent data to your extension, is you have to walk them through the process of invoking you. When you’re deep into the development of a particular aspect of the user interface or mechanical behavior of your extension, what you really want is to repeatedly invoke the extension with the same, predictable kinds of data. Luckily, it’s possible on both Mac and iOS platforms for a host app to invoke sharing extensions programmatically, so you just need to choose a Run target that will predictably invoke your extension upon launching.

[…]

If you’re working on a Mac-based Share extension, the key to invoking it at runtime is to enlist the help of the NSSharingService infrastructure. You simply ask it for a service with your identifier, and ask it to “perform.”

iCloud Drive Splitting Folders

Drew McCormack:

It’s difficult to know exactly what is happening, but it seems iCloud Drive is generating extraneous folders during conflict resolution.

[…]

For many apps, this is no big deal, and may never arise. But if your app stores data at specific paths in iCloud Drive, it could very easily become a problem.

[…]

If you are removing and re-adding folders in your app at a specific path in iCloud Drive, don’t be surprised if one day you discover the data is gone, and moved into a second version of the folder at a different path.

I consider this pretty undesirable behavior. No other sync solution I know does this. Dropbox doesn’t — although Dropbox does do something similar to this with files rather than directories — and the original iCloud file sync also didn’t do it.

RaceSplitter Rejected for Slide to Start

Matt Henderson:

In RaceSplitter, we use a slider labeled “Slide to Start Race” as the UI control for starting the race timer. This was introduced three years ago, in response to users inadvertently starting races when the control was a simple button. (Our customers appreciated this change, since, when staring at 500 participants on a start line, it’s all too easy to accidentally tap a start button.)

So three years and 13 versions later, Apple are now rejecting the app with the claim that this control could cause user confusion vis-a-vis the UI control that Apple used to use to unlock devices in versions of iOS predating iOS 7.