diff --git a/2013-09-23-ios7.md b/2013-09-23-ios7.md index 96c77806..1d7e106a 100644 --- a/2013-09-23-ios7.md +++ b/2013-09-23-ios7.md @@ -4,8 +4,8 @@ author: Mattt Thompson category: "" excerpt: "With the NDA finally lifted, we can finally talk about all of the amazing new APIs in iOS 7." status: - swift: 1.1 - reviewed: May 20, 2015 + swift: 2.0 + reviewed: Sep 12, 2015 --- With the NDA finally lifted, we can finally talk about all of the amazing new APIs in iOS 7. And there are a _lot_ of them. "1500 new APIs", by Apple's count during the WWDC Keynote. (Granted, a good portion of that could just be all of the changes from `id` to `instancetype`, but that's a huge number, regardless). @@ -25,9 +25,9 @@ But no longer! iOS 7 finally bakes-in Base64: ~~~{swift} let string = "Lorem ipsum dolor sit amet." if let data = string.dataUsingEncoding(NSUTF8StringEncoding) { - let base64EncodedString = data.base64EncodedStringWithOptions(NSDataBase64EncodingOptions.allZeros) - - println(base64EncodedString) // TG9yZW0gaXBzdW0gZG9sYXIgc2l0IGFtZXQu + let base64EncodedString = data.base64EncodedStringWithOptions([]) + + print(base64EncodedString) // TG9yZW0gaXBzdW0gZG9sYXIgc2l0IGFtZXQu } ~~~ @@ -49,8 +49,8 @@ if let components = NSURLComponents(string: "http://nshipster.com") { components.path = "/iOS7" components.query = "foo=bar" - println(components.scheme!) // http - println(components.URL!) // http://nshipster.com/iOS7?foo=bar + print(components.scheme!) // http + print(components.URL!) // http://nshipster.com/iOS7?foo=bar } ~~~ @@ -86,7 +86,7 @@ Anything with a notion of completed and total units is a candidate for `NSProgre let progress = NSProgress(totalUnitCount: 100) progress.completedUnitCount = 42; -println(progress.localizedDescription) // 42% completed +print(progress.localizedDescription) // 42% completed ~~~ ~~~{objective-c} @@ -133,8 +133,8 @@ Behold! ~~~{swift} let array = [1, 2, 3] as NSArray -println("First Object: \(array.firstObject)") // First Object: Optional(1) -println("Last Object: \(array.lastObject)") // Last Object: Optional(3) +print("First Object: \(array.firstObject)") // First Object: Optional(1) +print("Last Object: \(array.lastObject)") // Last Object: Optional(3) ~~~ ~~~{objective-c} @@ -161,8 +161,9 @@ let smileDetector = CIDetector(ofType: CIDetectorTypeFace, context: context, options: [CIDetectorTracking: true, CIDetectorAccuracy: CIDetectorAccuracyLow]) var features = smileDetector.featuresInImage(ciImage, options: [CIDetectorSmile: true]) + if let feature = features.first as? CIFaceFeature where feature.hasSmile { - UIImageWriteToSavedPhotosAlbum(UIImage(CIImage: ciImage)!, self, "didFinishWritingImage", &features) + UIImageWriteToSavedPhotosAlbum(UIImage(CIImage: ciImage), self, "didFinishWritingImage", &features) } else { label.text = "Say Cheese!" } @@ -194,11 +195,11 @@ let session = AVCaptureSession() let device = AVCaptureDevice.defaultDeviceWithMediaType(AVMediaTypeVideo) var error: NSError? -let input = AVCaptureDeviceInput(device: device, error: &error) -if let error = error { - println("Error: \(error)") -} else { +do { + let input = try AVCaptureDeviceInput(device: device) session.addInput(input) +} catch let error { + print("Error: \(error)") } let output = AVCaptureMetadataOutput() @@ -214,7 +215,7 @@ func captureOutput( captureOutput: AVCaptureOutput!, didOutputMetadataObjects metadataObjects: [AnyObject]!, fromConnection connection: AVCaptureConnection!) { - + var QRCode: String? for metadata in metadataObjects as! [AVMetadataObject] { if metadata.type == AVMetadataObjectTypeQRCode { @@ -223,7 +224,7 @@ func captureOutput( } } - println("QRCode: \(QRCode)") + print("QRCode: \(QRCode)") } ~~~ @@ -290,9 +291,13 @@ Even though the number of people who have actually read something saved for late ~~~{swift} import SafariServices -let url = NSURL(string: "http://nshipster.com/ios7") -SSReadingList.defaultReadingList().addReadingListItemWithURL(url, title: "NSHipster", - previewText: "...", error: nil) +let url = NSURL(string: "http://nshipster.com/ios7")! +do { + try SSReadingList.defaultReadingList()?.addReadingListItemWithURL(url, title: "NSHipster", + previewText: "...") +} catch let error { + print("Error: \(error)") +} ~~~ ~~~{objective-c} @@ -345,7 +350,7 @@ let distance = portland.distanceFromLocation(sanFrancisco) let formatter = MKDistanceFormatter() formatter.units = .Imperial -println(formatter.stringFromDistance(distance)) // 535 miles +print(formatter.stringFromDistance(distance)) // 535 miles ~~~ ~~~{objective-c} diff --git a/2014-06-09-ios8.md b/2014-06-09-ios8.md index 575d1284..74f80ab0 100644 --- a/2014-06-09-ios8.md +++ b/2014-06-09-ios8.md @@ -4,7 +4,8 @@ author: Mattt Thompson category: "" excerpt: "Ask anyone, and they'll tell you: WWDC 2014 was the one of the most exciting in recent memory. This week, we'll take a look beneath the headline features, and share some of the more obscure APIs that everyone should know about." status: - swift: 1.0 + swift: 2.0 + reviewed: Sep 12, 2015 --- Ask anyone, and they'll tell you: WWDC 2014 was one of the most exciting in recent memory. It was, first and foremost, a developer event, with nary a hardware announcement to upstage the latest software & developer tools. @@ -51,7 +52,7 @@ let energyFormatter = NSEnergyFormatter() energyFormatter.forFoodEnergyUse = true let joules = 10_000.0 -println(energyFormatter.stringFromJoules(joules)) // "2.39 Cal" +print(energyFormatter.stringFromJoules(joules)) // "2.39 Cal" ~~~ ### NSMassFormatter @@ -61,7 +62,7 @@ Although the fundamental unit of physical existence, mass is pretty much relegat ~~~{swift} let massFormatter = NSMassFormatter() let kilograms = 60.0 -println(massFormatter.stringFromKilograms(kilograms)) // "132 lb" +print(massFormatter.stringFromKilograms(kilograms)) // "132 lb" ~~~ ### NSLengthFormatter @@ -71,7 +72,7 @@ Rounding out the new `NSFormatter` subclasses is `NSLengthFormatter`. Think of i ~~~{swift} let lengthFormatter = NSLengthFormatter() let meters = 5_000.0 -println(lengthFormatter.stringFromMeters(meters)) // "3.107 mi" +print(lengthFormatter.stringFromMeters(meters)) // "3.107 mi" ~~~ ## CMPedometer @@ -86,15 +87,16 @@ import CoreMotion let lengthFormatter = NSLengthFormatter() let pedometer = CMPedometer() pedometer.startPedometerUpdatesFromDate(NSDate(), withHandler: { data, error in - if !error { - println("Steps Taken: \(data.numberOfSteps)") + if let data = data { + print("Steps Taken: \(data.numberOfSteps)") - let distance = data.distance.doubleValue - println("Distance: \(lengthFormatter.stringFromMeters(distance))") + if let distance = data.distance?.doubleValue { + print("Distance: \(lengthFormatter.stringFromMeters(distance))") - let time = data.endDate.timeIntervalSinceDate(data.startDate) - let speed = distance / time - println("Speed: \(lengthFormatter.stringFromMeters(speed)) / s") + let time = data.endDate.timeIntervalSinceDate(data.startDate) + let speed = distance / time + print("Speed: \(lengthFormatter.stringFromMeters(speed)) / s") + } } }) ~~~ @@ -109,8 +111,8 @@ import CoreMotion let altimeter = CMAltimeter() if CMAltimeter.isRelativeAltitudeAvailable() { altimeter.startRelativeAltitudeUpdatesToQueue(NSOperationQueue.mainQueue(), withHandler: { data, error in - if !error { - println("Relative Altitude: \(data.relativeAltitude)") + if let data = data { + print("Relative Altitude: \(data.relativeAltitude)") } }) } @@ -124,10 +126,9 @@ if CMAltimeter.isRelativeAltitudeAvailable() { import CoreLocation class LocationManagerDelegate: NSObject, CLLocationManagerDelegate { - func locationManager(manager: CLLocationManager!, didUpdateLocations locations: AnyObject[]!) { - let location: CLLocation? = locations[0] as? CLLocation - if let floor: CLFloor? = location?.floor { - println("Current Floor: \(floor?.level)") + func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { + if let floor = locations.first?.floor { + print("Current Floor: \(floor.level)") } } } @@ -148,28 +149,28 @@ The following example shows how statistics summed over the duration of the day c ~~~{swift} import HealthKit -let collection: HKStatisticsCollection? = ... -let statistics: HKStatistics? = collection!.statisticsForDate(NSDate()) -for item: AnyObject in statistics!.sources { - if let source = item as? HKSource { - if let quantity: HKQuantity = statistics!.sumQuantityForSource(source) { - if quantity.isCompatibleWithUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) { - let massFormatter = NSMassFormatter() - let kilograms = quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) - println(massFormatter.stringFromKilograms(kilograms)) - } - - if quantity.isCompatibleWithUnit(HKUnit.meterUnit()) { - let lengthFormatter = NSLengthFormatter() - let meters = quantity.doubleValueForUnit(HKUnit.meterUnit()) - println(lengthFormatter.stringFromMeters(meters)) - } - - if quantity.isCompatibleWithUnit(HKUnit.jouleUnit()) { - let energyFormatter = NSEnergyFormatter() - let joules = quantity.doubleValueForUnit(HKUnit.jouleUnit()) - println(energyFormatter.stringFromJoules(joules)) - } +let collection: HKStatisticsCollection? = nil//... +let statistics: HKStatistics? = collection?.statisticsForDate(NSDate()) +let sources: [HKSource] = statistics?.sources ?? [] + +for source in sources { + if let quantity: HKQuantity = statistics?.sumQuantityForSource(source) { + if quantity.isCompatibleWithUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) { + let massFormatter = NSMassFormatter() + let kilograms = quantity.doubleValueForUnit(HKUnit.gramUnitWithMetricPrefix(.Kilo)) + print(massFormatter.stringFromKilograms(kilograms)) + } + + if quantity.isCompatibleWithUnit(HKUnit.meterUnit()) { + let lengthFormatter = NSLengthFormatter() + let meters = quantity.doubleValueForUnit(HKUnit.meterUnit()) + print(lengthFormatter.stringFromMeters(meters)) + } + + if quantity.isCompatibleWithUnit(HKUnit.jouleUnit()) { + let energyFormatter = NSEnergyFormatter() + let joules = quantity.doubleValueForUnit(HKUnit.jouleUnit()) + print(energyFormatter.stringFromJoules(joules)) } } } @@ -196,8 +197,8 @@ NSStream.getStreamsToHostWithName("nshipster.com", Also filed under: "small but solid fixes", is this convenience method for `NSString`: ~~~{swift} -let string: NSString = "Café" -let substring: NSString = "É" +let string: String = "Café" +let substring: String = "É" string.localizedCaseInsensitiveContainsString(substring) // true ~~~ @@ -245,12 +246,13 @@ 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")!, completionHandler: { data, response, error in // ... }) let protectionSpace = NSURLProtectionSpace() -NSURLCredentialStorage.getCredentialsForProtectionSpace(protectionSpace: protectionSpace, task: task, completionHandler: { credentials in +let credentialStorage = NSURLCredentialStorage() +credentialStorage.getCredentialsForProtectionSpace(protectionSpace, task: task, completionHandler: { credentials in // ... }) ~~~ @@ -317,7 +319,7 @@ let configuration = WKWebViewConfiguration() configuration.preferences = preferences let webView = WKWebView(frame: self.view.bounds, configuration: configuration) -let request = NSURLRequest(URL: NSURL(string: "http://nshipster.com")) +let request = NSURLRequest(URL: NSURL(string: "http://nshipster.com")!) webView.loadRequest(request) ~~~