MusicMotion/Activity.swift
/* |
Copyright (C) 2016 Apple Inc. All Rights Reserved. |
See LICENSE.txt for this sample’s licensing information |
Abstract: |
This class represents a significant activity the user performed. |
*/ |
import Foundation |
import CoreMotion |
/** |
This struct is responsible for storing the activity data and providing relevant |
pedometer properties such as pace and distance. |
*/ |
struct Activity: CustomDebugStringConvertible { |
// MARK: Properties |
static let milesPerMeter = 0.000621371192 |
var activity: CMMotionActivity |
var startDate: Date |
var endDate: Date |
var timeInterval = 0.0 |
var numberOfSteps: Int? |
var distance: Int? |
var floorsAscended: Int? |
var floorsDescended: Int? |
// MARK: Initializers |
init(activity: CMMotionActivity, startDate: Date, endDate: Date, pedometerData: CMPedometerData? = nil) { |
self.activity = activity |
self.startDate = startDate |
self.endDate = endDate |
self.timeInterval = endDate.timeIntervalSince(startDate) |
guard let pedometerData = pedometerData , activity.walking || activity.running else { |
return |
} |
numberOfSteps = pedometerData.numberOfSteps.intValue |
if let distance = pedometerData.distance?.intValue , distance > 0 { |
self.distance = distance |
} |
if let floorsAscended = pedometerData.floorsAscended?.intValue { |
self.floorsAscended = floorsAscended |
} |
if let floorsDescended = pedometerData.floorsDescended?.intValue { |
self.floorsDescended = floorsDescended |
} |
} |
// MARK: Computed Properties |
var activityType: String { |
if activity.walking { |
return "Walking" |
} |
else if activity.running { |
return "Running" |
} |
else if activity.automotive { |
return "Automotive" |
} |
else if activity.cycling { |
return "Cycling" |
} |
else if activity.stationary { |
return "Stationary" |
} |
else { |
return "Unknown" |
} |
} |
var startDateDescription: String { |
return createLocalTimeDateStringFromDate(startDate) |
} |
var endDateDescription: String { |
return createLocalTimeDateStringFromDate(endDate) |
} |
var activityDuration: String { |
return createTimeStringFromSeconds(timeInterval) |
} |
var distanceInMiles: String { |
guard let distance = distance else { return "N/A" } |
return String(format: "%.7f", Double(distance) * Activity.milesPerMeter) |
} |
var calculatedPace: String { |
guard let distance = distance else { return "N/A" } |
let miles = Double(distance) * Activity.milesPerMeter |
let paceInSecondsPerMile = timeInterval / miles |
return createTimeStringFromSeconds(paceInSecondsPerMile) |
} |
// MARK: Helper Functions |
fileprivate func createTimeStringFromSeconds(_ seconds: TimeInterval) -> String { |
let calendar = NSCalendar.current |
let startDate = Date() |
let endDate = Date(timeInterval: seconds, since: startDate) |
let unitFlags: NSCalendar.Unit = [.hour, .minute, .second] |
let conversionInfo = (calendar as NSCalendar).components(unitFlags, from: startDate, to: endDate, options: []) |
return String(format: "%dh %dm %ds", conversionInfo.hour!, conversionInfo.minute!, conversionInfo.second!) |
} |
fileprivate func createLocalTimeDateStringFromDate(_ date: Date) -> String { |
return DateFormatter.localizedString(from: date, dateStyle: .medium, timeStyle: .medium) |
} |
// MARK: CustomDebugStringConvertible |
var debugDescription: String { |
return "ActivityType: \(activityType), StartDate: \(startDate), EndDate: \(endDate), TimeInterval: \(timeInterval), Steps: \(numberOfSteps), Distance: \(distance), FloorsAscended: \(floorsAscended), FloorsDescended: \(floorsDescended) " |
} |
} |
Copyright © 2016 Apple Inc. All Rights Reserved. Terms of Use | Privacy Policy | Updated: 2016-09-28