Archive for the 'Apple' Category

macOS installer cards

Thursday, September 29th, 2016

Being both a creature of habit and a digital packrat, I never install macOS from the “Install macOS” app.

Instead, what I do is have a cache of 8 GB class-10 microSDHC cards (usually bought from Micro Center, but they make great Amazon filler items, too), which I permanently assign as macOS installer media.

(I would buy SDHC cards, but Micro Center sells the microSDHC cards for cheaper—50¢ cheaper as I write this.)

Populating the card

Once you have a card, you’ll need to put the bits on it. DiskMaker X is the easiest way to do this, though there is also a manual process.

Labeling it

Anonymous cards all of the same capacity and speed and possibly even description does not scale well as an inventory system. Ideally, your card comes in a clamshell case, like the Micro Center ones do, or you can reassign such a case that came with another card. You can probably even buy empty microSD cases, like you can CD jewel-cases.

I have a Brother labeler that I use to print a small label with the release’s version and marketing name on it: “OS X 10.7 Lion”, “OS X 10.8 Mountain Lion”, “OS X 10.9 Mavericks”, “OS X 10.10 Yosemite”, “OS X 10.11 El Capitan”, and now “macOS 10.12 Sierra”. That label goes on the front of the case.

Photo of my flash memory cards on which I have the past several years' macOS installers. Lion was on an SD rather than microSD card; Micro Center have changed their case form factor a few times; I started printing rather than hand-writing labels with 10.9, and I haven't yet labeled the card that will go to Sierra.
I wrote this while the Sierra installer application was downloading.

And then done

The very pretty installation volume that DiskMaker X created for Sierra, complete with window background matching the installer icon.

Now you have labeled, permanent installer media that you can use forever (or however long the cards last). If you ever need to roll back to an old version, reinstall the dot-zero from the card and then combo-update up to whatever version you want.

Accurately ripping ISO 9660 CDs on a modern Mac

Sunday, August 28th, 2016

Here’s how diskutil list describes a CD-ROM I bought at the Big Book Sale in Fort Mason:

/dev/disk14 (external, physical):
   #:                       TYPE NAME                    SIZE       IDENTIFIER
   0:        CD_partition_scheme                        *97.5 MB    disk14
   1:     Apple_partition_scheme                         84.9 MB    disk14s1
   2:        Apple_partition_map                         1.5 KB     disk14s1s1
   3:                        ISO                         46.1 KB    disk14s1s2
   4:                  Apple_HFS Operation Neptune CD    84.5 MB    disk14s1s3

This is an ISO 9660 “hybrid” disc. It presents a Mac volume when mounted on a Mac and a DOS/Windows volume when mounted on a DOS or Windows machine.

The HFS volume here is a fiction; the real ISO 9660 volume (despite its name of “Apple_partition_scheme”) is disk14s1—the first partition.

If you copy this partition, with something like:

sudo cp /dev/disk14s1 Operation_Neptune.iso

You will then have an accurate ISO 9660 disk image that you can mount on your Mac, and thus see the Mac contents, or on your DOS or Windows machine, and see those contents.

Updates

Saturday, October 25th, 2014

The blog’s back up. It’s been down most of the year, as rather a lot of you noticed.

Thank you, everyone who told me. Every time you told me my blog was down, you were also telling me that you missed it, or at least you needed it for something. You’re part of why I kept meaning to bring it back, and why I eventually did.

I work for Apple now.

I’m on the Foundation and Core Foundation team, which is part of Cocoa. Part of my job is reading the Radars you file about those two frameworks and making sure they go to the right people.

I live in San Francisco now.

I moved early in the year, not long after I had to change hosting providers after TextDrive breathed its last (that was why the blog went down in the first place) and shortly before I started at my job.

I moved for the job; I work in Infinite Loop.

(I also moved because I love San Francisco. I’ve been here a couple of times before, and fell in love with it when I first stepped out of Civic Center BART onto Market Street.)

I probably won’t write as much here anymore.

A big part of that is time constraints: Subtract the job, the commute, three square meals, and sleep, and I don’t have a lot of time in a day to pound out a blog post.

Then, of course, there’s the nature of the job: Being at Apple means I know some things that aren’t public. Not a lot, but enough. Better to be careful than accidentally say something here that I’m not supposed to.

The same goes for my being active on Stack Overflow.

You’re welcome to ask a question and send me the link, but somebody else will probably get to it before I will.

And, of course, MacTech. See above. (If you have a subscription, you might have noticed this already—my last article ran in August, I think.)

I won’t be at MacTech Conference this year, either. This is the first time in the conference’s history that I won’t be at it. But plenty of other fine folks will who are worth listening to and who are good company.

That’s all I have to say for now. For those of you who use Twitter, I’m still there.

Until next time.

Simple starter Cocoa app ideas

Wednesday, December 11th, 2013

Inspired partly by tonight’s Hour of Code, here are some index-card-sized outlines of some simple app projects you can make as someone new to Cocoa.

Text editor/word processor

  • Document-based Mac app
  • In document window: NSTextView
  • Use NSAttributedString to read/write document data
  • Document types:
    • public.plain-text
    • public.rtf
    • com.apple.rtfd
    • com.microsoft.word.doc
  • Extra credit:
    • Add a ruler (NSRulerView)

Picture viewer

  • Document-based Mac app
  • In document window: IKImageView
  • Use CGImageSource to read image (picture) & its properties
  • Document types:
    • public.png
    • public.jpeg
  • Extra credit:
    • Floating inspector panel showing the properties in an NSTableView
    • Color-correction panel (IKImageEditPanel)
    • Support folders (public.folder): display images from folder in IKImageBrowserView

PDF viewer

  • Document-based Mac app
  • In document window: PDFView
  • Use PDFDocument to read from .pdf file
  • Document types:
    • com.adobe.pdf
  • Extra credit:
    • Toolbar with zoom in/out buttons, zoom % field, page number field

More good iOS games

Saturday, May 25th, 2013

Inspired by this post from last year by Mike Lee, here’s a list of the best games from my iOS app library.

Many games are excluded, for any of these reasons:

  • Games on this list must not be violent (e.g., I excluded Carmageddon and even Bastion, Sonic 2, and Sonic 4)
  • Games on this list must not be Zynga-tastic (e.g., I excluded Draw Something)
  • Games on this list must not be on last year’s list (see Mike’s post)

Also, I’ve restricted myself to iOS games. Some of the games below are available on multiple platforms, but all of the links are to the iOS App Store.

The games

(Enigmo violates the “not on Mike’s list” requirement, but I gave it a pass for two reasons: because I linked to both the iPhone and iPad versions, and because I linked to the sequel.)

Why you should almost always write a test app for your Radar bug reports

Wednesday, November 9th, 2011
  1. You’ll understand the bug better. This means you can write a better bug report, which will help Apple fix it more quickly (meaning you may get the fix more quickly).

  2. They’ll understand the bug better. This, too, helps Apple fix it more quickly.

  3. You may find that it is not a bug in the API at all, but that you were misusing it. Perhaps you were using something on a thread that you shouldn’t have been, or expecting some argument to be used a certain way when it’s actually used differently.

    In this case, you may be able to use the API after all, saving you the time you would have spent hacking around a non-bug. This also saves them the time they would have spent triaging and eventually responding to a non-bug.

    If your misunderstanding was borne out of poor documentation (misleading, inaccurate, vague, incomplete), you can file a bug report about that instead. Then the documentation gets better and future users of the same API avoid making the same error you did.

A test app isn’t appropriate for every kind of Radar, but when it is, including it helps everyone.

iOS device user guides on the iBookstore

Sunday, October 16th, 2011

Apple has user guides for their three iOS devices (not counting the TV, in which iOS is an implementation detail), for both iOS 4.3 and 5, free on the iBookstore:

iOS 4.3

iOS 5

Conferences 2011

Monday, September 12th, 2011

It’s that time again! Just like last year, there are a bunch of different conferences going on; unlike last year, I’m not going to even attempt to list all of them.

The two that I have a reason to mention are:

  • Voices That Matter. This time it’s in Boston, November 12 and 13. Their early bird pricing is still on through September; I’ll let their site tell you more. As I do whenever I mention it here, I have a coupon code for it, which is BSTBLOG. As usual, due to time and expense constraints, I won’t be attending this one.
  • MacTech Conference. I’m presenting again—same topic as last year, how to recognize, find, and fix bugs in Cocoa applications, but this time it’s the Xcode 4 edition. The early bird period has ended, but you can get the same $500 off by signing up through this referral link. The time and place is November 2, 3, and 4 in Universal City, California.

Last year at the MacTech Conference, I brought with me some of my useful Cocoa links business card. I’ll be doing that again this year, so if you attend the MacTech Conference, feel free to ask me for one.

I hope to see you at the MacTech Conference!

How to make me lose all interest in your app and not even want to try it much less buy it

Tuesday, April 26th, 2011

Choose any—or, preferably, none:

  • Make custom buttons, but don’t hire a professional designer to design them. Draw your UI in your pirated copy of Photoshop and make the best buttons you, fellow non-graphically-superpowered programmer, can manage, which look like you downloaded them from GeoCities in 1995 or got them out of a “1001 Buttons!” book from the same year.
  • Make custom UI controls (especially buttons) simply because you can.
  • Fill your App Store page’s “screenshots” section with images that are not purely screenshots. Showing an iPhone 4 with your app on it is a minus. Showing an older iPhone is another minus. Putting in your own inane blather marketing copy with your paint program’s text tool is a minus. Putting the iPhone and/or text on any kind of background is a minus. Any image that does not show the app at all is 500 minuses.
  • Show screenshots, but only of some of the app. Leave me wondering whether your app has the feature or UI pattern I’m looking for. (If your app is free, I’ll try it and find out. If it’s not, I won’t.)
  • Custom backgrounds without (good) custom UI. Extra debit if your background is plain white.
  • Abbr btn nms.

How to keep me actually interested and maybe even get me to buy your app:

  • If you make custom UI, make it awesome. Make a truly original UI that would belong on the cover of Macworld. Make it a custom UI with a purpose that guides and justifies the customizations. (Beware the difference between “purpose” and “theme”.) Otherwise, stick to plain Cocoa Touch controls wherever possible. Functional beats ugly.
  • If you go functional, follow the HIG. Either way, keep things clean and well-organized. Don’t force too much into a single screen. If you “have to” pack multiple things on a line, that’s too much. If you “have to” abbreviate words, that’s too much. Consider cutting features; simplicity is a virtue. If you need to break things out into other views, do it.
  • The screenshots section is for screenshots only. If you need to indicate a gesture, composite in a finger and an arrow, and don’t do that in more than one screenshot. No added text. Ever.

Don’t miss the comments. I’m sure some of you have some other don’ts to suggest that I forgot.

The application delegate and the new singletons

Friday, March 18th, 2011

Here is a global variable:

Wizard *gWizard;

I’ll call this a zeroth-order global, on the premise that I need to talk to exactly zero objects (including classes) to gain access to this object.

Next, let’s look at a singleton:

[Wizard sharedWizard]; //hope he's not busy

I’ll call this a first-order global, as we need to ask the class for it (1 step) to gain access to it.

Now, here’s a second-order global:

MyAppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];

(I use UIApplication here because I see this most frequently in Cocoa Touch code, but the pattern applies equally to Cocoa.)

And here’s a third-order global:

Wizard *wizard = [appDelegate wizard];

I need to (1) ask the UIApplication class for the application object, (2) ask that for its delegate, and (3) ask that for the wizard. (Assume here that wizard is a property, not a factory method that creates Wizards on the fly.)

None of these is any less global. If I can get to it from anywhere in the program without knowing about it directly, it is global.

Therefore, all the problems of globals apply:

  • What if two threads want to use the same Wizard?
  • What if the Wizard has a delegate of its own, and I have two objects that want to be its delegate?
  • What if the Wizard keeps internal state that may be corrupted by multiple objects trying to use it? (Nothing should have to worry about this outside of the Wizard itself.)

Your application’s objects form a graph. It should not be a complex one like this:

At the top, the application object. From it, its delegate. From it, your controller objects and a wizard. From each controller object, a path (colored in red) back to the delegate and then to the wizard.

Whenever you have paths bouncing around off of other objects like that, that’s a problem. The red arrows in the problem graph show where you violate the Law of Demeter.

Your object graph should, instead, be straightforward:

At the top, the application object. From it, its delegate. From it, your controller objects. From each one, a wizard.

Note that each of your controllers should own—or, if you prefer, hire—a Wizard all to itself. This eliminates contention between objects and reduces the likelihood of contention between threads (assuming each of the owning objects is supposed to only work on a single thread and not juggle multiple threads).

If contention is not a problem and you have a good reason why there should be only one Wizard, such as memory pressure or union regulations, then use a singleton. But use a real singleton, and only when necessary, and beware of singletons in disguise.

The new and improved Cocoa links card

Tuesday, March 15th, 2011

I’ve previously mentioned that I made a business card full of useful Cocoa and Cocoa Touch links to give to new Cocoa and Cocoa Touch programmers at events such as CocoaHeads.

Today, I have updated it and given it a web page. 1-up and 10-up (US Letter) PDFs are available there, as well as the full list of unshortened links.

I encourage you to print out the 10-up onto perforated business card paper, or have it professionally printed (keeping in mind that you probably won’t need 1000 of them), and make the cards available to novice Cocoa and Cocoa Touch programmers at the CocoaHeads or NSCoderNight events you attend. Just please be sure to print both sides, since my credit link is on the back.

Apple documentation search that works

Sunday, March 6th, 2011

You’ve probably tried searching Apple’s developer documentation like this:

The filter field on the ADC documentation library navigation page.

Edit: That’s the filter field, which is not what this post is about. The filter sucks. This isn’t just an easy way to use the filter field; it’s an entirely different solution. Read on.

You’ve probably been searching it like this:

Google.

(And yes, I know about site:developer.apple.com. That often isn’t much better than without it. Again, read on.)

There is a better way.

Better than that: A best way.

Setup

First, you must use Google Chrome or OmniWeb.

Go to your list of custom searches. In Chrome, open the Preferences and click on Manage:

Screenshot with arrow pointing to the Manage button.

In OmniWeb, open the Preferences and click on Shortcuts:

Screenshot of OmniWeb's Shortcuts pane.

Then add one or both of these searches:

For the Mac

Chrome OmniWeb
Name ADC Mac OS X Library
Keyword adcmac adcmac@
URL http://developer.apple.com/library/mac/search/?q=%s http://developer.apple.com/library/mac/search/?q=%@

For iOS

Chrome OmniWeb
Name ADC iOS Library
Keyword adcios adcios@
URL http://developer.apple.com/library/ios/search/?q=%s http://developer.apple.com/library/ios/search/?q=%@

Result

Notice how the results page gives you both guides and references at once, even giving specific-chapter links when relevant. You even get relevant technotes and Q&As. No wild goose chases, no PDF mines, no third-party old backup copies, no having to scroll past six hits of mailing-list threads and Stack Overflow questions. You get the docs, the right docs, and nothing but the docs.

For this specific purpose, you now have something better than Google.

Another Voices That Matter conference coupon

Friday, January 28th, 2011

The next Voices That Matter iPhone developers’ conference is April 9–10 in Seattle. Early-bird pricing lasts until February 25, and the coupon code this time is SEABLOG. The total for the “core conference” with both discounts is $395 USD.

As usual, I don’t expect to be there. Have fun without me!

End of the Graveyard

Saturday, December 4th, 2010

The iPhone Application Graveyard is now closed.

I’ve been meaning to do this for months; I’m just now getting around to doing it.

I have a few reasons:

The Graveyard has served its purpose.

The iPhone App Store today is more open and more free than it originally was. The rules are now available to App Store developers, and several apps that Apple previously either rejected or “pocket rejected”, most prominently Google Voice, are now available in the Store.

I don’t know how much of this is attributable to the Graveyard and how much is just Apple having figured these things out, but to whatever extent the Graveyard is responsible, it has done all it can.

The Graveyard can do no more.

Apple’s made very clear that they intend to “curate” the App Store. It will never be a completely free, do-as-thou-wilt market like the Mac market still is, and I have no hope that Apple will ever make the iPhone App Store optional like the Mac App Store will be.

I see no way that the App Stores can ever be more free without losing that curation factor. And it is a factor—I can’t ignore that Apple checking every application probably, hopefully filters out some effluent from the influent stream.

I don’t update it.

I’ve got a dozen different things to do that are more important than updating the Graveyard.

I want to work at Apple.

Cold, hard reality is that I want to work for Apple, and they will not hire a person that has a page on their website decrying their policies. (Don’t get me wrong: I wouldn’t expect them to.) This isn’t the only reason why I’m killing the Graveyard—everything I wrote above is true—but it is one of them.

So, this position is now open.

If you want to keep the Graveyard alive, you can do that by taking it over.

The Graveyard is implemented as a couple of plain-text hand-edited databases and a Python script that converts them to the web page (as a static HTML file) and Atom feed (as a static XML file). This is how the Graveyard stayed up in the face of being Fireballed, Macworlded, etc.

You can keep it that way, or you might turn it into a wiki. I leave the choice to you.

If you want to take over the Graveyard, email me. I’m sure you know my email address by now. I’ll send whoever I think can best run it a zip archive of the data files and Python script.

You may also be interested in the Application Submission Feedback site. I don’t know who runs it, but it’s a great guide to what you can’t do in the App Store.

Manpage Monday: memset_pattern(3)

Monday, September 6th, 2010

From the manpage:

     void
     memset_pattern4(void *b, const void *pattern4, size_t len);

     void
     memset_pattern8(void *b, const void *pattern8, size_t len);

     void
     memset_pattern16(void *b, const void *pattern16, size_t len);

These are analogous to memset(), except that they fill memory with a replicated pattern either 4, 8, or 16 bytes long.

Handy if you want to scribble 0xdeadbeef (or any other value of your choice) over something.

As noted in the manpage, these functions require Mac OS X 10.5 or later. I don’t know about iOS.

An iTunes imagine spot

Thursday, June 10th, 2010

Nik Fletcher writes:

If you’re an iPhone developer, you’ve probably been using AppViz, AppFigures or AppSales Mobile to download an process your iTunes sales reports. Today, however, Apple have released a new app of their own: iTunes Connect Mobile (iTunes Store Link)..

Wouldn’t it be cool if they released a version of iTunes Connect that could upload music and movies as well as view app statistics?

Imagine, for example, a moviemaker recording a movie on their iPhone 4, editing it in iMovie on their iPhone 4, and uploading it to iTunes from their iPhone 4.

Useful iTunes smart playlists

Thursday, May 20th, 2010

All of these are “All” (logical and/set intersection) playlists.

Music only

  • Playlist is Music (Library)
  • Kind does not contain “URL”
  • Kind does not contain “stream”
  • Kind does not contain “ideo” [sic]
  • Kind does not contain “PDF document”
  • Genre does not contain “Comedy”
  • Genre does not contain “Spoken Word”
  • Genre does not contain “Podcast”

Never played (music queue)

  • Playlist is “Music only”
  • Play Count is 0

≥ 3.5 stars

  • Playlist is “Music only”
  • Rating is greater than ★★★ · ·

iPod

The goal of this playlist is a balance between churn (so that I keep hearing music I haven’t heard in awhile) and quality (so that a bad or mediocre song does not take up space on my iPod that could have gone to a great song).

  • Playlist is “Music only”
  • Skip Count is less than 3
  • Playlist is “≥ 3.5 stars”
  • Time is less than 25 minutes (25:00)
  • Limit to 6 GB selected by least recently played

Customize standards and limit to your requirements.

Classical music (mostly excluded from this playlist by the Time criterion) enters my iPod through a separate playlist: a smart playlist selecting 12 hours of least-recently-played material from my “Programming music” dumb playlist.

Often-played but unrated music

If you’re like me, you have a lot of music that has racked up more than a few plays, but that you never rated. Most of this predates my installation of I Love Stars, with which I’ve rated nearly all of the music I’ve added since then.

By listening to this playlist with I Love Stars running, I’ll be able to rate all of these songs and so give the good-to-great ones a shot at being on my iPod. (I used to have “Play count ≥ 5” in the iPod smart playlist, but not everything that I have that has 5 or more plays merits inclusion on my iPod.)

  • Playlist is “Music only”
  • Play Count is greater than 4
  • Rating is · · · · ·

Setting the iPhone API documentation to iPad display mode on your Mac

Monday, April 5th, 2010

Those who’ve bought iPads have noticed that the iPhone API documentation comes in a special iPad-optimized flavor:

Basically, like an iPhone app for viewing the iPhone documentation. Here's a screenshot of the page in Safari on my Mac.

Yes, that’s desktop Safari showing it.

Contrary to my expectation, it does not use user-agent sniffing to detect an iPad. In fact, it’s detected by a JavaScript script (credit) when you go to an iPad-specific front page.

The code has a debugging feature, which they left in and you can (for now) enable to use the iPad display mode in your WebKit-based browser. Here’s how to enable it:

  1. Open any page on developer.apple.com.
  2. Open this URL:

    javascript:localStorage.setItem('debugSawtooth', 'true')
  3. Go to the iPad documentation list.

There are actually two interfaces, corresponding to the two orientations of a physical iPad. The one I showed above, with the API tree in a sidebar, is the landscape orientation; portrait moves the API tree into a pop-over, under a button labeled “Library”. The page chooses one or the other by the aspect ratio of the window.

“Sawtooth” has some drawbacks:

  • On a Mac, your scroll wheel (or two fingers) won’t work; you must drag the interface instead, which corresponds to finger-dragging on the actual device.
  • Once the interface loads, its size and orientation are fixed; it won’t adapt to a window resize until you reload. This, too, is only a problem on a Mac (you can’t resize your iPad).
  • There’s no way to copy a link to a specific document, unless you can find an internal link (the API-tree table view doesn’t count). This can be a problem if you want to link to, say, a framework reference.
  • You can’t get the Sawtooth interface unless you go through the iPad front page. If you go to a framework reference, class reference, programming guide, or other more specific page, you’ll get the regular interface. Same thing when going through the regular front page.

Even so, it’s pretty spiffy. I wish I had a version with all of the above problems fixed for viewing Mac API documentation.

* Credit: JR Ignacio found the JavaScript code and excerpted it into a GitHub paste.

Capture Cursor

Saturday, March 13th, 2010

Most people don’t know how to get the cursor that’s currently on the screen—a useful ability, especially if you’re writing screenshot or screen-recording software. I’ve written an app that demonstrates the technique, or at least tries to.

It’s a bit flaky. The API it uses, IOFramebuffer, doesn’t tell me how many frames there are or what format they’re in, so the app assumes ARGB in native byte-order and doesn’t worry about frames. This gives wrong results more of the time than I like.

I’ve filed a request for a higher-level API, which would make the task much easier and the app much shorter.

I’ve posted a build in the repository’s downloads area, in case you’d like to see it in action. If you want to build it yourself, you’ll need to download SGHotKeysLib and put the source where the Capture Cursor Xcode project expects it to be.

UPDATE 2010-08-28: I’ve pushed a change, [9cbec7dd5169], that deletes the IOFramebuffer-based category method and uses Snow Leopard’s new, far more reliable [NSCursor currentSystemCursor] instead. I suggest you do the same.

Voices That Matter iPhone Developers Conference 2010

Monday, February 22nd, 2010

I’m still Mac-only, so I still won’t be there, but here’s the information for this year:

  • The conference is in Seattle, Washington on April 24th and 25th.
  • The speakers, including Aaron Hillegass, Jonathan “Wolf” Rentzsch, Erica Sadun, and Eric Buck, will cover many different topics, including Core Data, Core Location and MapKit, in-app purchasing, UI design, and OpenGL ES.
  • Early bird pricing is $200 off until March 12th.
  • If you use the coupon code “PHBLOGS”, you’ll get another $100 off.

(I do still wonder what the “PH” stands for…)

If this sounds good to you, register for the conference.

See also Brent Simmons’s post about it. He wants to play pinball with you.