Skip to content

Commit

Permalink
Minor edits
Browse files Browse the repository at this point in the history
  • Loading branch information
natecook1000 committed Sep 15, 2015
1 parent 3d3076c commit 9fb42ea
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 34 deletions.
19 changes: 14 additions & 5 deletions 2013-08-19-nshashtable-and-nsmaptable.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,8 @@ hashTable.addObject("foo")
hashTable.addObject("bar")
hashTable.addObject(42)
hashTable.removeObject("bar")
print(hashTable.allObjects)
print("Members: \(hashTable.allObjects)")
~~~

~~~{objective-c}
NSHashTable *hashTable = [NSHashTable hashTableWithOptions:NSPointerFunctionsCopyIn];
[hashTable addObject:@"foo"];
Expand Down Expand Up @@ -65,17 +64,19 @@ NSLog(@"Members: %@", [hashTable allObjects]);
- `NSMapTable` can `copy` its values on input.
- `NSMapTable` can contain arbitrary pointers, and use pointer identity for equality and hashing checks.

> *Note:* `NSMapTable`'s focus on strong and weak references means that Swift's prevalent value types are a no go—reference types only, please.
### Usage

Instances where one might use `NSMapTable` include non-copyable keys and storing weak references to keyed delegates or another kind of weak object.

~~~{swift}
let delegate: AnyObject = ...
let mapTable = NSMapTable(keyOptions: .StrongMemory, valueOptions: .WeakMemory)
mapTable.setObject(delegate, forKey: "foo")
print("Keys: \(mapTable.keyEnumerator().allObjects)")
~~~

~~~{objective-c}
id delegate = ...;
NSMapTable *mapTable = [NSMapTable mapTableWithKeyOptions:NSMapTableStrongMemory
Expand Down Expand Up @@ -105,7 +106,11 @@ extension NSMapTable {
}
set {
setObject(newValue, forKey: key)
if newValue != nil {
setObject(newValue, forKey: key)
} else {
removeObjectForKey(key)
}
}
}
}
Expand All @@ -121,7 +126,11 @@ extension NSMapTable {
- (void)setObject:(id)obj forKeyedSubscript:(id)key
{
[self setObject:obj forKey:key];
if (obj != nil) {
[self setObject:obj forKey:key];
} else {
[self removeObjectForKey:key];
}
}
@end
Expand Down
7 changes: 1 addition & 6 deletions 2013-09-23-ios7.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,12 +292,7 @@ Even though the number of people who have actually read something saved for late
import SafariServices
let url = NSURL(string: "http://nshipster.com/ios7")!
do {
try SSReadingList.defaultReadingList()?.addReadingListItemWithURL(url, title: "NSHipster",
previewText: "...")
} catch let error {
print("Error: \(error)")
}
try? SSReadingList.defaultReadingList()?.addReadingListItemWithURL(url, title: "NSHipster", previewText: "...")
~~~

~~~{objective-c}
Expand Down
59 changes: 46 additions & 13 deletions 2014-06-09-ios8.md
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ import CoreMotion
let lengthFormatter = NSLengthFormatter()
let pedometer = CMPedometer()
pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { data, error in
pedometer.startPedometerUpdatesFromDate(NSDate()) { data, error in
if let data = data {
print("Steps Taken: \(data.numberOfSteps)")
Expand All @@ -98,7 +98,7 @@ pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { data, error in
print("Speed: \(lengthFormatter.stringFromMeters(speed)) / s")
}
}
})
}
~~~

## CMAltimeter
Expand All @@ -110,11 +110,11 @@ import CoreMotion
let altimeter = CMAltimeter()
if CMAltimeter.isRelativeAltitudeAvailable() {
altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { data, error in
altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue()) { data, error in
if let data = data {
print("Relative Altitude: \(data.relativeAltitude)")
}
})
}
}
~~~

Expand Down Expand Up @@ -149,12 +149,12 @@ The following example shows how statistics summed over the duration of the day c
~~~{swift}
import HealthKit
let collection: HKStatisticsCollection? = nil//...
let collection: HKStatisticsCollection? = ...
let statistics: HKStatistics? = collection?.statisticsForDate(NSDate())
let sources: [HKSource] = statistics?.sources ?? []
for source in sources {
if let quantity: HKQuantity = statistics?.sumQuantityForSource(source) {
if let quantity = statistics?.sumQuantityForSource(source) {
if quantity.isCompatibleWithUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) {
let massFormatter = NSMassFormatter()
let kilograms = quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo))
Expand Down Expand Up @@ -194,11 +194,11 @@ NSStream.getStreamsToHostWithName("nshipster.com",

## NSString -localizedCaseInsensitiveContainsString

Also filed under: "small but solid fixes", is this convenience method for `NSString`:
Also filed under: "small but solid fixes", is this convenience method for `String`/`NSString`:

~~~{swift}
let string: String = "Café"
let substring: String = "É"
let string = "Café"
let substring = "É"
string.localizedCaseInsensitiveContainsString(substring) // true
~~~
Expand Down Expand Up @@ -246,15 +246,15 @@ The Foundation URL Loading System has remained relatively unchanged since last y
import Foundation
let session = NSURLSession()
let task = session.dataTaskWithURL(NSURL(string: "http://nshipster.com")!, completionHandler: { data, response, error in
let task = session.dataTaskWithURL(NSURL(string: "http://nshipster.com")!) { data, response, error in
// ...
})
}
let protectionSpace = NSURLProtectionSpace()
let credentialStorage = NSURLCredentialStorage()
credentialStorage.getCredentialsForProtectionSpace(protectionSpace, task: task, completionHandler: { credentials in
credentialStorage.getCredentialsForProtectionSpace(protectionSpace, task: task) { credentials in
// ...
})
}
~~~

## kUTTypeToDoItem
Expand All @@ -275,6 +275,23 @@ Most users are completely unaware that most pictures taken with phones these day

New to the Image I/O framework is a convenient new option for `CGImageDestination`: `kCGImageMetadataShouldExcludeGPS`, which does what you'd expect.

~~~{swift}
import UIKit
import ImageIO
import MobileCoreServices
let image = ...
let fileURL = NSURL(fileURLWithPath: "/path/to/output.jpg")
let options: NSDictionary = [kCGImageDestinationLossyCompressionQuality as NSString: 0.75,
kCGImageMetadataShouldExcludeGPS as NSString: true]
if let imageDestination = CGImageDestinationCreateWithURL(fileURL, kUTTypeJPEG, 1, nil),
let cgImage = image.CGImage
{
CGImageDestinationAddImage(imageDestination, cgImage, options)
CGImageDestinationFinalize(imageDestination)
}
~~~
~~~{objective-c}
@import UIKit;
@import ImageIO;
Expand Down Expand Up @@ -346,6 +363,22 @@ Imagine: with CloudKit and LocalAuthentication, nearly all of the friction to cr

LocalAuthentication works in terms of an `LAContext` class, which evaluates a specified policy, and gives a thumbs up or thumbs down on user authentication. At no point is any biometric information made available to the application—everything is kept safe on the hardware itself.

~~~{swift}
let context = LAContext()
var error: NSError?
if context.canEvaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, error: &error) {
context.evaluatePolicy(.DeviceOwnerAuthenticationWithBiometrics, localizedReason: "...") { success, error in
if success {
// ...
} else {
print("Error: \(error)")
}
}
} else {
print("Error: \(error)")
}
~~~
~~~{objective-c}
LAContext *context = [[LAContext alloc] init];
NSError *error = nil;
Expand Down
14 changes: 4 additions & 10 deletions 2014-11-03-uisplitviewcontroller.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,6 @@ override func viewDidLoad() {
navigationItem.leftItemsSupplementBackButton = true
}
~~~

~~~{objective-c}
- (void)viewDidLoad {
[super viewDidLoad];
Expand Down Expand Up @@ -111,13 +110,9 @@ There is one more optimization we can do for the iPhone 6+ via [`UISplitViewCont
When the user first launches the app, we can make the master view controller fully displayed until the user selects a list item:

~~~{swift}
import UIKit
class SelectColorTableViewController: UITableViewController, UISplitViewControllerDelegate {
private var collapseDetailViewController = true
// MARK: UITableViewController
override func viewDidLoad() {
super.viewDidLoad()
Expand All @@ -126,7 +121,7 @@ class SelectColorTableViewController: UITableViewController, UISplitViewControll
// ...
// MARK: UITableViewDelegate
// MARK: - UITableViewDelegate
override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
collapseDetailViewController = false
Expand All @@ -139,13 +134,14 @@ class SelectColorTableViewController: UITableViewController, UISplitViewControll
}
}
~~~

~~~{objective-c}
@import UIKit;
// SelectColorTableViewController.h
@interface SelectColorTableViewController : UITableViewController <UISplitViewControllerDelegate>
@end
// SelectColorTableViewController.m
@interface SelectColorTableViewController ()
@property (nonatomic) BOOL shouldCollapseDetailViewController;
Expand All @@ -154,8 +150,6 @@ class SelectColorTableViewController: UITableViewController, UISplitViewControll
@implementation SelectColorTableViewController
#pragma mark - UITableViewController
- (void)viewDidLoad {
[super viewDidLoad];
Expand Down

0 comments on commit 9fb42ea

Please sign in to comment.