- Passport (+I-797B)
- Hoodie
- Bluetooth headphones
- Surface
- 3DS/Vita (+games for 3DS)
- Nexus 9
- Kindle
Season's Greetings, NSHipsters!
As the year winds down, and we take a moment to reflect on our experiences over the past months, one thing is clear: 2014 has been an incredible year professionally for Apple developers. So much has happened in such a short timespan, and yet it's hard to remember our relationship to Objective-C before Swift, or what APIs could have captivated our imagination as much as iOS 8 or WatchKit.
It's an NSHipster tradition to ask you, dear readers, to send in your favorite tips and tricks from the past year for publication over the New Year's holiday. This year, with the deluge of new developments—both from Cupertino and the community at large—there should be no shortage of interesting tidbits to share.
Submit your favorite piece of Swift or Objective-C trivia, framework arcana, hidden Xcode feature, or anything else you think is cool, and you could have it featured in the year-end blowout article. Just comment on this gist below!
If you're wondering about what to post, look to
// | |
// Warnings.xcconfig | |
// | |
// The list of warnings we (don’t) use, and the reasons why. | |
// | |
// :MARK: Warnings in use: | |
// :MARK: -everything | |
// We want the best possible diagnostics, so we simply enable everything that exists, and then opt–out of what doesn’t make sense for us. | |
// | |
// :MARK: - Warnings not to be promoted: |
// | |
// Defaults.xcconfig | |
// | |
// Common customizations/sanitizations of the platform defaults for our projects. | |
// | |
// For compatibility reasons, the iOS platform has a couple of not–so–sensible defaults. | |
// This file collects, and annotates the deviations from these defaults. | |
// | |
// :NOTE: Some of the settings herein may be redundant for newly created projects/targets: | |
// Xcode’s project/target templates take several (but not all!) of these issues into account. |
// | |
// Warnings.xcconfig | |
// | |
// The list of warnings we (don’t) use, and the reasons why. | |
// | |
// :MARK: Warnings in use: | |
// :MARK: -everything | |
// We want the best possible diagnostics, so we simply enable everything that exists, and then opt–out of what doesn’t make sense for us. | |
// | |
// :MARK: - Warnings not to be promoted: |
I'm not 100% sure this is all accurate but:
It seems as though share extension predicates are a lot more specific than we originally thought. For example, if Instapaper declares support for only NSExtensionActivationSupportsWebURLWithMaxCount = 1
, this means that activity controllers configured with a URL but also some other item types too, e.g. a string, won't show Instapaper.
So basically if you have multiple items in your activity items array, your controller will only show extensions that support all types. I imagine this would be extremely limiting, and as such, think the best option is to:
- Only include a single provider in your items array. The provider would have a placeholder of a single type that will be provided to any activity or extension that isn't specifically accounted for
- In the provider, specifically hardcode alternative item types for activities that need an alternative to the placeholder type:
- "Copy" activity could use photo data, if present
- "Mail" activity woul
find /Applications ~/Applications -maxdepth 3 -name "*.app" | while read a ; do echo; echo -n "$a ___ "; codesign -vd "${a}" 2>&1 | awk '/version/ {print $3}'; done | awk -F'___' '{print $2 " " $1}' | sort -u |
Suppose we want to add support for a new iOS 8 API in our framework that replaces an older iOS 7 API. There are a few problems we might face:
- The new API will crash if we call it on iOS 7
- The new API won't compile if we build it using the iOS 7 SDK
- The old API will raise a deprecation warning if built with a deployment target of iOS 8 and up
These three problems require three different technical solutions:
- We can avoid calling the new API on an old OS version by using runtime detection (e.g.
respondsToSelector:
) - We can avoid compiling new APIs on old SDKs using the
__IPHONE_OS_VERSION_MAX_ALLOWED
macro
#import <Foundation/Foundation.h> | |
#if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000 | |
@interface NSString (PSPDFModernizer) | |
// Added in iOS 8, retrofitted for iOS 7 | |
- (BOOL)containsString:(NSString *)aString; | |
@end |
// Copyright (c) 2012 Tumblr. All rights reserved. | |
// License: Apache 2.0 | |
// We're using an 'active' class instead of the default :active pseudo selector because we can add/remove it easily | |
var elementsWithActiveStateSelector = ['.tumblelog', '.control', '.audio-player', '.tag', 'a', '.video', | |
'.gif-container', '.external-image-placeholder'].join(','); | |
$('#content').on('touchstart', elementsWithActiveStateSelector, function() { | |
var $el = $(this); |