Archive for the ‘iOS’ Category

Solving Mathieu’s Phone: The mystery of disappearing gigs

The other day, Mathieu’s 16 GB phone suddenly had no space. Even after rebooting, even after reformatting (and not restoring from backup), all his spare bytes were being sucked into a black hole.

He had no songs, few apps, a modest number of photos, and under a gigabyte of space available, making him unable to compile, load, and tests his apps.

cvgmmpaxeaeooco

Each time he deleted one of his apps, the space would mysteriously fill up within a few minutes, adding to the ever increasing “other” bar in iTunes:

unspecified

This delete-then-lose-space behavior made me think that iCloud was trying to store files locally on his phone to reduce cloud access. I suggested that he disable iCloud and sync just the bare essentials like contacts, calendars, and notes. (Mathieu has a paid 300GB iCloud plan.) Sure enough once he logged out and rebooted, over 7GB of space was freed up and he was able to use his phone again.

I’m not super-familiar with iCloud so if anyone can further explain how this works, and how to set up the phone to limit it from glomming space, I’d sure appreciate being able to pass that along. Thanks!

Playgrounds Part III

Screen Shot 2016-06-14 at 2.49.47 PM

I have to call it a day, but I’m really happy with what I’ve learned about authoring Playground Books for iOS today. (I’m less happy learning about how to completely reset Xcode — either reboot your system or hop into terminal, do a ps -ax and grep for Xcode and then kill anything with the name in it.) I thought I’d share a few lessons.

If you are going to author for iOS, start with a new playground created from scratch in Xcode 8 rather than modifying an existing one. If you cannot import PlaygroundSupport, reboot your computer. If it doesn’t show up and you’re still using XCPlayground (now deprecated), you’re doing it wrong.

Understand that the Swift snapshot on iOS 10 is older than the Swift snapshot in Xcode so don’t expect to use really recent evolution implementations:

Screen Shot 2016-06-14 at 2.37.05 PM

I ended up implementing my own sequence functions to make my code work.

The easiest way to get started is just to AirDrop a normal playground.

Screen Shot 2016-06-14 at 3.09.40 PM

It will open automagically in Playgrounds for you. When you transfer books, you have to choose “open in Playgrounds” from the AirDrop menu.

If you want to author a Playgrounds Book before tomorrow’s session, just customize a blank document (download at your own risk). My blank book is a one-pager, and you can tweak the Contents.swift file in Blank.playgroundbook/Contents/Chapters/Document1.playgroundchapter/Pages/Blank.playgroundpage. There are manifests at every point along the way, try not to mess them up otherwise the book won’t open.

When authoring pages, either in a normal playground or playground book, you can annotate them to omit details that would otherwise clutter the interaction space or should not be visible to the reader. In my Spirograph playground (download at your own risk), I use special mix of normal playground markup (I have a couple of books that cover this markup format: my Doc Markup book and my Playgrounds book) and these new keywords:

  • Use #-hidden-code and #-end-hidden-code to exclude code from the reader’s view.
  • Mark editable areas with #-editable-code and #-end-editable-code, and if you like you can add a note to the opening tag.
  • To simplify code completion, you can globally omit code completion #-code-completion(everything, hide) and then choose which selectors to present, as I do in the following sample. You see this in the above screenshot, which offers one-tap access to just three customization points for my spirograph.
/*:
 **Spirograph:** Play around.
 
 - Note: The default values are:
 * minor: -3.0
 * offset: 130.0
 * color: .black()
 
 */
//#-hidden-code
import UIKit
import PlaygroundSupport

public var color = UIColor.black()
public var minor = -2.0
public var offset = 130.0

public func setMinor(_ value: Double) { minor = value }
public func setColor(_ value: UIColor) { color = value }
public func setOffset(_ value: Double) { offset = value }
//#-end-hidden-code
//#-code-completion(everything, hide)
//#-code-completion(identifier, show, setColor(_:), setMinor(_:), setOffset(_:))
//#-editable-code Tap to enter code
setMinor(-3.0)
setColor(.black())
setOffset(130.0)
//#-end-editable-code

//#-hidden-code
let liveView = UIImageView(600, 600, backgroundColor: .white())
PlaygroundPage.current.liveView = liveView
liveView.image = spiroImage(
 size: CGSize(width: 600.0, height: 600.0),
 samples: 4096, minor: minor, offset: offset, color: color)
//#-end-hidden-code

Parse to shut down on 28 Jan 2017

Kevin Lacker writes on the Parse blog,

We have a difficult announcement to make. Beginning today we’re winding down the Parse service, and Parse will be fully retired after a year-long period ending on January 28, 2017. We’re proud that we’ve been able to help so many of you build great mobile apps, but we need to focus our resources elsewhere.

We understand that this won’t be an easy transition, and we’re working hard to make this process as easy as possible. We are committed to maintaining the backend service during the sunset period, and are providing several tools to help migrate applications to other services.

Parse will release a database migration tool and will open source ParseServer. Regardless, this is going to come as a blow to a large segment of the iOS developer community.

More details at the New York Times.

Weekend Posts

CSS and Attributed Strings

Can you initialize an attributed string with CSS-populated HTML? This question popped up in #iphonedev. The answer is: kind of. HTML initialization is meant for lightweight use, not for full page layout. But yes, you can.

Screen Shot 2015-08-24 at 2.55.14 PM

This question in particular had to do with whether you could customize  list bullets:

Screen Shot 2015-08-24 at 3.05.37 PM

As far as I know, you cannot use externally sourced images but if you worked hard enough (and I’m not willing to do that), there are always attributed strings image attachments.

The upshot of all this is 1: I touched CSS. 2: I’m busy trying to figure out error naming. and 3: I figured that if it’s really important you’ll either use a web view or work out a post-hoc way to insert attachments that I’m not willing to spend any time on here but someone will point me to them if I throw out a post.

There you go.

source:

enum AttributedStringError : ErrorType {case Unconstructable}
func stringWithHTMLString(var string : String) throws -> NSAttributedString {
    string = string.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    if !string.hasPrefix("<html>") {string = "<html>" + string}
    if !string.hasSuffix("</html>") {string = string + "</html>"}
    guard let htmlData = string.dataUsingEncoding(NSUTF8StringEncoding) else {
        throw AttributedStringError.Unconstructable}
    var attributes : NSDictionary = [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType]
    let options = [String : AnyObject]()
    let aptr = AutoreleasingUnsafeMutablePointer<NSDictionary?>(&attributes)
    return try NSAttributedString(data: htmlData, options: options, documentAttributes: aptr)
}

Blast from the past: All I want for WWDC is…nothing

CCj7O_1VIAAa3fQ

Logo has been fixed by  Radek Pietruszewski ‏@radexp        

 

From February 2014: original post

February may seem early to you to be strategizing about Apple WWDC announcements. For tech writers, it’s crunch time. To plan books, posts, and other coverage, you try to anticipate how big a change is coming up and what areas will be affected.

For example, Victor was asking me the other day what I’d like to see in the next installments of iOS and OS X. My answer is the same as it’s been for years: “Bug fixes and security enhancements.” I’m a bit over the yearly update cycle.

Read On…

Flashback to Voice Control

Someone popped up today with a classic iPhone 3GS, looking for docs on the VoiceControl system. Sadly, Apple has long since expunged nearly everything VoiceControl related from their main site.

Screen Shot 2015-03-02 at 4.31.36 PM

 

Following some links, I hopped over to the Internet WayBack machine to find that not much has been saved. Although the main voice control page was there, few of the secondary pages, videos, or assets were archived. (You can still link to a couple of audio clips, and the second one on making calls still plays.)

I finally googled up the iPhone iOS 3.1 user guide, which contains about a page and a half of text. This material is still hosted, and I’d imagine this continuing for the foreseeable future.

It was an interesting reminder about the fleeting nature of information.

Size dumps

Make of this what you will. I’ve interspersed updates into everything that follows.

When I ran my older apps, everything ran at 320×568 on the new devices. To get the following numbers, I created entirely new projects. (Saniul Ahmed tweeted me that you need to provide current launch images to get the new dimensions.) Lesson: Update your launch images or create new projects to take full advantage of the new dimensions.

From the docs: “The iPhone 6 Plus uses a new Retina HD display with a screen scale of 3.0. To provide the best possible experience on these devices, include new artwork designed for this screen scale. In Xcode 6, asset catalogs can include images at 1x, 2x, and 3x sizes; simply add the new image assets and iOS will choose the correct assets when running on an iPhone 6 Plus. The image loading behavior in iOS also recognizes an @3x suffix.” So the 6 Plus is 3x. Right. (Even though it’s reporting oddly  in the below info dump.)

Compare and contrast with the marketing text: “The size of the new, higher-resolution Retina HD displays on iPhone 6 and iPhone 6 Plus may be the first thing you notice.” (The same  HD mention is here as well.) But the 6 non-plus is reporting correctly for @2x ,not @3x, so I suspect the marketing text is wrong. (Thanks akempgen)

Lesson: The 6 plus uses a 3x scale. The 6 does not. Retina HD seems to mean something different between marketing text (high density) and developer docs (3x resolution).

More explanation about iPhone 6 screens from the guys at PaintCode. Read about it here. Lesson: This new stuff is strange.

With no further ado, here are my original tests.

Testing iPhone 6 plus
iPhone Simulator
iPhone OS
8.0
iPhone Simulator
<UIView: 0x7f854596f7a0; frame = (0 0; 414 736); autoresize = W+H; layer = <CALayer: 0x7f854596bd50>>
<UIWindow: 0x7f854596e1e0; frame = (0 0; 414 736); gestureRecognizers = <NSArray: 0x7f854596edd0>; layer = <UIWindowLayer: 0x7f854596c0d0>>

Testing iPhone 6
iPhone Simulator
iPhone OS
8.0
iPhone Simulator
<UIView: 0x7ffb11415b80; frame = (0 0; 375 667); autoresize = W+H; layer = <CALayer: 0x7ffb11402be0>>
<UIWindow: 0x7ffb14113000; frame = (0 0; 375 667); gestureRecognizers = <NSArray: 0x7ffb14113a20>; layer = <UIWindowLayer: 0x7ffb1410f410>>

Testing iPhone 5s
iPhone Simulator
iPhone OS
8.0
iPhone Simulator
<UIView: 0x7fcb21d13d90; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7fcb21d13090>>
<UIWindow: 0x7fcb21d10e70; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7fcb21d11770>; layer = <UIWindowLayer: 0x7fcb21d0d140>>

Testing iPhone 5
iPhone Simulator
iPhone OS
8.0
iPhone Simulator
<UIView: 0x7a0d6a50; frame = (0 0; 320 568); autoresize = W+H; layer = <CALayer: 0x7a0d6310>>
<UIWindow: 0x7a17a5c0; frame = (0 0; 320 568); gestureRecognizers = <NSArray: 0x7a17ac00>; layer = <UIWindowLayer: 0x7a17a550>>

Testing iPhone 4s
iPhone Simulator
iPhone OS
8.0
iPhone Simulator
<UIView: 0x7ae9a000; frame = (0 0; 320 480); autoresize = W+H; layer = <CALayer: 0x7ae9c730>>
<UIWindow: 0x7ae9c600; frame = (0 0; 320 480); gestureRecognizers = <NSArray: 0x7ae9cb20>; layer = <UIWindowLayer: 0x7ae9c210>>

Anyway, this was what I tested out:
Screen Shot 2014-09-15 at 2.54.04 PM

Auto Layout: iOS 8

It’s been a pretty exciting summer as far as Auto Layout goes. I’m busy going over material so I can get some dates and work estimates to Trina on a possible 3rd edition of Auto Layout. Between Swift, OSX, iOS 8, and whatever is going to be announced in September, it looks like a particularly interesting place to be.

I can’t tell you how thrilled I am about active, the property that self-installs and removes constraints to their natural destination. I submitted my first radar on this back before the first edition was even published. Now with the third edition, I suppose I’ll be all “Yeah, that’s my radar baby!”

The long iOS 8 summer first gave us left and right layout guides, a la the top and bottom guides we first encountered in iOS 7 but they soon disappeared and have since been replaced by a suite of Margin-based layout attributes:

    NSLayoutAttributeLeftMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeRightMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeTopMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeBottomMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeLeadingMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeTrailingMargin NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeCenterXWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),
    NSLayoutAttributeCenterYWithinMargins NS_ENUM_AVAILABLE_IOS(8_0),

Comments and properties in the UIView header file indicate a layout tree of margins. I think it’s fair to assume this ties into the adaptive application that runs properly both on full-screen as well as side-by-side.

/*
 -layoutMargins returns a set of insets from the edge of the view's bounds that denote a default spacing for laying out content.
 If preservesSuperviewLayoutMargins is YES, margins cascade down the view tree, adjusting for geometry offsets, so that setting the left value of layoutMargins on a superview will affect the left value of layoutMargins for subviews positioned close to the left edge of their superview's bounds
 If your view subclass uses layoutMargins in its layout or drawing, override -layoutMarginsDidChange in order to refresh your view if the margins change.
 */
@property (nonatomic) UIEdgeInsets layoutMargins NS_AVAILABLE_IOS(8_0);
@property (nonatomic) BOOL preservesSuperviewLayoutMargins NS_AVAILABLE_IOS(8_0); // default is NO - set to enable pass-through or cascading behavior of margins from this view’s parent to its children
- (void)layoutMarginsDidChange NS_AVAILABLE_IOS(8_0);

Unfortunately, the material from WWDC is light on details and these updates didn’t take place until fairly recent betas. Got any insights into how this material will play out? I’d love to hear it. (And thanks in advance!)