diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..5188dd5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +Pods/ +VisualEyes/Supporting-files/ diff --git a/Podfile b/Podfile new file mode 100644 index 0000000..a5c5adf --- /dev/null +++ b/Podfile @@ -0,0 +1,17 @@ +# Uncomment the next line to define a global platform for your project +platform :ios, '9.0' + +target 'VisualEyes' do + # Comment the next line if you're not using Swift and don't want to use dynamic frameworks + use_frameworks! + + # Pods for VisualEyes + pod 'Alamofire' + pod 'SwiftyJSON' + pod 'Firebase/Core' + pod 'Firebase/MLVision' + pod 'Firebase/MLVisionFaceModel' + pod 'Firebase/Core' + pod 'Firebase/Storage' + +end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..e0083e3 --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,157 @@ +PODS: + - Alamofire (4.8.1) + - Firebase/Core (5.16.0): + - Firebase/CoreOnly + - FirebaseAnalytics (= 5.5.0) + - Firebase/CoreOnly (5.16.0): + - FirebaseCore (= 5.2.0) + - Firebase/MLVision (5.16.0): + - Firebase/CoreOnly + - FirebaseMLVision (= 0.14.0) + - Firebase/MLVisionFaceModel (5.16.0): + - Firebase/CoreOnly + - FirebaseMLVisionFaceModel (= 0.14.0) + - Firebase/Storage (5.16.0): + - Firebase/CoreOnly + - FirebaseStorage (= 3.1.0) + - FirebaseAnalytics (5.5.0): + - FirebaseCore (~> 5.2) + - FirebaseInstanceID (~> 3.4) + - GoogleAppMeasurement (= 5.5.0) + - GoogleUtilities/AppDelegateSwizzler (~> 5.2) + - GoogleUtilities/MethodSwizzler (~> 5.2) + - GoogleUtilities/Network (~> 5.2) + - "GoogleUtilities/NSData+zlib (~> 5.2)" + - nanopb (~> 0.3) + - FirebaseAuthInterop (1.0.0) + - FirebaseCore (5.2.0): + - GoogleUtilities/Logger (~> 5.2) + - FirebaseInstanceID (3.4.0): + - FirebaseCore (~> 5.2) + - GoogleUtilities/Environment (~> 5.3) + - GoogleUtilities/UserDefaults (~> 5.3) + - FirebaseMLCommon (0.14.0): + - FirebaseCore (~> 5.2) + - FirebaseInstanceID (~> 3.4) + - GoogleUtilities/UserDefaults (~> 5.3) + - GTMSessionFetcher/Core (~> 1.1) + - FirebaseMLVision (0.14.0): + - FirebaseCore (~> 5.2) + - FirebaseMLCommon (~> 0.14) + - GoogleAPIClientForREST/Core (~> 1.3) + - GoogleAPIClientForREST/Vision (~> 1.3) + - GoogleMobileVision/Detector (~> 1.4) + - FirebaseMLVisionFaceModel (0.14.0): + - GoogleMobileVision/FaceDetector (~> 1.4) + - FirebaseStorage (3.1.0): + - FirebaseAuthInterop (~> 1.0) + - FirebaseCore (~> 5.2) + - GTMSessionFetcher/Core (~> 1.1) + - GoogleAPIClientForREST/Core (1.3.8): + - GTMSessionFetcher (>= 1.1.7) + - GoogleAPIClientForREST/Vision (1.3.8): + - GoogleAPIClientForREST/Core + - GTMSessionFetcher (>= 1.1.7) + - GoogleAppMeasurement (5.5.0): + - GoogleUtilities/AppDelegateSwizzler (~> 5.2) + - GoogleUtilities/MethodSwizzler (~> 5.2) + - GoogleUtilities/Network (~> 5.2) + - "GoogleUtilities/NSData+zlib (~> 5.2)" + - nanopb (~> 0.3) + - GoogleMobileVision/Detector (1.5.0): + - GoogleToolboxForMac/Logger (~> 2.1) + - "GoogleToolboxForMac/NSData+zlib (~> 2.1)" + - GTMSessionFetcher/Core (~> 1.1) + - Protobuf (~> 3.1) + - GoogleMobileVision/FaceDetector (1.5.0): + - GoogleMobileVision/Detector (~> 1.5) + - GoogleToolboxForMac/Defines (2.2.0) + - GoogleToolboxForMac/Logger (2.2.0): + - GoogleToolboxForMac/Defines (= 2.2.0) + - "GoogleToolboxForMac/NSData+zlib (2.2.0)": + - GoogleToolboxForMac/Defines (= 2.2.0) + - GoogleUtilities/AppDelegateSwizzler (5.3.7): + - GoogleUtilities/Environment + - GoogleUtilities/Logger + - GoogleUtilities/Network + - GoogleUtilities/Environment (5.3.7) + - GoogleUtilities/Logger (5.3.7): + - GoogleUtilities/Environment + - GoogleUtilities/MethodSwizzler (5.3.7): + - GoogleUtilities/Logger + - GoogleUtilities/Network (5.3.7): + - GoogleUtilities/Logger + - "GoogleUtilities/NSData+zlib" + - GoogleUtilities/Reachability + - "GoogleUtilities/NSData+zlib (5.3.7)" + - GoogleUtilities/Reachability (5.3.7): + - GoogleUtilities/Logger + - GoogleUtilities/UserDefaults (5.3.7): + - GoogleUtilities/Logger + - GTMSessionFetcher (1.2.1): + - GTMSessionFetcher/Full (= 1.2.1) + - GTMSessionFetcher/Core (1.2.1) + - GTMSessionFetcher/Full (1.2.1): + - GTMSessionFetcher/Core (= 1.2.1) + - nanopb (0.3.901): + - nanopb/decode (= 0.3.901) + - nanopb/encode (= 0.3.901) + - nanopb/decode (0.3.901) + - nanopb/encode (0.3.901) + - Protobuf (3.6.1) + - SwiftyJSON (4.2.0) + +DEPENDENCIES: + - Alamofire + - Firebase/Core + - Firebase/MLVision + - Firebase/MLVisionFaceModel + - Firebase/Storage + - SwiftyJSON + +SPEC REPOS: + https://github.com/cocoapods/specs.git: + - Alamofire + - Firebase + - FirebaseAnalytics + - FirebaseAuthInterop + - FirebaseCore + - FirebaseInstanceID + - FirebaseMLCommon + - FirebaseMLVision + - FirebaseMLVisionFaceModel + - FirebaseStorage + - GoogleAPIClientForREST + - GoogleAppMeasurement + - GoogleMobileVision + - GoogleToolboxForMac + - GoogleUtilities + - GTMSessionFetcher + - nanopb + - Protobuf + - SwiftyJSON + +SPEC CHECKSUMS: + Alamofire: 16ce2c353fb72865124ddae8a57c5942388f4f11 + Firebase: 749a8ff4962f9d8c79dda1966de20f6f77583d67 + FirebaseAnalytics: d35d47c03c50c73c14a7fd31463c5775843e78a9 + FirebaseAuthInterop: 0ffa57668be100582bb7643d4fcb7615496c41fc + FirebaseCore: ea2d1816723ef21492b8e9113303e1350db5e08c + FirebaseInstanceID: 97ea7a5dca9afd72c79bfcdddb7a44aa1cbb42a1 + FirebaseMLCommon: d8a789e36a7faa175b1a5d1139e7fc7323c8db7b + FirebaseMLVision: 07c0da3ceaa5ecde621528a985748d6098a84388 + FirebaseMLVisionFaceModel: 8c80355e22cfcf100ad2ac9c618536d19daf266b + FirebaseStorage: 29075f874c2b3cf61e5221a62c4ceefc809e5412 + GoogleAPIClientForREST: 5447a194eae517986cafe6421a5330b80b820591 + GoogleAppMeasurement: 621f3bc6211d5ba548debe01fafad30cf5ab6859 + GoogleMobileVision: a1f93108b3527d67339e2de80e1db76645f9e8b9 + GoogleToolboxForMac: ff31605b7d66400dcec09bed5861689aebadda4d + GoogleUtilities: 111a012f4c3a29c9e7c954c082fafd6ee3c999c0 + GTMSessionFetcher: 32aeca0aa144acea523e1c8e053089dec2cb98ca + nanopb: 2901f78ea1b7b4015c860c2fdd1ea2fee1a18d48 + Protobuf: 1eb9700044745f00181c136ef21b8ff3ad5a0fd5 + SwiftyJSON: c4bcba26dd9ec7a027fc8eade48e2c911f229e96 + +PODFILE CHECKSUM: 7193d3473dd453a7b19a347bea2ba13640a95de2 + +COCOAPODS: 1.5.3 diff --git a/README.md b/README.md new file mode 100755 index 0000000..530b4c2 --- /dev/null +++ b/README.md @@ -0,0 +1,22 @@ +# Visual Eyes + +**Powered by Azure Cognitive Services, ARKIT2 and Firebase** + +Eye-tracking and emotion prediction of user's reaction to marketing materials. Dynamically store user's picture and reaction data at backend. Proof of concept at _BizHacks_. + +**First Place**, *Best Buy Price Winner* out of 400+ people. + + +Video demo incoming
+ +*Click the image above to watch a demo* + +## Architecture + + + + +Architecture diagram incoming
+ +The frontend tracks the user's eye tracing data, and calculate the coordinate of the point users are looking at on the plane. It is also taking a picture of users every 5 seconds, and uses Azure face detection APIs from +cognitive services to predict user's age and emotion during the period. All the user data generated with the app are stored and uploaded to Firebase for future analysis and data visualization. diff --git a/VisualEyes.xcodeproj/project.pbxproj b/VisualEyes.xcodeproj/project.pbxproj new file mode 100644 index 0000000..c2837cd --- /dev/null +++ b/VisualEyes.xcodeproj/project.pbxproj @@ -0,0 +1,498 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 50; + objects = { + +/* Begin PBXBuildFile section */ + 0BF9B2CC22076CF400A3CDCF /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF9B2CB22076CF400A3CDCF /* AppDelegate.swift */; }; + 0BF9B2CE22076CF400A3CDCF /* art.scnassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BF9B2CD22076CF400A3CDCF /* art.scnassets */; }; + 0BF9B2D022076CF400A3CDCF /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF9B2CF22076CF400A3CDCF /* ViewController.swift */; }; + 0BF9B2D522076CF500A3CDCF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 0BF9B2D422076CF500A3CDCF /* Assets.xcassets */; }; + 0BF9B2E42207721B00A3CDCF /* GoogleService-Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 0BF9B2E32207721B00A3CDCF /* GoogleService-Info.plist */; }; + 0BF9B2E6220772F300A3CDCF /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF9B2E5220772F300A3CDCF /* Extensions.swift */; }; + 0BF9B2E82207733A00A3CDCF /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0BF9B2E72207733A00A3CDCF /* Main.storyboard */; }; + 0BF9B2EA2207735B00A3CDCF /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 0BF9B2E92207735B00A3CDCF /* LaunchScreen.storyboard */; }; + 0BF9B2EC220773C300A3CDCF /* DataViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF9B2EB220773C300A3CDCF /* DataViewController.swift */; }; + 0BF9B2EE220773E200A3CDCF /* UserData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF9B2ED220773E200A3CDCF /* UserData.swift */; }; + 0BF9B2F22207795600A3CDCF /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0BF9B2F12207795600A3CDCF /* Constants.swift */; }; + 2DCD06BA50953DDDDE3EDDA2 /* Pods_VisualEyes.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 437902C14C559B0E30A0F1FF /* Pods_VisualEyes.framework */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 0BF9B2C822076CF400A3CDCF /* VisualEyes.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VisualEyes.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 0BF9B2CB22076CF400A3CDCF /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; + 0BF9B2CD22076CF400A3CDCF /* art.scnassets */ = {isa = PBXFileReference; lastKnownFileType = wrapper.scnassets; path = art.scnassets; sourceTree = ""; }; + 0BF9B2CF22076CF400A3CDCF /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; + 0BF9B2D422076CF500A3CDCF /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 0BF9B2D922076CF500A3CDCF /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 0BF9B2E32207721B00A3CDCF /* GoogleService-Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "GoogleService-Info.plist"; sourceTree = ""; }; + 0BF9B2E5220772F300A3CDCF /* Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Extensions.swift; sourceTree = ""; }; + 0BF9B2E72207733A00A3CDCF /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = Main.storyboard; sourceTree = ""; }; + 0BF9B2E92207735B00A3CDCF /* LaunchScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = LaunchScreen.storyboard; sourceTree = ""; }; + 0BF9B2EB220773C300A3CDCF /* DataViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataViewController.swift; sourceTree = ""; }; + 0BF9B2ED220773E200A3CDCF /* UserData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserData.swift; sourceTree = ""; }; + 0BF9B2F12207795600A3CDCF /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = ""; }; + 437902C14C559B0E30A0F1FF /* Pods_VisualEyes.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VisualEyes.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B0853EB2C3FF4C845DA3BBB9 /* Pods-VisualEyes.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisualEyes.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VisualEyes/Pods-VisualEyes.debug.xcconfig"; sourceTree = ""; }; + E3DFC43421D8D9527BD0FA10 /* Pods-VisualEyes.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VisualEyes.release.xcconfig"; path = "Pods/Target Support Files/Pods-VisualEyes/Pods-VisualEyes.release.xcconfig"; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 0BF9B2C522076CF400A3CDCF /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 2DCD06BA50953DDDDE3EDDA2 /* Pods_VisualEyes.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 00C2EBCD0AB255D7834FB171 /* Pods */ = { + isa = PBXGroup; + children = ( + B0853EB2C3FF4C845DA3BBB9 /* Pods-VisualEyes.debug.xcconfig */, + E3DFC43421D8D9527BD0FA10 /* Pods-VisualEyes.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; + 0BF9B2BF22076CF400A3CDCF = { + isa = PBXGroup; + children = ( + 0BF9B2CA22076CF400A3CDCF /* VisualEyes */, + 0BF9B2C922076CF400A3CDCF /* Products */, + 00C2EBCD0AB255D7834FB171 /* Pods */, + BFC23705C47CB0B1FE4A9968 /* Frameworks */, + ); + sourceTree = ""; + }; + 0BF9B2C922076CF400A3CDCF /* Products */ = { + isa = PBXGroup; + children = ( + 0BF9B2C822076CF400A3CDCF /* VisualEyes.app */, + ); + name = Products; + sourceTree = ""; + }; + 0BF9B2CA22076CF400A3CDCF /* VisualEyes */ = { + isa = PBXGroup; + children = ( + 0BF9B2F02207791C00A3CDCF /* Supporting-files */, + 0BF9B2EF2207790200A3CDCF /* Extensions */, + 0BF9B2E222076D2A00A3CDCF /* Controller */, + 0BF9B2E122076D2200A3CDCF /* View */, + 0BF9B2E022076D1800A3CDCF /* Model */, + 0BF9B2CB22076CF400A3CDCF /* AppDelegate.swift */, + 0BF9B2CD22076CF400A3CDCF /* art.scnassets */, + 0BF9B2D422076CF500A3CDCF /* Assets.xcassets */, + ); + path = VisualEyes; + sourceTree = ""; + }; + 0BF9B2E022076D1800A3CDCF /* Model */ = { + isa = PBXGroup; + children = ( + 0BF9B2ED220773E200A3CDCF /* UserData.swift */, + ); + path = Model; + sourceTree = ""; + }; + 0BF9B2E122076D2200A3CDCF /* View */ = { + isa = PBXGroup; + children = ( + 0BF9B2E92207735B00A3CDCF /* LaunchScreen.storyboard */, + 0BF9B2E72207733A00A3CDCF /* Main.storyboard */, + ); + path = View; + sourceTree = ""; + }; + 0BF9B2E222076D2A00A3CDCF /* Controller */ = { + isa = PBXGroup; + children = ( + 0BF9B2CF22076CF400A3CDCF /* ViewController.swift */, + 0BF9B2EB220773C300A3CDCF /* DataViewController.swift */, + ); + path = Controller; + sourceTree = ""; + }; + 0BF9B2EF2207790200A3CDCF /* Extensions */ = { + isa = PBXGroup; + children = ( + 0BF9B2E5220772F300A3CDCF /* Extensions.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 0BF9B2F02207791C00A3CDCF /* Supporting-files */ = { + isa = PBXGroup; + children = ( + 0BF9B2E32207721B00A3CDCF /* GoogleService-Info.plist */, + 0BF9B2D922076CF500A3CDCF /* Info.plist */, + 0BF9B2F12207795600A3CDCF /* Constants.swift */, + ); + path = "Supporting-files"; + sourceTree = ""; + }; + BFC23705C47CB0B1FE4A9968 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 437902C14C559B0E30A0F1FF /* Pods_VisualEyes.framework */, + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 0BF9B2C722076CF400A3CDCF /* VisualEyes */ = { + isa = PBXNativeTarget; + buildConfigurationList = 0BF9B2DC22076CF500A3CDCF /* Build configuration list for PBXNativeTarget "VisualEyes" */; + buildPhases = ( + 01A6B35C974950A6DAD87A7B /* [CP] Check Pods Manifest.lock */, + 0BF9B2C422076CF400A3CDCF /* Sources */, + 0BF9B2C522076CF400A3CDCF /* Frameworks */, + 0BF9B2C622076CF400A3CDCF /* Resources */, + A2EF076D93FC3F9BBCBECA2C /* [CP] Embed Pods Frameworks */, + 3D5EE7D8A2186DCF29AA6C30 /* [CP] Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = VisualEyes; + productName = VisualEyes; + productReference = 0BF9B2C822076CF400A3CDCF /* VisualEyes.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 0BF9B2C022076CF400A3CDCF /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1010; + LastUpgradeCheck = 1010; + ORGANIZATIONNAME = "Alex Zhang"; + TargetAttributes = { + 0BF9B2C722076CF400A3CDCF = { + CreatedOnToolsVersion = 10.1; + }; + }; + }; + buildConfigurationList = 0BF9B2C322076CF400A3CDCF /* Build configuration list for PBXProject "VisualEyes" */; + compatibilityVersion = "Xcode 9.3"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 0BF9B2BF22076CF400A3CDCF; + productRefGroup = 0BF9B2C922076CF400A3CDCF /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 0BF9B2C722076CF400A3CDCF /* VisualEyes */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 0BF9B2C622076CF400A3CDCF /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0BF9B2CE22076CF400A3CDCF /* art.scnassets in Resources */, + 0BF9B2E42207721B00A3CDCF /* GoogleService-Info.plist in Resources */, + 0BF9B2EA2207735B00A3CDCF /* LaunchScreen.storyboard in Resources */, + 0BF9B2E82207733A00A3CDCF /* Main.storyboard in Resources */, + 0BF9B2D522076CF500A3CDCF /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 01A6B35C974950A6DAD87A7B /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-VisualEyes-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + 3D5EE7D8A2186DCF29AA6C30 /* [CP] Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-VisualEyes/Pods-VisualEyes-resources.sh", + "${PODS_CONFIGURATION_BUILD_DIR}/GoogleMobileVision/GoogleMVFaceDetectorResources.bundle", + ); + name = "[CP] Copy Pods Resources"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/GoogleMVFaceDetectorResources.bundle", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VisualEyes/Pods-VisualEyes-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + A2EF076D93FC3F9BBCBECA2C /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${SRCROOT}/Pods/Target Support Files/Pods-VisualEyes/Pods-VisualEyes-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Alamofire/Alamofire.framework", + "${BUILT_PRODUCTS_DIR}/GTMSessionFetcher/GTMSessionFetcher.framework", + "${BUILT_PRODUCTS_DIR}/GoogleAPIClientForREST/GoogleAPIClientForREST.framework", + "${BUILT_PRODUCTS_DIR}/GoogleToolboxForMac/GoogleToolboxForMac.framework", + "${BUILT_PRODUCTS_DIR}/GoogleUtilities/GoogleUtilities.framework", + "${BUILT_PRODUCTS_DIR}/Protobuf/Protobuf.framework", + "${BUILT_PRODUCTS_DIR}/SwiftyJSON/SwiftyJSON.framework", + "${BUILT_PRODUCTS_DIR}/nanopb/nanopb.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputFileListPaths = ( + ); + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Alamofire.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GTMSessionFetcher.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleAPIClientForREST.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleToolboxForMac.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/GoogleUtilities.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Protobuf.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/SwiftyJSON.framework", + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/nanopb.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VisualEyes/Pods-VisualEyes-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 0BF9B2C422076CF400A3CDCF /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 0BF9B2EC220773C300A3CDCF /* DataViewController.swift in Sources */, + 0BF9B2D022076CF400A3CDCF /* ViewController.swift in Sources */, + 0BF9B2E6220772F300A3CDCF /* Extensions.swift in Sources */, + 0BF9B2EE220773E200A3CDCF /* UserData.swift in Sources */, + 0BF9B2CC22076CF400A3CDCF /* AppDelegate.swift in Sources */, + 0BF9B2F22207795600A3CDCF /* Constants.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 0BF9B2DA22076CF500A3CDCF /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 0BF9B2DB22076CF500A3CDCF /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 12.1; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 0BF9B2DD22076CF500A3CDCF /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = B0853EB2C3FF4C845DA3BBB9 /* Pods-VisualEyes.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 3287ZJLF32; + INFOPLIST_FILE = "$(SRCROOT)/VisualEyes/Supporting-files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.alexzhang.VisualEyes; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 0BF9B2DE22076CF500A3CDCF /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = E3DFC43421D8D9527BD0FA10 /* Pods-VisualEyes.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CODE_SIGN_STYLE = Automatic; + DEVELOPMENT_TEAM = 3287ZJLF32; + INFOPLIST_FILE = "$(SRCROOT)/VisualEyes/Supporting-files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + PRODUCT_BUNDLE_IDENTIFIER = com.alexzhang.VisualEyes; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_VERSION = 4.2; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 0BF9B2C322076CF400A3CDCF /* Build configuration list for PBXProject "VisualEyes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0BF9B2DA22076CF500A3CDCF /* Debug */, + 0BF9B2DB22076CF500A3CDCF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 0BF9B2DC22076CF500A3CDCF /* Build configuration list for PBXNativeTarget "VisualEyes" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 0BF9B2DD22076CF500A3CDCF /* Debug */, + 0BF9B2DE22076CF500A3CDCF /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 0BF9B2C022076CF400A3CDCF /* Project object */; +} diff --git a/VisualEyes.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/VisualEyes.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..7930595 --- /dev/null +++ b/VisualEyes.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/VisualEyes.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/VisualEyes.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/VisualEyes.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/VisualEyes.xcodeproj/project.xcworkspace/xcuserdata/alexzhang.xcuserdatad/UserInterfaceState.xcuserstate b/VisualEyes.xcodeproj/project.xcworkspace/xcuserdata/alexzhang.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..1148938 Binary files /dev/null and b/VisualEyes.xcodeproj/project.xcworkspace/xcuserdata/alexzhang.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/VisualEyes.xcodeproj/xcuserdata/alexzhang.xcuserdatad/xcschemes/xcschememanagement.plist b/VisualEyes.xcodeproj/xcuserdata/alexzhang.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..a50203d --- /dev/null +++ b/VisualEyes.xcodeproj/xcuserdata/alexzhang.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,14 @@ + + + + + SchemeUserState + + VisualEyes.xcscheme_^#shared#^_ + + orderHint + 12 + + + + diff --git a/VisualEyes.xcworkspace/contents.xcworkspacedata b/VisualEyes.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..496f7d7 --- /dev/null +++ b/VisualEyes.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/VisualEyes.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist b/VisualEyes.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist new file mode 100644 index 0000000..18d9810 --- /dev/null +++ b/VisualEyes.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist @@ -0,0 +1,8 @@ + + + + + IDEDidComputeMac32BitWarning + + + diff --git a/VisualEyes.xcworkspace/xcuserdata/alexzhang.xcuserdatad/UserInterfaceState.xcuserstate b/VisualEyes.xcworkspace/xcuserdata/alexzhang.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..f143a9c Binary files /dev/null and b/VisualEyes.xcworkspace/xcuserdata/alexzhang.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/VisualEyes/AppDelegate.swift b/VisualEyes/AppDelegate.swift new file mode 100644 index 0000000..797f8b5 --- /dev/null +++ b/VisualEyes/AppDelegate.swift @@ -0,0 +1,47 @@ +// +// AppDelegate.swift +// VisualEyes +// +// Created by Alex Zhang on 2019-02-03. +// Copyright © 2019 Alex Zhang. All rights reserved. +// + +import UIKit +import Firebase + +@UIApplicationMain +class AppDelegate: UIResponder, UIApplicationDelegate { + + var window: UIWindow? + + + func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { + // Override point for customization after application launch. + FirebaseApp.configure() + return true + } + + func applicationWillResignActive(_ application: UIApplication) { + // 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. + // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. + } + + func applicationDidEnterBackground(_ application: UIApplication) { + // 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. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. + } + + func applicationWillEnterForeground(_ application: UIApplication) { + // 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. + } + + func applicationDidBecomeActive(_ application: UIApplication) { + // 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. + } + + func applicationWillTerminate(_ application: UIApplication) { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. + } + + +} diff --git a/VisualEyes/Assets.xcassets/AppIcon.appiconset/Contents.json b/VisualEyes/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..d8db8d6 --- /dev/null +++ b/VisualEyes/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,98 @@ +{ + "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "29x29", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "40x40", + "scale" : "3x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "60x60", + "scale" : "3x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "29x29", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "40x40", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "76x76", + "scale" : "2x" + }, + { + "idiom" : "ipad", + "size" : "83.5x83.5", + "scale" : "2x" + }, + { + "idiom" : "ios-marketing", + "size" : "1024x1024", + "scale" : "1x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/BGWhite.imageset/BGWhite.png b/VisualEyes/Assets.xcassets/BGWhite.imageset/BGWhite.png new file mode 100644 index 0000000..5919fe4 Binary files /dev/null and b/VisualEyes/Assets.xcassets/BGWhite.imageset/BGWhite.png differ diff --git a/VisualEyes/Assets.xcassets/BGWhite.imageset/Contents.json b/VisualEyes/Assets.xcassets/BGWhite.imageset/Contents.json new file mode 100644 index 0000000..1e1e330 --- /dev/null +++ b/VisualEyes/Assets.xcassets/BGWhite.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "BGWhite.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/Contents.json b/VisualEyes/Assets.xcassets/Contents.json new file mode 100755 index 0000000..da4a164 --- /dev/null +++ b/VisualEyes/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/Screen Shot 2019-02-02 at 4.11.52 AM.imageset/Contents.json b/VisualEyes/Assets.xcassets/Screen Shot 2019-02-02 at 4.11.52 AM.imageset/Contents.json new file mode 100644 index 0000000..77a33eb --- /dev/null +++ b/VisualEyes/Assets.xcassets/Screen Shot 2019-02-02 at 4.11.52 AM.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Screen Shot 2019-02-02 at 4.11.52 AM.jpg", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/Screen Shot 2019-02-02 at 4.11.52 AM.imageset/Screen Shot 2019-02-02 at 4.11.52 AM.jpg b/VisualEyes/Assets.xcassets/Screen Shot 2019-02-02 at 4.11.52 AM.imageset/Screen Shot 2019-02-02 at 4.11.52 AM.jpg new file mode 100644 index 0000000..2919734 Binary files /dev/null and b/VisualEyes/Assets.xcassets/Screen Shot 2019-02-02 at 4.11.52 AM.imageset/Screen Shot 2019-02-02 at 4.11.52 AM.jpg differ diff --git a/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/Contents.json b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/Contents.json new file mode 100644 index 0000000..9342bb9 --- /dev/null +++ b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btn_heart_black_outline.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btn_heart_black_outline@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btn_heart_black_outline@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline.png b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline.png new file mode 100644 index 0000000..f1dc133 Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline.png differ diff --git a/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline@2x.png b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline@2x.png new file mode 100644 index 0000000..7b4c10b Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline@2x.png differ diff --git a/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline@3x.png b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline@3x.png new file mode 100644 index 0000000..e90970d Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_heart_black_outline.imageset/btn_heart_black_outline@3x.png differ diff --git a/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/Contents.json b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/Contents.json new file mode 100644 index 0000000..2785a3a --- /dev/null +++ b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btn_heart_red_solid.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btn_heart_red_solid@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btn_heart_red_solid@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid.png b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid.png new file mode 100644 index 0000000..e9f1024 Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid.png differ diff --git a/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid@2x.png b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid@2x.png new file mode 100644 index 0000000..4acba49 Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid@2x.png differ diff --git a/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid@3x.png b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid@3x.png new file mode 100644 index 0000000..e1aaa82 Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_heart_red_solid.imageset/btn_heart_red_solid@3x.png differ diff --git a/VisualEyes/Assets.xcassets/btn_options_black.imageset/Contents.json b/VisualEyes/Assets.xcassets/btn_options_black.imageset/Contents.json new file mode 100644 index 0000000..bc66f4f --- /dev/null +++ b/VisualEyes/Assets.xcassets/btn_options_black.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "btn_options_black.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "btn_options_black@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "btn_options_black@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black.png b/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black.png new file mode 100644 index 0000000..64bf1bf Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black.png differ diff --git a/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black@2x.png b/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black@2x.png new file mode 100644 index 0000000..a2a1281 Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black@2x.png differ diff --git a/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black@3x.png b/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black@3x.png new file mode 100644 index 0000000..579a6a8 Binary files /dev/null and b/VisualEyes/Assets.xcassets/btn_options_black.imageset/btn_options_black@3x.png differ diff --git a/VisualEyes/Assets.xcassets/certificate.imageset/Contents.json b/VisualEyes/Assets.xcassets/certificate.imageset/Contents.json new file mode 100644 index 0000000..ee82ddb --- /dev/null +++ b/VisualEyes/Assets.xcassets/certificate.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "certificate.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/certificate.imageset/certificate.png b/VisualEyes/Assets.xcassets/certificate.imageset/certificate.png new file mode 100644 index 0000000..c9ec387 Binary files /dev/null and b/VisualEyes/Assets.xcassets/certificate.imageset/certificate.png differ diff --git a/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/Contents.json b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/Contents.json new file mode 100644 index 0000000..3f4a026 --- /dev/null +++ b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tab_find_friends_black.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "tab_find_friends_black@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "tab_find_friends_black@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black.png b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black.png new file mode 100644 index 0000000..d85b6bc Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black.png differ diff --git a/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black@2x.png b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black@2x.png new file mode 100644 index 0000000..f5838ac Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black@2x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black@3x.png b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black@3x.png new file mode 100644 index 0000000..643f55f Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_find_friends_black.imageset/tab_find_friends_black@3x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_home_black.imageset/Contents.json b/VisualEyes/Assets.xcassets/tab_home_black.imageset/Contents.json new file mode 100644 index 0000000..71c3b3c --- /dev/null +++ b/VisualEyes/Assets.xcassets/tab_home_black.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tab_home_black.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "tab_home_black@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "tab_home_black@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black.png b/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black.png new file mode 100644 index 0000000..8741d20 Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black.png differ diff --git a/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black@2x.png b/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black@2x.png new file mode 100644 index 0000000..f5d16ec Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black@2x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black@3x.png b/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black@3x.png new file mode 100644 index 0000000..ea2e756 Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_home_black.imageset/tab_home_black@3x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_plus_black.imageset/Contents.json b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/Contents.json new file mode 100644 index 0000000..9701c41 --- /dev/null +++ b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tab_plus_black.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "tab_plus_black@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "tab_plus_black@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black.png b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black.png new file mode 100644 index 0000000..3e52f4a Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black.png differ diff --git a/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black@2x.png b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black@2x.png new file mode 100644 index 0000000..4457333 Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black@2x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black@3x.png b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black@3x.png new file mode 100644 index 0000000..16be321 Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_plus_black.imageset/tab_plus_black@3x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_profile_black.imageset/Contents.json b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/Contents.json new file mode 100644 index 0000000..385ca01 --- /dev/null +++ b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tab_profile_black.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "tab_profile_black@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "tab_profile_black@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black.png b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black.png new file mode 100644 index 0000000..b7a7114 Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black.png differ diff --git a/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black@2x.png b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black@2x.png new file mode 100644 index 0000000..afb642b Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black@2x.png differ diff --git a/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black@3x.png b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black@3x.png new file mode 100644 index 0000000..fbcf718 Binary files /dev/null and b/VisualEyes/Assets.xcassets/tab_profile_black.imageset/tab_profile_black@3x.png differ diff --git a/VisualEyes/Assets.xcassets/ve1.imageset/Contents.json b/VisualEyes/Assets.xcassets/ve1.imageset/Contents.json new file mode 100644 index 0000000..b7e01cb --- /dev/null +++ b/VisualEyes/Assets.xcassets/ve1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ve1.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/ve1.imageset/ve1.png b/VisualEyes/Assets.xcassets/ve1.imageset/ve1.png new file mode 100644 index 0000000..f57dd8f Binary files /dev/null and b/VisualEyes/Assets.xcassets/ve1.imageset/ve1.png differ diff --git a/VisualEyes/Assets.xcassets/ve2-1.imageset/Contents.json b/VisualEyes/Assets.xcassets/ve2-1.imageset/Contents.json new file mode 100644 index 0000000..4fad775 --- /dev/null +++ b/VisualEyes/Assets.xcassets/ve2-1.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ve2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/ve2-1.imageset/ve2.png b/VisualEyes/Assets.xcassets/ve2-1.imageset/ve2.png new file mode 100644 index 0000000..66882b4 Binary files /dev/null and b/VisualEyes/Assets.xcassets/ve2-1.imageset/ve2.png differ diff --git a/VisualEyes/Assets.xcassets/ve2.imageset/Contents.json b/VisualEyes/Assets.xcassets/ve2.imageset/Contents.json new file mode 100644 index 0000000..4fad775 --- /dev/null +++ b/VisualEyes/Assets.xcassets/ve2.imageset/Contents.json @@ -0,0 +1,21 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ve2.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VisualEyes/Assets.xcassets/ve2.imageset/ve2.png b/VisualEyes/Assets.xcassets/ve2.imageset/ve2.png new file mode 100644 index 0000000..66882b4 Binary files /dev/null and b/VisualEyes/Assets.xcassets/ve2.imageset/ve2.png differ diff --git a/VisualEyes/Controller/DataViewController.swift b/VisualEyes/Controller/DataViewController.swift new file mode 100644 index 0000000..dde602b --- /dev/null +++ b/VisualEyes/Controller/DataViewController.swift @@ -0,0 +1,22 @@ +// +// DataViewController.swift +// VisualEyes +// +// Created by Alex Zhang on 2019-02-03. +// Copyright © 2019 Alex Zhang. All rights reserved. +// + +import Foundation +import UIKit + +class DataViewController: UIViewController, +UINavigationControllerDelegate { + var userDataD : UserData! + + override func viewDidLoad() { + print("======================================in DATAVIEWCONTRLWLEER") + print(userDataD.age) + + } + +} diff --git a/VisualEyes/Controller/ViewController.swift b/VisualEyes/Controller/ViewController.swift new file mode 100644 index 0000000..c459184 --- /dev/null +++ b/VisualEyes/Controller/ViewController.swift @@ -0,0 +1,350 @@ +// +// ViewController.swift +// VisualEyes +// +// Created by Alex Zhang on 2019-02-03. +// Copyright © 2019 Alex Zhang. All rights reserved. +// + +import UIKit +import SceneKit +import ARKit +import WebKit +import Alamofire +import SwiftyJSON +import Firebase +import FirebaseStorage + +class ViewController: UIViewController, ARSCNViewDelegate, ARSessionDelegate, UINavigationControllerDelegate { + + @IBOutlet weak var webView: WKWebView! + @IBOutlet var sceneView: ARSCNView! + @IBOutlet weak var eyePositionIndicatorView: UIView! + @IBOutlet weak var eyePositionIndicatorCenterView: UIView! + @IBOutlet weak var blurBarView: UIVisualEffectView! + @IBOutlet weak var lookAtPositionXLabel: UILabel! + @IBOutlet weak var lookAtPositionYLabel: UILabel! + @IBOutlet weak var distanceLabel: UILabel! + @IBOutlet weak var analysisButton: UIButton! + + let phoneWidth = 834 * 3; + let phoneHeight = 1112 * 3; + var m_data : [UInt8] = [UInt8](repeating: 0, count: 834*3 * 1112*3) + let azureURL: String = Constants.Azure.AZUREURL + var faceNode: SCNNode = SCNNode() + var testlink: String = "https://cdn.images.express.co.uk/img/dynamic/galleries/x701/389530.jpg" + var userDataModel = UserData() + + var eyeLNode: SCNNode = { + let geometry = SCNCone(topRadius: 0.005, bottomRadius: 0, height: 0.2) + geometry.radialSegmentCount = 3 + geometry.firstMaterial?.diffuse.contents = UIColor.blue + let node = SCNNode() + node.geometry = geometry + node.eulerAngles.x = -.pi / 2 + node.position.z = 0.1 + let parentNode = SCNNode() + parentNode.addChildNode(node) + return parentNode + }() + + var eyeRNode: SCNNode = { + let geometry = SCNCone(topRadius: 0.005, bottomRadius: 0, height: 0.2) + geometry.radialSegmentCount = 3 + geometry.firstMaterial?.diffuse.contents = UIColor.blue + let node = SCNNode() + node.geometry = geometry + node.eulerAngles.x = -.pi / 2 + node.position.z = 0.1 + let parentNode = SCNNode() + parentNode.addChildNode(node) + return parentNode + }() + + var lookAtTargetEyeLNode: SCNNode = SCNNode() + var lookAtTargetEyeRNode: SCNNode = SCNNode() + + // actual physical size of iPhoneX screen + let phoneScreenSize = CGSize(width: 0.178, height: 0.247) + + // actual point size of iPhoneX screen + let phoneScreenPointSize = CGSize(width: 834, height: 1112) + + var virtualPhoneNode: SCNNode = SCNNode() + + var virtualScreenNode: SCNNode = { + + let screenGeometry = SCNPlane(width: 1, height: 1) + screenGeometry.firstMaterial?.isDoubleSided = true + screenGeometry.firstMaterial?.diffuse.contents = UIColor.green + return SCNNode(geometry: screenGeometry) + }() + + var eyeLookAtPositionXs: [CGFloat] = [] + + var eyeLookAtPositionYs: [CGFloat] = [] + + override var preferredStatusBarStyle: UIStatusBarStyle { + return UIStatusBarStyle.lightContent + } + + override func viewDidLoad() { + + super.viewDidLoad() + navigationController?.delegate = self + initializeDesigns() + webView.load(URLRequest(url: URL(string: Constants.BestBuy.ONLINESTOREURL)!)) + + // Setup Design Elements + eyePositionIndicatorView.layer.cornerRadius = eyePositionIndicatorView.bounds.width / 2 + sceneView.layer.cornerRadius = 28 + eyePositionIndicatorCenterView.layer.cornerRadius = 4 + + blurBarView.layer.cornerRadius = 36 + blurBarView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + webView.layer.cornerRadius = 16 + webView.layer.maskedCorners = [.layerMinXMinYCorner, .layerMaxXMinYCorner] + + // Set the view's delegate + sceneView.delegate = self + sceneView.session.delegate = self + sceneView.automaticallyUpdatesLighting = true + + // Setup Scenegraph + sceneView.scene.rootNode.addChildNode(faceNode) + sceneView.scene.rootNode.addChildNode(virtualPhoneNode) + virtualPhoneNode.addChildNode(virtualScreenNode) + faceNode.addChildNode(eyeLNode) + faceNode.addChildNode(eyeRNode) + eyeLNode.addChildNode(lookAtTargetEyeLNode) + eyeRNode.addChildNode(lookAtTargetEyeRNode) + + // Set LookAtTargetEye at 2 meters away from the center of eyeballs to create segment vector + lookAtTargetEyeLNode.position.z = 2 + lookAtTargetEyeRNode.position.z = 2 + } + + func initializeDesigns() { + analysisButton.layer.cornerRadius = 5 + analysisButton.layer.borderWidth = 1 + + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + + // Create a session configuration + guard ARFaceTrackingConfiguration.isSupported else { return } + let configuration = ARFaceTrackingConfiguration() + configuration.isLightEstimationEnabled = true + + // Run the view's session + sceneView.session.run(configuration, options: [.resetTracking, .removeExistingAnchors]) + } + + override func viewWillDisappear(_ animated: Bool) { + super.viewWillDisappear(animated) + + // Pause the view's session + sceneView.session.pause() + } + + // MARK: - ARSCNViewDelegate + + func renderer(_ renderer: SCNSceneRenderer, didAdd node: SCNNode, for anchor: ARAnchor) { + + faceNode.transform = node.transform + guard let faceAnchor = anchor as? ARFaceAnchor else { return } + + update(withFaceAnchor: faceAnchor) + } + + // MARK: - update(ARFaceAnchor) + + func update(withFaceAnchor anchor: ARFaceAnchor) { + + eyeRNode.simdTransform = anchor.rightEyeTransform + eyeLNode.simdTransform = anchor.leftEyeTransform + + var eyeLLookAt = CGPoint() + var eyeRLookAt = CGPoint() + + + let heightCompensation: CGFloat = 312 + + DispatchQueue.main.async { + + // Perform Hit test using the ray segments that are drawn by the center of the eyeballs to somewhere two meters away at direction of where users look at to the virtual plane that place at the same orientation of the phone screen + + let phoneScreenEyeRHitTestResults = self.virtualPhoneNode.hitTestWithSegment(from: self.lookAtTargetEyeRNode.worldPosition, to: self.eyeRNode.worldPosition, options: nil) + + let phoneScreenEyeLHitTestResults = self.virtualPhoneNode.hitTestWithSegment(from: self.lookAtTargetEyeLNode.worldPosition, to: self.eyeLNode.worldPosition, options: nil) + + for result in phoneScreenEyeRHitTestResults { + + eyeRLookAt.x = CGFloat(result.localCoordinates.x) / (self.phoneScreenSize.width / 2) * self.phoneScreenPointSize.width + + eyeRLookAt.y = CGFloat(result.localCoordinates.y) / (self.phoneScreenSize.height / 2) * self.phoneScreenPointSize.height + heightCompensation + } + + for result in phoneScreenEyeLHitTestResults { + + eyeLLookAt.x = CGFloat(result.localCoordinates.x) / (self.phoneScreenSize.width / 2) * self.phoneScreenPointSize.width + + eyeLLookAt.y = CGFloat(result.localCoordinates.y) / (self.phoneScreenSize.height / 2) * self.phoneScreenPointSize.height + heightCompensation + } + + // Add the latest position and keep up to 8 recent position to smooth with. + let smoothThresholdNumber: Int = 10 + self.eyeLookAtPositionXs.append((eyeRLookAt.x + eyeLLookAt.x) / 2) + self.eyeLookAtPositionYs.append(-(eyeRLookAt.y + eyeLLookAt.y) / 2) + self.eyeLookAtPositionXs = Array(self.eyeLookAtPositionXs.suffix(smoothThresholdNumber)) + self.eyeLookAtPositionYs = Array(self.eyeLookAtPositionYs.suffix(smoothThresholdNumber)) + + let smoothEyeLookAtPositionX = self.eyeLookAtPositionXs.average! + let smoothEyeLookAtPositionY = self.eyeLookAtPositionYs.average! + + // update indicator position + self.eyePositionIndicatorView.transform = CGAffineTransform(translationX: smoothEyeLookAtPositionX, y: smoothEyeLookAtPositionY) + + // update eye look at labels values + self.lookAtPositionXLabel.text = "\(Int(round(smoothEyeLookAtPositionX + self.phoneScreenPointSize.width / 2)))" + + self.lookAtPositionYLabel.text = "\(Int(round(smoothEyeLookAtPositionY + self.phoneScreenPointSize.height / 2)))" + + // Calculate distance of the eyes to the camera + let distanceL = self.eyeLNode.worldPosition - SCNVector3Zero + let distanceR = self.eyeRNode.worldPosition - SCNVector3Zero + + // Average distance from two eyes + let distance = (distanceL.length() + distanceR.length()) / 2 + + // Update distance label value + self.distanceLabel.text = "\(Int(round(distance * 100))) cm" + + + } + + } + + @IBAction func buttonPressssed(_ sender: UIButton){ + snapShotCurrentUserFace() + } + + func snapShotCurrentUserFace() { + let image = self.sceneView.snapshot() + print(image) + uiImagetoURL(image: image) + } + + + func uiImagetoURL (image: UIImage) { + let imageData = image.jpegData(compressionQuality: 0.8) + let documentsURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first! + let fileURL = documentsURL.appendingPathComponent("tempImage.jpg") + print(fileURL) + try? imageData?.write(to: fileURL, options: []) + + getImageData(url1: fileURL) + } + + func getImageData(url1: URL) { + // let config = CLDConfiguration(cloudName: "CLOUD_NAME", secure: "true") + // let cloudinary = CLDCloudinary(configuration: config) + var downloadURL1: URL? + let storage = Storage.storage() + let storageRef = storage.reference() + let mountainsRef = storageRef.child("images/mountains.jpg") + let localFile = url1 + let metadata = StorageMetadata() + metadata.contentType = "image/jpeg" + // Upload file and metadata + let uploadTask = mountainsRef.putFile(from: localFile, metadata: nil) { metadata, error in + guard let metadata = metadata else { + // Uh-oh, an error occurred! + print(error.debugDescription) + return + + } + // Metadata contains file metadata such as size, content-type. + let size = metadata.size + + // You can also access to download URL after upload. + mountainsRef.downloadURL { (url, error) in + guard let downloadURL = url else { + // Uh-oh, an error occurred! + print(error.debugDescription) + + return + } + print("====download url of the image============line 274") + print(downloadURL) + downloadURL1 = downloadURL + + + let headers: HTTPHeaders = [ + "Content-Type" : "application/json", + "Ocp-Apim-Subscription-Key": Constants.Azure.SUBSCRIPTIONKEY, + ] + print(downloadURL1?.absoluteString) + //some parameters included in Constants.Azure.AZUREURL + let parameters: Parameters = [ + // "returnFaceId":true, + // "returnFaceLandmarks": false, + // "returnFaceAttributes": "age, gender, emotion, hair, makeup, occlusion, accessories, blur", + "url" : downloadURL1?.absoluteString + ] + + Alamofire.request(self.azureURL, method: .post, parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON { response in + if response.result.isSuccess { + print("successfully get JSON data!") + let jso: JSON = JSON(response.result.value!) + //print out the returned json for testing + print(jso) + self.updateUserData(json: jso) + }else{ + print("fail to get JSON response!") + DispatchQueue.main.async { + self.navigationItem.title = "Fail to get image infomation" + } + } + } + } + } + } + + func updateUserData (json: JSON) { + self.userDataModel.age = json[0]["faceAttributes"]["age"].intValue + self.userDataModel.gender = json[0]["faceAttributes"]["gender"].stringValue + self.userDataModel.neutral = json[0]["faceAttributes"]["emotion"]["neutral"].doubleValue + self.userDataModel.happiness = json[0]["faceAttributes"]["emotion"]["happiness"].doubleValue + self.userDataModel.anger = json[0]["faceAttributes"]["emotion"]["anger"].doubleValue + self.userDataModel.disgust = json[0]["faceAttributes"]["emotion"]["disgust"].doubleValue + self.userDataModel.fear = json[0]["faceAttributes"]["emotion"]["fear"].doubleValue + self.userDataModel.sadness = json[0]["faceAttributes"]["emotion"]["sadness"].doubleValue + self.userDataModel.contempt = json[0]["faceAttributes"]["emotion"]["contempt"].doubleValue + self.userDataModel.surprise = json[0]["faceAttributes"]["emotion"]["surprise"].doubleValue + } + + override func prepare(for segue: UIStoryboardSegue, sender: Any?) { + if (segue.identifier == "toData") { + print("find seggg!!!!!!!!!!!!!!!!!") + let destinationVC = segue.destination as! DataViewController + destinationVC.userDataD = userDataModel + print("set seggg!!!!!!!!!!!!!!!!!") + } + + } + + func renderer(_ renderer: SCNSceneRenderer, updateAtTime time: TimeInterval) { + virtualPhoneNode.transform = (sceneView.pointOfView?.transform)! + + } + + func renderer(_ renderer: SCNSceneRenderer, didUpdate node: SCNNode, for anchor: ARAnchor) { + faceNode.transform = node.transform + guard let faceAnchor = anchor as? ARFaceAnchor else { return } + update(withFaceAnchor: faceAnchor) + } + +} diff --git a/VisualEyes/Extensions/Extensions.swift b/VisualEyes/Extensions/Extensions.swift new file mode 100644 index 0000000..ee932dc --- /dev/null +++ b/VisualEyes/Extensions/Extensions.swift @@ -0,0 +1,35 @@ +// +// Extensions.swift +// VisualEyes +// +// Created by Alex Zhang on 2019-02-03. +// Copyright © 2019 Alex Zhang. All rights reserved. +// + +import SceneKit + +extension SCNVector3 { + func length() -> Float { + return sqrtf(x * x + y * y + z * z) + } +} + +func - (l: SCNVector3, r: SCNVector3) -> SCNVector3 { + return SCNVector3Make(l.x - r.x, l.y - r.y, l.z - r.z) +} + +extension Collection where Element == CGFloat, Index == Int { + /// Return the mean of a list of CGFloat. Used with `recentVirtualObjectDistances`. + var average: CGFloat? { + guard !isEmpty else { + return nil + } + + let sum = reduce(CGFloat(0)) { current, next -> CGFloat in + return current + next + } + + return sum / CGFloat(count) + } +} + diff --git a/VisualEyes/Model/UserData.swift b/VisualEyes/Model/UserData.swift new file mode 100644 index 0000000..7821153 --- /dev/null +++ b/VisualEyes/Model/UserData.swift @@ -0,0 +1,41 @@ +// +// UserData.swift +// VisualEyes +// +// Created by Alex Zhang on 2019-02-03. +// Copyright © 2019 Alex Zhang. All rights reserved. +// + +import Foundation + +class UserData { + + var fear : Double + var happiness : Double + var contempt : Double + var disgust : Double + var surprise : Double + var sadness : Double + var anger : Double + var neutral : Double + var smile : Double + var gender: String + var age : Int + + + init() { + fear = 0.0 + happiness = 0.0 + contempt = 0.0 + disgust = 0.0 + surprise = 0.0 + sadness = 0.0 + anger = 0.0 + neutral = 0.0 + smile = 0.0 + + gender = "" + age = 0 + } + +} diff --git a/VisualEyes/View/LaunchScreen.storyboard b/VisualEyes/View/LaunchScreen.storyboard new file mode 100755 index 0000000..2942bc6 --- /dev/null +++ b/VisualEyes/View/LaunchScreen.storyboard @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VisualEyes/View/Main.storyboard b/VisualEyes/View/Main.storyboard new file mode 100755 index 0000000..dcf50a6 --- /dev/null +++ b/VisualEyes/View/Main.storyboard @@ -0,0 +1,246 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VisualEyes/art.scnassets/ship.scn b/VisualEyes/art.scnassets/ship.scn new file mode 100644 index 0000000..e22648f Binary files /dev/null and b/VisualEyes/art.scnassets/ship.scn differ diff --git a/VisualEyes/art.scnassets/texture.png b/VisualEyes/art.scnassets/texture.png new file mode 100644 index 0000000..ba39258 Binary files /dev/null and b/VisualEyes/art.scnassets/texture.png differ