Ilya Loshkarev loshkarev.i@gmail.com
SFEDU 2017
// Authorize for location tracking in foreground
locationManager.requestWhenInUseAuthorization()
// Authorize for location tracking in background
locationManager.requestAlwaysAuthorization()
Fails silently without permission
Requires related privacy keys in Info.plist
.authorizedAlways // authorization for background updates
.authorizedWhenInUse // authorization for foreground updates
.notDetermined // authorization is not granted yet
.restricted // authorization is restricted by the device
.denied // authorization is explicitly denied
CLLocationManager.authorizationStatus()
locationManager.startUpdatingLocation()
locationManager.startMonitoringSignificantLocationChanges()
locationManager.startUpdatingHeading()
locationManager.startMonitoring(for: CLRegion)
locationManager(_:didChangeAuthorization:)
locationManager(_:didUpdateLocations:)
locationManager(_:didUpdateTo:from:)
locationManager(_:didUpdateHeading:)
locationManager(_:didEnterRegion:)
The protocol whose methods you use to receive events from an associated location manager object
var coordinate: CLLocationCoordinate2D
var altitude: CLLocationDistance
var timestamp: Date
var speed: CLLocationSpeed
var course: CLLocationDirection
locationManager.desiredAccuracy = kCLLocationAccuracyNearestTenMeters
locationManager.distanceFilter = 1
let accuracy = locationManager.location!.horisontalAccuracy
Less accurate location methods save battery power
mapView.mapType = .hybrid
mapView.showBuildings = true
Provides an embeddable map interface, similar to the one provided by the Maps application
protocol MKAnnotation : NSObjectProtocol {
public var coordinate: CLLocationCoordinate2D { get }
optional public var title: String? { get }
optional public var subtitle: String? { get }
}
To use this protocol, you adopt it in any custom objects that store or represent annotation data
mapView(_:viewFor:)
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? {
let pin = mapView.dequeueReusableAnnotationView(
withIdentifier: "pinAnnotationView") as! MKPinAnnotationView
pin.annotation = annotation
return pin
}
Annotation views remain anchored to the map at the point specified by their associated annotation object
geocodeAddressString(addressString: String,
completionHandler:([CLPlacemark]?, Error?) -> Void)
reverseGeocodeLocation(_ location: CLLocation,
completionHandler: ([CLPlacemark]?, Error?) -> Void)
Provides services for converting between a coordinate and the user-friendly representation of that coordinate
AVAsset
is a container for media streams
let player = AVPlayer(url: videoURL)
if player.currentItem.status == .readyToPlay {
player.play()
}
AVPlayer
is a basic object to play media files
AVAsset
is a container for media streams
let player = AVPlayer(url: videoURL)
let playerViewController = AVPlayerViewController()
playerViewController.player = player
self.present(playerViewController, animated: true) {
if let player = playerViewController.player!,
player.currentItem.status == .readyToPlay {
playerViewController.player!.play()
}
}
AVPlayerViewController
is a default way of presenting audio and video
Most AVPlayer callbacks are KVO based
// new item
player.addObserver(self, forKeyPath: "currentItem",
options: [.new, .initial] , context: nil)
// errors
player.addObserver(self, forKeyPath: "status",
options: nil , context: nil)
// update periodically
player.addPeriodicTimeObserver(
forInterval: CMTimeMake(1, 100), queue: DispatchQueue.main) {
time in print(String(format: "%02.2f", CMTimeGetSeconds(time)))
}
let queuePlayer = AVQueuePlayer()
let playerItem = AVPlayerItem(url:fileURL)
queuePlayer.insert(playerItem, afterItem:nil)
// queue as many items as you like
queuePlayer.play()
let recorder = AVAudioRecorder(url: resultURL, settings: [:])?
if recorder.prepareToRecord() {
recorder.record()
}
let session = AVCaptureSession()
let frontalCamera = AVCaptureDevice.defaultDevice(
withDeviceType: .builtInWideAngleCamera,
mediaType: AVMediaTypeVideo, position: .front)
if let input = try? AVCaptureDevice(frontalCamera) {
session.addInput(input)
}
view.setSession(session,
showVideoPreview: true, showAudioPreview: true)
view.delegate = self
AVCaptureView
is a default way of presenting a video capture
let asset = AVURLAsset(streamURL)
asset.resourceLoader.setDelegate(self, queue: DispatchQueue.main)
// play video/audio
let playerItem = AVPlayerItem(asset:asset)
let player = AVPlayer(playerItem)
// pause if playerItem is not ready yet
NSNotificationCenter.default.addObserver(self,
selector: #selector(pauseIfStalled),
name: AVPlayerItemPlaybackStalledNotification, object: nil)
player.play()
If you don't need to handle loading process events
default resourceLoader works just fine
let session = AVCaptureSession()
Allows to access any capture devices
and configure capture settings
Manages the notification-related activities for your app
let center = UNUserNotificationCenter.current()
center.getNotificationSettings
{ setting in print(settings.authorizationStatus) }
center.requestAuthorization(options: [.alert, .sound, .badge])
{ granted, error in print (granted) }
func userNotificationCenter(_ center: UNUserNotificationCenter,
didReceive response: UNNotificationResponse,
withCompletionHandler completionHandler: @escaping () -> Void)
{ /* user taped on notififcation */ }
func userNotificationCenter(_ center: UNUserNotificationCenter,
willPresent notification: UNNotification,
withCompletionHandler completionHandler:
@escaping (UNNotificationPresentationOptions) -> Void)
{ /* notification should be presented in foreground */ }
Stores the content of a local or remote notification
var content = UNMutableNotificationContent()
content.title = "Notification"
content.body = "Hello Word!"
content.badge = 42
content.sound = UNNotificationSound.default()
content.attachments = [ try UNNotificationAttachment(
identifier: "attachmentImage", url: imageUrl, options: nil) ]
Provides common behavior for subclasses that trigger the delivery of a notification
UNTimeIntervalNotificationTrigger // triggers after timeout
UNCalendarNotificationTrigger // triggers at specified moment
UNLocationNotificationTrigger // triggers for location in region
Contains a notification’s content and the condition that triggers its delivery
let request = UNNotificationRequest( identifier: "notificationID",
content: content, trigger: trigger)
center.add(request) { error in print(error?.localizedDescription) }
UIApplication.shared.registerForRemoteNotifications()
application(_:didRegisterForRemoteNotificationsWithDeviceToken:)
application(_:didFailToRegisterForRemoteNotificationsWithError:)
Device token should be sent by Provider to APN Services
for the notification to be delivered
func application(_ application: UIApplication,
didReceiveRemoteNotification userInfo: [AnyHashable : Any],
fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void)) {
guard let data = userInfo as? [String : Any] else { return }
// process data and call handler
completionHandler(.newData)
}
The system launches your app
(and puts it in the background state)
when a remote notification arrives
Provides additional notififcation handling logic
class NotificationService: UNNotificationServiceExtension {
override func didReceiveNotificationRequest(
request: UNNotificationRequest,
withContentHandler contentHandler: (UNNotificationContent) -> Void)
{ /* populate notification content */ }
override func serviceExtensionTimeWillExpire()
{ /* notififcation will be terminated */ }
}
Additional binary target compiled by Xcode
Allows to configure UIViewController
as an attachment for notififcation
Additional binary target compiled by Xcode