Updating SceneKit WWDC 2013 slides for Xcode 7

With recent changes to the AppKit headers, you need to make a couple of changes to the WWDC 2013 SceneKit Slides code to get it to build. There are some cool examples in that year’s talk/sample code that didn’t make it into 2014’s.

In the ASCPresentationViewController, switch from a method declaration for the -view superclass override to a property in the header, and specify @dynamic for that property in the implementation.

@property (strong) SCNView *view;

//- (SCNView *)view;

 

@dynamic view;

//- (SCNView *)view {

//    return (SCNView *)[super view];

//}

I also updated the .xcodeproj to current standards, and fixed a couple of int/NSInteger/NSUinteger mismatches.

I’ve submitted it to Apple as rdar://23829155. In the meantime, here are the diffs:

diff --git a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h
index 7d66316..bb0e54f 100644
--- a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h
+++ b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.h
@@ -55,7 +55,9 @@
@property (weak) id <ASCPresentationDelegate> delegate;

// View controller
-- (SCNView *)view;
+// Hal Mueller change: make this a property, @dynamic, to compile under Xcode 7/10.11 SDK
+@property (strong) SCNView *view;
+//- (SCNView *)view;
- (id)initWithContentsOfFile:(NSString *)path;

// Presentation outline
diff --git a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m
index 46d9e00..1c914b6 100644
--- a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m
+++ b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCPresentationViewController.m
@@ -91,9 +91,10 @@ typedef NS_ENUM(NSUInteger, ASCLightName) {

#pragma mark - View controller

-- (SCNView *)view {
- return (SCNView *)[super view];
-}
+@dynamic view;
+//- (SCNView *)view {
+// return (SCNView *)[super view];
+//}

- (id)initWithContentsOfFile:(NSString *)path {
if ((self = [super initWithNibName:nil bundle:nil])) {
@@ -660,12 +661,12 @@ typedef NS_ENUM(NSUInteger, ASCLightName) {

#pragma mark - Misc

-CGFloat _lightSaturationAtSlideIndex(int index) {
+CGFloat _lightSaturationAtSlideIndex(NSInteger index) {
if (index >= 4) return 0.1; // colored
return 0; // black and white
}

-CGFloat _lightHueAtSlideIndex(int index) {
+CGFloat _lightHueAtSlideIndex(NSInteger index) {
if (index == 4) return 0; // red
if (index == 5) return 200/360.0; // blue
return 0; // black and white
diff --git a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m
index ce17c6f..cdc12a4 100644
--- a/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m
+++ b/SceneKit_Slides_WWDC2013/Scene Kit Session WWDC 2013/Sources/ASCSlideTextManager.m
@@ -71,7 +71,7 @@ static CGFloat const TEXT_FLATNESS = 0.4;
return self;
}

-- (NSColor *)colorForTextType:(ASCTextType)type level:(int)level {
+- (NSColor *)colorForTextType:(ASCTextType)type level:(NSUInteger)level {
switch (type) {
case ASCTextTypeSubtitle:
return [NSColor colorWithDeviceRed:160/255.0 green:182/255.0 blue:203/255.0 alpha:1];
Advertisements

iOS 6 maps are better for applications

I’m very happy to see the new look brought to iOS maps via Apple’s switch to an in-house solution. Much noise has been made about the errors and the lost detail. I think the lost detail is an improvement.

The other night, a friend and I did a side-by-side comparison of my app HistoryPointer on iOS 6 and iOS 5 (bonus points if you can figure out where we were sitting). HistoryPointer displays a bunch of points of interest on a map (further details aren’t especially relevant). On the top is the HistoryPointer running on iOS 6 (with maps from Apple); on the bottom it’s running under iOS 5 (with maps from Google).

IMG 1009

Photo

To my eye, the iOS 6 version is much easier to read when you’re looking for the overlaid points of interest.There are fewer labels on the Apple map than on the Google map. The color scheme is less intrusive. There are some problems with label placement on the Apple map: State Route 99, for example, near the right-hand edge, is missing its street name (Aurora Avenue) on the Apple version even though other less important streets are labeled.

I see lots of potential in this move. There’s a control panel to adjust label size on map views. There’s obviously some dynamic label generation and pruning going on. I like the prospect of enhancements to MapKit to allow programmatic control of many of these parameters. Imagine what you could do with API to do these things:

  • adjust the size of (or omit!) certain kinds of labels.
  • control the orientation of the map to maximize the use of the screen space. North doesn’t always have to be up.
  • apply a custom color scheme, so that your overlaid data is easier to read.
  • omit certain kinds of features. Not everyone wants driving directions. There are many applications where the streets, highways, and manmade features are simply clutter.

Think about the possibilities. How would you like your app’s MKMapView to be different? File those radars! I have several of my own in mind.

Brent Simmons: Notes from Mac programming class guest lecture

Last week, Brent Simmons was kind enough to visit the Mac programming class I’m teaching. He’s posted the notes from his talk online:

Notes from Mac programming class guest lecture: “The idea behind the lecture was to talk about what makes a great Mac app. I took that as an excuse to talk about everything from work habits to UI to marketing. “

(Via Brent Simmons inessential.com.)

iPhone responsiveness and memory usage

From fellow Big Nerd Ranch alum Jonathan Saggau:

iPhone responsiveness and memory usage: “I recently answered a question on a private mailing list about how to make a network – based (XML parsing and such) iPhone application more responsive. I’ve been encouraged to post it here by a few folks (Thanks, guys! You know who you are.). So, I figure ‘why not?’ Here you go. (Slightly modified)

(Via Jonathan Saggau’s Blog.)

AdMob ads, click bids, and spend rates

I’ve been running AdMob ads on the latest version of my iPhone Tides app. Earlier this week I decided to transfer some of the revenue into an AdMob ad purchase account, to experiment with advertising the app that was running the ads.

Setting up the ad on the AdMob site was quick and easy. I entered text and uploaded the app icon, and used the AdMob wizard to link to Tides in the iPhone App Store. There was no additional graphics work required. I entered a fairly low CPC bid of $.10 per click, quite a bit less than what appeared to be the going rate.

The next morning I checked my stats. No ads had been run, and no expenditure was registered. Hmm. I’ll try bumping up the bid to $.25.

Within 15 minutes I received 3 emails from the AdMob monitoring service. First was a note saying my ad had been approved. A few minutes later I had a warning that my ad account balance was low. Then came a note that my ad account balance was zero and my ads had been stopped. I checked the AdMob dashboard, and it showed only a handful of ad impressions, but a zero balance. Several hours later, the AdMob dashboard had caught up with reality.

From this experiment, I have these suggestions for small developers advertising on the iPhone:

  • The AdMob advertiser dashboard is not as responsive as other parts of their system. Don’t count on it for up-to-the-minute information on your campaign.

  • Set a very low, or even zero, bid rate for your campaign, until you see that your ad has been approved.
  • Although AdMob might look at lot like Google AdWords, they are very different programs. AdMob doesn’t give you nearly the same granularity of control as AdWords does. There is no keyword targeting for iPhone ads; you can’t be nearly as precise as you can with Google AdWords.
  • Keep your bid quite low. The fill rate for AdMob advertising within iPhone apps is running at about 70-90%, sometimes even less. So as long as your bid is high enough to get a bit of visibility, your ads will run. Make bid increases gradually. You aren’t bidding against other advertisers; you’re bidding against empty space.
  • Turn on the “daily budget” option. As of this writing the minimum daily budget is $100, which I think is quite high for a small developer. But even a number that large can be a useful safety valve for runaway campaigns.

How to Price Your iPhone App out of Existence

Finally, someone is talking some sense about iPhone App Store pricing. Andy Finnell writes, in How to Price Your iPhone App out of Existence: “By setting the price expectations so low, you are lying to your customers. You are saying ‘I can sustain development of this app for this price,’ when in fact, you can’t.”

(Via Safe from the Losing Fight.)