Activity recognition using core motion

as i want to tract activity of iphone user using core motion framework , guide me through .

Accepted Reply

Here's some sample code using a Data Model and SwiftUI

**** The Data Model

import Foundation

import CoreMotion

class DataModel : ObservableObject {

    var activityManager : CMMotionActivityManager?

    @Published var activities = [CMMotionActivity] () // (remove the space before the ()

    init() {

        if !CMMotionActivityManager.isActivityAvailable() {

            print("Activity Monitoring not available")

            return

        }

        activityManager = CMMotionActivityManager()

        if activityManager == nil {  // check just to be sure initialised OK

            print("Unable to initialise Activity Manager")

            return

        }

        activityManager!.startActivityUpdates(to: OperationQueue.main) { (motion) in

            guard let newMotion = motion else { return }

            self.activities.append(newMotion)

        }

    }

}

extension CMMotionActivity {

    func activityString() -> String {

        // returns a compound string of activities e.g. Stationary Automotive

        var output = ""

        if stationary { output = output + "Stationary "}

        if walking { output = output + "Walking "}

        if running { output = output + "Running "}

        if automotive { output = output + "Automotive "}

        if cycling { output = output + "Cycling "}

        if unknown { output = output + "Unknown "}

        return output

    }

}

**** The Main App (if generated in Xcode 12+)

import SwiftUI

@main

struct Activity_TrackerApp: App {

    @StateObject var dataModel = DataModel()

    var body: some Scene {

        WindowGroup {

            ContentView()

                .environmentObject(dataModel)

        }

    }

}

**** The Content View

import SwiftUI

struct ContentView: View {

    @EnvironmentObject var dataModel: DataModel

    var body: some View {

        ScrollView {

            ForEach(dataModel.activities, id:\.startDate) {activity in

                HStack{

                    Text(activity.startDate, style: .date)

                    Text(activity.startDate, style: .time)

                    Text(activity.activityString())

                }

            }

        }

    }

}

You must also add a Plist key for Privacy - Motion Usage Description and say why you're recording activity.

This is a very rough UI, but it should get you started. You'll also need (??) to turn off monitoring at some point and deal with entering and exiting background mode.

Good luck and regards, Michaela

  • can you please send me source file.

  • No, it's better that you create your own project in whatever version of Xcode that you have, adapting accordingly. I think (from memory) that Xcode 12 onwards creates SwiftUI apps by default, so you would only need to create your new project and then: Create a Swift file called DataModel and add the code I've given; Modify your new project's App file to add the @StateObject and .environmentObject lines I've given; Modify ContentView to be as I've described; Add your Plist entry as described.

  • @AncientCoder, thanks works well on XCode 12+ as you indicated. can you provide any perspective on how the same functionality would be made to work on Apple Watch (natively or as a watch/phone hybrid) - Thx. Arsene

Replies

Here's some sample code using a Data Model and SwiftUI

**** The Data Model

import Foundation

import CoreMotion

class DataModel : ObservableObject {

    var activityManager : CMMotionActivityManager?

    @Published var activities = [CMMotionActivity] () // (remove the space before the ()

    init() {

        if !CMMotionActivityManager.isActivityAvailable() {

            print("Activity Monitoring not available")

            return

        }

        activityManager = CMMotionActivityManager()

        if activityManager == nil {  // check just to be sure initialised OK

            print("Unable to initialise Activity Manager")

            return

        }

        activityManager!.startActivityUpdates(to: OperationQueue.main) { (motion) in

            guard let newMotion = motion else { return }

            self.activities.append(newMotion)

        }

    }

}

extension CMMotionActivity {

    func activityString() -> String {

        // returns a compound string of activities e.g. Stationary Automotive

        var output = ""

        if stationary { output = output + "Stationary "}

        if walking { output = output + "Walking "}

        if running { output = output + "Running "}

        if automotive { output = output + "Automotive "}

        if cycling { output = output + "Cycling "}

        if unknown { output = output + "Unknown "}

        return output

    }

}

**** The Main App (if generated in Xcode 12+)

import SwiftUI

@main

struct Activity_TrackerApp: App {

    @StateObject var dataModel = DataModel()

    var body: some Scene {

        WindowGroup {

            ContentView()

                .environmentObject(dataModel)

        }

    }

}

**** The Content View

import SwiftUI

struct ContentView: View {

    @EnvironmentObject var dataModel: DataModel

    var body: some View {

        ScrollView {

            ForEach(dataModel.activities, id:\.startDate) {activity in

                HStack{

                    Text(activity.startDate, style: .date)

                    Text(activity.startDate, style: .time)

                    Text(activity.activityString())

                }

            }

        }

    }

}

You must also add a Plist key for Privacy - Motion Usage Description and say why you're recording activity.

This is a very rough UI, but it should get you started. You'll also need (??) to turn off monitoring at some point and deal with entering and exiting background mode.

Good luck and regards, Michaela

  • can you please send me source file.

  • No, it's better that you create your own project in whatever version of Xcode that you have, adapting accordingly. I think (from memory) that Xcode 12 onwards creates SwiftUI apps by default, so you would only need to create your new project and then: Create a Swift file called DataModel and add the code I've given; Modify your new project's App file to add the @StateObject and .environmentObject lines I've given; Modify ContentView to be as I've described; Add your Plist entry as described.

  • @AncientCoder, thanks works well on XCode 12+ as you indicated. can you provide any perspective on how the same functionality would be made to work on Apple Watch (natively or as a watch/phone hybrid) - Thx. Arsene