├── ReadmeResources
├── Gesture1.gif
├── Gesture2.gif
└── Gesture3.gif
├── .gitmodules
├── GRTiOSFramework
├── GRTiOS.xcodeproj
│ └── project.xcworkspace
│ │ └── contents.xcworkspacedata
├── BridgingHeader.h
├── VectorDouble.h
├── VectorFloat.h
├── GRTiOSFramework
│ ├── GRTiOS.h
│ └── Info.plist
├── GRTiOSFrameworkTests
│ ├── Info.plist
│ └── GRTiOSFrameworkTests.swift
├── GestureRecognitionPipeline.h
├── VectorDouble.mm
├── VectorFloat.mm
└── GestureRecognitionPipeline.mm
├── GRT-iOS-HelloWorld
├── GRT-iOS-HelloWorld.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── project.pbxproj
├── GRT-iOS-HelloWorld-Bridging-Header.h
├── GRT-iOS-HelloWorldTests
│ ├── Info.plist
│ └── GRT_iOS_HelloWorldTests.swift
├── GRT-iOS-HelloWorldUITests
│ ├── Info.plist
│ └── GRT_iOS_HelloWorldUITests.swift
├── AcceleremoterManager.swift
└── GRT-iOS-HelloWorld
│ ├── Info.plist
│ ├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
│ ├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
│ ├── AppDelegate.swift
│ ├── TrainingViewController.swift
│ └── PredictionViewController.swift
├── GRT-HelloWorld.xcworkspace
└── contents.xcworkspacedata
├── .gitignore
└── README.md
/ReadmeResources/Gesture1.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/narner/GRT-iOS-HelloWorld/HEAD/ReadmeResources/Gesture1.gif
--------------------------------------------------------------------------------
/ReadmeResources/Gesture2.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/narner/GRT-iOS-HelloWorld/HEAD/ReadmeResources/Gesture2.gif
--------------------------------------------------------------------------------
/ReadmeResources/Gesture3.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/narner/GRT-iOS-HelloWorld/HEAD/ReadmeResources/Gesture3.gif
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "grt"]
2 | path = grt
3 | url = https://github.com/nickgillian/grt.git
4 | [submodule "SwiftR"]
5 | path = SwiftR
6 | url = https://github.com/kalanyuz/SwiftR.git
7 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GRTiOS.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/GRTiOSFramework/BridgingHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // BridgingHeader.h
3 | // grt
4 | //
5 | // Created by mjahnen on 18/11/15.
6 | // Copyright © 2015 jahnen. All rights reserved.
7 | //
8 |
9 | #ifndef BridgingHeader_h
10 | #define BridgingHeader_h
11 |
12 | #import "GestureRecognitionPipeline.h"
13 |
14 |
15 | #endif /* BridgingHeader_h */
16 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld-Bridging-Header.h:
--------------------------------------------------------------------------------
1 | //
2 | // GRT-iOS-HelloWorld-Bridging-Header.h
3 | // GRT-iOS-HelloWorld
4 | //
5 | // Created by Nicholas Arner on 8/17/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | #ifndef GRT_iOS_HelloWorld_Bridging_Header_h
10 | #define GRT_iOS_HelloWorld_Bridging_Header_h
11 |
12 | #import
13 |
14 | #endif /* GRT_iOS_HelloWorld_Bridging_Header_h */
15 |
--------------------------------------------------------------------------------
/GRTiOSFramework/VectorDouble.h:
--------------------------------------------------------------------------------
1 | //
2 | // VectorDouble.h
3 | // grt
4 | //
5 | // Created by M J on 09/12/15.
6 | // Copyright © 2015 jahnen. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface VectorDouble : NSObject
12 |
13 | - (instancetype)initWithSize:(NSInteger) size;
14 |
15 | - (void)pushBack:(double)value;
16 | - (void)clear;
17 |
18 | #ifdef __cplusplus
19 | - (GRT::VectorDouble *)cppInstance;
20 | #endif
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/GRTiOSFramework/VectorFloat.h:
--------------------------------------------------------------------------------
1 | //
2 | // VectorFloat.h
3 | // GRTiOS
4 | //
5 | // Created by Nicholas Arner on 8/22/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface VectorFloat : NSObject
12 |
13 | - (instancetype)initWithSize:(NSInteger) size;
14 |
15 | - (void)pushBack:(double)value;
16 | - (void)clear;
17 |
18 | #ifdef __cplusplus
19 | - (GRT::VectorFloat *)cppInstance;
20 | #endif
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/GRT-HelloWorld.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GRTiOSFramework/GRTiOS.h:
--------------------------------------------------------------------------------
1 | //
2 | // GRTiOS.h
3 | // GRTiOS
4 | //
5 | // Created by Nicholas Arner on 8/16/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | //! Project version number for GRTiOSFramework.
13 | FOUNDATION_EXPORT double GRTiOSFrameworkVersionNumber;
14 |
15 | //! Project version string for GRTiOSFramework.
16 | FOUNDATION_EXPORT const unsigned char GRTiOSFrameworkVersionString[];
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GRTiOSFrameworkTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorldTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorldUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GRTiOSFramework/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | $(CURRENT_PROJECT_VERSION)
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GestureRecognitionPipeline.h:
--------------------------------------------------------------------------------
1 | //
2 | // GestureRecognitionPipeline.h
3 | // grt
4 | //
5 | // Created by mjahnen on 25/11/15.
6 | // Copyright © 2015 jahnen. All rights reserved.
7 | // Modified by Nick Arner, 2017
8 | //
9 |
10 | #import
11 | #import "VectorDouble.h"
12 | #import "VectorFloat.h"
13 |
14 | @interface GestureRecognitionPipeline : NSObject
15 |
16 | @property (readonly, getter = predictedClassLabel) NSUInteger predictedClassLabel;
17 | @property (readonly, getter = maximumLikelihood) double maximumLikelihood;
18 |
19 | - (BOOL)savePipeline:(NSURL *)url;
20 | - (BOOL)loadPipeline:(NSURL *)url;
21 | - (BOOL)saveClassificationData:(NSURL *)url;
22 | - (BOOL)loadClassificationData:(NSURL *)url;
23 | - (BOOL)setClassifier:(NSString *)classifier;
24 | - (BOOL)predict:(VectorDouble *)inputVector;
25 | - (void)addSamplesToClassificationDataForGesture:(NSUInteger)gesture :(VectorFloat*)vectorData;
26 | - (BOOL)trainPipeline;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/GRTiOSFramework/VectorDouble.mm:
--------------------------------------------------------------------------------
1 | //
2 | // VectorDouble.m
3 | // grt
4 | //
5 | // Created by M J on 09/12/15.
6 | // Copyright © 2015 jahnen. All rights reserved.
7 | //
8 |
9 | #ifdef __cplusplus
10 | #include "grt.h"
11 | #endif
12 |
13 | #import "VectorDouble.h"
14 |
15 | @interface VectorDouble()
16 | @property GRT::VectorDouble *instance;
17 | @end
18 |
19 | @implementation VectorDouble
20 |
21 | - (instancetype)init
22 | {
23 | self = [super init];
24 | if (self) {
25 | self.instance = new GRT::VectorDouble;
26 | }
27 | return self;
28 | }
29 |
30 | - (instancetype)initWithSize:(NSInteger) size
31 | {
32 | self = [super init];
33 | if (self) {
34 | self.instance = new GRT::VectorDouble(size);
35 | }
36 | return self;
37 | }
38 |
39 | - (void)dealloc
40 | {
41 | delete self.instance;
42 | }
43 |
44 | - (void)pushBack:(double) value
45 | {
46 | self.instance->push_back(value);
47 | }
48 |
49 | - (void)clear
50 | {
51 | self.instance->clear();
52 | }
53 |
54 | - (GRT::VectorDouble *)cppInstance
55 | {
56 | return self.instance;
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/GRTiOSFramework/VectorFloat.mm:
--------------------------------------------------------------------------------
1 | //
2 | // VectorFloat.m
3 | // GRTiOS
4 | //
5 | // Created by Nicholas Arner on 8/22/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #ifdef __cplusplus
12 | #include "grt.h"
13 | #endif
14 |
15 | #import "VectorFloat.h"
16 |
17 | @interface VectorFloat()
18 | @property GRT::VectorFloat *instance;
19 | @end
20 |
21 | @implementation VectorFloat
22 |
23 | - (instancetype)init
24 | {
25 | self = [super init];
26 | if (self) {
27 | self.instance = new GRT::VectorFloat;
28 | }
29 | return self;
30 | }
31 |
32 | - (instancetype)initWithSize:(NSInteger) size
33 | {
34 | self = [super init];
35 | if (self) {
36 | self.instance = new GRT::VectorFloat(size);
37 | }
38 | return self;
39 | }
40 |
41 | - (void)dealloc
42 | {
43 | delete self.instance;
44 | }
45 |
46 | - (void)pushBack:(double) value
47 | {
48 | self.instance->push_back(value);
49 | }
50 |
51 | - (void)clear
52 | {
53 | self.instance->clear();
54 | }
55 |
56 | - (GRT::VectorFloat *)cppInstance
57 | {
58 | return self.instance;
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GRTiOSFrameworkTests/GRTiOSFrameworkTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GRTiOSFrameworkTests.swift
3 | // GRTiOSFrameworkTests
4 | //
5 | // Created by Nicholas Arner on 8/16/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import GRTiOSFramework
11 |
12 | class GRTiOSFrameworkTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorldTests/GRT_iOS_HelloWorldTests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GRT_iOS_HelloWorldTests.swift
3 | // GRT-iOS-HelloWorldTests
4 | //
5 | // Created by Nicholas Arner on 8/17/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | import XCTest
10 | @testable import GRT_iOS_HelloWorld
11 |
12 | class GRT_iOS_HelloWorldTests: XCTestCase {
13 |
14 | override func setUp() {
15 | super.setUp()
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 | }
18 |
19 | override func tearDown() {
20 | // Put teardown code here. This method is called after the invocation of each test method in the class.
21 | super.tearDown()
22 | }
23 |
24 | func testExample() {
25 | // This is an example of a functional test case.
26 | // Use XCTAssert and related functions to verify your tests produce the correct results.
27 | }
28 |
29 | func testPerformanceExample() {
30 | // This is an example of a performance test case.
31 | self.measure {
32 | // Put the code you want to measure the time of here.
33 | }
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/AcceleremoterManager.swift:
--------------------------------------------------------------------------------
1 | //
2 | // CoreMotionManager.swift
3 | // WatchGRT
4 | //
5 | // Created by M J on 02/12/15.
6 | // Copyright © 2015 jahnen. All rights reserved.
7 | // Modified by Nick Arner
8 | //
9 |
10 | import Foundation
11 | import CoreMotion
12 |
13 | class AccelerometerManager {
14 | private let motionManager = CMMotionManager()
15 | private let motionQueue = OperationQueue()
16 |
17 | init() {
18 | motionQueue.name = "CoreMotion"
19 |
20 | motionManager.accelerometerUpdateInterval = 1/60.0
21 | }
22 |
23 | func start(accHandler: @escaping (_ x: Double, _ y: Double, _ z: Double) -> Void) {
24 | let handler: CMAccelerometerHandler = {(data: CMAccelerometerData?, error: Error?) -> Void in
25 | guard let acceleration = data?.acceleration else {
26 | print("Error: data is nil: \(String(describing: error))")
27 | return
28 | }
29 |
30 | accHandler(acceleration.x, acceleration.y, acceleration.z)
31 | }
32 | motionManager.startAccelerometerUpdates(to: motionQueue, withHandler: handler)
33 | }
34 |
35 | func stop() {
36 | motionManager.stopAccelerometerUpdates()
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorldUITests/GRT_iOS_HelloWorldUITests.swift:
--------------------------------------------------------------------------------
1 | //
2 | // GRT_iOS_HelloWorldUITests.swift
3 | // GRT-iOS-HelloWorldUITests
4 | //
5 | // Created by Nicholas Arner on 8/17/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | import XCTest
10 |
11 | class GRT_iOS_HelloWorldUITests: XCTestCase {
12 |
13 | override func setUp() {
14 | super.setUp()
15 |
16 | // Put setup code here. This method is called before the invocation of each test method in the class.
17 |
18 | // In UI tests it is usually best to stop immediately when a failure occurs.
19 | continueAfterFailure = false
20 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
21 | XCUIApplication().launch()
22 |
23 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
24 | }
25 |
26 | override func tearDown() {
27 | // Put teardown code here. This method is called after the invocation of each test method in the class.
28 | super.tearDown()
29 | }
30 |
31 | func testExample() {
32 | // Use recording to get started writing UI tests.
33 | // Use XCTAssert and related functions to verify your tests produce the correct results.
34 | }
35 |
36 | }
37 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 | LSRequiresIPhoneOS
22 |
23 | UILaunchStoryboardName
24 | LaunchScreen
25 | UIMainStoryboardFile
26 | Main
27 | UIRequiredDeviceCapabilities
28 |
29 | armv7
30 |
31 | UISupportedInterfaceOrientations
32 |
33 | UIInterfaceOrientationPortrait
34 |
35 | UISupportedInterfaceOrientations~ipad
36 |
37 | UIInterfaceOrientationPortrait
38 | UIInterfaceOrientationPortraitUpsideDown
39 | UIInterfaceOrientationLandscapeLeft
40 | UIInterfaceOrientationLandscapeRight
41 |
42 |
43 |
44 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData/
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata/
19 |
20 | ## Other
21 | *.moved-aside
22 | *.xccheckout
23 | *.xcscmblueprint
24 |
25 | ## Obj-C/Swift specific
26 | *.hmap
27 | *.ipa
28 | *.dSYM.zip
29 | *.dSYM
30 |
31 | # CocoaPods
32 | #
33 | # We recommend against adding the Pods directory to your .gitignore. However
34 | # you should judge for yourself, the pros and cons are mentioned at:
35 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
36 | #
37 | # Pods/
38 |
39 | # Carthage
40 | #
41 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
42 | # Carthage/Checkouts
43 |
44 | Carthage/Build
45 |
46 | # fastlane
47 | #
48 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
49 | # screenshots whenever they are needed.
50 | # For more information about the recommended setup visit:
51 | # https://docs.fastlane.tools/best-practices/source-control/#source-control
52 |
53 | fastlane/report.xml
54 | fastlane/Preview.html
55 | fastlane/screenshots
56 | fastlane/test_output
57 |
58 | # Code Injection
59 | #
60 | # After new code Injection tools there's a generated folder /iOSInjectionProject
61 | # https://github.com/johnno1962/injectionforxcode
62 |
63 | iOSInjectionProject/
64 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # GRT-iOS-HelloWorld
2 | An example of how to integrate the Gesture Recognition Toolkit into an
3 | iPhone app
4 |
5 |
6 | The [Gesture Recognition Toolkit](https://github.com/nickgillian/grt) is a "cross-platform, open-source, C++ machine learning library
7 | designed for real-time gesture recognition". This repository contains the project outlined in my blog posts, [Integrating the GRT into an
8 | iPhone app](https://nickarner.com/notes/integrating-the-grt-into-an-iphone-project-august-29-2017/) and [Machine-Learning powered Gesture Recognition on iOS](https://nickarner.com/notes/machine-learning-powered-gesture-recognition-on-ios-october-7-2017/).
9 |
10 | Here are some of the gestures I was able to train the system to
11 | recognize:
12 |
13 | 
14 |
15 | 
16 |
17 | 
18 |
19 | [SwiftR](https://github.com/kalanyuz/SwiftR) is used for visualizing
20 | the acellerometer data.
21 |
22 |
23 | ## NOTE:
24 | Since I worked on this project, there's been a lot of advancemenrts in [Apple's CoreML framework](https://developer.apple.com/documentation/coreml), including the ability to [create Motion Activity Classifiers using CreateML](https://developer.apple.com/videos/play/wwdc2019/426/). If you're looking to create a gestural recognition system for iOS from scratch, I would recommend taking a look at the linked Apple talk.
25 |
26 | Additional resources:
27 | * [Activity Classification with Create ML, CoreML3, and Skafos: Part 1](https://medium.com/skafosai/activity-classification-with-create-ml-coreml3-and-skafos-part-1-8f130b5701f6)
28 |
29 | * [GestureAI-CoreML-iOS](https://github.com/akimach/GestureAI-CoreML-iOS)
30 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // GRT-iOS-HelloWorld
4 | //
5 | // Created by Nicholas Arner on 8/17/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | var window: UIWindow?
15 | var pipeline: GestureRecognitionPipeline?
16 |
17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
18 |
19 | //Create an instance of a gesture recognition pipeline to be used as a global variable, accesible by both our training and prediction view controllers
20 | self.pipeline = GestureRecognitionPipeline()
21 |
22 | return true
23 | }
24 |
25 | func applicationWillResignActive(_ application: UIApplication) {
26 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
27 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
28 | }
29 |
30 | func applicationDidEnterBackground(_ application: UIApplication) {
31 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
33 | }
34 |
35 | func applicationWillEnterForeground(_ application: UIApplication) {
36 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
37 | }
38 |
39 | func applicationDidBecomeActive(_ application: UIApplication) {
40 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
41 | }
42 |
43 | func applicationWillTerminate(_ application: UIApplication) {
44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
45 | }
46 |
47 |
48 | }
49 |
50 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/TrainingViewController.swift:
--------------------------------------------------------------------------------
1 | //
2 | // TrainingViewController.swift
3 | // GRT-iOS-HelloWorld
4 | //
5 | // Created by Nicholas Arner on 8/17/17.
6 | // Copyright © 2017 Nicholas Arner. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import GRTiOS
11 | import SwiftR
12 |
13 | class TrainingViewController: UIViewController {
14 |
15 | @IBOutlet var gestureSelector: UISegmentedControl!
16 | @IBOutlet var trainButton: UIButton!
17 | @IBOutlet weak var graphView: SRMergePlotView! {
18 | didSet {
19 | graphView.title = "Accelerometer Data"
20 | graphView.totalSecondsToDisplay = 0.5
21 | }
22 | }
23 |
24 | fileprivate let accelerometerManager = AccelerometerManager()
25 | fileprivate var currentFilePath: String!
26 | fileprivate var currentFileHandle: FileHandle?
27 |
28 | var trainButtonSelected:Bool = false
29 | var pipeline: GestureRecognitionPipeline?
30 |
31 | fileprivate var anotherDataTimer: Timer?
32 |
33 | override func viewDidLoad() {
34 | super.viewDidLoad()
35 | // Do any additional setup after loading the view, typically from a nib.
36 | let appDelegate = UIApplication.shared.delegate as! AppDelegate
37 |
38 | trainButton.addTarget(self, action:#selector(TrainBtnPressed(_:)), for: .touchDown);
39 | trainButton.addTarget(self, action:#selector(TrainBtnReleased(_:)), for: .touchUpInside);
40 |
41 | graphView.totalChannelsToDisplay = 3
42 |
43 | //Create an instance of a GRT pipeline
44 | self.pipeline = appDelegate.pipeline!
45 | }
46 |
47 | override func viewWillAppear(_ animated: Bool) {
48 | startAccellerometer()
49 | }
50 |
51 | override func viewWillDisappear(_ animated: Bool) {
52 | accelerometerManager.stop()
53 | }
54 |
55 | func startAccellerometer() {
56 |
57 | accelerometerManager.start( accHandler: { (x, y, z) -> Void in
58 | let gestureClass = self.gestureSelector.selectedSegmentIndex
59 |
60 | //Add the accellerometer data to a vector, which is how we'll store the classification data
61 | let vector = VectorFloat()
62 | vector.clear()
63 | vector.pushBack(x)
64 | vector.pushBack(y)
65 | vector.pushBack(z)
66 |
67 | print("x", x)
68 | print("y", y)
69 | print("z", z)
70 | print("Gesture class is %@", gestureClass);
71 | self.graphView.addData([x, y, z])
72 |
73 | if (self.trainButton.isSelected == true) {
74 | self.pipeline!.addSamplesToClassificationData(forGesture: UInt(gestureClass), vector)
75 | }
76 |
77 | })
78 | }
79 |
80 | func TrainBtnPressed(_ sender: Any) {
81 | trainButton.isSelected = true
82 | }
83 |
84 | func TrainBtnReleased(_ sender: Any) {
85 | trainButton.isSelected = false
86 | }
87 |
88 |
89 | @IBAction func savePipeline(_ sender: Any) {
90 | // Set URL for saving the pipeline to
91 | let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
92 | let pipelineURL = documentsUrl.appendingPathComponent("train.grt")
93 |
94 | // Remove the pipeline if it already exists
95 | let _ = try? FileManager.default.removeItem(at: pipelineURL)
96 |
97 | let pipelineSaveResult = self.pipeline?.save(pipelineURL)
98 | if !pipelineSaveResult! {
99 | let userAlert = UIAlertController(title: "Error", message: "Failed to save pipeline", preferredStyle: .alert)
100 | self.present(userAlert, animated: true, completion: { _ in })
101 | let cancel = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil)
102 | userAlert.addAction(cancel)
103 | }
104 |
105 | // Save the training data as a CSV file
106 | let classificiationDataURL = documentsUrl.appendingPathComponent("trainingData.csv")
107 |
108 | let _ = try? FileManager.default.removeItem(at: classificiationDataURL)
109 |
110 | let classificationSaveResult = self.pipeline?.saveClassificationData(classificiationDataURL)
111 |
112 | if !classificationSaveResult! {
113 | let userAlert = UIAlertController(title: "Error", message: "Failed to save classification data", preferredStyle: .alert)
114 | self.present(userAlert, animated: true, completion: { _ in })
115 | let cancel = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil)
116 | userAlert.addAction(cancel)
117 | }
118 | }
119 |
120 | override func didReceiveMemoryWarning() {
121 | super.didReceiveMemoryWarning()
122 | // Dispose of any resources that can be recreated.
123 | }
124 |
125 | }
126 |
127 |
--------------------------------------------------------------------------------
/GRTiOSFramework/GestureRecognitionPipeline.mm:
--------------------------------------------------------------------------------
1 | //
2 | // GestureRecognitionPipeline.m
3 | // grt
4 | //
5 | // Created by mjahnen on 25/11/15.
6 | // Copyright © 2015 jahnen. All rights reserved.
7 | // Modified by Nick Arner, 2017
8 | //
9 |
10 | #ifdef __cplusplus
11 | #include "GRT.h"
12 | #include
13 | #include
14 | #endif
15 |
16 | #import "GestureRecognitionPipeline.h"
17 |
18 | class NSLogStream: public std::streambuf {
19 | public:
20 | NSLogStream(std::ostream& stream) :
21 | orgStream(stream)
22 | {
23 | // Swap the the old buffer in ostream with this buffer.
24 | orgBuf = orgStream.rdbuf(this);
25 | }
26 |
27 | ~NSLogStream(){
28 | orgStream.rdbuf(orgBuf); // Restore old buffer
29 | }
30 |
31 | protected:
32 | int_type overflow(int_type c) {
33 | if(!traits_type::eq_int_type(c, traits_type::eof()))
34 | {
35 | char_type const t = traits_type::to_char_type(c);
36 | this->xsputn(&t, 1);
37 | }
38 | return !traits_type::eof();
39 | }
40 |
41 | int sync() {
42 | return 0;
43 | }
44 |
45 | virtual std::streamsize xsputn(const char *msg, std::streamsize count){
46 | std::string s(msg,count);
47 | NSLog(@"GRT cout: %@", @(s.c_str()));
48 | return count;
49 | }
50 |
51 | private:
52 | std::streambuf *orgBuf;
53 | std::ostream& orgStream;
54 | };
55 |
56 | @interface GestureRecognitionPipeline()
57 | @property GRT::GestureRecognitionPipeline *instance;
58 | @property GRT::ClassificationData *classificationData;
59 | @property GRT::ClassificationData *trainingData;
60 | @property GRT::VectorFloat *sampleData;
61 |
62 | @property NSLogStream *nsLogStream;
63 | @end
64 |
65 | @implementation GestureRecognitionPipeline
66 |
67 |
68 | - (instancetype)init {
69 | self = [super init];
70 | if (self) {
71 | self.instance = new GRT::GestureRecognitionPipeline;
72 | self.classificationData = new GRT::ClassificationData;
73 | self.trainingData = new GRT::ClassificationData;
74 | [self setClassifier];
75 | // Redirect cout to NSLog
76 | self.nsLogStream = new NSLogStream(std::cout);
77 | }
78 | return self;
79 | }
80 |
81 | - (void)dealloc {
82 | delete self.instance;
83 | delete self.nsLogStream;
84 | }
85 |
86 | //// pipeline configuration
87 | - (void)setClassifier {
88 | GRT::RandomForests classifier;
89 | self.instance->setClassifier(classifier);
90 | classifier.enableNullRejection(true);
91 | self.instance->addPostProcessingModule(GRT::ClassLabelTimeoutFilter(500, GRT::ClassLabelTimeoutFilter::ALL_CLASS_LABELS));
92 | self.classificationData->setNumDimensions(3);
93 | }
94 |
95 | //// save and load pipeline
96 | - (BOOL)savePipeline:(NSURL *)url {
97 | BOOL result = self.instance->savePipelineToFile(std::string([url fileSystemRepresentation]));
98 | return result;
99 | }
100 |
101 | - (BOOL)loadPipeline:(NSURL *)url {
102 |
103 | BOOL result = self.instance->load(std::string([url fileSystemRepresentation]));
104 |
105 | if (result) {
106 | std::cout << "GRT config";
107 | std::cout << self.instance->getModelAsString();
108 | std::cout << "GRT info: " << self.instance->getInfo();
109 | }
110 |
111 | return result;
112 | }
113 |
114 | //// and load classification data
115 | - (BOOL)saveClassificationData:(NSURL *)url {
116 |
117 | BOOL result = self.classificationData->save(std::string([url fileSystemRepresentation]));
118 |
119 | return result;
120 | }
121 |
122 | - (BOOL)loadClassificationData:(NSURL *)url {
123 |
124 | BOOL result = self.classificationData->load(std::string([url fileSystemRepresentation]));
125 | return result;
126 | }
127 |
128 | - (void)addSamplesToClassificationDataForGesture:(NSUInteger)gesture :(VectorFloat*)vectorData {
129 |
130 | self.classificationData->addSample(gesture, *[vectorData cppInstance]);
131 | }
132 |
133 | - (BOOL)trainPipeline {
134 | *self.trainingData = self.classificationData->split(80);
135 | BOOL trainSuccess = self.instance->train( *(self.trainingData) );
136 |
137 | std::cout << "STATS " << self.classificationData->getStatsAsString();
138 |
139 |
140 | GRT::TestResult testResults = self.instance->getTestResults();
141 |
142 | std::cout << "Pipeline Test Accuracy: " << self.instance->getTestAccuracy() << std::endl;
143 |
144 |
145 | GRT::Vector< GRT::UINT > classLabels = self.instance->getClassLabels();
146 |
147 | std::cout << "Precision: ";
148 | for (GRT::UINT k=0; kgetNumClassesInModel(); k++) {
149 | std::cout << "\t" << self.instance->getTestPrecision(classLabels[k]);
150 | }std::cout << std::endl;
151 |
152 | return trainSuccess;
153 | }
154 |
155 | - (NSUInteger)predictedClassLabel {
156 | return self.instance->getPredictedClassLabel();
157 | }
158 |
159 | - (double)maximumLikelihood {
160 | return self.instance->getMaximumLikelihood();
161 | }
162 |
163 | - (BOOL)predict:(VectorDouble *) inputVector {
164 | return self.instance->predict(*[inputVector cppInstance]);
165 | }
166 |
167 | @end
168 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/PredictionViewController.swift:
--------------------------------------------------------------------------------
1 |
2 | //
3 | // PredictionViewController.swift
4 | // GRT-iOS-HelloWorld
5 | //
6 | // Created by Nicholas Arner on 8/22/17.
7 | // Copyright © 2017 Nicholas Arner. All rights reserved.
8 | //
9 |
10 | import UIKit
11 | import GRTiOS
12 | import SwiftR
13 |
14 | class PredictionViewController: UIViewController {
15 |
16 | @IBOutlet var gestureOneCountLabel: UILabel!
17 | @IBOutlet var gestureTwoCountLabel: UILabel!
18 | @IBOutlet var gestureThreeCountLabel: UILabel!
19 |
20 | @IBOutlet weak var graphView: SRMergePlotView! {
21 | didSet {
22 | graphView.title = "Accelerometer Data"
23 | graphView.totalSecondsToDisplay = 0.5
24 | }
25 | }
26 |
27 | var gestureOneCount: UInt = 0
28 | var gestureTwoCount: UInt = 0
29 | var gestureThreeCount: UInt = 0
30 |
31 | fileprivate let accelerometerManager = AccelerometerManager()
32 |
33 | var currentClassLabel = 0 as UInt
34 | var labelUpdateTime = Date.timeIntervalSinceReferenceDate
35 | let vector = VectorDouble()
36 | var pipeline: GestureRecognitionPipeline?
37 |
38 | override func viewDidLoad() {
39 | let appDelegate = UIApplication.shared.delegate as! AppDelegate
40 | self.pipeline = appDelegate.pipeline!
41 |
42 | initPipeline()
43 | graphView.totalChannelsToDisplay = 3
44 | }
45 |
46 | override func viewWillDisappear(_ animated: Bool) {
47 | accelerometerManager.stop()
48 | resetGestureCount()
49 | }
50 |
51 | func resetGestureCount() {
52 | gestureOneCountLabel.text = "Gesture 1 count: "
53 | gestureTwoCountLabel.text = "Gesture 2 count: "
54 | gestureThreeCountLabel.text = "Gesture 3 count: "
55 | gestureOneCount = 0
56 | gestureTwoCount = 0
57 | gestureThreeCount = 0
58 | }
59 |
60 | func initPipeline(){
61 |
62 | //Load the GRT pipeline and the training data files from the documents directory
63 | let documentsUrl = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
64 |
65 | let pipelineURL = documentsUrl.appendingPathComponent("train.grt")
66 | let classificiationDataURL = documentsUrl.appendingPathComponent("trainingData.csv")
67 |
68 | let pipelineResult:Bool = pipeline!.load(pipelineURL)
69 | let classificationDataResult:Bool = pipeline!.loadClassificationData(classificiationDataURL)
70 |
71 | if pipelineResult == false {
72 | let userAlert = UIAlertController(title: "Error", message: "Couldn't load pipeline", preferredStyle: .alert)
73 | let cancel = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil)
74 | userAlert.addAction(cancel)
75 | self.present(userAlert, animated: true, completion: { _ in })
76 | }
77 |
78 | if classificationDataResult == false {
79 | let userAlert = UIAlertController(title: "Error", message: "Couldn't load classification data", preferredStyle: .alert)
80 | self.present(userAlert, animated: true, completion: { _ in })
81 | let cancel = UIAlertAction(title: "Dismiss", style: .cancel, handler: nil)
82 | userAlert.addAction(cancel)
83 | }
84 |
85 | //If the files have been loaded successfully, we can train the pipeline, and then start real-time gesture prediction
86 | else if (classificationDataResult && pipelineResult) {
87 | pipeline?.train()
88 | performGesturePrediction()
89 | }
90 | }
91 |
92 | func performGesturePrediction() {
93 | accelerometerManager.start { (x, y, z) -> Void in
94 | self.vector.clear()
95 | self.vector.pushBack(x)
96 | self.vector.pushBack(y)
97 | self.vector.pushBack(z)
98 | //Use the incoming accellerometer data to predict what the performed gesture class is
99 | self.pipeline?.predict(self.vector)
100 |
101 | DispatchQueue.main.async {
102 | self.updateGestureCountLabels(gesture: (self.pipeline?.predictedClassLabel)!)
103 | print("PRECITED GESTURE", self.pipeline?.predictedClassLabel ?? 0);
104 | self.graphView.addData([x, y, z])
105 | }
106 |
107 | }
108 | }
109 |
110 | func updateGestureCountLabels(gesture: UInt){
111 |
112 | if gesture == 0 {
113 | //do nothing
114 | } else if (gesture == 1){
115 | gestureOneCount = gestureOneCount + 1
116 | let gestureOneCountVal = String(gestureOneCount)
117 | gestureOneCountLabel.text = ("Gesture 1 count: " + gestureOneCountVal)
118 | } else if (gesture == 2){
119 | gestureTwoCount = gestureTwoCount + 1
120 | let gestureTwoCountVal = String(gestureTwoCount)
121 | gestureTwoCountLabel.text = ("Gesture 2 count: " + gestureTwoCountVal)
122 | } else if (gesture == 3){
123 | gestureThreeCount = gestureThreeCount + 1
124 | let gestureThreeCountVal = String(gestureThreeCount)
125 | gestureThreeCountLabel.text = ("Gesture 3 count: " + gestureThreeCountVal)
126 | }
127 |
128 | }
129 |
130 | }
131 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
32 |
33 |
34 |
35 |
36 |
42 |
48 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
117 |
123 |
129 |
135 |
136 |
137 |
138 |
139 |
140 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
--------------------------------------------------------------------------------
/GRT-iOS-HelloWorld/GRT-iOS-HelloWorld.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | E4775E7A1F5EF5D500D306FD /* TrainingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4775E791F5EF5D500D306FD /* TrainingViewController.swift */; };
11 | E488D4A21F4C8DD2004A5CC6 /* PredictionViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = E488D4A11F4C8DD2004A5CC6 /* PredictionViewController.swift */; };
12 | E4AB6D371F5EF38A00917F2B /* AcceleremoterManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4AB6D361F5EF38A00917F2B /* AcceleremoterManager.swift */; };
13 | E4C972DA1F45DA0400406BCF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C972D91F45DA0400406BCF /* AppDelegate.swift */; };
14 | E4C972DF1F45DA0400406BCF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4C972DD1F45DA0400406BCF /* Main.storyboard */; };
15 | E4C972E11F45DA0400406BCF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E4C972E01F45DA0400406BCF /* Assets.xcassets */; };
16 | E4C972E41F45DA0400406BCF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = E4C972E21F45DA0400406BCF /* LaunchScreen.storyboard */; };
17 | E4C972EF1F45DA0400406BCF /* GRT_iOS_HelloWorldTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C972EE1F45DA0400406BCF /* GRT_iOS_HelloWorldTests.swift */; };
18 | E4C972FA1F45DA0400406BCF /* GRT_iOS_HelloWorldUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E4C972F91F45DA0400406BCF /* GRT_iOS_HelloWorldUITests.swift */; };
19 | E4F789791F460C5C00683570 /* GRTiOS.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E4F7895B1F45E7D900683570 /* GRTiOS.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
20 | E4F8BFDD1F7C337200415AF3 /* SwiftR.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E4F8BFDE1F7C337200415AF3 /* SwiftR.framework */; };
21 | E4F8BFE11F7C36BE00415AF3 /* SwiftR.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E4F8BFDE1F7C337200415AF3 /* SwiftR.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
22 | /* End PBXBuildFile section */
23 |
24 | /* Begin PBXContainerItemProxy section */
25 | E4C972EB1F45DA0400406BCF /* PBXContainerItemProxy */ = {
26 | isa = PBXContainerItemProxy;
27 | containerPortal = E4C972CE1F45DA0400406BCF /* Project object */;
28 | proxyType = 1;
29 | remoteGlobalIDString = E4C972D51F45DA0400406BCF;
30 | remoteInfo = "GRT-iOS-HelloWorld";
31 | };
32 | E4C972F61F45DA0400406BCF /* PBXContainerItemProxy */ = {
33 | isa = PBXContainerItemProxy;
34 | containerPortal = E4C972CE1F45DA0400406BCF /* Project object */;
35 | proxyType = 1;
36 | remoteGlobalIDString = E4C972D51F45DA0400406BCF;
37 | remoteInfo = "GRT-iOS-HelloWorld";
38 | };
39 | E4F7895A1F45E7D900683570 /* PBXContainerItemProxy */ = {
40 | isa = PBXContainerItemProxy;
41 | containerPortal = E4F789491F45E7D800683570 /* GRTiOS.xcodeproj */;
42 | proxyType = 2;
43 | remoteGlobalIDString = E4065B251F44930300990FA4;
44 | remoteInfo = GRTiOS;
45 | };
46 | E4F7895C1F45E7D900683570 /* PBXContainerItemProxy */ = {
47 | isa = PBXContainerItemProxy;
48 | containerPortal = E4F789491F45E7D800683570 /* GRTiOS.xcodeproj */;
49 | proxyType = 2;
50 | remoteGlobalIDString = E4065B2E1F44930300990FA4;
51 | remoteInfo = GRTiOSTests;
52 | };
53 | E4F7897A1F460C5C00683570 /* PBXContainerItemProxy */ = {
54 | isa = PBXContainerItemProxy;
55 | containerPortal = E4F789491F45E7D800683570 /* GRTiOS.xcodeproj */;
56 | proxyType = 1;
57 | remoteGlobalIDString = E4065B241F44930300990FA4;
58 | remoteInfo = GRTiOS;
59 | };
60 | /* End PBXContainerItemProxy section */
61 |
62 | /* Begin PBXCopyFilesBuildPhase section */
63 | E4F7897C1F460C5D00683570 /* Embed Frameworks */ = {
64 | isa = PBXCopyFilesBuildPhase;
65 | buildActionMask = 2147483647;
66 | dstPath = "";
67 | dstSubfolderSpec = 10;
68 | files = (
69 | E4F8BFE11F7C36BE00415AF3 /* SwiftR.framework in Embed Frameworks */,
70 | E4F789791F460C5C00683570 /* GRTiOS.framework in Embed Frameworks */,
71 | );
72 | name = "Embed Frameworks";
73 | runOnlyForDeploymentPostprocessing = 0;
74 | };
75 | /* End PBXCopyFilesBuildPhase section */
76 |
77 | /* Begin PBXFileReference section */
78 | E41951FF1F4B6D3E0016E511 /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; };
79 | E4775E791F5EF5D500D306FD /* TrainingViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrainingViewController.swift; sourceTree = ""; };
80 | E488D4A11F4C8DD2004A5CC6 /* PredictionViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PredictionViewController.swift; sourceTree = ""; };
81 | E4AB6D361F5EF38A00917F2B /* AcceleremoterManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = AcceleremoterManager.swift; path = ../AcceleremoterManager.swift; sourceTree = ""; };
82 | E4C972D61F45DA0400406BCF /* GRT-iOS-HelloWorld.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "GRT-iOS-HelloWorld.app"; sourceTree = BUILT_PRODUCTS_DIR; };
83 | E4C972D91F45DA0400406BCF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
84 | E4C972DE1F45DA0400406BCF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
85 | E4C972E01F45DA0400406BCF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
86 | E4C972E31F45DA0400406BCF /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
87 | E4C972E51F45DA0400406BCF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
88 | E4C972EA1F45DA0400406BCF /* GRT-iOS-HelloWorldTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GRT-iOS-HelloWorldTests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
89 | E4C972EE1F45DA0400406BCF /* GRT_iOS_HelloWorldTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRT_iOS_HelloWorldTests.swift; sourceTree = ""; };
90 | E4C972F01F45DA0400406BCF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
91 | E4C972F51F45DA0400406BCF /* GRT-iOS-HelloWorldUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "GRT-iOS-HelloWorldUITests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
92 | E4C972F91F45DA0400406BCF /* GRT_iOS_HelloWorldUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRT_iOS_HelloWorldUITests.swift; sourceTree = ""; };
93 | E4C972FB1F45DA0400406BCF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
94 | E4F7892C1F45DB0500683570 /* GRTiOSFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GRTiOSFramework.framework; path = "../GRTiOSFramework/build/Debug-iphoneos/GRTiOSFramework.framework"; sourceTree = ""; };
95 | E4F7892E1F45DCDA00683570 /* GRTiOSFramework.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GRTiOSFramework.framework; path = "../../../../Library/Developer/Xcode/DerivedData/GRT-HelloWorld-gjbanovjypsdbdgdyuofejqirqpd/Build/Products/Debug-iphonesimulator/GRTiOSFramework.framework"; sourceTree = ""; };
96 | E4F789301F45DEAC00683570 /* GRTiOS.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = GRTiOS.framework; path = "../../../../Library/Developer/Xcode/DerivedData/GRT-HelloWorld-gjbanovjypsdbdgdyuofejqirqpd/Build/Products/Debug-iphonesimulator/GRTiOS.framework"; sourceTree = ""; };
97 | E4F789371F45E2BE00683570 /* GRT-iOS-HelloWorld-Bridging-Header.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "GRT-iOS-HelloWorld-Bridging-Header.h"; sourceTree = ""; };
98 | E4F789461F45E7D800683570 /* BridgingHeader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BridgingHeader.h; sourceTree = ""; };
99 | E4F789471F45E7D800683570 /* GestureRecognitionPipeline.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GestureRecognitionPipeline.h; sourceTree = ""; };
100 | E4F789481F45E7D800683570 /* GestureRecognitionPipeline.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = GestureRecognitionPipeline.mm; sourceTree = ""; };
101 | E4F789491F45E7D800683570 /* GRTiOS.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; path = GRTiOS.xcodeproj; sourceTree = ""; };
102 | E4F7894D1F45E7D900683570 /* GRTiOS.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GRTiOS.h; sourceTree = ""; };
103 | E4F7894E1F45E7D900683570 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
104 | E4F789501F45E7D900683570 /* GRTiOSFrameworkTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GRTiOSFrameworkTests.swift; sourceTree = ""; };
105 | E4F789511F45E7D900683570 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
106 | E4F789531F45E7D900683570 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
107 | E4F789561F45E7D900683570 /* VectorDouble.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = VectorDouble.h; sourceTree = ""; };
108 | E4F789571F45E7D900683570 /* VectorDouble.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = VectorDouble.mm; sourceTree = ""; };
109 | E4F8BFDE1F7C337200415AF3 /* SwiftR.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = SwiftR.framework; sourceTree = BUILT_PRODUCTS_DIR; };
110 | /* End PBXFileReference section */
111 |
112 | /* Begin PBXFrameworksBuildPhase section */
113 | E4C972D31F45DA0400406BCF /* Frameworks */ = {
114 | isa = PBXFrameworksBuildPhase;
115 | buildActionMask = 2147483647;
116 | files = (
117 | E4F8BFDD1F7C337200415AF3 /* SwiftR.framework in Frameworks */,
118 | );
119 | runOnlyForDeploymentPostprocessing = 0;
120 | };
121 | E4C972E71F45DA0400406BCF /* Frameworks */ = {
122 | isa = PBXFrameworksBuildPhase;
123 | buildActionMask = 2147483647;
124 | files = (
125 | );
126 | runOnlyForDeploymentPostprocessing = 0;
127 | };
128 | E4C972F21F45DA0400406BCF /* Frameworks */ = {
129 | isa = PBXFrameworksBuildPhase;
130 | buildActionMask = 2147483647;
131 | files = (
132 | );
133 | runOnlyForDeploymentPostprocessing = 0;
134 | };
135 | /* End PBXFrameworksBuildPhase section */
136 |
137 | /* Begin PBXGroup section */
138 | E4C972CD1F45DA0400406BCF = {
139 | isa = PBXGroup;
140 | children = (
141 | E4F789371F45E2BE00683570 /* GRT-iOS-HelloWorld-Bridging-Header.h */,
142 | E4C972D81F45DA0400406BCF /* GRT-iOS-HelloWorld */,
143 | E4C972ED1F45DA0400406BCF /* GRT-iOS-HelloWorldTests */,
144 | E4C972F81F45DA0400406BCF /* GRT-iOS-HelloWorldUITests */,
145 | E4C972D71F45DA0400406BCF /* Products */,
146 | E4F7892B1F45DB0500683570 /* Frameworks */,
147 | );
148 | sourceTree = "";
149 | };
150 | E4C972D71F45DA0400406BCF /* Products */ = {
151 | isa = PBXGroup;
152 | children = (
153 | E4C972D61F45DA0400406BCF /* GRT-iOS-HelloWorld.app */,
154 | E4C972EA1F45DA0400406BCF /* GRT-iOS-HelloWorldTests.xctest */,
155 | E4C972F51F45DA0400406BCF /* GRT-iOS-HelloWorldUITests.xctest */,
156 | );
157 | name = Products;
158 | sourceTree = "";
159 | };
160 | E4C972D81F45DA0400406BCF /* GRT-iOS-HelloWorld */ = {
161 | isa = PBXGroup;
162 | children = (
163 | E4775E791F5EF5D500D306FD /* TrainingViewController.swift */,
164 | E488D4A11F4C8DD2004A5CC6 /* PredictionViewController.swift */,
165 | E4C972D91F45DA0400406BCF /* AppDelegate.swift */,
166 | E4AB6D361F5EF38A00917F2B /* AcceleremoterManager.swift */,
167 | E4C972DD1F45DA0400406BCF /* Main.storyboard */,
168 | E4C972E01F45DA0400406BCF /* Assets.xcassets */,
169 | E4C972E21F45DA0400406BCF /* LaunchScreen.storyboard */,
170 | E4C972E51F45DA0400406BCF /* Info.plist */,
171 | );
172 | path = "GRT-iOS-HelloWorld";
173 | sourceTree = "";
174 | };
175 | E4C972ED1F45DA0400406BCF /* GRT-iOS-HelloWorldTests */ = {
176 | isa = PBXGroup;
177 | children = (
178 | E4C972EE1F45DA0400406BCF /* GRT_iOS_HelloWorldTests.swift */,
179 | E4C972F01F45DA0400406BCF /* Info.plist */,
180 | );
181 | path = "GRT-iOS-HelloWorldTests";
182 | sourceTree = "";
183 | };
184 | E4C972F81F45DA0400406BCF /* GRT-iOS-HelloWorldUITests */ = {
185 | isa = PBXGroup;
186 | children = (
187 | E4C972F91F45DA0400406BCF /* GRT_iOS_HelloWorldUITests.swift */,
188 | E4C972FB1F45DA0400406BCF /* Info.plist */,
189 | );
190 | path = "GRT-iOS-HelloWorldUITests";
191 | sourceTree = "";
192 | };
193 | E4F7892B1F45DB0500683570 /* Frameworks */ = {
194 | isa = PBXGroup;
195 | children = (
196 | E4F8BFDE1F7C337200415AF3 /* SwiftR.framework */,
197 | E41951FF1F4B6D3E0016E511 /* CoreMotion.framework */,
198 | E4F789451F45E7D800683570 /* GRTiOSFramework */,
199 | E4F789301F45DEAC00683570 /* GRTiOS.framework */,
200 | E4F7892E1F45DCDA00683570 /* GRTiOSFramework.framework */,
201 | E4F7892C1F45DB0500683570 /* GRTiOSFramework.framework */,
202 | );
203 | name = Frameworks;
204 | sourceTree = "";
205 | };
206 | E4F789451F45E7D800683570 /* GRTiOSFramework */ = {
207 | isa = PBXGroup;
208 | children = (
209 | E4F789461F45E7D800683570 /* BridgingHeader.h */,
210 | E4F789471F45E7D800683570 /* GestureRecognitionPipeline.h */,
211 | E4F789481F45E7D800683570 /* GestureRecognitionPipeline.mm */,
212 | E4F789491F45E7D800683570 /* GRTiOS.xcodeproj */,
213 | E4F7894C1F45E7D900683570 /* GRTiOSFramework */,
214 | E4F7894F1F45E7D900683570 /* GRTiOSFrameworkTests */,
215 | E4F789521F45E7D900683570 /* iOS-GRT-HelloWorld */,
216 | E4F789541F45E7D900683570 /* iOS-GRT-HelloWorldTests */,
217 | E4F789551F45E7D900683570 /* iOS-GRT-HelloWorldUITests */,
218 | E4F789561F45E7D900683570 /* VectorDouble.h */,
219 | E4F789571F45E7D900683570 /* VectorDouble.mm */,
220 | );
221 | name = GRTiOSFramework;
222 | path = ../GRTiOSFramework;
223 | sourceTree = "";
224 | };
225 | E4F7894A1F45E7D800683570 /* Products */ = {
226 | isa = PBXGroup;
227 | children = (
228 | E4F7895B1F45E7D900683570 /* GRTiOS.framework */,
229 | E4F7895D1F45E7D900683570 /* GRTiOSTests.xctest */,
230 | );
231 | name = Products;
232 | sourceTree = "";
233 | };
234 | E4F7894C1F45E7D900683570 /* GRTiOSFramework */ = {
235 | isa = PBXGroup;
236 | children = (
237 | E4F7894D1F45E7D900683570 /* GRTiOS.h */,
238 | E4F7894E1F45E7D900683570 /* Info.plist */,
239 | );
240 | path = GRTiOSFramework;
241 | sourceTree = "";
242 | };
243 | E4F7894F1F45E7D900683570 /* GRTiOSFrameworkTests */ = {
244 | isa = PBXGroup;
245 | children = (
246 | E4F789501F45E7D900683570 /* GRTiOSFrameworkTests.swift */,
247 | E4F789511F45E7D900683570 /* Info.plist */,
248 | );
249 | path = GRTiOSFrameworkTests;
250 | sourceTree = "";
251 | };
252 | E4F789521F45E7D900683570 /* iOS-GRT-HelloWorld */ = {
253 | isa = PBXGroup;
254 | children = (
255 | E4F789531F45E7D900683570 /* Assets.xcassets */,
256 | );
257 | path = "iOS-GRT-HelloWorld";
258 | sourceTree = "";
259 | };
260 | E4F789541F45E7D900683570 /* iOS-GRT-HelloWorldTests */ = {
261 | isa = PBXGroup;
262 | children = (
263 | );
264 | path = "iOS-GRT-HelloWorldTests";
265 | sourceTree = "";
266 | };
267 | E4F789551F45E7D900683570 /* iOS-GRT-HelloWorldUITests */ = {
268 | isa = PBXGroup;
269 | children = (
270 | );
271 | path = "iOS-GRT-HelloWorldUITests";
272 | sourceTree = "";
273 | };
274 | /* End PBXGroup section */
275 |
276 | /* Begin PBXNativeTarget section */
277 | E4C972D51F45DA0400406BCF /* GRT-iOS-HelloWorld */ = {
278 | isa = PBXNativeTarget;
279 | buildConfigurationList = E4C972FE1F45DA0400406BCF /* Build configuration list for PBXNativeTarget "GRT-iOS-HelloWorld" */;
280 | buildPhases = (
281 | E4C972D21F45DA0400406BCF /* Sources */,
282 | E4C972D31F45DA0400406BCF /* Frameworks */,
283 | E4C972D41F45DA0400406BCF /* Resources */,
284 | E4F7897C1F460C5D00683570 /* Embed Frameworks */,
285 | );
286 | buildRules = (
287 | );
288 | dependencies = (
289 | E4F7897B1F460C5C00683570 /* PBXTargetDependency */,
290 | );
291 | name = "GRT-iOS-HelloWorld";
292 | productName = "GRT-iOS-HelloWorld";
293 | productReference = E4C972D61F45DA0400406BCF /* GRT-iOS-HelloWorld.app */;
294 | productType = "com.apple.product-type.application";
295 | };
296 | E4C972E91F45DA0400406BCF /* GRT-iOS-HelloWorldTests */ = {
297 | isa = PBXNativeTarget;
298 | buildConfigurationList = E4C973011F45DA0400406BCF /* Build configuration list for PBXNativeTarget "GRT-iOS-HelloWorldTests" */;
299 | buildPhases = (
300 | E4C972E61F45DA0400406BCF /* Sources */,
301 | E4C972E71F45DA0400406BCF /* Frameworks */,
302 | E4C972E81F45DA0400406BCF /* Resources */,
303 | );
304 | buildRules = (
305 | );
306 | dependencies = (
307 | E4C972EC1F45DA0400406BCF /* PBXTargetDependency */,
308 | );
309 | name = "GRT-iOS-HelloWorldTests";
310 | productName = "GRT-iOS-HelloWorldTests";
311 | productReference = E4C972EA1F45DA0400406BCF /* GRT-iOS-HelloWorldTests.xctest */;
312 | productType = "com.apple.product-type.bundle.unit-test";
313 | };
314 | E4C972F41F45DA0400406BCF /* GRT-iOS-HelloWorldUITests */ = {
315 | isa = PBXNativeTarget;
316 | buildConfigurationList = E4C973041F45DA0400406BCF /* Build configuration list for PBXNativeTarget "GRT-iOS-HelloWorldUITests" */;
317 | buildPhases = (
318 | E4C972F11F45DA0400406BCF /* Sources */,
319 | E4C972F21F45DA0400406BCF /* Frameworks */,
320 | E4C972F31F45DA0400406BCF /* Resources */,
321 | );
322 | buildRules = (
323 | );
324 | dependencies = (
325 | E4C972F71F45DA0400406BCF /* PBXTargetDependency */,
326 | );
327 | name = "GRT-iOS-HelloWorldUITests";
328 | productName = "GRT-iOS-HelloWorldUITests";
329 | productReference = E4C972F51F45DA0400406BCF /* GRT-iOS-HelloWorldUITests.xctest */;
330 | productType = "com.apple.product-type.bundle.ui-testing";
331 | };
332 | /* End PBXNativeTarget section */
333 |
334 | /* Begin PBXProject section */
335 | E4C972CE1F45DA0400406BCF /* Project object */ = {
336 | isa = PBXProject;
337 | attributes = {
338 | LastSwiftUpdateCheck = 0830;
339 | LastUpgradeCheck = 0830;
340 | ORGANIZATIONNAME = "Nicholas Arner";
341 | TargetAttributes = {
342 | E4C972D51F45DA0400406BCF = {
343 | CreatedOnToolsVersion = 8.3.3;
344 | DevelopmentTeam = MCCU4CZ5B9;
345 | ProvisioningStyle = Automatic;
346 | };
347 | E4C972E91F45DA0400406BCF = {
348 | CreatedOnToolsVersion = 8.3.3;
349 | ProvisioningStyle = Automatic;
350 | TestTargetID = E4C972D51F45DA0400406BCF;
351 | };
352 | E4C972F41F45DA0400406BCF = {
353 | CreatedOnToolsVersion = 8.3.3;
354 | ProvisioningStyle = Automatic;
355 | TestTargetID = E4C972D51F45DA0400406BCF;
356 | };
357 | };
358 | };
359 | buildConfigurationList = E4C972D11F45DA0400406BCF /* Build configuration list for PBXProject "GRT-iOS-HelloWorld" */;
360 | compatibilityVersion = "Xcode 3.2";
361 | developmentRegion = English;
362 | hasScannedForEncodings = 0;
363 | knownRegions = (
364 | en,
365 | Base,
366 | );
367 | mainGroup = E4C972CD1F45DA0400406BCF;
368 | productRefGroup = E4C972D71F45DA0400406BCF /* Products */;
369 | projectDirPath = "";
370 | projectReferences = (
371 | {
372 | ProductGroup = E4F7894A1F45E7D800683570 /* Products */;
373 | ProjectRef = E4F789491F45E7D800683570 /* GRTiOS.xcodeproj */;
374 | },
375 | );
376 | projectRoot = "";
377 | targets = (
378 | E4C972D51F45DA0400406BCF /* GRT-iOS-HelloWorld */,
379 | E4C972E91F45DA0400406BCF /* GRT-iOS-HelloWorldTests */,
380 | E4C972F41F45DA0400406BCF /* GRT-iOS-HelloWorldUITests */,
381 | );
382 | };
383 | /* End PBXProject section */
384 |
385 | /* Begin PBXReferenceProxy section */
386 | E4F7895B1F45E7D900683570 /* GRTiOS.framework */ = {
387 | isa = PBXReferenceProxy;
388 | fileType = wrapper.framework;
389 | path = GRTiOS.framework;
390 | remoteRef = E4F7895A1F45E7D900683570 /* PBXContainerItemProxy */;
391 | sourceTree = BUILT_PRODUCTS_DIR;
392 | };
393 | E4F7895D1F45E7D900683570 /* GRTiOSTests.xctest */ = {
394 | isa = PBXReferenceProxy;
395 | fileType = wrapper.cfbundle;
396 | path = GRTiOSTests.xctest;
397 | remoteRef = E4F7895C1F45E7D900683570 /* PBXContainerItemProxy */;
398 | sourceTree = BUILT_PRODUCTS_DIR;
399 | };
400 | /* End PBXReferenceProxy section */
401 |
402 | /* Begin PBXResourcesBuildPhase section */
403 | E4C972D41F45DA0400406BCF /* Resources */ = {
404 | isa = PBXResourcesBuildPhase;
405 | buildActionMask = 2147483647;
406 | files = (
407 | E4C972E41F45DA0400406BCF /* LaunchScreen.storyboard in Resources */,
408 | E4C972E11F45DA0400406BCF /* Assets.xcassets in Resources */,
409 | E4C972DF1F45DA0400406BCF /* Main.storyboard in Resources */,
410 | );
411 | runOnlyForDeploymentPostprocessing = 0;
412 | };
413 | E4C972E81F45DA0400406BCF /* Resources */ = {
414 | isa = PBXResourcesBuildPhase;
415 | buildActionMask = 2147483647;
416 | files = (
417 | );
418 | runOnlyForDeploymentPostprocessing = 0;
419 | };
420 | E4C972F31F45DA0400406BCF /* Resources */ = {
421 | isa = PBXResourcesBuildPhase;
422 | buildActionMask = 2147483647;
423 | files = (
424 | );
425 | runOnlyForDeploymentPostprocessing = 0;
426 | };
427 | /* End PBXResourcesBuildPhase section */
428 |
429 | /* Begin PBXSourcesBuildPhase section */
430 | E4C972D21F45DA0400406BCF /* Sources */ = {
431 | isa = PBXSourcesBuildPhase;
432 | buildActionMask = 2147483647;
433 | files = (
434 | E488D4A21F4C8DD2004A5CC6 /* PredictionViewController.swift in Sources */,
435 | E4AB6D371F5EF38A00917F2B /* AcceleremoterManager.swift in Sources */,
436 | E4775E7A1F5EF5D500D306FD /* TrainingViewController.swift in Sources */,
437 | E4C972DA1F45DA0400406BCF /* AppDelegate.swift in Sources */,
438 | );
439 | runOnlyForDeploymentPostprocessing = 0;
440 | };
441 | E4C972E61F45DA0400406BCF /* Sources */ = {
442 | isa = PBXSourcesBuildPhase;
443 | buildActionMask = 2147483647;
444 | files = (
445 | E4C972EF1F45DA0400406BCF /* GRT_iOS_HelloWorldTests.swift in Sources */,
446 | );
447 | runOnlyForDeploymentPostprocessing = 0;
448 | };
449 | E4C972F11F45DA0400406BCF /* Sources */ = {
450 | isa = PBXSourcesBuildPhase;
451 | buildActionMask = 2147483647;
452 | files = (
453 | E4C972FA1F45DA0400406BCF /* GRT_iOS_HelloWorldUITests.swift in Sources */,
454 | );
455 | runOnlyForDeploymentPostprocessing = 0;
456 | };
457 | /* End PBXSourcesBuildPhase section */
458 |
459 | /* Begin PBXTargetDependency section */
460 | E4C972EC1F45DA0400406BCF /* PBXTargetDependency */ = {
461 | isa = PBXTargetDependency;
462 | target = E4C972D51F45DA0400406BCF /* GRT-iOS-HelloWorld */;
463 | targetProxy = E4C972EB1F45DA0400406BCF /* PBXContainerItemProxy */;
464 | };
465 | E4C972F71F45DA0400406BCF /* PBXTargetDependency */ = {
466 | isa = PBXTargetDependency;
467 | target = E4C972D51F45DA0400406BCF /* GRT-iOS-HelloWorld */;
468 | targetProxy = E4C972F61F45DA0400406BCF /* PBXContainerItemProxy */;
469 | };
470 | E4F7897B1F460C5C00683570 /* PBXTargetDependency */ = {
471 | isa = PBXTargetDependency;
472 | name = GRTiOS;
473 | targetProxy = E4F7897A1F460C5C00683570 /* PBXContainerItemProxy */;
474 | };
475 | /* End PBXTargetDependency section */
476 |
477 | /* Begin PBXVariantGroup section */
478 | E4C972DD1F45DA0400406BCF /* Main.storyboard */ = {
479 | isa = PBXVariantGroup;
480 | children = (
481 | E4C972DE1F45DA0400406BCF /* Base */,
482 | );
483 | name = Main.storyboard;
484 | sourceTree = "";
485 | };
486 | E4C972E21F45DA0400406BCF /* LaunchScreen.storyboard */ = {
487 | isa = PBXVariantGroup;
488 | children = (
489 | E4C972E31F45DA0400406BCF /* Base */,
490 | );
491 | name = LaunchScreen.storyboard;
492 | sourceTree = "";
493 | };
494 | /* End PBXVariantGroup section */
495 |
496 | /* Begin XCBuildConfiguration section */
497 | E4C972FC1F45DA0400406BCF /* Debug */ = {
498 | isa = XCBuildConfiguration;
499 | buildSettings = {
500 | ALWAYS_SEARCH_USER_PATHS = NO;
501 | CLANG_ANALYZER_NONNULL = YES;
502 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
503 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
504 | CLANG_CXX_LIBRARY = "libc++";
505 | CLANG_ENABLE_MODULES = YES;
506 | CLANG_ENABLE_OBJC_ARC = YES;
507 | CLANG_WARN_BOOL_CONVERSION = YES;
508 | CLANG_WARN_CONSTANT_CONVERSION = YES;
509 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
510 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
511 | CLANG_WARN_EMPTY_BODY = YES;
512 | CLANG_WARN_ENUM_CONVERSION = YES;
513 | CLANG_WARN_INFINITE_RECURSION = YES;
514 | CLANG_WARN_INT_CONVERSION = YES;
515 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
516 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
517 | CLANG_WARN_UNREACHABLE_CODE = YES;
518 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
519 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
520 | COPY_PHASE_STRIP = NO;
521 | DEBUG_INFORMATION_FORMAT = dwarf;
522 | ENABLE_STRICT_OBJC_MSGSEND = YES;
523 | ENABLE_TESTABILITY = YES;
524 | GCC_C_LANGUAGE_STANDARD = gnu99;
525 | GCC_DYNAMIC_NO_PIC = NO;
526 | GCC_NO_COMMON_BLOCKS = YES;
527 | GCC_OPTIMIZATION_LEVEL = 0;
528 | GCC_PREPROCESSOR_DEFINITIONS = (
529 | "DEBUG=1",
530 | "$(inherited)",
531 | );
532 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
533 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
534 | GCC_WARN_UNDECLARED_SELECTOR = YES;
535 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
536 | GCC_WARN_UNUSED_FUNCTION = YES;
537 | GCC_WARN_UNUSED_VARIABLE = YES;
538 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
539 | MTL_ENABLE_DEBUG_INFO = YES;
540 | ONLY_ACTIVE_ARCH = YES;
541 | SDKROOT = iphoneos;
542 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
543 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
544 | TARGETED_DEVICE_FAMILY = "1,2";
545 | };
546 | name = Debug;
547 | };
548 | E4C972FD1F45DA0400406BCF /* Release */ = {
549 | isa = XCBuildConfiguration;
550 | buildSettings = {
551 | ALWAYS_SEARCH_USER_PATHS = NO;
552 | CLANG_ANALYZER_NONNULL = YES;
553 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
554 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
555 | CLANG_CXX_LIBRARY = "libc++";
556 | CLANG_ENABLE_MODULES = YES;
557 | CLANG_ENABLE_OBJC_ARC = YES;
558 | CLANG_WARN_BOOL_CONVERSION = YES;
559 | CLANG_WARN_CONSTANT_CONVERSION = YES;
560 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
561 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
562 | CLANG_WARN_EMPTY_BODY = YES;
563 | CLANG_WARN_ENUM_CONVERSION = YES;
564 | CLANG_WARN_INFINITE_RECURSION = YES;
565 | CLANG_WARN_INT_CONVERSION = YES;
566 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
567 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
568 | CLANG_WARN_UNREACHABLE_CODE = YES;
569 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
570 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
571 | COPY_PHASE_STRIP = NO;
572 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
573 | ENABLE_NS_ASSERTIONS = NO;
574 | ENABLE_STRICT_OBJC_MSGSEND = YES;
575 | GCC_C_LANGUAGE_STANDARD = gnu99;
576 | GCC_NO_COMMON_BLOCKS = YES;
577 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
578 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
579 | GCC_WARN_UNDECLARED_SELECTOR = YES;
580 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
581 | GCC_WARN_UNUSED_FUNCTION = YES;
582 | GCC_WARN_UNUSED_VARIABLE = YES;
583 | IPHONEOS_DEPLOYMENT_TARGET = 10.3;
584 | MTL_ENABLE_DEBUG_INFO = NO;
585 | SDKROOT = iphoneos;
586 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
587 | TARGETED_DEVICE_FAMILY = "1,2";
588 | VALIDATE_PRODUCT = YES;
589 | };
590 | name = Release;
591 | };
592 | E4C972FF1F45DA0400406BCF /* Debug */ = {
593 | isa = XCBuildConfiguration;
594 | buildSettings = {
595 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
596 | DEVELOPMENT_TEAM = MCCU4CZ5B9;
597 | INFOPLIST_FILE = "GRT-iOS-HelloWorld/Info.plist";
598 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
599 | PRODUCT_BUNDLE_IDENTIFIER = "embodiedMediaSystems.GRT-iOS-HelloWorld";
600 | PRODUCT_NAME = "$(TARGET_NAME)";
601 | SWIFT_OBJC_BRIDGING_HEADER = "GRT-iOS-HelloWorld-Bridging-Header.h";
602 | SWIFT_VERSION = 3.0;
603 | };
604 | name = Debug;
605 | };
606 | E4C973001F45DA0400406BCF /* Release */ = {
607 | isa = XCBuildConfiguration;
608 | buildSettings = {
609 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
610 | DEVELOPMENT_TEAM = MCCU4CZ5B9;
611 | INFOPLIST_FILE = "GRT-iOS-HelloWorld/Info.plist";
612 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
613 | PRODUCT_BUNDLE_IDENTIFIER = "embodiedMediaSystems.GRT-iOS-HelloWorld";
614 | PRODUCT_NAME = "$(TARGET_NAME)";
615 | SWIFT_OBJC_BRIDGING_HEADER = "GRT-iOS-HelloWorld-Bridging-Header.h";
616 | SWIFT_VERSION = 3.0;
617 | };
618 | name = Release;
619 | };
620 | E4C973021F45DA0400406BCF /* Debug */ = {
621 | isa = XCBuildConfiguration;
622 | buildSettings = {
623 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
624 | BUNDLE_LOADER = "$(TEST_HOST)";
625 | INFOPLIST_FILE = "GRT-iOS-HelloWorldTests/Info.plist";
626 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
627 | PRODUCT_BUNDLE_IDENTIFIER = "embodiedMediaSystems.GRT-iOS-HelloWorldTests";
628 | PRODUCT_NAME = "$(TARGET_NAME)";
629 | SWIFT_VERSION = 3.0;
630 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRT-iOS-HelloWorld.app/GRT-iOS-HelloWorld";
631 | };
632 | name = Debug;
633 | };
634 | E4C973031F45DA0400406BCF /* Release */ = {
635 | isa = XCBuildConfiguration;
636 | buildSettings = {
637 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
638 | BUNDLE_LOADER = "$(TEST_HOST)";
639 | INFOPLIST_FILE = "GRT-iOS-HelloWorldTests/Info.plist";
640 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
641 | PRODUCT_BUNDLE_IDENTIFIER = "embodiedMediaSystems.GRT-iOS-HelloWorldTests";
642 | PRODUCT_NAME = "$(TARGET_NAME)";
643 | SWIFT_VERSION = 3.0;
644 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/GRT-iOS-HelloWorld.app/GRT-iOS-HelloWorld";
645 | };
646 | name = Release;
647 | };
648 | E4C973051F45DA0400406BCF /* Debug */ = {
649 | isa = XCBuildConfiguration;
650 | buildSettings = {
651 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
652 | INFOPLIST_FILE = "GRT-iOS-HelloWorldUITests/Info.plist";
653 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
654 | PRODUCT_BUNDLE_IDENTIFIER = "embodiedMediaSystems.GRT-iOS-HelloWorldUITests";
655 | PRODUCT_NAME = "$(TARGET_NAME)";
656 | SWIFT_VERSION = 3.0;
657 | TEST_TARGET_NAME = "GRT-iOS-HelloWorld";
658 | };
659 | name = Debug;
660 | };
661 | E4C973061F45DA0400406BCF /* Release */ = {
662 | isa = XCBuildConfiguration;
663 | buildSettings = {
664 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
665 | INFOPLIST_FILE = "GRT-iOS-HelloWorldUITests/Info.plist";
666 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
667 | PRODUCT_BUNDLE_IDENTIFIER = "embodiedMediaSystems.GRT-iOS-HelloWorldUITests";
668 | PRODUCT_NAME = "$(TARGET_NAME)";
669 | SWIFT_VERSION = 3.0;
670 | TEST_TARGET_NAME = "GRT-iOS-HelloWorld";
671 | };
672 | name = Release;
673 | };
674 | /* End XCBuildConfiguration section */
675 |
676 | /* Begin XCConfigurationList section */
677 | E4C972D11F45DA0400406BCF /* Build configuration list for PBXProject "GRT-iOS-HelloWorld" */ = {
678 | isa = XCConfigurationList;
679 | buildConfigurations = (
680 | E4C972FC1F45DA0400406BCF /* Debug */,
681 | E4C972FD1F45DA0400406BCF /* Release */,
682 | );
683 | defaultConfigurationIsVisible = 0;
684 | defaultConfigurationName = Release;
685 | };
686 | E4C972FE1F45DA0400406BCF /* Build configuration list for PBXNativeTarget "GRT-iOS-HelloWorld" */ = {
687 | isa = XCConfigurationList;
688 | buildConfigurations = (
689 | E4C972FF1F45DA0400406BCF /* Debug */,
690 | E4C973001F45DA0400406BCF /* Release */,
691 | );
692 | defaultConfigurationIsVisible = 0;
693 | defaultConfigurationName = Release;
694 | };
695 | E4C973011F45DA0400406BCF /* Build configuration list for PBXNativeTarget "GRT-iOS-HelloWorldTests" */ = {
696 | isa = XCConfigurationList;
697 | buildConfigurations = (
698 | E4C973021F45DA0400406BCF /* Debug */,
699 | E4C973031F45DA0400406BCF /* Release */,
700 | );
701 | defaultConfigurationIsVisible = 0;
702 | defaultConfigurationName = Release;
703 | };
704 | E4C973041F45DA0400406BCF /* Build configuration list for PBXNativeTarget "GRT-iOS-HelloWorldUITests" */ = {
705 | isa = XCConfigurationList;
706 | buildConfigurations = (
707 | E4C973051F45DA0400406BCF /* Debug */,
708 | E4C973061F45DA0400406BCF /* Release */,
709 | );
710 | defaultConfigurationIsVisible = 0;
711 | defaultConfigurationName = Release;
712 | };
713 | /* End XCConfigurationList section */
714 | };
715 | rootObject = E4C972CE1F45DA0400406BCF /* Project object */;
716 | }
717 |
--------------------------------------------------------------------------------