From 30cfb11a9f0450eec0c7036062643dd29ffbef0d Mon Sep 17 00:00:00 2001 From: bogdans-telenav Date: Fri, 3 Mar 2017 18:12:29 +0200 Subject: [PATCH] Release 1.5.1 --- OSCTests/Info.plist | 22 + OSCTests/MatcherDataSet.json | 59 + OSCTests/OSCTests.m | 76 + OpenStreetView.xcodeproj/project.pbxproj | 1799 ++++++++--- .../OpenStreetView.xcscmblueprint | 25 - .../xcschemes/OSC_ORBB_Dev.xcscheme | 91 + .../xcschemes/OpenStreetView.xcscheme | 24 +- .../xcschemes/OpenStreetViewRelease.xcscheme | 10 +- .../xcschemes/xcschememanagement.plist | 15 + .../contents.xcworkspacedata | 10 + OpenStreetView/.pb.cc | 94 + OpenStreetView/.pb.h | 58 + OpenStreetView/AppDelegate.m | 101 +- OpenStreetView/Base.lproj/LaunchScreen.xib | 8 +- OpenStreetView/Base.lproj/Main.storyboard | 2825 ++++++++++++----- .../BuisnessLogic/OSVLocationManager.h | 12 +- .../BuisnessLogic/OSVLocationManager.m | 141 +- OpenStreetView/BuisnessLogic/OSVLogger.m | 16 + .../BuisnessLogic/OSVPersistentManager.h | 6 +- .../BuisnessLogic/OSVPersistentManager.m | 68 +- .../BuisnessLogic/OSVSyncController.m | 33 +- .../BuisnessLogic/OSVUserDefaults.h | 30 +- .../BuisnessLogic/OSVUserDefaults.m | 115 +- .../BuisnessLogic/OSVUtils+FileManager.m | 78 +- .../BuisnessLogic/OSVUtils+Location.m | 127 +- OpenStreetView/BuisnessLogic/OSVUtils.h | 48 +- .../AppIcon.appiconset/Contents.json | 20 + .../chevroninv.imageset/Contents.json | 23 + .../chevroninv.imageset/chevron.png | Bin 0 -> 856 bytes .../chevroninv.imageset/chevron@2x.png | Bin 0 -> 1289 bytes .../chevroninv.imageset/chevron@3x.png | Bin 0 -> 1783 bytes .../facebook.imageset/Contents.json | 23 + .../facebook.imageset/facebook.png | Bin 0 -> 310 bytes .../facebook.imageset/facebook@2x.png | Bin 0 -> 508 bytes .../facebook.imageset/facebook@3x.png | Bin 0 -> 727 bytes .../google.imageset/Contents.json | 23 + .../google.imageset/google.png | Bin 0 -> 871 bytes .../google.imageset/google@2x.png | Bin 0 -> 1808 bytes .../google.imageset/google@3x.png | Bin 0 -> 2780 bytes .../inactivePoints.imageset/Contents.json | 56 + .../inactivePoints.png | Bin 0 -> 1545 bytes .../inactivePoints@2x.png | Bin 0 -> 3888 bytes .../inactivePoints@3x.png | Bin 0 -> 6395 bytes .../leaderboard.imageset/Contents.json | 23 + .../leaderboard.imageset/leaderboard.png | Bin 0 -> 244 bytes .../leaderboard.imageset/leaderboard@2x.png | Bin 0 -> 345 bytes .../leaderboard.imageset/leaderboard@3x.png | Bin 0 -> 444 bytes .../multiplier.imageset/Contents.json | 23 + .../multiplier.imageset/multiplier.png | Bin 0 -> 1259 bytes .../multiplier.imageset/multiplier@2x.png | Bin 0 -> 2577 bytes .../multiplier.imageset/multiplier@3x.png | Bin 0 -> 5314 bytes .../noWifi.imageset/Contents.json | 23 + .../noWifi.imageset/noWifi.png | Bin 0 -> 2118 bytes .../noWifi.imageset/noWifi@2x.png | Bin 0 -> 4451 bytes .../noWifi.imageset/noWifi@3x.png | Bin 0 -> 8055 bytes .../Contents.json | 23 + .../openstreetmapLogosvg.png | Bin 0 -> 3258 bytes .../openstreetmapLogosvg@2x.png | Bin 0 -> 10697 bytes .../openstreetmapLogosvg@3x.png | Bin 0 -> 20986 bytes .../pointsRecording.imageset/Contents.json | 56 + .../pointsRecording.png | Bin 0 -> 1630 bytes .../pointsRecording@2x.png | Bin 0 -> 4046 bytes .../pointsRecording@3x.png | Bin 0 -> 6647 bytes .../Contents.json | 21 + .../splashscreen_background.png | Bin 0 -> 184274 bytes .../Contents.json | 23 + .../windyRoadLineTall.png | Bin 0 -> 8655 bytes .../windyRoadLineTall@2x.png | Bin 0 -> 18476 bytes .../windyRoadLineTall@3x.png | Bin 0 -> 29883 bytes .../Contents.json | 23 + .../windyRoadLineTall.png | Bin 0 -> 10172 bytes .../windyRoadLineTall@2x.png | Bin 0 -> 22238 bytes .../windyRoadLineTall@3x.png | Bin 0 -> 35396 bytes .../windyRoadLineTall.imageset/Contents.json | 23 + .../windyRoadLineTall.png | Bin 0 -> 10413 bytes .../windyRoadLineTall@2x.png | Bin 0 -> 22639 bytes .../windyRoadLineTall@3x.png | Bin 0 -> 36684 bytes OpenStreetView/Info.plist | 53 +- OpenStreetView/InfoBeta.plist | 53 +- OpenStreetView/InfoEnterprise.plist | 53 +- OpenStreetView/LoginViewController.swift | 102 + .../Models/Categories/OSVPhoto+Relm.m | 47 +- .../Categories/OSVServerSequence+Convertor.m | 30 + OpenStreetView/Models/OSVSequence.h | 3 + OpenStreetView/Models/OSVSequence.m | 1 + OpenStreetView/Models/OSVServerSequence.h | 8 +- OpenStreetView/Models/OSVServerSequence.m | 3 + OpenStreetView/NSAttributedString+Additions.h | 3 + OpenStreetView/NSAttributedString+Additions.m | 38 + .../{ => OBDLib}/OBDDevice+Internal.h | 0 OpenStreetView/{ => OBDLib}/OBDDevice.h | 0 OpenStreetView/{ => OBDLib}/OBDDevice.m | 30 +- .../{ => OBDLib}/OBDDeviceDelegate.h | 0 OpenStreetView/{ => OBDLib}/OBDLib.h | 0 OpenStreetView/{ => OBDLib}/OBDSensors.h | 2 +- OpenStreetView/{ => OBDLib}/OBDService.h | 0 OpenStreetView/{ => OBDLib}/OBDService.m | 38 +- .../{ => OBDLib}/OBDServiceDelegate.h | 3 +- OpenStreetView/{ => OBDLib}/OBDUtils.h | 0 OpenStreetView/{ => OBDLib}/OBDUtils.m | 6 +- OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h | 21 + OpenStreetView/OSMAPI/Models/OSMUser.h | 5 +- OpenStreetView/OSMAPI/OSMAPI.h | 8 +- OpenStreetView/OSMAPI/OSMAPI.m | 94 +- OpenStreetView/OSVAPI/Models/OSVMetadata.h | 1 + OpenStreetView/OSVAPI/Models/OSVMetadata.m | 6 +- OpenStreetView/OSVAPI/Models/OSVUser.h | 22 +- OpenStreetView/OSVAPI/Models/OSVUser.m | 9 +- OpenStreetView/OSVAPI/OSVAPI+Mix.m | 138 +- OpenStreetView/OSVAPI/OSVAPI+Photos.m | 9 +- OpenStreetView/OSVAPI/OSVAPI+Sequences.m | 95 +- OpenStreetView/OSVAPI/OSVAPI+Video.m | 2 +- OpenStreetView/OSVAPI/OSVAPI.h | 13 +- OpenStreetView/OSVAPI/OSVAPIConfigurator.h | 4 + OpenStreetView/OSVAPI/OSVAPIConfigurator.m | 29 +- OpenStreetView/OSVBaseUser+OSM.h | 16 - OpenStreetView/OSVBaseUser+OSM.m | 25 - OpenStreetView/OSVBaseUser.m | 9 +- OpenStreetView/OSVBasicMapController.m | 91 +- OpenStreetView/OSVCameraGamificationManager.h | 69 + OpenStreetView/OSVCameraGamificationManager.m | 454 +++ OpenStreetView/OSVCameraMapManager.h | 8 + OpenStreetView/OSVCameraMapManager.m | 174 +- OpenStreetView/OSVCropedLabel.h | 14 - OpenStreetView/OSVCropedLabel.m | 31 - OpenStreetView/OSVDebugViewController.m | 111 +- ...OSVDissmissFullScreenAnimationController.m | 3 +- OpenStreetView/OSVDissmissRecordTransition.h | 14 + OpenStreetView/OSVDissmissRecordTransition.m | 54 + OpenStreetView/OSVExpandableCell.h | 20 - OpenStreetView/OSVExpandableCell.m | 26 - .../OSVFullScreenAnimationController.m | 1 - .../OSVFullScreenImageViewController.m | 25 +- OpenStreetView/OSVGalleryCell.h | 18 - OpenStreetView/OSVGalleryCell.m | 27 - OpenStreetView/OSVGamificationInfo.h | 26 + OpenStreetView/OSVGamificationInfo.m | 13 + OpenStreetView/OSVGamificationProfileCell.h | 26 + OpenStreetView/OSVGamificationProfileCell.m | 40 + OpenStreetView/OSVIntroViewController.h | 19 + OpenStreetView/OSVIntroViewController.m | 35 + OpenStreetView/OSVIntroViewController.xib | 67 + OpenStreetView/OSVLeftMenuViewController.m | 79 +- .../OSVLocalNotificationsController.h | 18 + .../OSVLocalNotificationsController.m | 64 + OpenStreetView/OSVLocalTracksViewController.m | 69 +- OpenStreetView/OSVLogItem.h | 2 - OpenStreetView/OSVLoginController.h | 20 +- OpenStreetView/OSVLoginController.m | 209 +- OpenStreetView/OSVMainMenuFactory.m | 61 +- OpenStreetView/OSVMyProfileViewController.m | 408 ++- OpenStreetView/OSVNavigationController.m | 20 + OpenStreetView/OSVOBDController.m | 35 +- OpenStreetView/OSVPhotoSyncController.h | 2 +- OpenStreetView/OSVPhotoSyncController.m | 23 +- OpenStreetView/OSVPolyline.h | 3 +- OpenStreetView/OSVPolyline.m | 8 + OpenStreetView/OSVPopTransition.h | 17 + OpenStreetView/OSVPopTransition.m | 121 + OpenStreetView/OSVPushTransition.h | 16 + OpenStreetView/OSVPushTransition.m | 100 + OpenStreetView/OSVRecordTransition.h | 15 + OpenStreetView/OSVRecordTransition.m | 65 + OpenStreetView/OSVRedButton.h | 13 - OpenStreetView/OSVRedButton.m | 24 - OpenStreetView/OSVScoreDetailsView.h | 47 + OpenStreetView/OSVScoreDetailsView.m | 61 + OpenStreetView/OSVScoreHistory+Realm.h | 17 + OpenStreetView/OSVScoreHistory+Realm.m | 46 + OpenStreetView/OSVScoreHistory.h | 26 + OpenStreetView/OSVScoreHistory.m | 40 + OpenStreetView/OSVSensorLibManager.h | 6 + OpenStreetView/OSVSensorLibManager.mm | 188 +- OpenStreetView/OSVSensorsManager.h | 7 +- OpenStreetView/OSVSensorsManager.m | 111 +- OpenStreetView/OSVSequenceSectionHeaderView.h | 23 - OpenStreetView/OSVSequenceSectionHeaderView.m | 71 - .../OSVSequenceSectionHeaderView.xib | 73 - OpenStreetView/OSVSettingsDetails.m | 4 +- OpenStreetView/OSVSettingsMenuFactory.h | 7 +- OpenStreetView/OSVSettingsMenuFactory.m | 300 +- OpenStreetView/OSVSplashViewController.h | 15 + OpenStreetView/OSVSplashViewController.m | 60 + OpenStreetView/OSVSyncUtils.h | 2 - OpenStreetView/OSVSyncUtils.m | 13 +- OpenStreetView/OSVTipPageViewController.h | 4 +- OpenStreetView/OSVTipPageViewController.xib | 26 +- OpenStreetView/OSVTipView.xib | 20 +- OpenStreetView/OSVTrackCell.h | 2 + OpenStreetView/OSVTrackCell.m | 2 +- OpenStreetView/OSVTrackLogger.h | 2 +- OpenStreetView/OSVTrackLogger.m | 143 +- OpenStreetView/OSVTrackMatcher.h | 22 + OpenStreetView/OSVTrackMatcher.m | 361 +++ OpenStreetView/OSVTrackSyncController.h | 15 +- OpenStreetView/OSVTrackSyncController.m | 199 +- OpenStreetView/OSVUploadViewController.m | 79 +- OpenStreetView/OSVUtils+Device.m | 24 + OpenStreetView/OSVUtils+Gamification.m | 37 + OpenStreetView/OSVVideoRecorder.h | 2 +- OpenStreetView/OSVVideoRecorder.m | 44 +- .../OpenStreetView-Bridging-Header.h | 22 + .../OpenStreetViewRelease-Bridging-Header.h | 20 + OpenStreetView/PortraitViewController.swift | 30 + OpenStreetView/RLMScoreHistory.h | 22 + OpenStreetView/RLMScoreHistory.m | 17 + OpenStreetView/ScoreHistory.swift | 70 + OpenStreetView/ScoreManager.swift | 105 + OpenStreetView/SummaryViewController.swift | 79 + .../SideMenu/LGSideMenuController.m | 2 +- OpenStreetView/UIDevice+Aditions.m | 6 +- OpenStreetView/UIView+Additions.h | 1 + OpenStreetView/UIViewController+Additions.h | 15 + OpenStreetView/UIViewController+Additions.m | 117 + .../ViewControllers/AVCamViewController.h | 8 +- .../ViewControllers/AVCamViewController.m | 118 +- .../ViewControllers/OSVCamViewController.h | 10 + .../ViewControllers/OSVCamViewController.m | 324 +- .../ViewControllers/OSVCameraManager.h | 22 +- .../ViewControllers/OSVCameraManager.m | 736 ++--- .../ViewControllers/OSVLayersViewController.m | 21 +- .../OSVLeaderboardViewController.h | 13 + .../OSVLeaderboardViewController.m | 258 ++ .../ViewControllers/OSVMapViewController.h | 3 +- .../ViewControllers/OSVMapViewController.m | 132 +- .../OSVSettingsViewController.m | 26 +- .../OSVVideoPlayerViewController.m | 227 +- OpenStreetView/Views/OSVRankCell.h | 17 + OpenStreetView/Views/OSVRankCell.m | 24 + OpenStreetView/Views/OSVRankHeaderCell.h | 17 + OpenStreetView/Views/OSVRankHeaderCell.m | 17 + OpenStreetView/Views/OSVSettingsButtonCell.h | 19 - OpenStreetView/Views/OSVSettingsButtonCell.m | 23 - OpenStreetView/Views/OSVTipView.h | 7 + OpenStreetView/Views/OSVTipView.m | 191 +- OpenStreetView/Views/OSVUnderlineButton.h | 13 + OpenStreetView/Views/OSVUnderlineButton.m | 47 + OpenStreetView/exif_iOS.proto | 28 + OpenStreetView/oSVLogoV1.png | Bin 5773 -> 21409 bytes OpenStreetView/oSVLogoV1@2x.png | Bin 12502 -> 29033 bytes OpenStreetView/oSVLogoV1@3x.png | Bin 19804 -> 36662 bytes OpenStreetViewUITests/OpenStreetViewUITests.m | 1 + Podfile | 14 +- Podfile.lock | 87 + photoShutter2.caf | Bin 91366 -> 0 bytes 245 files changed, 11503 insertions(+), 3516 deletions(-) create mode 100644 OSCTests/Info.plist create mode 100644 OSCTests/MatcherDataSet.json create mode 100644 OSCTests/OSCTests.m delete mode 100644 OpenStreetView.xcodeproj/project.xcworkspace/xcshareddata/OpenStreetView.xcscmblueprint create mode 100644 OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OSC_ORBB_Dev.xcscheme create mode 100644 OpenStreetView.xcworkspace/contents.xcworkspacedata create mode 100644 OpenStreetView/.pb.cc create mode 100644 OpenStreetView/.pb.h create mode 100644 OpenStreetView/Images.xcassets/chevroninv.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/chevroninv.imageset/chevron.png create mode 100644 OpenStreetView/Images.xcassets/chevroninv.imageset/chevron@2x.png create mode 100644 OpenStreetView/Images.xcassets/chevroninv.imageset/chevron@3x.png create mode 100644 OpenStreetView/Images.xcassets/facebook.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/facebook.imageset/facebook.png create mode 100644 OpenStreetView/Images.xcassets/facebook.imageset/facebook@2x.png create mode 100644 OpenStreetView/Images.xcassets/facebook.imageset/facebook@3x.png create mode 100644 OpenStreetView/Images.xcassets/google.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/google.imageset/google.png create mode 100644 OpenStreetView/Images.xcassets/google.imageset/google@2x.png create mode 100644 OpenStreetView/Images.xcassets/google.imageset/google@3x.png create mode 100644 OpenStreetView/Images.xcassets/inactivePoints.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/inactivePoints.imageset/inactivePoints.png create mode 100644 OpenStreetView/Images.xcassets/inactivePoints.imageset/inactivePoints@2x.png create mode 100644 OpenStreetView/Images.xcassets/inactivePoints.imageset/inactivePoints@3x.png create mode 100644 OpenStreetView/Images.xcassets/leaderboard.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard.png create mode 100644 OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard@2x.png create mode 100644 OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard@3x.png create mode 100644 OpenStreetView/Images.xcassets/multiplier.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/multiplier.imageset/multiplier.png create mode 100644 OpenStreetView/Images.xcassets/multiplier.imageset/multiplier@2x.png create mode 100644 OpenStreetView/Images.xcassets/multiplier.imageset/multiplier@3x.png create mode 100644 OpenStreetView/Images.xcassets/noWifi.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/noWifi.imageset/noWifi.png create mode 100644 OpenStreetView/Images.xcassets/noWifi.imageset/noWifi@2x.png create mode 100644 OpenStreetView/Images.xcassets/noWifi.imageset/noWifi@3x.png create mode 100644 OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg.png create mode 100644 OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg@2x.png create mode 100644 OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg@3x.png create mode 100644 OpenStreetView/Images.xcassets/pointsRecording.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording.png create mode 100644 OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording@2x.png create mode 100644 OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording@3x.png create mode 100644 OpenStreetView/Images.xcassets/splashscreen_background.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/splashscreen_background.imageset/splashscreen_background.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/windyRoadLineTall.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/windyRoadLineTall@2x.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/windyRoadLineTall@3x.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-2.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-2.imageset/windyRoadLineTall.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-2.imageset/windyRoadLineTall@2x.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall-2.imageset/windyRoadLineTall@3x.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/Contents.json create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall@2x.png create mode 100644 OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall@3x.png create mode 100644 OpenStreetView/LoginViewController.swift rename OpenStreetView/{ => OBDLib}/OBDDevice+Internal.h (100%) rename OpenStreetView/{ => OBDLib}/OBDDevice.h (100%) rename OpenStreetView/{ => OBDLib}/OBDDevice.m (98%) rename OpenStreetView/{ => OBDLib}/OBDDeviceDelegate.h (100%) rename OpenStreetView/{ => OBDLib}/OBDLib.h (100%) rename OpenStreetView/{ => OBDLib}/OBDSensors.h (99%) rename OpenStreetView/{ => OBDLib}/OBDService.h (100%) rename OpenStreetView/{ => OBDLib}/OBDService.m (86%) rename OpenStreetView/{ => OBDLib}/OBDServiceDelegate.h (98%) rename OpenStreetView/{ => OBDLib}/OBDUtils.h (100%) rename OpenStreetView/{ => OBDLib}/OBDUtils.m (99%) create mode 100644 OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h delete mode 100644 OpenStreetView/OSVBaseUser+OSM.h delete mode 100644 OpenStreetView/OSVBaseUser+OSM.m create mode 100644 OpenStreetView/OSVCameraGamificationManager.h create mode 100644 OpenStreetView/OSVCameraGamificationManager.m delete mode 100644 OpenStreetView/OSVCropedLabel.h delete mode 100644 OpenStreetView/OSVCropedLabel.m create mode 100644 OpenStreetView/OSVDissmissRecordTransition.h create mode 100644 OpenStreetView/OSVDissmissRecordTransition.m delete mode 100644 OpenStreetView/OSVExpandableCell.h delete mode 100644 OpenStreetView/OSVExpandableCell.m delete mode 100644 OpenStreetView/OSVGalleryCell.h delete mode 100644 OpenStreetView/OSVGalleryCell.m create mode 100644 OpenStreetView/OSVGamificationInfo.h create mode 100644 OpenStreetView/OSVGamificationInfo.m create mode 100644 OpenStreetView/OSVGamificationProfileCell.h create mode 100644 OpenStreetView/OSVGamificationProfileCell.m create mode 100644 OpenStreetView/OSVIntroViewController.h create mode 100644 OpenStreetView/OSVIntroViewController.m create mode 100644 OpenStreetView/OSVIntroViewController.xib create mode 100644 OpenStreetView/OSVLocalNotificationsController.h create mode 100644 OpenStreetView/OSVLocalNotificationsController.m create mode 100644 OpenStreetView/OSVPopTransition.h create mode 100644 OpenStreetView/OSVPopTransition.m create mode 100644 OpenStreetView/OSVPushTransition.h create mode 100644 OpenStreetView/OSVPushTransition.m create mode 100644 OpenStreetView/OSVRecordTransition.h create mode 100644 OpenStreetView/OSVRecordTransition.m delete mode 100644 OpenStreetView/OSVRedButton.h delete mode 100644 OpenStreetView/OSVRedButton.m create mode 100644 OpenStreetView/OSVScoreDetailsView.h create mode 100644 OpenStreetView/OSVScoreDetailsView.m create mode 100644 OpenStreetView/OSVScoreHistory+Realm.h create mode 100644 OpenStreetView/OSVScoreHistory+Realm.m create mode 100644 OpenStreetView/OSVScoreHistory.h create mode 100644 OpenStreetView/OSVScoreHistory.m delete mode 100644 OpenStreetView/OSVSequenceSectionHeaderView.h delete mode 100644 OpenStreetView/OSVSequenceSectionHeaderView.m delete mode 100644 OpenStreetView/OSVSequenceSectionHeaderView.xib create mode 100644 OpenStreetView/OSVSplashViewController.h create mode 100644 OpenStreetView/OSVSplashViewController.m create mode 100644 OpenStreetView/OSVTrackMatcher.h create mode 100644 OpenStreetView/OSVTrackMatcher.m create mode 100644 OpenStreetView/OSVUtils+Device.m create mode 100644 OpenStreetView/OSVUtils+Gamification.m create mode 100644 OpenStreetView/OpenStreetView-Bridging-Header.h create mode 100644 OpenStreetView/OpenStreetViewRelease-Bridging-Header.h create mode 100644 OpenStreetView/PortraitViewController.swift create mode 100644 OpenStreetView/RLMScoreHistory.h create mode 100644 OpenStreetView/RLMScoreHistory.m create mode 100644 OpenStreetView/ScoreHistory.swift create mode 100644 OpenStreetView/ScoreManager.swift create mode 100644 OpenStreetView/SummaryViewController.swift create mode 100644 OpenStreetView/UIViewController+Additions.h create mode 100644 OpenStreetView/UIViewController+Additions.m create mode 100644 OpenStreetView/ViewControllers/OSVLeaderboardViewController.h create mode 100644 OpenStreetView/ViewControllers/OSVLeaderboardViewController.m create mode 100644 OpenStreetView/Views/OSVRankCell.h create mode 100644 OpenStreetView/Views/OSVRankCell.m create mode 100644 OpenStreetView/Views/OSVRankHeaderCell.h create mode 100644 OpenStreetView/Views/OSVRankHeaderCell.m delete mode 100644 OpenStreetView/Views/OSVSettingsButtonCell.h delete mode 100644 OpenStreetView/Views/OSVSettingsButtonCell.m create mode 100644 OpenStreetView/Views/OSVUnderlineButton.h create mode 100644 OpenStreetView/Views/OSVUnderlineButton.m create mode 100644 OpenStreetView/exif_iOS.proto create mode 100644 Podfile.lock delete mode 100644 photoShutter2.caf diff --git a/OSCTests/Info.plist b/OSCTests/Info.plist new file mode 100644 index 0000000..18527d6 --- /dev/null +++ b/OSCTests/Info.plist @@ -0,0 +1,22 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.skobbler.OSCTests + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleVersion + 1 + + diff --git a/OSCTests/MatcherDataSet.json b/OSCTests/MatcherDataSet.json new file mode 100644 index 0000000..09a6fb0 --- /dev/null +++ b/OSCTests/MatcherDataSet.json @@ -0,0 +1,59 @@ +[ + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773108, 23.591604], + "distance":18.46, + "description":"Midle bottom" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773102, 23.592602], + "distance":28.25, + "description":"Exterior bottom right" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773109, 23.590691], + "distance":25.14, + "description":"Exterior bottom left" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773484, 23.590600], + "distance":28.48, + "description":"Exterior top left" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773409, 23.592524], + "distance":24.67, + "description":"Exterior top right" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773361, 23.591657], + "distance":9.21, + "description":"Midle top" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773305, 23.591074], + "distance":0.51, + "description":"Midle top very close" + }, + { + "segmentStartLocation":[46.773304, 23.590858], + "segmentEndLocation":[46.773253, 23.592299], + "aLocation":[46.773217, 23.592151], + "aLocationOnSegment":[46.773258, 23.592155], + "distance":5.3, + "description":"Midle bottom very close" + } +] diff --git a/OSCTests/OSCTests.m b/OSCTests/OSCTests.m new file mode 100644 index 0000000..d4b3c2f --- /dev/null +++ b/OSCTests/OSCTests.m @@ -0,0 +1,76 @@ +// +// OSCTests.m +// OSCTests +// +// Created by Bogdan Sala on 03/02/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import +#import "OSVUtils.h" + +@interface OSCTests : XCTestCase +@property (strong, nonatomic) NSArray *dataSet; +@end + +@implementation OSCTests + +- (void)setUp { + [super setUp]; + NSString *filePath = [[NSBundle mainBundle] pathForResource:@"MatcherDataSet" ofType:@"json"]; + NSError *deserializingError; + NSURL *localFileURL = [NSURL fileURLWithPath:filePath]; + NSData *contentOfLocalFile = [NSData dataWithContentsOfURL:localFileURL]; + self.dataSet = [NSJSONSerialization JSONObjectWithData:contentOfLocalFile + options:NSJSONReadingAllowFragments + error:&deserializingError]; + +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + NSLog(@">--- count: %ld ---<",self.dataSet.count); + for (NSDictionary *dict in self.dataSet) { + NSArray *aLocation = dict[@"aLocation"]; + NSArray *aStart = dict[@"segmentStartLocation"]; + NSArray *aEnd = dict[@"segmentEndLocation"]; + NSString *aDesc = dict[@"description"]; + NSNumber *aDistance = dict[@"distance"]; + + CLLocation *location = [[CLLocation alloc] initWithLatitude:[aLocation[0] doubleValue] longitude:[aLocation[1] doubleValue]]; + CLLocation *start = [[CLLocation alloc] initWithLatitude:[aStart[0] doubleValue] longitude:[aStart[1] doubleValue]]; + CLLocation *end = [[CLLocation alloc] initWithLatitude:[aEnd[0] doubleValue] longitude:[aEnd[1] doubleValue]]; + + double distance; + [OSVUtils nearestLocationToLocation:location + onLineSegmentLocationA:start + locationB:end + distance:&distance]; + XCTAssert(ABS(distance - aDistance.doubleValue) < 1, @"\n %@ %f expected:%f result:%f \n", aDesc, distance - aDistance.doubleValue, aDistance.doubleValue, distance); + + NSLog(@"%f",ABS(distance - aDistance.doubleValue)); + } +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + for (NSDictionary *dict in self.dataSet) { + NSArray *aLocation = dict[@"aLocation"]; + NSArray *aStart = dict[@"segmentStartLocation"]; + NSArray *aEnd = dict[@"segmentEndLocation"]; + + CLLocation *location = [[CLLocation alloc] initWithLatitude:[aLocation[0] doubleValue] longitude:[aLocation[1] doubleValue]]; + CLLocation *start = [[CLLocation alloc] initWithLatitude:[aStart[0] doubleValue] longitude:[aStart[1] doubleValue]]; + CLLocation *end = [[CLLocation alloc] initWithLatitude:[aEnd[0] doubleValue] longitude:[aEnd[1] doubleValue]]; + double distance; + [OSVUtils nearestLocationToLocation:location onLineSegmentLocationA:start locationB:end distance:&distance]; + } + }]; +} + +@end diff --git a/OpenStreetView.xcodeproj/project.pbxproj b/OpenStreetView.xcodeproj/project.pbxproj index 8ca3ec9..59e9a38 100644 --- a/OpenStreetView.xcodeproj/project.pbxproj +++ b/OpenStreetView.xcodeproj/project.pbxproj @@ -15,6 +15,8 @@ CC01677F1D2E4CB000E8297D /* OSVInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167301D2D665500E8297D /* OSVInfoCell.m */; }; CC0167DE1D2E856100E8297D /* OSVSensorLibManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC0167DD1D2E856100E8297D /* OSVSensorLibManager.mm */; }; CC0167DF1D2E856100E8297D /* OSVSensorLibManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC0167DD1D2E856100E8297D /* OSVSensorLibManager.mm */; }; + CC0167E21D2EB0CF00E8297D /* OSVLocalTracksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167E11D2EB0CF00E8297D /* OSVLocalTracksViewController.m */; }; + CC0167E31D2EB0CF00E8297D /* OSVLocalTracksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167E11D2EB0CF00E8297D /* OSVLocalTracksViewController.m */; }; CC0167E71D2EBA8100E8297D /* OSVLocalTrackCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167E61D2EBA8100E8297D /* OSVLocalTrackCell.m */; }; CC0167E81D2EBA8100E8297D /* OSVLocalTrackCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167E61D2EBA8100E8297D /* OSVLocalTrackCell.m */; }; CC0167EA1D2F9A8200E8297D /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC0167E91D2F9A8200E8297D /* CoreMedia.framework */; }; @@ -37,11 +39,12 @@ CC06B6481C75F71C00E2B0DB /* OSVSegmentedViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC06B6461C75F71C00E2B0DB /* OSVSegmentedViewCell.xib */; }; CC06B6961C776A1A00E2B0DB /* OSVPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = CC06B6951C776A1A00E2B0DB /* OSVPolyline.m */; }; CC09AD7D1C73672100443761 /* UIDevice+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC09AD7C1C73672100443761 /* UIDevice+Aditions.m */; }; + CC12A1DE1C2404240019DB21 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC12A1DC1C2404240019DB21 /* Fabric.framework */; }; + CC12A1DF1C2404240019DB21 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC12A1DD1C2404240019DB21 /* Crashlytics.framework */; }; CC12FCFA1D51DA1A00EB1177 /* OSVCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC12FCF91D51DA1A00EB1177 /* OSVCameraManager.m */; }; CC12FCFB1D51DA1A00EB1177 /* OSVCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC12FCF91D51DA1A00EB1177 /* OSVCameraManager.m */; }; CC1529201C02618D00BD29DC /* OSVFullScreenImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC15291F1C02618D00BD29DC /* OSVFullScreenImageViewController.m */; }; CC1529771C039DC500BD29DC /* OSVBaseUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1529761C039DC500BD29DC /* OSVBaseUser.m */; }; - CC15297B1C039F3100BD29DC /* OSVBaseUser+OSM.m in Sources */ = {isa = PBXBuildFile; fileRef = CC15297A1C039F3100BD29DC /* OSVBaseUser+OSM.m */; }; CC160EA71C5A335A000185D3 /* OSVSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC160EA61C5A335A000185D3 /* OSVSliderCell.m */; }; CC16AE2F1CE4821B001EA02A /* OSVVideoPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC16AE2E1CE4821B001EA02A /* OSVVideoPlayer.m */; }; CC16AE301CE4826E001EA02A /* OSVVideoPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC16AE2E1CE4821B001EA02A /* OSVVideoPlayer.m */; }; @@ -65,28 +68,36 @@ CC19F2E41BAE9395006C8FCC /* OSVServerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2E31BAE9395006C8FCC /* OSVServerSequence.m */; }; CC19F2EB1BAF15A1006C8FCC /* OSVServerPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2EA1BAF15A1006C8FCC /* OSVServerPhoto.m */; }; CC19F3191BB05FFC006C8FCC /* OSVSequenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F3181BB05FFC006C8FCC /* OSVSequenceCell.m */; }; - CC1B3D521D74884700F07098 /* OSVCameraMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1B3D511D74884700F07098 /* OSVCameraMapManager.m */; }; - CC1B3D551D74885C00F07098 /* OSVSettingsMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1B3D541D74885C00F07098 /* OSVSettingsMenuFactory.m */; }; CC1E50371BF2048200BD4A1A /* OSVDebugViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50361BF2048200BD4A1A /* OSVDebugViewController.m */; }; CC1E503B1BF209BA00BD4A1A /* OSVMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E503A1BF209BA00BD4A1A /* OSVMenuItem.m */; }; CC1E503E1BF20A5100BD4A1A /* OSVSectionItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E503D1BF20A5100BD4A1A /* OSVSectionItem.m */; }; + CC1E50411BF26B1200BD4A1A /* OSVSettingsMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50401BF26B1200BD4A1A /* OSVSettingsMenuFactory.m */; }; CC1E50521BF2986900BD4A1A /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50511BF2986900BD4A1A /* UIAlertView+Blocks.m */; }; CC1E50571BF3A38A00BD4A1A /* OSVBasicMapController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50561BF3A38A00BD4A1A /* OSVBasicMapController.m */; }; - CC1FFCE51D58A48300958B8E /* OBDService.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1FFCDB1D58A48300958B8E /* OBDService.m */; }; - CC1FFCE61D58A48300958B8E /* OBDService.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1FFCDB1D58A48300958B8E /* OBDService.m */; }; - CC1FFCE71D58A48300958B8E /* OBDDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1FFCDE1D58A48300958B8E /* OBDDevice.m */; }; - CC1FFCE81D58A48300958B8E /* OBDDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1FFCDE1D58A48300958B8E /* OBDDevice.m */; }; - CC1FFCE91D58A48300958B8E /* OBDUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1FFCE31D58A48300958B8E /* OBDUtils.m */; }; - CC1FFCEA1D58A48300958B8E /* OBDUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1FFCE31D58A48300958B8E /* OBDUtils.m */; }; + CC1E866F1DFB2996002660F4 /* OSVScoreDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E866E1DFB2996002660F4 /* OSVScoreDetailsView.m */; }; + CC1E86701DFB2996002660F4 /* OSVScoreDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E866E1DFB2996002660F4 /* OSVScoreDetailsView.m */; }; + CC1E86731DFEB451002660F4 /* OSVTrackMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E86721DFEB451002660F4 /* OSVTrackMatcher.m */; }; + CC1E86741DFEB451002660F4 /* OSVTrackMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E86721DFEB451002660F4 /* OSVTrackMatcher.m */; }; CC225EC51D227A65000EC04C /* OSVDotedPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = CC225EC41D227A65000EC04C /* OSVDotedPolyline.m */; }; CC225EC61D227A65000EC04C /* OSVDotedPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = CC225EC41D227A65000EC04C /* OSVDotedPolyline.m */; }; CC2573CF1C003D16000EDB3E /* UIColor+OSVColor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573CE1C003D16000EDB3E /* UIColor+OSVColor.m */; }; CC2573E71C0052FF000EDB3E /* UIBarButtonItem+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573E61C0052FF000EDB3E /* UIBarButtonItem+Aditions.m */; }; CC2573EC1C00570D000EDB3E /* SKSearchResult+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573EB1C00570D000EDB3E /* SKSearchResult+Aditions.m */; }; - CC29AD9C1BA8807700538BD3 /* InfoEnterprise.plist in Resources */ = {isa = PBXBuildFile; fileRef = CC29AD9B1BA8807700538BD3 /* InfoEnterprise.plist */; }; + CC2794711E2CED630085866F /* OSVUtils+Gamification.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2794701E2CED4F0085866F /* OSVUtils+Gamification.m */; }; + CC2794721E2CED630085866F /* OSVUtils+Gamification.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2794701E2CED4F0085866F /* OSVUtils+Gamification.m */; }; + CC2794731E2CED640085866F /* OSVUtils+Gamification.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2794701E2CED4F0085866F /* OSVUtils+Gamification.m */; }; + CC2794751E2D0C2E0085866F /* SummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2794741E2D0C2E0085866F /* SummaryViewController.swift */; }; + CC2794761E2D0C2E0085866F /* SummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2794741E2D0C2E0085866F /* SummaryViewController.swift */; }; + CC2794771E2D0C2E0085866F /* SummaryViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC2794741E2D0C2E0085866F /* SummaryViewController.swift */; }; + CC27947B1E2E1FD10085866F /* OSVIntroViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2794791E2E1FD10085866F /* OSVIntroViewController.m */; }; + CC27947C1E2E1FD10085866F /* OSVIntroViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2794791E2E1FD10085866F /* OSVIntroViewController.m */; }; + CC27947D1E2E1FD10085866F /* OSVIntroViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2794791E2E1FD10085866F /* OSVIntroViewController.m */; }; + CC27947E1E2E1FD10085866F /* OSVIntroViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC27947A1E2E1FD10085866F /* OSVIntroViewController.xib */; }; + CC27947F1E2E1FD10085866F /* OSVIntroViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC27947A1E2E1FD10085866F /* OSVIntroViewController.xib */; }; + CC2794801E2E1FD10085866F /* OSVIntroViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC27947A1E2E1FD10085866F /* OSVIntroViewController.xib */; }; CC31DB241C1F0D9D00A0E83D /* OSVReachablityController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC31DB231C1F0D9D00A0E83D /* OSVReachablityController.m */; }; - CC359DA01CC4DC88007DBD49 /* photoShutter2.caf in Resources */ = {isa = PBXBuildFile; fileRef = CC359D9E1CC4DBF6007DBD49 /* photoShutter2.caf */; }; - CC359DA11CC4DC88007DBD49 /* photoShutter2.caf in Resources */ = {isa = PBXBuildFile; fileRef = CC359D9E1CC4DBF6007DBD49 /* photoShutter2.caf */; }; + CC3692BD1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3692BC1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m */; }; + CC3692BE1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3692BC1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m */; }; CC3833791D395906005F228B /* OSVUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3833781D395906005F228B /* OSVUser.m */; }; CC38337A1D395906005F228B /* OSVUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3833781D395906005F228B /* OSVUser.m */; }; CC38A7411D40CC7D0027D5F1 /* oSVLogoV1.png in Resources */ = {isa = PBXBuildFile; fileRef = CC38A73E1D40CC7D0027D5F1 /* oSVLogoV1.png */; }; @@ -115,10 +126,7 @@ CC410AE41D12B9C7000220BA /* OSVFullScreenAnimationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC410AE21D12B9C7000220BA /* OSVFullScreenAnimationController.m */; }; CC410AE71D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC410AE61D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m */; }; CC410AE81D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC410AE61D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m */; }; - CC42A3741D5B4DCA001541DD /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC42A36C1D5B4649001541DD /* Crashlytics.framework */; }; - CC42A3751D5B4DE2001541DD /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC42A36E1D5B464F001541DD /* Fabric.framework */; }; - CC42A3761D5B4DF0001541DD /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC42A36C1D5B4649001541DD /* Crashlytics.framework */; }; - CC42A3771D5B4DFC001541DD /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC42A36E1D5B464F001541DD /* Fabric.framework */; }; + CC4128E31D6EE39000B8AA35 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A31BA02455005B5E9A /* LaunchScreen.xib */; }; CC4536541CA59363005C4490 /* ELM327.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF721CA1601400EC3F70 /* ELM327.m */; }; CC4536551CA59365005C4490 /* ELM327Command.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF741CA1601400EC3F70 /* ELM327Command.m */; }; CC4536561CA59368005C4490 /* ELM327ResponseParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF761CA1601400EC3F70 /* ELM327ResponseParser.m */; }; @@ -133,7 +141,27 @@ CC4ACCDD1CF8DD9A009562C3 /* OSVTipView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC6E45901CCE7577007DB5CA /* OSVTipView.xib */; }; CC4C7B411D3D3C1200B902E8 /* OSVLayersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C7B401D3D3C1200B902E8 /* OSVLayersViewController.m */; }; CC4C7B421D3D3C1200B902E8 /* OSVLayersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C7B401D3D3C1200B902E8 /* OSVLayersViewController.m */; }; + CC4E167B1DABA36A0037827E /* OSVRecordTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E167A1DABA36A0037827E /* OSVRecordTransition.m */; }; + CC4E167C1DABA36A0037827E /* OSVRecordTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E167A1DABA36A0037827E /* OSVRecordTransition.m */; }; + CC4E167F1DABEFB00037827E /* OSVDissmissRecordTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E167E1DABEFB00037827E /* OSVDissmissRecordTransition.m */; }; + CC4E16801DABEFB00037827E /* OSVDissmissRecordTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E167E1DABEFB00037827E /* OSVDissmissRecordTransition.m */; }; + CC4E16831DACE7780037827E /* OSVPushTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E16821DACE7780037827E /* OSVPushTransition.m */; }; + CC4E16841DACE7780037827E /* OSVPushTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E16821DACE7780037827E /* OSVPushTransition.m */; }; + CC4E16871DAD3D570037827E /* OSVPopTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E16861DAD3D570037827E /* OSVPopTransition.m */; }; + CC4E16881DAD3D570037827E /* OSVPopTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E16861DAD3D570037827E /* OSVPopTransition.m */; }; CC5492DF1C48DA190081AC56 /* OSVUploadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5492DE1C48DA190081AC56 /* OSVUploadViewController.m */; }; + CC59A57C1E5DBAAB00A84996 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC59A57B1E5DBAAB00A84996 /* SafariServices.framework */; }; + CC59A57D1E5DC06A00A84996 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC59A57B1E5DBAAB00A84996 /* SafariServices.framework */; }; + CC59A57E1E5DC09200A84996 /* SafariServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC59A57B1E5DBAAB00A84996 /* SafariServices.framework */; }; + CC59A5991E5DF42700A84996 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC59A5981E5DF42700A84996 /* LoginViewController.swift */; }; + CC59A59A1E5DF42700A84996 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC59A5981E5DF42700A84996 /* LoginViewController.swift */; }; + CC59A59B1E5DF42700A84996 /* LoginViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC59A5981E5DF42700A84996 /* LoginViewController.swift */; }; + CC5CADF91E41E38A007AA999 /* UIViewController+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CADF81E41E38A007AA999 /* UIViewController+Additions.m */; }; + CC5CADFA1E41E38A007AA999 /* UIViewController+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CADF81E41E38A007AA999 /* UIViewController+Additions.m */; }; + CC5CADFB1E41E38A007AA999 /* UIViewController+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CADF81E41E38A007AA999 /* UIViewController+Additions.m */; }; + CC5CADFE1E41F0E6007AA999 /* OSVCameraGamificationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CADFD1E41F0E6007AA999 /* OSVCameraGamificationManager.m */; }; + CC5CADFF1E41F0E6007AA999 /* OSVCameraGamificationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CADFD1E41F0E6007AA999 /* OSVCameraGamificationManager.m */; }; + CC5CAE001E41F0E6007AA999 /* OSVCameraGamificationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CADFD1E41F0E6007AA999 /* OSVCameraGamificationManager.m */; }; CC5CC2761D2BC2AC002963D2 /* OSVMainMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CC2751D2BC2AC002963D2 /* OSVMainMenuFactory.m */; }; CC5CC2771D2BC2AC002963D2 /* OSVMainMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CC2751D2BC2AC002963D2 /* OSVMainMenuFactory.m */; }; CC5EB4151C46741F006F3FD0 /* OSVLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5EB4141C46741F006F3FD0 /* OSVLogger.m */; }; @@ -148,15 +176,20 @@ CC65DF811CA1601400EC3F70 /* ELM327ResponseParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF761CA1601400EC3F70 /* ELM327ResponseParser.m */; }; CC65DF821CA1601400EC3F70 /* FLWifiScanTool.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF781CA1601400EC3F70 /* FLWifiScanTool.m */; }; CC65DF851CA1674F00EC3F70 /* OSVOBDController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF841CA1674F00EC3F70 /* OSVOBDController.m */; }; + CC69145D1D671D19005B6855 /* OSVCameraMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC69145C1D671D19005B6855 /* OSVCameraMapManager.m */; }; + CC69145E1D671D19005B6855 /* OSVCameraMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC69145C1D671D19005B6855 /* OSVCameraMapManager.m */; }; CC6E45911CCE7577007DB5CA /* OSVTipView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC6E45901CCE7577007DB5CA /* OSVTipView.xib */; }; CC6E45941CCE75F4007DB5CA /* OSVTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC6E45931CCE75F4007DB5CA /* OSVTipView.m */; }; CC791E5C1BF0A0E700E5CBD3 /* OSVUploadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC791E5B1BF0A0E700E5CBD3 /* OSVUploadCell.m */; }; CC791E5F1BF0A11100E5CBD3 /* OSVSettingsSwitchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC791E5E1BF0A11100E5CBD3 /* OSVSettingsSwitchCell.m */; }; - CC7A63FD1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7A63FB1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m */; }; - CC7A63FE1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7A63FB1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m */; }; CC7A64011CA2CFF6007C9F3B /* OSVOBDController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF841CA1674F00EC3F70 /* OSVOBDController.m */; }; CC7A64051CA2FE85007C9F3B /* OSVOBDData.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7A64041CA2FE85007C9F3B /* OSVOBDData.m */; }; CC7A64061CA2FE85007C9F3B /* OSVOBDData.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7A64041CA2FE85007C9F3B /* OSVOBDData.m */; }; + CC7AEBBC1E07EC5E00D587A9 /* exif_iOS.proto in Resources */ = {isa = PBXBuildFile; fileRef = CC7AEBBB1E07EC5E00D587A9 /* exif_iOS.proto */; }; + CC7B2AD31DE3061900025B67 /* RLMScoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7B2AD21DE3061900025B67 /* RLMScoreHistory.m */; }; + CC7B2AD41DE3061900025B67 /* RLMScoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7B2AD21DE3061900025B67 /* RLMScoreHistory.m */; }; + CC7B2AD81DE3092B00025B67 /* OSVScoreHistory+Realm.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7B2AD71DE3092B00025B67 /* OSVScoreHistory+Realm.m */; }; + CC7B2AD91DE3092B00025B67 /* OSVScoreHistory+Realm.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7B2AD71DE3092B00025B67 /* OSVScoreHistory+Realm.m */; }; CC7C6A3F1CF5E01F00C03051 /* CERangeSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7C6A3A1CF5E01F00C03051 /* CERangeSlider.m */; }; CC7C6A401CF5E01F00C03051 /* CERangeSliderKnobLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7C6A3C1CF5E01F00C03051 /* CERangeSliderKnobLayer.m */; }; CC7C6A411CF5E01F00C03051 /* CERangeSliderTrackLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7C6A3E1CF5E01F00C03051 /* CERangeSliderTrackLayer.m */; }; @@ -186,10 +219,9 @@ CC8960F71D2B9E5300501341 /* OSVMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8960F51D2B9E5300501341 /* OSVMainViewController.m */; }; CC8960FA1D2B9ECF00501341 /* OSVLeftMenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8960F91D2B9ECF00501341 /* OSVLeftMenuViewController.m */; }; CC8960FB1D2B9ECF00501341 /* OSVLeftMenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8960F91D2B9ECF00501341 /* OSVLeftMenuViewController.m */; }; + CC8A08F61DB63393002167AB /* OSVLocalNotificationsController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8A08F51DB63393002167AB /* OSVLocalNotificationsController.m */; }; + CC8A08F71DB63393002167AB /* OSVLocalNotificationsController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8A08F51DB63393002167AB /* OSVLocalNotificationsController.m */; }; CC90C5D71BFB620800F7C69D /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC90C5D61BFB620800F7C69D /* ImageIO.framework */; }; - CC91D5D01BFC751E003A6409 /* OSVExpandableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC91D5CF1BFC751E003A6409 /* OSVExpandableCell.m */; }; - CC91D5D31BFDE88E003A6409 /* OSVSequenceSectionHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC91D5D21BFDE88E003A6409 /* OSVSequenceSectionHeaderView.m */; }; - CC91D5D51BFDE8AA003A6409 /* OSVSequenceSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC91D5D41BFDE8AA003A6409 /* OSVSequenceSectionHeaderView.xib */; }; CC92B0961D35674A004F7EF8 /* NSAttributedString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0951D35674A004F7EF8 /* NSAttributedString+Additions.m */; }; CC92B0971D35674A004F7EF8 /* NSAttributedString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0951D35674A004F7EF8 /* NSAttributedString+Additions.m */; }; CC92B09A1D356F19004F7EF8 /* CALayer+XibConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0991D356F19004F7EF8 /* CALayer+XibConfiguration.m */; }; @@ -204,10 +236,207 @@ CC92B0AE1D37C5D4004F7EF8 /* UIView+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0AC1D37C5D4004F7EF8 /* UIView+Additions.m */; }; CC92B0B11D37DC74004F7EF8 /* OSVSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0B01D37DC74004F7EF8 /* OSVSlider.m */; }; CC92B0B21D37DC74004F7EF8 /* OSVSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0B01D37DC74004F7EF8 /* OSVSlider.m */; }; + CC92F6791E095E5C00427256 /* OSVSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6481BA84F4A00A4CDEE /* OSVSettingsViewController.m */; }; + CC92F67A1E095E5C00427256 /* AVCamPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6931BA850BB00A4CDEE /* AVCamPreviewView.m */; }; + CC92F67B1E095E5C00427256 /* OSVSyncController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6851BA8506400A4CDEE /* OSVSyncController.m */; }; + CC92F67C1E095E5C00427256 /* NSStreamAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF6E1CA1601400EC3F70 /* NSStreamAdditions.m */; }; + CC92F67D1E095E5C00427256 /* OSVLoadingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE34A101BCD221000B54066 /* OSVLoadingCell.m */; }; + CC92F67E1E095E5C00427256 /* OSVTrackCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC01672C1D2D654100E8297D /* OSVTrackCell.m */; }; + CC92F67F1E095E5C00427256 /* UIBarButtonItem+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573E61C0052FF000EDB3E /* UIBarButtonItem+Aditions.m */; }; + CC92F6801E095E5C00427256 /* OSVSectionItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E503D1BF20A5100BD4A1A /* OSVSectionItem.m */; }; + CC92F6811E095E5C00427256 /* OSVBasicMapController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50561BF3A38A00BD4A1A /* OSVBasicMapController.m */; }; + CC92F6821E095E5C00427256 /* AFPropertyListRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1862001BCF73F900FE0F75 /* AFPropertyListRequestOperation.m */; }; + CC92F6831E095E5C00427256 /* OSVPhotoSyncController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F063B1C6B6D7E00441593 /* OSVPhotoSyncController.m */; }; + CC92F6841E095E5C00427256 /* OSVLocalNotificationsController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8A08F51DB63393002167AB /* OSVLocalNotificationsController.m */; }; + CC92F6851E095E5C00427256 /* OBDUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE4D1DA4FFBD00F367DD /* OBDUtils.m */; }; + CC92F6861E095E5C00427256 /* OSVServerSequence+Convertor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2D71BAC2CFF006C8FCC /* OSVServerSequence+Convertor.m */; }; + CC92F6871E095E5C00427256 /* OSVButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF822E11C0745B900E607D9 /* OSVButton.m */; }; + CC92F6881E095E5C00427256 /* OSVPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = CC06B6951C776A1A00E2B0DB /* OSVPolyline.m */; }; + CC92F6891E095E5C00427256 /* OSVSettingsSwitchCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC791E5E1BF0A11100E5CBD3 /* OSVSettingsSwitchCell.m */; }; + CC92F68A1E095E5C00427256 /* ELM327Command.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF741CA1601400EC3F70 /* ELM327Command.m */; }; + CC92F68B1E095E5C00427256 /* OSVUtils+Location.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9458621BDA324100DFFD1A /* OSVUtils+Location.m */; }; + CC92F68C1E095E5C00427256 /* OSVMainViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8960F51D2B9E5300501341 /* OSVMainViewController.m */; }; + CC92F68D1E095E5C00427256 /* OSVDebugViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50361BF2048200BD4A1A /* OSVDebugViewController.m */; }; + CC92F68E1E095E5C00427256 /* OSVPhotoData.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F064E1C6C9E4800441593 /* OSVPhotoData.m */; }; + CC92F68F1E095E5C00427256 /* OSVUserDefaults.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6871BA8506400A4CDEE /* OSVUserDefaults.m */; }; + CC92F6901E095E5C00427256 /* OSMParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E2D1C2012A40089CA0B /* OSMParser.m */; }; + CC92F6911E095E5C00427256 /* OBDService.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE4A1DA4FFBD00F367DD /* OBDService.m */; }; + CC92F6921E095E5C00427256 /* OSVSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2E01BAE937B006C8FCC /* OSVSequence.m */; }; + CC92F6931E095E5C00427256 /* OSVUtils+Device.m in Sources */ = {isa = PBXBuildFile; fileRef = CC99BB251D9421B80029E58D /* OSVUtils+Device.m */; }; + CC92F6941E095E5C00427256 /* OSVPhotoPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC410ADC1D117427000220BA /* OSVPhotoPlayer.m */; }; + CC92F6951E095E5C00427256 /* OSVSequenceCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F3181BB05FFC006C8FCC /* OSVSequenceCell.m */; }; + CC92F6961E095E5C00427256 /* OSVMainMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5CC2751D2BC2AC002963D2 /* OSVMainMenuFactory.m */; }; + CC92F6971E095E5C00427256 /* OSVUploadViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5492DE1C48DA190081AC56 /* OSVUploadViewController.m */; }; + CC92F6981E095E5C00427256 /* OSVPopTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E16861DAD3D570037827E /* OSVPopTransition.m */; }; + CC92F6991E095E5C00427256 /* OSVLocalTrackCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167E61D2EBA8100E8297D /* OSVLocalTrackCell.m */; }; + CC92F69A1E095E5C00427256 /* OSVRankCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE754301DDDEA7A007625DD /* OSVRankCell.m */; }; + CC92F69B1E095E5C00427256 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFD49991BA02455005B5E9A /* AppDelegate.m */; }; + CC92F69C1E095E5C00427256 /* OSVTrackSyncController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06381C6B6D5100441593 /* OSVTrackSyncController.m */; }; + CC92F69D1E095E5C00427256 /* OSVTipView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC6E45931CCE75F4007DB5CA /* OSVTipView.m */; }; + CC92F69E1E095E5C00427256 /* OSVDissmissFullScreenAnimationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC410AE61D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m */; }; + CC92F69F1E095E5C00427256 /* OSVServerPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2EA1BAF15A1006C8FCC /* OSVServerPhoto.m */; }; + CC92F6A01E095E5C00427256 /* OSVAPISpeedometer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06911C6DF46000441593 /* OSVAPISpeedometer.m */; }; + CC92F6A11E095E5C00427256 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1862021BCF73F900FE0F75 /* AFURLConnectionOperation.m */; }; + CC92F6A21E095E5C00427256 /* OSVLeaderboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3692BC1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m */; }; + CC92F6A31E095E5C00427256 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50511BF2986900BD4A1A /* UIAlertView+Blocks.m */; }; + CC92F6A41E095E5C00427256 /* OSVCloseButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0A81D377877004F7EF8 /* OSVCloseButton.m */; }; + CC92F6A51E095E5C00427256 /* OSVSegmentedViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC06B6451C75F71C00E2B0DB /* OSVSegmentedViewCell.m */; }; + CC92F6A61E095E5C00427256 /* OSVPushTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E16821DACE7780037827E /* OSVPushTransition.m */; }; + CC92F6A71E095E5C00427256 /* ConnectivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = CC18622D1BCF76E000FE0F75 /* ConnectivityHandler.m */; }; + CC92F6A81E095E5C00427256 /* OSVMapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6461BA84F4A00A4CDEE /* OSVMapViewController.m */; }; + CC92F6A91E095E5C00427256 /* NSAttributedString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0951D35674A004F7EF8 /* NSAttributedString+Additions.m */; }; + CC92F6AA1E095E5C00427256 /* OSVVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB952DF1CE60EB9006D5BBD /* OSVVideo.m */; }; + CC92F6AB1E095E5C00427256 /* AFJSONRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1861FB1BCF73F900FE0F75 /* AFJSONRequestOperation.m */; }; + CC92F6AC1E095E5C00427256 /* OSVUtils+Image.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD92BBA1BE7709E002F9341 /* OSVUtils+Image.m */; }; + CC92F6AD1E095E5C00427256 /* OSVSettingsMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50401BF26B1200BD4A1A /* OSVSettingsMenuFactory.m */; }; + CC92F6AE1E095E5C00427256 /* OSVCamViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6441BA84F4A00A4CDEE /* OSVCamViewController.m */; }; + CC92F6AF1E095E5C00427256 /* UIColor+OSVColor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573CE1C003D16000EDB3E /* UIColor+OSVColor.m */; }; + CC92F6B01E095E5C00427256 /* OSVSplashViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCA96A01DA77E9100D32CE7 /* OSVSplashViewController.m */; }; + CC92F6B11E095E5C00427256 /* OSVRankHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE7542C1DDDEA08007625DD /* OSVRankHeaderCell.m */; }; + CC92F6B21E095E5C00427256 /* OSVAPI+Video.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB952CF1CE5EAD3006D5BBD /* OSVAPI+Video.m */; }; + CC92F6B31E095E5C00427256 /* OSVBasicCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0168751D34ED7F00E8297D /* OSVBasicCell.m */; }; + CC92F6B41E095E5C00427256 /* OSVCameraMapManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC69145C1D671D19005B6855 /* OSVCameraMapManager.m */; }; + CC92F6B51E095E5C00427256 /* OBDDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE441DA4FFBD00F367DD /* OBDDevice.m */; }; + CC92F6B61E095E5C00427256 /* OSVMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E391C2025440089CA0B /* OSVMetadata.m */; }; + CC92F6B71E095E5C00427256 /* KAProgressLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0A11D3665D9004F7EF8 /* KAProgressLabel.m */; }; + CC92F6B81E095E5C00427256 /* OSVPhoto+Relm.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6971BA850D900A4CDEE /* OSVPhoto+Relm.m */; }; + CC92F6B91E095E5C00427256 /* ELM327.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF721CA1601400EC3F70 /* ELM327.m */; }; + CC92F6BA1E095E5C00427256 /* FLScanTool.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF5F1CA1601400EC3F70 /* FLScanTool.m */; }; + CC92F6BB1E095E5C00427256 /* OSVDetailsCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0168711D34EC8700E8297D /* OSVDetailsCell.m */; }; + CC92F6BC1E095E5C00427256 /* OSVGamificationProfileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD426B41DE44C870006F74B /* OSVGamificationProfileCell.m */; }; + CC92F6BD1E095E5C00427256 /* FLWifiScanTool.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF781CA1601400EC3F70 /* FLWifiScanTool.m */; }; + CC92F6BE1E095E5C00427256 /* OSVGamificationInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD426B81DE46A700006F74B /* OSVGamificationInfo.m */; }; + CC92F6BF1E095E5C00427256 /* ELM327ResponseParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF761CA1601400EC3F70 /* ELM327ResponseParser.m */; }; + CC92F6C01E095E5C00427256 /* OSVSectionHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC01686D1D34D92D00E8297D /* OSVSectionHeaderCell.m */; }; + CC92F6C11E095E5C00427256 /* OSVSequenceMapController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF10DA11BF4A3C200A620EF /* OSVSequenceMapController.m */; }; + CC92F6C21E095E5C00427256 /* OSVAPI+Mix.m in Sources */ = {isa = PBXBuildFile; fileRef = CC40CEB11D1BF3E60006D619 /* OSVAPI+Mix.m */; }; + CC92F6C31E095E5C00427256 /* OSVVideoPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC16AE2E1CE4821B001EA02A /* OSVVideoPlayer.m */; }; + CC92F6C41E095E5C00427256 /* OSVFullScreenImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC15291F1C02618D00BD29DC /* OSVFullScreenImageViewController.m */; }; + CC92F6C51E095E5C00427256 /* OSVSensorLibManager.mm in Sources */ = {isa = PBXBuildFile; fileRef = CC0167DD1D2E856100E8297D /* OSVSensorLibManager.mm */; }; + CC92F6C61E095E5C00427256 /* UIDevice+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC09AD7C1C73672100443761 /* UIDevice+Aditions.m */; }; + CC92F6C71E095E5C00427256 /* OSVMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E503A1BF209BA00BD4A1A /* OSVMenuItem.m */; }; + CC92F6C81E095E5C00427256 /* OSVPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6351BA84F1A00A4CDEE /* OSVPhoto.m */; }; + CC92F6C91E095E5C00427256 /* OSVServerPhoto+Convertor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2D41BAC28C0006C8FCC /* OSVServerPhoto+Convertor.m */; }; + CC92F6CA1E095E5C00427256 /* OSVVideoRecorder.m in Sources */ = {isa = PBXBuildFile; fileRef = CCBE0F0F1C8DF5CF00A43F37 /* OSVVideoRecorder.m */; }; + CC92F6CB1E095E5C00427256 /* OSVScoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF0B4851DDB38F900D80961 /* OSVScoreHistory.m */; }; + CC92F6CC1E095E5C00427256 /* NSFileManager+Godzippa.m in Sources */ = {isa = PBXBuildFile; fileRef = CC40F3A51D13FE840028E488 /* NSFileManager+Godzippa.m */; }; + CC92F6CD1E095E5C00427256 /* CERangeSliderKnobLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7C6A3C1CF5E01F00C03051 /* CERangeSliderKnobLayer.m */; }; + CC92F6CE1E095E5C00427256 /* AFHTTPClient.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1861F51BCF73F900FE0F75 /* AFHTTPClient.m */; }; + CC92F6CF1E095E5C00427256 /* OSVSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0B01D37DC74004F7EF8 /* OSVSlider.m */; }; + CC92F6D01E095E5C00427256 /* AFImageRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1861F91BCF73F900FE0F75 /* AFImageRequestOperation.m */; }; + CC92F6D11E095E5C00427256 /* UIImageView+AFNetworking.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1862061BCF73F900FE0F75 /* UIImageView+AFNetworking.m */; }; + CC92F6D21E095E5C00427256 /* RLMScoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7B2AD21DE3061900025B67 /* RLMScoreHistory.m */; }; + CC92F6D31E095E5C00427256 /* OSVUtils+FileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9458651BDA32D300DFFD1A /* OSVUtils+FileManager.m */; }; + CC92F6D41E095E5C00427256 /* AVCamViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6421BA84F4A00A4CDEE /* AVCamViewController.m */; }; + CC92F6D51E095E5C00427256 /* OSVAPIConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB69D541C3E856D00832788 /* OSVAPIConfigurator.m */; }; + CC92F6D61E095E5C00427256 /* OSVMyProfileViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC39374E1D2D2CC700669EFC /* OSVMyProfileViewController.m */; }; + CC92F6D71E095E5C00427256 /* OSVSettingsOptionCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0168931D35125C00E8297D /* OSVSettingsOptionCell.m */; }; + CC92F6D81E095E5C00427256 /* FLScanToolResponseParser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF661CA1601400EC3F70 /* FLScanToolResponseParser.m */; }; + CC92F6D91E095E5C00427256 /* OSVSyncUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06451C6B7E6A00441593 /* OSVSyncUtils.m */; }; + CC92F6DA1E095E5C00427256 /* OSVAPI+Photos.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E3B1C2025440089CA0B /* OSVAPI+Photos.m */; }; + CC92F6DB1E095E5C00427256 /* FLScanToolCommand.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF621CA1601400EC3F70 /* FLScanToolCommand.m */; }; + CC92F6DC1E095E5C00427256 /* OSVAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E3E1C2025440089CA0B /* OSVAPI.m */; }; + CC92F6DD1E095E5C00427256 /* OSVImageCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF822DE1C06FDAE00E607D9 /* OSVImageCollectionViewCell.m */; }; + CC92F6DE1E095E5C00427256 /* OSVLocationManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6811BA8506400A4CDEE /* OSVLocationManager.m */; }; + CC92F6DF1E095E5C00427256 /* OSVSettingsDetails.m in Sources */ = {isa = PBXBuildFile; fileRef = CC01688E1D35104B00E8297D /* OSVSettingsDetails.m */; }; + CC92F6E01E095E5C00427256 /* OSVLeftMenuViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8960F91D2B9ECF00501341 /* OSVLeftMenuViewController.m */; }; + CC92F6E11E095E5C00427256 /* OSVLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5EB4141C46741F006F3FD0 /* OSVLogger.m */; }; + CC92F6E21E095E5C00427256 /* OSVLayersViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4C7B401D3D3C1200B902E8 /* OSVLayersViewController.m */; }; + CC92F6E31E095E5C00427256 /* UIView+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0AC1D37C5D4004F7EF8 /* UIView+Additions.m */; }; + CC92F6E41E095E5C00427256 /* OSVTrackCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06481C6B85E400441593 /* OSVTrackCache.m */; }; + CC92F6E51E095E5C00427256 /* OSVAPIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E401C2025440089CA0B /* OSVAPIUtils.m */; }; + CC92F6E61E095E5C00427256 /* OSVDissmissRecordTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E167E1DABEFB00037827E /* OSVDissmissRecordTransition.m */; }; + CC92F6E71E095E5C00427256 /* OSVScoreDetailsView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E866E1DFB2996002660F4 /* OSVScoreDetailsView.m */; }; + CC92F6E91E095E5C00427256 /* OSVPersistentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6831BA8506400A4CDEE /* OSVPersistentManager.m */; }; + CC92F6EA1E095E5C00427256 /* OSVTrackMatcher.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E86721DFEB451002660F4 /* OSVTrackMatcher.m */; }; + CC92F6EB1E095E5C00427256 /* OSVBaseUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1529761C039DC500BD29DC /* OSVBaseUser.m */; }; + CC92F6EC1E095E5C00427256 /* OSVInfoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167301D2D665500E8297D /* OSVInfoCell.m */; }; + CC92F6ED1E095E5C00427256 /* OSVAPI+Sequences.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E3C1C2025440089CA0B /* OSVAPI+Sequences.m */; }; + CC92F6EE1E095E5C00427256 /* OSVLocalTracksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167E11D2EB0CF00E8297D /* OSVLocalTracksViewController.m */; }; + CC92F6EF1E095E5C00427256 /* NSData+Godzippa.m in Sources */ = {isa = PBXBuildFile; fileRef = CC40F3A31D13FE840028E488 /* NSData+Godzippa.m */; }; + CC92F6F01E095E5C00427256 /* OSVFullScreenImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCBE0F151C8F1D9D00A43F37 /* OSVFullScreenImageCell.m */; }; + CC92F6F11E095E5C00427256 /* OSVUnderlineButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE754351DDE08EE007625DD /* OSVUnderlineButton.m */; }; + CC92F6F21E095E5C00427256 /* CERangeSlider.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7C6A3A1CF5E01F00C03051 /* CERangeSlider.m */; }; + CC92F6F31E095E5C00427256 /* OSVNavigationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0168531D30235D00E8297D /* OSVNavigationController.m */; }; + CC92F6F41E095E5C00427256 /* OSVTipPageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCBBCFE11D1D638700B9104F /* OSVTipPageViewController.m */; }; + CC92F6F51E095E5C00427256 /* OSVVideoPlayerViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC16AE361CE4892B001EA02A /* OSVVideoPlayerViewController.m */; }; + CC92F6F61E095E5C00427256 /* TPPropertyAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9726481C1634A80034DE96 /* TPPropertyAnimation.m */; }; + CC92F6F71E095E5C00427256 /* OSVServerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2E31BAE9395006C8FCC /* OSVServerSequence.m */; }; + CC92F6F81E095E5C00427256 /* RLMPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C63C1BA84F2C00A4CDEE /* RLMPhoto.m */; }; + CC92F6F91E095E5C00427256 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFD49961BA02455005B5E9A /* main.m */; }; + CC92F6FA1E095E5C00427256 /* OSVSensorsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CCDEFA641C88864700A542BA /* OSVSensorsManager.m */; }; + CC92F6FC1E095E5C00427256 /* OSVMainMenuCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3937301D2BDBEB00669EFC /* OSVMainMenuCell.m */; }; + CC92F6FD1E095E5C00427256 /* OSVSliderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC160EA61C5A335A000185D3 /* OSVSliderCell.m */; }; + CC92F6FE1E095E5C00427256 /* OSVRecordTransition.m in Sources */ = {isa = PBXBuildFile; fileRef = CC4E167A1DABA36A0037827E /* OSVRecordTransition.m */; }; + CC92F6FF1E095E5C00427256 /* OSVOBDData.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7A64041CA2FE85007C9F3B /* OSVOBDData.m */; }; + CC92F7001E095E5C00427256 /* OSVReachablityController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC31DB231C1F0D9D00A0E83D /* OSVReachablityController.m */; }; + CC92F7011E095E5C00427256 /* OSMAPI.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E321C2012A40089CA0B /* OSMAPI.m */; }; + CC92F7021E095E5C00427256 /* OSVMyTracksCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC0167281D2D647D00E8297D /* OSVMyTracksCell.m */; }; + CC92F7031E095E5C00427256 /* OSVLoginController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC40CEB51D1BF8250006D619 /* OSVLoginController.m */; }; + CC92F7041E095E5C00427256 /* OSVAPISerialOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFADD3C1BB309A500A5AAFA /* OSVAPISerialOperation.m */; }; + CC92F7051E095E5C00427256 /* CALayer+XibConfiguration.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B0991D356F19004F7EF8 /* CALayer+XibConfiguration.m */; }; + CC92F7061E095E5C00427256 /* OSVUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3833781D395906005F228B /* OSVUser.m */; }; + CC92F7071E095E5C00427256 /* NSMutableAttributedString+Additions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC92B09D1D362E2A004F7EF8 /* NSMutableAttributedString+Additions.m */; }; + CC92F7081E095E5C00427256 /* AFNetworkActivityIndicatorManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1861FD1BCF73F900FE0F75 /* AFNetworkActivityIndicatorManager.m */; }; + CC92F7091E095E5C00427256 /* FLECUSensor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF691CA1601400EC3F70 /* FLECUSensor.m */; }; + CC92F70A1E095E5C00427256 /* OSVMyProfileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3937531D2D4D7A00669EFC /* OSVMyProfileCell.m */; }; + CC92F70B1E095E5C00427256 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = CC18622F1BCF76E000FE0F75 /* Reachability.m */; }; + CC92F70C1E095E5C00427256 /* AFXMLRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1862041BCF73F900FE0F75 /* AFXMLRequestOperation.m */; }; + CC92F70D1E095E5C00427256 /* LGSideMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC8960F01D2B937A00501341 /* LGSideMenuController.m */; }; + CC92F70E1E095E5C00427256 /* OSMUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E301C2012A40089CA0B /* OSMUser.m */; }; + CC92F70F1E095E5C00427256 /* OSVUploadCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC791E5B1BF0A0E700E5CBD3 /* OSVUploadCell.m */; }; + CC92F7101E095E5C00427256 /* SKSearchResult+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573EB1C00570D000EDB3E /* SKSearchResult+Aditions.m */; }; + CC92F7111E095E5C00427256 /* OSVScoreHistory+Realm.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7B2AD71DE3092B00025B67 /* OSVScoreHistory+Realm.m */; }; + CC92F7131E095E5C00427256 /* OSVCameraManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC12FCF91D51DA1A00EB1177 /* OSVCameraManager.m */; }; + CC92F7141E095E5C00427256 /* CERangeSliderTrackLayer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7C6A3E1CF5E01F00C03051 /* CERangeSliderTrackLayer.m */; }; + CC92F7151E095E5C00427256 /* OSVTrackLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F064B1C6C877500441593 /* OSVTrackLogger.m */; }; + CC92F7161E095E5C00427256 /* AFOAuth1Client.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1862091BCF73F900FE0F75 /* AFOAuth1Client.m */; }; + CC92F7171E095E5C00427256 /* OSVFullScreenAnimationController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC410AE21D12B9C7000220BA /* OSVFullScreenAnimationController.m */; }; + CC92F7181E095E5C00427256 /* AFHTTPRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1861F71BCF73F900FE0F75 /* AFHTTPRequestOperation.m */; }; + CC92F7191E095E5C00427256 /* OSVLogItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06511C6CD9D300441593 /* OSVLogItem.m */; }; + CC92F71A1E095E5C00427256 /* OSVOBDController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF841CA1674F00EC3F70 /* OSVOBDController.m */; }; + CC92F71B1E095E5C00427256 /* OSVDotedPolyline.m in Sources */ = {isa = PBXBuildFile; fileRef = CC225EC41D227A65000EC04C /* OSVDotedPolyline.m */; }; + CC92F71C1E095E5C00427256 /* OSVUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6891BA8506400A4CDEE /* OSVUtils.m */; }; + CC92F71D1E095E5C00427256 /* FLScanToolResponse.m in Sources */ = {isa = PBXBuildFile; fileRef = CC65DF641CA1601400EC3F70 /* FLScanToolResponse.m */; }; + CC92F71F1E095E5C00427256 /* AVFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC06B62A1C75BBD900E2B0DB /* AVFoundation.framework */; }; + CC92F7201E095E5C00427256 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC06B6281C75BBC300E2B0DB /* SystemConfiguration.framework */; }; + CC92F7211E095E5C00427256 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC06B6261C75BBB700E2B0DB /* CoreTelephony.framework */; }; + CC92F7221E095E5C00427256 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC7F068E1C6DEF3900441593 /* MobileCoreServices.framework */; }; + CC92F7231E095E5C00427256 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC90C5D61BFB620800F7C69D /* ImageIO.framework */; }; + CC92F7261E095E5C00427256 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49CD1BA02F25005B5E9A /* libc++.dylib */; }; + CC92F7271E095E5C00427256 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49CB1BA02F19005B5E9A /* libz.dylib */; }; + CC92F7281E095E5C00427256 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C91BA02F0F005B5E9A /* CoreMotion.framework */; }; + CC92F72A1E095E5C00427256 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C71BA02F07005B5E9A /* CoreGraphics.framework */; }; + CC92F72B1E095E5C00427256 /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC0167E91D2F9A8200E8297D /* CoreMedia.framework */; }; + CC92F72D1E095E5C00427256 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C51BA02EFF005B5E9A /* QuartzCore.framework */; }; + CC92F72E1E095E5C00427256 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C31BA02EF7005B5E9A /* OpenGLES.framework */; }; + CC92F72F1E095E5C00427256 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C11BA02EEE005B5E9A /* CoreLocation.framework */; }; + CC92F7301E095E5C00427256 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC12A1DD1C2404240019DB21 /* Crashlytics.framework */; }; + CC92F7311E095E5C00427256 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49BF1BA02EE7005B5E9A /* Foundation.framework */; }; + CC92F7321E095E5C00427256 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC12A1DC1C2404240019DB21 /* Fabric.framework */; }; + CC92F7331E095E5C00427256 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49BD1BA02EDA005B5E9A /* UIKit.framework */; }; + CC92F7371E095E5C00427256 /* oSVLogoV1.png in Resources */ = {isa = PBXBuildFile; fileRef = CC38A73E1D40CC7D0027D5F1 /* oSVLogoV1.png */; }; + CC92F7381E095E5C00427256 /* oSVLogoV1@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = CC38A73F1D40CC7D0027D5F1 /* oSVLogoV1@2x.png */; }; + CC92F7391E095E5C00427256 /* oSVLogoV1@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = CC38A7401D40CC7D0027D5F1 /* oSVLogoV1@3x.png */; }; + CC92F73D1E095E5C00427256 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CCFD499E1BA02455005B5E9A /* Main.storyboard */; }; + CC92F73E1E095E5C00427256 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A31BA02455005B5E9A /* LaunchScreen.xib */; }; + CC92F73F1E095E5C00427256 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CCB56F541C28072D00FFFC39 /* Localizable.strings */; }; + CC92F7401E095E5C00427256 /* OSVTipView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC6E45901CCE7577007DB5CA /* OSVTipView.xib */; }; + CC92F7411E095E5C00427256 /* OSVSegmentedViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC06B6461C75F71C00E2B0DB /* OSVSegmentedViewCell.xib */; }; + CC92F7421E095E5C00427256 /* OSVFullScreenImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCBE0F161C8F1D9D00A43F37 /* OSVFullScreenImageCell.xib */; }; + CC92F7431E095E5C00427256 /* OSVTipPageViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCBBCFE21D1D638700B9104F /* OSVTipPageViewController.xib */; }; + CC92F7441E095E5C00427256 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A11BA02455005B5E9A /* Images.xcassets */; }; + CC92F75B1E0AD75E00427256 /* ScoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92F75A1E0AD75D00427256 /* ScoreManager.swift */; }; + CC92F75C1E0AD75E00427256 /* ScoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92F75A1E0AD75D00427256 /* ScoreManager.swift */; }; + CC92F75D1E0AD75E00427256 /* ScoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92F75A1E0AD75D00427256 /* ScoreManager.swift */; }; + CC92F75F1E0C147700427256 /* ScoreHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92F75E1E0C147700427256 /* ScoreHistory.swift */; }; + CC92F7601E0C147700427256 /* ScoreHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92F75E1E0C147700427256 /* ScoreHistory.swift */; }; + CC92F7611E0C147700427256 /* ScoreHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = CC92F75E1E0C147700427256 /* ScoreHistory.swift */; }; CC9458631BDA324100DFFD1A /* OSVUtils+Location.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9458621BDA324100DFFD1A /* OSVUtils+Location.m */; }; CC9458661BDA32D300DFFD1A /* OSVUtils+FileManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9458651BDA32D300DFFD1A /* OSVUtils+FileManager.m */; }; CC97264B1C1634A80034DE96 /* TPPropertyAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9726481C1634A80034DE96 /* TPPropertyAnimation.m */; }; - CCA16C1F1C92D1DA001EEB57 /* InfoBeta.plist in Resources */ = {isa = PBXBuildFile; fileRef = CCA16C1E1C92D1DA001EEB57 /* InfoBeta.plist */; }; + CC99BB261D9421B80029E58D /* OSVUtils+Device.m in Sources */ = {isa = PBXBuildFile; fileRef = CC99BB251D9421B80029E58D /* OSVUtils+Device.m */; }; + CC99BB271D9421B80029E58D /* OSVUtils+Device.m in Sources */ = {isa = PBXBuildFile; fileRef = CC99BB251D9421B80029E58D /* OSVUtils+Device.m */; }; CCA16C261C92F64B001EEB57 /* OSVSettingsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6481BA84F4A00A4CDEE /* OSVSettingsViewController.m */; }; CCA16C271C92F64B001EEB57 /* AVCamPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6931BA850BB00A4CDEE /* AVCamPreviewView.m */; }; CCA16C281C92F64B001EEB57 /* OSVSyncController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6851BA8506400A4CDEE /* OSVSyncController.m */; }; @@ -234,21 +463,18 @@ CCA16C3F1C92F64B001EEB57 /* OSVServerPhoto.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2EA1BAF15A1006C8FCC /* OSVServerPhoto.m */; }; CCA16C401C92F64B001EEB57 /* OSVAPISpeedometer.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06911C6DF46000441593 /* OSVAPISpeedometer.m */; }; CCA16C411C92F64B001EEB57 /* AFURLConnectionOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1862021BCF73F900FE0F75 /* AFURLConnectionOperation.m */; }; - CCA16C421C92F64B001EEB57 /* OSVExpandableCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC91D5CF1BFC751E003A6409 /* OSVExpandableCell.m */; }; CCA16C431C92F64B001EEB57 /* UIAlertView+Blocks.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50511BF2986900BD4A1A /* UIAlertView+Blocks.m */; }; CCA16C441C92F64B001EEB57 /* OSVSegmentedViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CC06B6451C75F71C00E2B0DB /* OSVSegmentedViewCell.m */; }; CCA16C451C92F64B001EEB57 /* ConnectivityHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = CC18622D1BCF76E000FE0F75 /* ConnectivityHandler.m */; }; CCA16C461C92F64B001EEB57 /* OSVMapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6461BA84F4A00A4CDEE /* OSVMapViewController.m */; }; CCA16C471C92F64B001EEB57 /* AFJSONRequestOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1861FB1BCF73F900FE0F75 /* AFJSONRequestOperation.m */; }; CCA16C491C92F64B001EEB57 /* OSVUtils+Image.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD92BBA1BE7709E002F9341 /* OSVUtils+Image.m */; }; - CCA16C4B1C92F64B001EEB57 /* OSVSequenceSectionHeaderView.m in Sources */ = {isa = PBXBuildFile; fileRef = CC91D5D21BFDE88E003A6409 /* OSVSequenceSectionHeaderView.m */; }; + CCA16C4A1C92F64B001EEB57 /* OSVSettingsMenuFactory.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E50401BF26B1200BD4A1A /* OSVSettingsMenuFactory.m */; }; CCA16C4D1C92F64B001EEB57 /* OSVCamViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6441BA84F4A00A4CDEE /* OSVCamViewController.m */; }; CCA16C4E1C92F64B001EEB57 /* UIColor+OSVColor.m in Sources */ = {isa = PBXBuildFile; fileRef = CC2573CE1C003D16000EDB3E /* UIColor+OSVColor.m */; }; - CCA16C4F1C92F64B001EEB57 /* OSVGalleryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE6C45C1C102F12005DC6FF /* OSVGalleryCell.m */; }; CCA16C501C92F64B001EEB57 /* OSVMetadata.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E391C2025440089CA0B /* OSVMetadata.m */; }; CCA16C511C92F64B001EEB57 /* OSVPhoto+Relm.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6971BA850D900A4CDEE /* OSVPhoto+Relm.m */; }; CCA16C521C92F64B001EEB57 /* OSVSequenceMapController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF10DA11BF4A3C200A620EF /* OSVSequenceMapController.m */; }; - CCA16C531C92F64B001EEB57 /* OSVRedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF823051C0884DD00E607D9 /* OSVRedButton.m */; }; CCA16C541C92F64B001EEB57 /* OSVFullScreenImageViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CC15291F1C02618D00BD29DC /* OSVFullScreenImageViewController.m */; }; CCA16C561C92F64B001EEB57 /* UIDevice+Aditions.m in Sources */ = {isa = PBXBuildFile; fileRef = CC09AD7C1C73672100443761 /* UIDevice+Aditions.m */; }; CCA16C571C92F64B001EEB57 /* OSVMenuItem.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1E503A1BF209BA00BD4A1A /* OSVMenuItem.m */; }; @@ -269,11 +495,9 @@ CCA16C671C92F64B001EEB57 /* OSVLogger.m in Sources */ = {isa = PBXBuildFile; fileRef = CC5EB4141C46741F006F3FD0 /* OSVLogger.m */; }; CCA16C681C92F64B001EEB57 /* OSVTrackCache.m in Sources */ = {isa = PBXBuildFile; fileRef = CC7F06481C6B85E400441593 /* OSVTrackCache.m */; }; CCA16C691C92F64B001EEB57 /* OSVAPIUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E401C2025440089CA0B /* OSVAPIUtils.m */; }; - CCA16C6A1C92F64B001EEB57 /* OSVBaseUser+OSM.m in Sources */ = {isa = PBXBuildFile; fileRef = CC15297A1C039F3100BD29DC /* OSVBaseUser+OSM.m */; }; CCA16C6B1C92F64B001EEB57 /* OSVPersistentManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6831BA8506400A4CDEE /* OSVPersistentManager.m */; }; CCA16C6C1C92F64B001EEB57 /* OSVBaseUser.m in Sources */ = {isa = PBXBuildFile; fileRef = CC1529761C039DC500BD29DC /* OSVBaseUser.m */; }; CCA16C6D1C92F64B001EEB57 /* OSVAPI+Sequences.m in Sources */ = {isa = PBXBuildFile; fileRef = CC881E3C1C2025440089CA0B /* OSVAPI+Sequences.m */; }; - CCA16C6E1C92F64B001EEB57 /* OSVCropedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE6C45F1C105008005DC6FF /* OSVCropedLabel.m */; }; CCA16C6F1C92F64B001EEB57 /* OSVFullScreenImageCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCBE0F151C8F1D9D00A43F37 /* OSVFullScreenImageCell.m */; }; CCA16C711C92F64B001EEB57 /* TPPropertyAnimation.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9726481C1634A80034DE96 /* TPPropertyAnimation.m */; }; CCA16C721C92F64B001EEB57 /* OSVServerSequence.m in Sources */ = {isa = PBXBuildFile; fileRef = CC19F2E31BAE9395006C8FCC /* OSVServerSequence.m */; }; @@ -300,26 +524,25 @@ CCA16C8C1C92F64B001EEB57 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC06B6261C75BBB700E2B0DB /* CoreTelephony.framework */; }; CCA16C8D1C92F64B001EEB57 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC7F068E1C6DEF3900441593 /* MobileCoreServices.framework */; }; CCA16C8E1C92F64B001EEB57 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC90C5D61BFB620800F7C69D /* ImageIO.framework */; }; + CCA16C8F1C92F64B001EEB57 /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49CD1BA02F25005B5E9A /* libc++.dylib */; }; + CCA16C901C92F64B001EEB57 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49CB1BA02F19005B5E9A /* libz.dylib */; }; CCA16C911C92F64B001EEB57 /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C91BA02F0F005B5E9A /* CoreMotion.framework */; }; CCA16C931C92F64B001EEB57 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C71BA02F07005B5E9A /* CoreGraphics.framework */; }; CCA16C941C92F64B001EEB57 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C51BA02EFF005B5E9A /* QuartzCore.framework */; }; CCA16C961C92F64B001EEB57 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C31BA02EF7005B5E9A /* OpenGLES.framework */; }; CCA16C971C92F64B001EEB57 /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C11BA02EEE005B5E9A /* CoreLocation.framework */; }; + CCA16C981C92F64B001EEB57 /* Crashlytics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC12A1DD1C2404240019DB21 /* Crashlytics.framework */; }; CCA16C991C92F64B001EEB57 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49BF1BA02EE7005B5E9A /* Foundation.framework */; }; + CCA16C9A1C92F64B001EEB57 /* Fabric.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC12A1DC1C2404240019DB21 /* Fabric.framework */; }; CCA16C9B1C92F64B001EEB57 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49BD1BA02EDA005B5E9A /* UIKit.framework */; }; CCA16C9F1C92F64B001EEB57 /* OSVSegmentedViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC06B6461C75F71C00E2B0DB /* OSVSegmentedViewCell.xib */; }; - CCA16CA01C92F64B001EEB57 /* InfoEnterprise.plist in Resources */ = {isa = PBXBuildFile; fileRef = CC29AD9B1BA8807700538BD3 /* InfoEnterprise.plist */; }; CCA16CA11C92F64B001EEB57 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CCFD499E1BA02455005B5E9A /* Main.storyboard */; }; CCA16CA21C92F64B001EEB57 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A31BA02455005B5E9A /* LaunchScreen.xib */; }; - CCA16CA31C92F64B001EEB57 /* InfoBeta.plist in Resources */ = {isa = PBXBuildFile; fileRef = CCA16C1E1C92D1DA001EEB57 /* InfoBeta.plist */; }; CCA16CA51C92F64B001EEB57 /* OSVFullScreenImageCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCBE0F161C8F1D9D00A43F37 /* OSVFullScreenImageCell.xib */; }; CCA16CA61C92F64B001EEB57 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CCB56F541C28072D00FFFC39 /* Localizable.strings */; }; - CCA16CA71C92F64B001EEB57 /* OSVSequenceSectionHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = CC91D5D41BFDE8AA003A6409 /* OSVSequenceSectionHeaderView.xib */; }; CCA16CA81C92F64B001EEB57 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A11BA02455005B5E9A /* Images.xcassets */; }; CCB56F551C28072D00FFFC39 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = CCB56F541C28072D00FFFC39 /* Localizable.strings */; }; CCB69D551C3E856D00832788 /* OSVAPIConfigurator.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB69D541C3E856D00832788 /* OSVAPIConfigurator.m */; }; - CCB88C781D830C15000CADD6 /* OSVLocalTracksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB88C771D830C15000CADD6 /* OSVLocalTracksViewController.m */; }; - CCB88C791D830E52000CADD6 /* OSVLocalTracksViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB88C771D830C15000CADD6 /* OSVLocalTracksViewController.m */; }; CCB952D01CE5EAD3006D5BBD /* OSVAPI+Video.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB952CF1CE5EAD3006D5BBD /* OSVAPI+Video.m */; }; CCB952D11CE5EAD3006D5BBD /* OSVAPI+Video.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB952CF1CE5EAD3006D5BBD /* OSVAPI+Video.m */; }; CCB952E01CE60EB9006D5BBD /* OSVVideo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCB952DF1CE60EB9006D5BBD /* OSVVideo.m */; }; @@ -344,21 +567,41 @@ CCC2C68F1BA8506400A4CDEE /* OSVUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6891BA8506400A4CDEE /* OSVUtils.m */; }; CCC2C6941BA850BB00A4CDEE /* AVCamPreviewView.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6931BA850BB00A4CDEE /* AVCamPreviewView.m */; }; CCC2C69A1BA850D900A4CDEE /* OSVPhoto+Relm.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6971BA850D900A4CDEE /* OSVPhoto+Relm.m */; }; + CCCA96901DA6354D00D32CE7 /* OBDDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE441DA4FFBD00F367DD /* OBDDevice.m */; }; + CCCA96911DA6355200D32CE7 /* OBDService.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE4A1DA4FFBD00F367DD /* OBDService.m */; }; + CCCA96921DA6355600D32CE7 /* OBDUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE4D1DA4FFBD00F367DD /* OBDUtils.m */; }; + CCCA96A11DA77E9100D32CE7 /* OSVSplashViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCA96A01DA77E9100D32CE7 /* OSVSplashViewController.m */; }; + CCCA96A21DA77E9100D32CE7 /* OSVSplashViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCA96A01DA77E9100D32CE7 /* OSVSplashViewController.m */; }; + CCCD8E1C1D5DB6900056C7AF /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CC0167E91D2F9A8200E8297D /* CoreMedia.framework */; }; + CCCDBE4E1DA4FFBD00F367DD /* OBDDevice.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE441DA4FFBD00F367DD /* OBDDevice.m */; }; + CCCDBE4F1DA4FFBD00F367DD /* OBDService.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE4A1DA4FFBD00F367DD /* OBDService.m */; }; + CCCDBE501DA4FFBD00F367DD /* OBDUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CCCDBE4D1DA4FFBD00F367DD /* OBDUtils.m */; }; + CCD426B51DE44C870006F74B /* OSVGamificationProfileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD426B41DE44C870006F74B /* OSVGamificationProfileCell.m */; }; + CCD426B61DE44C870006F74B /* OSVGamificationProfileCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD426B41DE44C870006F74B /* OSVGamificationProfileCell.m */; }; + CCD426B91DE46A700006F74B /* OSVGamificationInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD426B81DE46A700006F74B /* OSVGamificationInfo.m */; }; + CCD426BA1DE46A700006F74B /* OSVGamificationInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD426B81DE46A700006F74B /* OSVGamificationInfo.m */; }; CCD92BBB1BE7709E002F9341 /* OSVUtils+Image.m in Sources */ = {isa = PBXBuildFile; fileRef = CCD92BBA1BE7709E002F9341 /* OSVUtils+Image.m */; }; CCDEFA661C88864700A542BA /* OSVSensorsManager.m in Sources */ = {isa = PBXBuildFile; fileRef = CCDEFA641C88864700A542BA /* OSVSensorsManager.m */; }; CCE34A111BCD221000B54066 /* OSVLoadingCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE34A101BCD221000B54066 /* OSVLoadingCell.m */; }; - CCE6C45D1C102F12005DC6FF /* OSVGalleryCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE6C45C1C102F12005DC6FF /* OSVGalleryCell.m */; }; - CCE6C4611C106288005DC6FF /* OSVCropedLabel.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE6C45F1C105008005DC6FF /* OSVCropedLabel.m */; }; + CCE7542D1DDDEA08007625DD /* OSVRankHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE7542C1DDDEA08007625DD /* OSVRankHeaderCell.m */; }; + CCE7542E1DDDEA08007625DD /* OSVRankHeaderCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE7542C1DDDEA08007625DD /* OSVRankHeaderCell.m */; }; + CCE754311DDDEA7A007625DD /* OSVRankCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE754301DDDEA7A007625DD /* OSVRankCell.m */; }; + CCE754321DDDEA7A007625DD /* OSVRankCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE754301DDDEA7A007625DD /* OSVRankCell.m */; }; + CCE754361DDE08EE007625DD /* OSVUnderlineButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE754351DDE08EE007625DD /* OSVUnderlineButton.m */; }; + CCE754371DDE08EE007625DD /* OSVUnderlineButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCE754351DDE08EE007625DD /* OSVUnderlineButton.m */; }; + CCEC8A091E38B4510049093A /* PortraitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCEC8A081E38B4510049093A /* PortraitViewController.swift */; }; + CCEC8A0A1E38B4510049093A /* PortraitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCEC8A081E38B4510049093A /* PortraitViewController.swift */; }; + CCEC8A0B1E38B4510049093A /* PortraitViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = CCEC8A081E38B4510049093A /* PortraitViewController.swift */; }; + CCF0B4861DDB38F900D80961 /* OSVScoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF0B4851DDB38F900D80961 /* OSVScoreHistory.m */; }; + CCF0B4871DDB38F900D80961 /* OSVScoreHistory.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF0B4851DDB38F900D80961 /* OSVScoreHistory.m */; }; CCF10DA21BF4A3C200A620EF /* OSVSequenceMapController.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF10DA11BF4A3C200A620EF /* OSVSequenceMapController.m */; }; CCF822DF1C06FDAE00E607D9 /* OSVImageCollectionViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF822DE1C06FDAE00E607D9 /* OSVImageCollectionViewCell.m */; }; CCF822E21C0745B900E607D9 /* OSVButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF822E11C0745B900E607D9 /* OSVButton.m */; }; - CCF823061C0884DD00E607D9 /* OSVRedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF823051C0884DD00E607D9 /* OSVRedButton.m */; }; CCFADD3D1BB309A500A5AAFA /* OSVAPISerialOperation.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFADD3C1BB309A500A5AAFA /* OSVAPISerialOperation.m */; }; CCFD49971BA02455005B5E9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFD49961BA02455005B5E9A /* main.m */; }; CCFD499A1BA02455005B5E9A /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFD49991BA02455005B5E9A /* AppDelegate.m */; }; CCFD49A01BA02455005B5E9A /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = CCFD499E1BA02455005B5E9A /* Main.storyboard */; }; CCFD49A21BA02455005B5E9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A11BA02455005B5E9A /* Images.xcassets */; }; - CCFD49A51BA02455005B5E9A /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = CCFD49A31BA02455005B5E9A /* LaunchScreen.xib */; }; CCFD49BE1BA02EDA005B5E9A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49BD1BA02EDA005B5E9A /* UIKit.framework */; }; CCFD49C01BA02EE7005B5E9A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49BF1BA02EE7005B5E9A /* Foundation.framework */; }; CCFD49C21BA02EEE005B5E9A /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C11BA02EEE005B5E9A /* CoreLocation.framework */; }; @@ -366,11 +609,55 @@ CCFD49C61BA02EFF005B5E9A /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C51BA02EFF005B5E9A /* QuartzCore.framework */; }; CCFD49C81BA02F07005B5E9A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C71BA02F07005B5E9A /* CoreGraphics.framework */; }; CCFD49CA1BA02F10005B5E9A /* CoreMotion.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49C91BA02F0F005B5E9A /* CoreMotion.framework */; }; - D82CA580ABF5EE3A56569CAD /* Pods_OpenStreetViewRelease.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0D96C56BCF2E540BBEFFA744 /* Pods_OpenStreetViewRelease.framework */; }; - DC811D40DA55683BAC93A812 /* Pods_OpenStreetView.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53A86B025D720FA16CBA4524 /* Pods_OpenStreetView.framework */; }; + CCFD49CC1BA02F19005B5E9A /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49CB1BA02F19005B5E9A /* libz.dylib */; }; + CCFD49CE1BA02F25005B5E9A /* libc++.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = CCFD49CD1BA02F25005B5E9A /* libc++.dylib */; }; + CCFF57931E44D0960031B8BE /* OSCTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCFF57921E44D0960031B8BE /* OSCTests.m */; }; + CCFF579D1E44D1980031B8BE /* MatcherDataSet.json in Resources */ = {isa = PBXBuildFile; fileRef = CCFF579C1E44D1980031B8BE /* MatcherDataSet.json */; }; + CCFF579E1E44D2930031B8BE /* MatcherDataSet.json in Resources */ = {isa = PBXBuildFile; fileRef = CCFF579C1E44D1980031B8BE /* MatcherDataSet.json */; }; + CCFF579F1E44D6170031B8BE /* OSVUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = CCC2C6891BA8506400A4CDEE /* OSVUtils.m */; }; + CCFF57A01E44D7000031B8BE /* OSVUtils+Location.m in Sources */ = {isa = PBXBuildFile; fileRef = CC9458621BDA324100DFFD1A /* OSVUtils+Location.m */; }; /* End PBXBuildFile section */ +/* Begin PBXContainerItemProxy section */ + CCFF57951E44D0960031B8BE /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CCFD49891BA02455005B5E9A /* Project object */; + proxyType = 1; + remoteGlobalIDString = CCFD49901BA02455005B5E9A; + remoteInfo = OpenStreetView; + }; +/* End PBXContainerItemProxy section */ + /* Begin PBXCopyFilesBuildPhase section */ + CC02D2C91D92CD16000E98BF /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + CC92F7451E095E5C00427256 /* CopyFiles */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 7; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CC92F7461E095E5C00427256 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; CCA16CAA1C92F64B001EEB57 /* CopyFiles */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -402,15 +689,6 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ - 0D96C56BCF2E540BBEFFA744 /* Pods_OpenStreetViewRelease.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OpenStreetViewRelease.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 244418F01B0BB9BE8E5468A5 /* Pods-OpenStreetViewRelease.enterprise.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetViewRelease.enterprise.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetViewRelease/Pods-OpenStreetViewRelease.enterprise.xcconfig"; sourceTree = ""; }; - 53A86B025D720FA16CBA4524 /* Pods_OpenStreetView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_OpenStreetView.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 568DA0768A3FBE3F9CED9C76 /* Pods-OpenStreetView.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetView.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetView/Pods-OpenStreetView.debug.xcconfig"; sourceTree = ""; }; - 61065ED006F711614BE2E2D3 /* Pods-OpenStreetViewRelease.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetViewRelease.release.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetViewRelease/Pods-OpenStreetViewRelease.release.xcconfig"; sourceTree = ""; }; - 76EFDE20412EDAEF4D2AEAC5 /* Pods-OpenStreetView.enterprise.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetView.enterprise.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetView/Pods-OpenStreetView.enterprise.xcconfig"; sourceTree = ""; }; - 918840F1F96F2026A7C60A46 /* Pods-OpenStreetView.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetView.beta.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetView/Pods-OpenStreetView.beta.xcconfig"; sourceTree = ""; }; - B5994CEE8F0652F6972FCE4A /* Pods-OpenStreetViewRelease.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetViewRelease.beta.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetViewRelease/Pods-OpenStreetViewRelease.beta.xcconfig"; sourceTree = ""; }; - BCCC682778267DD5632A0C68 /* Pods-OpenStreetViewRelease.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetViewRelease.debug.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetViewRelease/Pods-OpenStreetViewRelease.debug.xcconfig"; sourceTree = ""; }; CC0167271D2D647D00E8297D /* OSVMyTracksCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVMyTracksCell.h; sourceTree = ""; }; CC0167281D2D647D00E8297D /* OSVMyTracksCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVMyTracksCell.m; sourceTree = ""; }; CC01672B1D2D654100E8297D /* OSVTrackCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVTrackCell.h; sourceTree = ""; }; @@ -419,6 +697,8 @@ CC0167301D2D665500E8297D /* OSVInfoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVInfoCell.m; sourceTree = ""; }; CC0167DC1D2E856100E8297D /* OSVSensorLibManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSensorLibManager.h; sourceTree = ""; }; CC0167DD1D2E856100E8297D /* OSVSensorLibManager.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = OSVSensorLibManager.mm; sourceTree = ""; }; + CC0167E01D2EB0CF00E8297D /* OSVLocalTracksViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVLocalTracksViewController.h; sourceTree = ""; }; + CC0167E11D2EB0CF00E8297D /* OSVLocalTracksViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVLocalTracksViewController.m; sourceTree = ""; }; CC0167E51D2EBA8100E8297D /* OSVLocalTrackCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVLocalTrackCell.h; sourceTree = ""; }; CC0167E61D2EBA8100E8297D /* OSVLocalTrackCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVLocalTrackCell.m; sourceTree = ""; }; CC0167E91D2F9A8200E8297D /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; }; @@ -444,14 +724,14 @@ CC06B6951C776A1A00E2B0DB /* OSVPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVPolyline.m; sourceTree = ""; }; CC09AD7B1C73672100443761 /* UIDevice+Aditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIDevice+Aditions.h"; sourceTree = ""; }; CC09AD7C1C73672100443761 /* UIDevice+Aditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIDevice+Aditions.m"; sourceTree = ""; }; + CC12A1DC1C2404240019DB21 /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Fabric.framework; path = Pods/Fabric/iOS/Fabric.framework; sourceTree = ""; }; + CC12A1DD1C2404240019DB21 /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crashlytics.framework; path = Pods/Crashlytics/iOS/Crashlytics.framework; sourceTree = ""; }; CC12FCF81D51DA1A00EB1177 /* OSVCameraManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVCameraManager.h; path = ViewControllers/OSVCameraManager.h; sourceTree = ""; }; CC12FCF91D51DA1A00EB1177 /* OSVCameraManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVCameraManager.m; path = ViewControllers/OSVCameraManager.m; sourceTree = ""; }; CC15291E1C02618D00BD29DC /* OSVFullScreenImageViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVFullScreenImageViewController.h; sourceTree = ""; }; CC15291F1C02618D00BD29DC /* OSVFullScreenImageViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVFullScreenImageViewController.m; sourceTree = ""; }; CC1529751C039DC500BD29DC /* OSVBaseUser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVBaseUser.h; sourceTree = ""; }; CC1529761C039DC500BD29DC /* OSVBaseUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVBaseUser.m; sourceTree = ""; }; - CC1529791C039F3100BD29DC /* OSVBaseUser+OSM.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OSVBaseUser+OSM.h"; sourceTree = ""; }; - CC15297A1C039F3100BD29DC /* OSVBaseUser+OSM.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OSVBaseUser+OSM.m"; sourceTree = ""; }; CC160EA51C5A335A000185D3 /* OSVSliderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSliderCell.h; sourceTree = ""; }; CC160EA61C5A335A000185D3 /* OSVSliderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSliderCell.m; sourceTree = ""; }; CC16AE2D1CE4821B001EA02A /* OSVVideoPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVVideoPlayer.h; sourceTree = ""; }; @@ -495,31 +775,22 @@ CC19F2EA1BAF15A1006C8FCC /* OSVServerPhoto.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVServerPhoto.m; sourceTree = ""; }; CC19F3171BB05FFC006C8FCC /* OSVSequenceCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSequenceCell.h; sourceTree = ""; }; CC19F3181BB05FFC006C8FCC /* OSVSequenceCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSequenceCell.m; sourceTree = ""; }; - CC1B3D501D74884700F07098 /* OSVCameraMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVCameraMapManager.h; sourceTree = ""; }; - CC1B3D511D74884700F07098 /* OSVCameraMapManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVCameraMapManager.m; sourceTree = ""; }; - CC1B3D531D74885C00F07098 /* OSVSettingsMenuFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSettingsMenuFactory.h; sourceTree = ""; }; - CC1B3D541D74885C00F07098 /* OSVSettingsMenuFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSettingsMenuFactory.m; sourceTree = ""; }; CC1E50351BF2048200BD4A1A /* OSVDebugViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVDebugViewController.h; sourceTree = ""; }; CC1E50361BF2048200BD4A1A /* OSVDebugViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVDebugViewController.m; sourceTree = ""; }; CC1E50391BF209BA00BD4A1A /* OSVMenuItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVMenuItem.h; sourceTree = ""; }; CC1E503A1BF209BA00BD4A1A /* OSVMenuItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVMenuItem.m; sourceTree = ""; }; CC1E503C1BF20A5100BD4A1A /* OSVSectionItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSectionItem.h; sourceTree = ""; }; CC1E503D1BF20A5100BD4A1A /* OSVSectionItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSectionItem.m; sourceTree = ""; }; + CC1E503F1BF26B1200BD4A1A /* OSVSettingsMenuFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSettingsMenuFactory.h; sourceTree = ""; }; + CC1E50401BF26B1200BD4A1A /* OSVSettingsMenuFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSettingsMenuFactory.m; sourceTree = ""; }; CC1E50501BF2986900BD4A1A /* UIAlertView+Blocks.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIAlertView+Blocks.h"; sourceTree = ""; }; CC1E50511BF2986900BD4A1A /* UIAlertView+Blocks.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIAlertView+Blocks.m"; sourceTree = ""; }; CC1E50551BF3A38A00BD4A1A /* OSVBasicMapController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVBasicMapController.h; sourceTree = ""; }; CC1E50561BF3A38A00BD4A1A /* OSVBasicMapController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVBasicMapController.m; sourceTree = ""; }; - CC1FFCDA1D58A48300958B8E /* OBDService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDService.h; sourceTree = ""; }; - CC1FFCDB1D58A48300958B8E /* OBDService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OBDService.m; sourceTree = ""; }; - CC1FFCDC1D58A48300958B8E /* OBDServiceDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDServiceDelegate.h; sourceTree = ""; }; - CC1FFCDD1D58A48300958B8E /* OBDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDDevice.h; sourceTree = ""; }; - CC1FFCDE1D58A48300958B8E /* OBDDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OBDDevice.m; sourceTree = ""; }; - CC1FFCDF1D58A48300958B8E /* OBDDevice+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OBDDevice+Internal.h"; sourceTree = ""; }; - CC1FFCE01D58A48300958B8E /* OBDDeviceDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDDeviceDelegate.h; sourceTree = ""; }; - CC1FFCE11D58A48300958B8E /* OBDSensors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDSensors.h; sourceTree = ""; }; - CC1FFCE21D58A48300958B8E /* OBDUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDUtils.h; sourceTree = ""; }; - CC1FFCE31D58A48300958B8E /* OBDUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OBDUtils.m; sourceTree = ""; }; - CC1FFCE41D58A48300958B8E /* OBDLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OBDLib.h; sourceTree = ""; }; + CC1E866D1DFB2996002660F4 /* OSVScoreDetailsView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVScoreDetailsView.h; sourceTree = ""; }; + CC1E866E1DFB2996002660F4 /* OSVScoreDetailsView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVScoreDetailsView.m; sourceTree = ""; }; + CC1E86711DFEB451002660F4 /* OSVTrackMatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVTrackMatcher.h; sourceTree = ""; }; + CC1E86721DFEB451002660F4 /* OSVTrackMatcher.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVTrackMatcher.m; sourceTree = ""; }; CC225EC31D227A65000EC04C /* OSVDotedPolyline.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVDotedPolyline.h; path = Views/OSVDotedPolyline.h; sourceTree = ""; }; CC225EC41D227A65000EC04C /* OSVDotedPolyline.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVDotedPolyline.m; path = Views/OSVDotedPolyline.m; sourceTree = ""; }; CC2573CD1C003D16000EDB3E /* UIColor+OSVColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIColor+OSVColor.h"; sourceTree = ""; }; @@ -528,10 +799,16 @@ CC2573E61C0052FF000EDB3E /* UIBarButtonItem+Aditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIBarButtonItem+Aditions.m"; sourceTree = ""; }; CC2573EA1C00570D000EDB3E /* SKSearchResult+Aditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "SKSearchResult+Aditions.h"; sourceTree = ""; }; CC2573EB1C00570D000EDB3E /* SKSearchResult+Aditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "SKSearchResult+Aditions.m"; sourceTree = ""; }; + CC2794701E2CED4F0085866F /* OSVUtils+Gamification.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OSVUtils+Gamification.m"; sourceTree = ""; }; + CC2794741E2D0C2E0085866F /* SummaryViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SummaryViewController.swift; sourceTree = ""; }; + CC2794781E2E1FD10085866F /* OSVIntroViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVIntroViewController.h; sourceTree = ""; }; + CC2794791E2E1FD10085866F /* OSVIntroViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVIntroViewController.m; sourceTree = ""; }; + CC27947A1E2E1FD10085866F /* OSVIntroViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OSVIntroViewController.xib; sourceTree = ""; }; CC29AD9B1BA8807700538BD3 /* InfoEnterprise.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = InfoEnterprise.plist; sourceTree = ""; }; CC31DB221C1F0D9D00A0E83D /* OSVReachablityController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVReachablityController.h; sourceTree = ""; }; CC31DB231C1F0D9D00A0E83D /* OSVReachablityController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVReachablityController.m; sourceTree = ""; }; - CC359D9E1CC4DBF6007DBD49 /* photoShutter2.caf */ = {isa = PBXFileReference; lastKnownFileType = file; path = photoShutter2.caf; sourceTree = ""; }; + CC3692BB1DDC9F3D001EAA1E /* OSVLeaderboardViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVLeaderboardViewController.h; path = ViewControllers/OSVLeaderboardViewController.h; sourceTree = ""; }; + CC3692BC1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVLeaderboardViewController.m; path = ViewControllers/OSVLeaderboardViewController.m; sourceTree = ""; }; CC3833781D395906005F228B /* OSVUser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVUser.m; sourceTree = ""; }; CC38A73E1D40CC7D0027D5F1 /* oSVLogoV1.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = oSVLogoV1.png; sourceTree = ""; }; CC38A73F1D40CC7D0027D5F1 /* oSVLogoV1@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "oSVLogoV1@2x.png"; sourceTree = ""; }; @@ -558,12 +835,24 @@ CC410AE21D12B9C7000220BA /* OSVFullScreenAnimationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVFullScreenAnimationController.m; sourceTree = ""; }; CC410AE51D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVDissmissFullScreenAnimationController.h; sourceTree = ""; }; CC410AE61D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVDissmissFullScreenAnimationController.m; sourceTree = ""; }; - CC42A36C1D5B4649001541DD /* Crashlytics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Crashlytics.framework; path = Pods/Crashlytics/iOS/Crashlytics.framework; sourceTree = ""; }; - CC42A36E1D5B464F001541DD /* Fabric.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Fabric.framework; path = Pods/Fabric/iOS/Fabric.framework; sourceTree = ""; }; CC4C7B3F1D3D3C1200B902E8 /* OSVLayersViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVLayersViewController.h; path = ViewControllers/OSVLayersViewController.h; sourceTree = ""; }; CC4C7B401D3D3C1200B902E8 /* OSVLayersViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVLayersViewController.m; path = ViewControllers/OSVLayersViewController.m; sourceTree = ""; }; + CC4E16791DABA36A0037827E /* OSVRecordTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVRecordTransition.h; sourceTree = ""; }; + CC4E167A1DABA36A0037827E /* OSVRecordTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVRecordTransition.m; sourceTree = ""; }; + CC4E167D1DABEFB00037827E /* OSVDissmissRecordTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVDissmissRecordTransition.h; sourceTree = ""; }; + CC4E167E1DABEFB00037827E /* OSVDissmissRecordTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVDissmissRecordTransition.m; sourceTree = ""; }; + CC4E16811DACE7780037827E /* OSVPushTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVPushTransition.h; sourceTree = ""; }; + CC4E16821DACE7780037827E /* OSVPushTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVPushTransition.m; sourceTree = ""; }; + CC4E16851DAD3D570037827E /* OSVPopTransition.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVPopTransition.h; sourceTree = ""; }; + CC4E16861DAD3D570037827E /* OSVPopTransition.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVPopTransition.m; sourceTree = ""; }; CC5492DD1C48DA190081AC56 /* OSVUploadViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVUploadViewController.h; sourceTree = ""; }; CC5492DE1C48DA190081AC56 /* OSVUploadViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVUploadViewController.m; sourceTree = ""; }; + CC59A57B1E5DBAAB00A84996 /* SafariServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SafariServices.framework; path = System/Library/Frameworks/SafariServices.framework; sourceTree = SDKROOT; }; + CC59A5981E5DF42700A84996 /* LoginViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoginViewController.swift; sourceTree = ""; }; + CC5CADF71E41E38A007AA999 /* UIViewController+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIViewController+Additions.h"; sourceTree = ""; }; + CC5CADF81E41E38A007AA999 /* UIViewController+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+Additions.m"; sourceTree = ""; }; + CC5CADFC1E41F0E6007AA999 /* OSVCameraGamificationManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVCameraGamificationManager.h; sourceTree = ""; }; + CC5CADFD1E41F0E6007AA999 /* OSVCameraGamificationManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVCameraGamificationManager.m; sourceTree = ""; }; CC5CC2741D2BC2AC002963D2 /* OSVMainMenuFactory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVMainMenuFactory.h; sourceTree = ""; }; CC5CC2751D2BC2AC002963D2 /* OSVMainMenuFactory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVMainMenuFactory.m; sourceTree = ""; }; CC5EB4131C46741F006F3FD0 /* OSVLogger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVLogger.h; path = BuisnessLogic/OSVLogger.h; sourceTree = ""; }; @@ -593,6 +882,8 @@ CC65DF781CA1601400EC3F70 /* FLWifiScanTool.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FLWifiScanTool.m; sourceTree = ""; }; CC65DF831CA1674F00EC3F70 /* OSVOBDController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVOBDController.h; sourceTree = ""; }; CC65DF841CA1674F00EC3F70 /* OSVOBDController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVOBDController.m; sourceTree = ""; }; + CC69145B1D671D19005B6855 /* OSVCameraMapManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVCameraMapManager.h; sourceTree = ""; }; + CC69145C1D671D19005B6855 /* OSVCameraMapManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVCameraMapManager.m; sourceTree = ""; }; CC6E45901CCE7577007DB5CA /* OSVTipView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OSVTipView.xib; sourceTree = ""; }; CC6E45921CCE75F4007DB5CA /* OSVTipView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVTipView.h; path = Views/OSVTipView.h; sourceTree = ""; }; CC6E45931CCE75F4007DB5CA /* OSVTipView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVTipView.m; path = Views/OSVTipView.m; sourceTree = ""; }; @@ -606,10 +897,13 @@ CC791E5B1BF0A0E700E5CBD3 /* OSVUploadCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVUploadCell.m; path = Views/OSVUploadCell.m; sourceTree = ""; }; CC791E5D1BF0A11100E5CBD3 /* OSVSettingsSwitchCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVSettingsSwitchCell.h; path = Views/OSVSettingsSwitchCell.h; sourceTree = ""; }; CC791E5E1BF0A11100E5CBD3 /* OSVSettingsSwitchCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVSettingsSwitchCell.m; path = Views/OSVSettingsSwitchCell.m; sourceTree = ""; }; - CC7A63FA1CA2CFE8007C9F3B /* OSVSettingsButtonCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVSettingsButtonCell.h; path = Views/OSVSettingsButtonCell.h; sourceTree = ""; }; - CC7A63FB1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVSettingsButtonCell.m; path = Views/OSVSettingsButtonCell.m; sourceTree = ""; }; CC7A64031CA2FE85007C9F3B /* OSVOBDData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVOBDData.h; sourceTree = ""; }; CC7A64041CA2FE85007C9F3B /* OSVOBDData.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVOBDData.m; sourceTree = ""; }; + CC7AEBBB1E07EC5E00D587A9 /* exif_iOS.proto */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = exif_iOS.proto; sourceTree = ""; }; + CC7B2AD11DE3061900025B67 /* RLMScoreHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RLMScoreHistory.h; sourceTree = ""; }; + CC7B2AD21DE3061900025B67 /* RLMScoreHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RLMScoreHistory.m; sourceTree = ""; }; + CC7B2AD61DE3092B00025B67 /* OSVScoreHistory+Realm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "OSVScoreHistory+Realm.h"; sourceTree = ""; }; + CC7B2AD71DE3092B00025B67 /* OSVScoreHistory+Realm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OSVScoreHistory+Realm.m"; sourceTree = ""; }; CC7C6A391CF5E01F00C03051 /* CERangeSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CERangeSlider.h; sourceTree = ""; }; CC7C6A3A1CF5E01F00C03051 /* CERangeSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = CERangeSlider.m; sourceTree = ""; }; CC7C6A3B1CF5E01F00C03051 /* CERangeSliderKnobLayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CERangeSliderKnobLayer.h; sourceTree = ""; }; @@ -655,12 +949,9 @@ CC8960F51D2B9E5300501341 /* OSVMainViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVMainViewController.m; path = ViewControllers/OSVMainViewController.m; sourceTree = ""; }; CC8960F81D2B9ECF00501341 /* OSVLeftMenuViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVLeftMenuViewController.h; sourceTree = ""; }; CC8960F91D2B9ECF00501341 /* OSVLeftMenuViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVLeftMenuViewController.m; sourceTree = ""; }; + CC8A08F41DB63393002167AB /* OSVLocalNotificationsController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVLocalNotificationsController.h; sourceTree = ""; }; + CC8A08F51DB63393002167AB /* OSVLocalNotificationsController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVLocalNotificationsController.m; sourceTree = ""; }; CC90C5D61BFB620800F7C69D /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; }; - CC91D5CE1BFC751E003A6409 /* OSVExpandableCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVExpandableCell.h; sourceTree = ""; }; - CC91D5CF1BFC751E003A6409 /* OSVExpandableCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVExpandableCell.m; sourceTree = ""; }; - CC91D5D11BFDE88E003A6409 /* OSVSequenceSectionHeaderView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSequenceSectionHeaderView.h; sourceTree = ""; }; - CC91D5D21BFDE88E003A6409 /* OSVSequenceSectionHeaderView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSequenceSectionHeaderView.m; sourceTree = ""; }; - CC91D5D41BFDE8AA003A6409 /* OSVSequenceSectionHeaderView.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = OSVSequenceSectionHeaderView.xib; sourceTree = ""; }; CC92B0941D35674A004F7EF8 /* NSAttributedString+Additions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+Additions.h"; sourceTree = ""; }; CC92B0951D35674A004F7EF8 /* NSAttributedString+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+Additions.m"; sourceTree = ""; }; CC92B0981D356F19004F7EF8 /* CALayer+XibConfiguration.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "CALayer+XibConfiguration.h"; sourceTree = ""; }; @@ -675,20 +966,25 @@ CC92B0AC1D37C5D4004F7EF8 /* UIView+Additions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+Additions.m"; sourceTree = ""; }; CC92B0AF1D37DC74004F7EF8 /* OSVSlider.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSlider.h; sourceTree = ""; }; CC92B0B01D37DC74004F7EF8 /* OSVSlider.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSlider.m; sourceTree = ""; }; + CC92F7501E095E5C00427256 /* OSC_ORBB_Dev.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSC_ORBB_Dev.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CC92F7531E0AD74100427256 /* OpenStreetView-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenStreetView-Bridging-Header.h"; sourceTree = ""; }; + CC92F7541E0AD74100427256 /* OpenStreetViewRelease-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OpenStreetViewRelease-Bridging-Header.h"; sourceTree = ""; }; + CC92F7551E0AD74100427256 /* OSC_ORBB_Dev-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "OSC_ORBB_Dev-Bridging-Header.h"; sourceTree = ""; }; + CC92F75A1E0AD75D00427256 /* ScoreManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScoreManager.swift; sourceTree = ""; }; + CC92F75E1E0C147700427256 /* ScoreHistory.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScoreHistory.swift; sourceTree = ""; }; CC9458621BDA324100DFFD1A /* OSVUtils+Location.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OSVUtils+Location.m"; path = "BuisnessLogic/OSVUtils+Location.m"; sourceTree = ""; }; CC9458651BDA32D300DFFD1A /* OSVUtils+FileManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OSVUtils+FileManager.m"; path = "BuisnessLogic/OSVUtils+FileManager.m"; sourceTree = ""; }; CC9726471C1634A80034DE96 /* TPPropertyAnimation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TPPropertyAnimation.h; sourceTree = ""; }; CC9726481C1634A80034DE96 /* TPPropertyAnimation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TPPropertyAnimation.m; sourceTree = ""; }; + CC99BB251D9421B80029E58D /* OSVUtils+Device.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OSVUtils+Device.m"; sourceTree = ""; }; CCA16C1E1C92D1DA001EEB57 /* InfoBeta.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = InfoBeta.plist; sourceTree = ""; }; - CCA16CB61C92F64B001EEB57 /* OSV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSV.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CCA16CB61C92F64B001EEB57 /* OSC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSC.app; sourceTree = BUILT_PRODUCTS_DIR; }; CCB56F541C28072D00FFFC39 /* Localizable.strings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.strings; path = Localizable.strings; sourceTree = ""; }; CCB56F561C28088B00FFFC39 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/Main.strings; sourceTree = ""; }; CCB56F571C28088B00FFFC39 /* ro */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ro; path = ro.lproj/LaunchScreen.strings; sourceTree = ""; }; CCB56F581C285E8800FFFC39 /* RLMBoundingBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RLMBoundingBox.h; path = Models/Persistent/RLMBoundingBox.h; sourceTree = ""; }; CCB69D531C3E856D00832788 /* OSVAPIConfigurator.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVAPIConfigurator.h; sourceTree = ""; }; CCB69D541C3E856D00832788 /* OSVAPIConfigurator.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVAPIConfigurator.m; sourceTree = ""; }; - CCB88C761D830C15000CADD6 /* OSVLocalTracksViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVLocalTracksViewController.h; sourceTree = ""; }; - CCB88C771D830C15000CADD6 /* OSVLocalTracksViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVLocalTracksViewController.m; sourceTree = ""; }; CCB952CF1CE5EAD3006D5BBD /* OSVAPI+Video.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OSVAPI+Video.m"; sourceTree = ""; }; CCB952DE1CE60EB9006D5BBD /* OSVVideo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVVideo.h; sourceTree = ""; }; CCB952DF1CE60EB9006D5BBD /* OSVVideo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVVideo.m; sourceTree = ""; }; @@ -726,15 +1022,37 @@ CCC2C6931BA850BB00A4CDEE /* AVCamPreviewView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = AVCamPreviewView.m; path = Views/AVCamPreviewView.m; sourceTree = ""; }; CCC2C6961BA850D900A4CDEE /* OSVPhoto+Relm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OSVPhoto+Relm.h"; path = "Models/Categories/OSVPhoto+Relm.h"; sourceTree = ""; }; CCC2C6971BA850D900A4CDEE /* OSVPhoto+Relm.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "OSVPhoto+Relm.m"; path = "Models/Categories/OSVPhoto+Relm.m"; sourceTree = ""; }; + CCCA969F1DA77E9100D32CE7 /* OSVSplashViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSplashViewController.h; sourceTree = ""; }; + CCCA96A01DA77E9100D32CE7 /* OSVSplashViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSplashViewController.m; sourceTree = ""; }; + CCCDBE431DA4FFBD00F367DD /* OBDDevice.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDDevice.h; path = OBDLib/OBDDevice.h; sourceTree = ""; }; + CCCDBE441DA4FFBD00F367DD /* OBDDevice.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OBDDevice.m; path = OBDLib/OBDDevice.m; sourceTree = ""; }; + CCCDBE451DA4FFBD00F367DD /* OBDDevice+Internal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "OBDDevice+Internal.h"; path = "OBDLib/OBDDevice+Internal.h"; sourceTree = ""; }; + CCCDBE461DA4FFBD00F367DD /* OBDDeviceDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDDeviceDelegate.h; path = OBDLib/OBDDeviceDelegate.h; sourceTree = ""; }; + CCCDBE471DA4FFBD00F367DD /* OBDLib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDLib.h; path = OBDLib/OBDLib.h; sourceTree = ""; }; + CCCDBE481DA4FFBD00F367DD /* OBDSensors.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDSensors.h; path = OBDLib/OBDSensors.h; sourceTree = ""; }; + CCCDBE491DA4FFBD00F367DD /* OBDService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDService.h; path = OBDLib/OBDService.h; sourceTree = ""; }; + CCCDBE4A1DA4FFBD00F367DD /* OBDService.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OBDService.m; path = OBDLib/OBDService.m; sourceTree = ""; }; + CCCDBE4B1DA4FFBD00F367DD /* OBDServiceDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDServiceDelegate.h; path = OBDLib/OBDServiceDelegate.h; sourceTree = ""; }; + CCCDBE4C1DA4FFBD00F367DD /* OBDUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OBDUtils.h; path = OBDLib/OBDUtils.h; sourceTree = ""; }; + CCCDBE4D1DA4FFBD00F367DD /* OBDUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OBDUtils.m; path = OBDLib/OBDUtils.m; sourceTree = ""; }; + CCD426B31DE44C870006F74B /* OSVGamificationProfileCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVGamificationProfileCell.h; sourceTree = ""; }; + CCD426B41DE44C870006F74B /* OSVGamificationProfileCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVGamificationProfileCell.m; sourceTree = ""; }; + CCD426B71DE46A700006F74B /* OSVGamificationInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVGamificationInfo.h; sourceTree = ""; }; + CCD426B81DE46A700006F74B /* OSVGamificationInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVGamificationInfo.m; sourceTree = ""; }; CCD92BBA1BE7709E002F9341 /* OSVUtils+Image.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "OSVUtils+Image.m"; sourceTree = ""; }; CCDEFA641C88864700A542BA /* OSVSensorsManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSensorsManager.m; sourceTree = ""; }; CCDEFA651C88864700A542BA /* OSVSensorsManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSensorsManager.h; sourceTree = ""; }; CCE34A0F1BCD221000B54066 /* OSVLoadingCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVLoadingCell.h; sourceTree = ""; }; CCE34A101BCD221000B54066 /* OSVLoadingCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVLoadingCell.m; sourceTree = ""; }; - CCE6C45B1C102F12005DC6FF /* OSVGalleryCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVGalleryCell.h; sourceTree = ""; }; - CCE6C45C1C102F12005DC6FF /* OSVGalleryCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVGalleryCell.m; sourceTree = ""; }; - CCE6C45E1C105008005DC6FF /* OSVCropedLabel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVCropedLabel.h; sourceTree = ""; }; - CCE6C45F1C105008005DC6FF /* OSVCropedLabel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVCropedLabel.m; sourceTree = ""; }; + CCE7542B1DDDEA08007625DD /* OSVRankHeaderCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVRankHeaderCell.h; path = Views/OSVRankHeaderCell.h; sourceTree = ""; }; + CCE7542C1DDDEA08007625DD /* OSVRankHeaderCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVRankHeaderCell.m; path = Views/OSVRankHeaderCell.m; sourceTree = ""; }; + CCE7542F1DDDEA7A007625DD /* OSVRankCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVRankCell.h; path = Views/OSVRankCell.h; sourceTree = ""; }; + CCE754301DDDEA7A007625DD /* OSVRankCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVRankCell.m; path = Views/OSVRankCell.m; sourceTree = ""; }; + CCE754341DDE08EE007625DD /* OSVUnderlineButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = OSVUnderlineButton.h; path = Views/OSVUnderlineButton.h; sourceTree = ""; }; + CCE754351DDE08EE007625DD /* OSVUnderlineButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = OSVUnderlineButton.m; path = Views/OSVUnderlineButton.m; sourceTree = ""; }; + CCEC8A081E38B4510049093A /* PortraitViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PortraitViewController.swift; sourceTree = ""; }; + CCF0B4841DDB38F900D80961 /* OSVScoreHistory.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVScoreHistory.h; sourceTree = ""; }; + CCF0B4851DDB38F900D80961 /* OSVScoreHistory.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVScoreHistory.m; sourceTree = ""; }; CCF10DA01BF4A3C200A620EF /* OSVSequenceMapController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVSequenceMapController.h; sourceTree = ""; }; CCF10DA11BF4A3C200A620EF /* OSVSequenceMapController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVSequenceMapController.m; sourceTree = ""; }; CCF822971C05B0C700E607D9 /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Config.xcconfig; path = ../Config.xcconfig; sourceTree = ""; }; @@ -742,11 +1060,9 @@ CCF822DE1C06FDAE00E607D9 /* OSVImageCollectionViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVImageCollectionViewCell.m; sourceTree = ""; }; CCF822E01C0745B900E607D9 /* OSVButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVButton.h; sourceTree = ""; }; CCF822E11C0745B900E607D9 /* OSVButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVButton.m; sourceTree = ""; }; - CCF823041C0884DD00E607D9 /* OSVRedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVRedButton.h; sourceTree = ""; }; - CCF823051C0884DD00E607D9 /* OSVRedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVRedButton.m; sourceTree = ""; }; CCFADD3B1BB309A500A5AAFA /* OSVAPISerialOperation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OSVAPISerialOperation.h; sourceTree = ""; }; CCFADD3C1BB309A500A5AAFA /* OSVAPISerialOperation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OSVAPISerialOperation.m; sourceTree = ""; }; - CCFD49911BA02455005B5E9A /* OSV.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSV.app; sourceTree = BUILT_PRODUCTS_DIR; }; + CCFD49911BA02455005B5E9A /* OSC.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OSC.app; sourceTree = BUILT_PRODUCTS_DIR; }; CCFD49951BA02455005B5E9A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; CCFD49961BA02455005B5E9A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; CCFD49981BA02455005B5E9A /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; @@ -763,29 +1079,62 @@ CCFD49C51BA02EFF005B5E9A /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; CCFD49C71BA02F07005B5E9A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; CCFD49C91BA02F0F005B5E9A /* CoreMotion.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMotion.framework; path = System/Library/Frameworks/CoreMotion.framework; sourceTree = SDKROOT; }; - D3A9DC100926C3AD8E6C6DA0 /* Pods-OpenStreetView.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-OpenStreetView.release.xcconfig"; path = "Pods/Target Support Files/Pods-OpenStreetView/Pods-OpenStreetView.release.xcconfig"; sourceTree = ""; }; + CCFD49CB1BA02F19005B5E9A /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + CCFD49CD1BA02F25005B5E9A /* libc++.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libc++.dylib"; path = "usr/lib/libc++.dylib"; sourceTree = SDKROOT; }; + CCFF57901E44D0960031B8BE /* OSCTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = OSCTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + CCFF57921E44D0960031B8BE /* OSCTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OSCTests.m; sourceTree = ""; }; + CCFF57941E44D0960031B8BE /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + CCFF579C1E44D1980031B8BE /* MatcherDataSet.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = MatcherDataSet.json; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + CC92F71E1E095E5C00427256 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + CC59A57E1E5DC09200A84996 /* SafariServices.framework in Frameworks */, + CC92F71F1E095E5C00427256 /* AVFoundation.framework in Frameworks */, + CC92F7201E095E5C00427256 /* SystemConfiguration.framework in Frameworks */, + CC92F7211E095E5C00427256 /* CoreTelephony.framework in Frameworks */, + CC92F7221E095E5C00427256 /* MobileCoreServices.framework in Frameworks */, + CC92F7231E095E5C00427256 /* ImageIO.framework in Frameworks */, + CC92F7261E095E5C00427256 /* libc++.dylib in Frameworks */, + CC92F7271E095E5C00427256 /* libz.dylib in Frameworks */, + CC92F7281E095E5C00427256 /* CoreMotion.framework in Frameworks */, + CC92F72A1E095E5C00427256 /* CoreGraphics.framework in Frameworks */, + CC92F72B1E095E5C00427256 /* CoreMedia.framework in Frameworks */, + CC92F72D1E095E5C00427256 /* QuartzCore.framework in Frameworks */, + CC92F72E1E095E5C00427256 /* OpenGLES.framework in Frameworks */, + CC92F72F1E095E5C00427256 /* CoreLocation.framework in Frameworks */, + CC92F7301E095E5C00427256 /* Crashlytics.framework in Frameworks */, + CC92F7311E095E5C00427256 /* Foundation.framework in Frameworks */, + CC92F7321E095E5C00427256 /* Fabric.framework in Frameworks */, + CC92F7331E095E5C00427256 /* UIKit.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; CCA16C881C92F64B001EEB57 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CC42A3751D5B4DE2001541DD /* Fabric.framework in Frameworks */, - CC42A3741D5B4DCA001541DD /* Crashlytics.framework in Frameworks */, + CC59A57D1E5DC06A00A84996 /* SafariServices.framework in Frameworks */, CCA16C8A1C92F64B001EEB57 /* AVFoundation.framework in Frameworks */, CCA16C8B1C92F64B001EEB57 /* SystemConfiguration.framework in Frameworks */, CCA16C8C1C92F64B001EEB57 /* CoreTelephony.framework in Frameworks */, CCA16C8D1C92F64B001EEB57 /* MobileCoreServices.framework in Frameworks */, CCA16C8E1C92F64B001EEB57 /* ImageIO.framework in Frameworks */, + CCA16C8F1C92F64B001EEB57 /* libc++.dylib in Frameworks */, + CCA16C901C92F64B001EEB57 /* libz.dylib in Frameworks */, CCA16C911C92F64B001EEB57 /* CoreMotion.framework in Frameworks */, CCA16C931C92F64B001EEB57 /* CoreGraphics.framework in Frameworks */, + CCCD8E1C1D5DB6900056C7AF /* CoreMedia.framework in Frameworks */, CCA16C941C92F64B001EEB57 /* QuartzCore.framework in Frameworks */, CCA16C961C92F64B001EEB57 /* OpenGLES.framework in Frameworks */, CCA16C971C92F64B001EEB57 /* CoreLocation.framework in Frameworks */, + CCA16C981C92F64B001EEB57 /* Crashlytics.framework in Frameworks */, CCA16C991C92F64B001EEB57 /* Foundation.framework in Frameworks */, + CCA16C9A1C92F64B001EEB57 /* Fabric.framework in Frameworks */, CCA16C9B1C92F64B001EEB57 /* UIKit.framework in Frameworks */, - D82CA580ABF5EE3A56569CAD /* Pods_OpenStreetViewRelease.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -793,22 +1142,31 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - CC42A3771D5B4DFC001541DD /* Fabric.framework in Frameworks */, - CC42A3761D5B4DF0001541DD /* Crashlytics.framework in Frameworks */, + CC59A57C1E5DBAAB00A84996 /* SafariServices.framework in Frameworks */, CC0167EA1D2F9A8200E8297D /* CoreMedia.framework in Frameworks */, CC06B62B1C75BBD900E2B0DB /* AVFoundation.framework in Frameworks */, CC06B6291C75BBC300E2B0DB /* SystemConfiguration.framework in Frameworks */, CC06B6271C75BBB700E2B0DB /* CoreTelephony.framework in Frameworks */, CC7F068F1C6DEF3900441593 /* MobileCoreServices.framework in Frameworks */, CC90C5D71BFB620800F7C69D /* ImageIO.framework in Frameworks */, + CCFD49CE1BA02F25005B5E9A /* libc++.dylib in Frameworks */, + CCFD49CC1BA02F19005B5E9A /* libz.dylib in Frameworks */, CCFD49CA1BA02F10005B5E9A /* CoreMotion.framework in Frameworks */, CCFD49C81BA02F07005B5E9A /* CoreGraphics.framework in Frameworks */, CCFD49C61BA02EFF005B5E9A /* QuartzCore.framework in Frameworks */, CCFD49C41BA02EF7005B5E9A /* OpenGLES.framework in Frameworks */, CCFD49C21BA02EEE005B5E9A /* CoreLocation.framework in Frameworks */, + CC12A1DF1C2404240019DB21 /* Crashlytics.framework in Frameworks */, CCFD49C01BA02EE7005B5E9A /* Foundation.framework in Frameworks */, + CC12A1DE1C2404240019DB21 /* Fabric.framework in Frameworks */, CCFD49BE1BA02EDA005B5E9A /* UIKit.framework in Frameworks */, - DC811D40DA55683BAC93A812 /* Pods_OpenStreetView.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + CCFF578D1E44D0960031B8BE /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( ); runOnlyForDeploymentPostprocessing = 0; }; @@ -874,8 +1232,8 @@ children = ( CC1529751C039DC500BD29DC /* OSVBaseUser.h */, CC1529761C039DC500BD29DC /* OSVBaseUser.m */, - CC1529791C039F3100BD29DC /* OSVBaseUser+OSM.h */, - CC15297A1C039F3100BD29DC /* OSVBaseUser+OSM.m */, + CCD426B71DE46A700006F74B /* OSVGamificationInfo.h */, + CCD426B81DE46A700006F74B /* OSVGamificationInfo.m */, ); name = User; sourceTree = ""; @@ -963,10 +1321,10 @@ CC1E503A1BF209BA00BD4A1A /* OSVMenuItem.m */, CC1E503C1BF20A5100BD4A1A /* OSVSectionItem.h */, CC1E503D1BF20A5100BD4A1A /* OSVSectionItem.m */, + CC1E503F1BF26B1200BD4A1A /* OSVSettingsMenuFactory.h */, + CC1E50401BF26B1200BD4A1A /* OSVSettingsMenuFactory.m */, CC5CC2741D2BC2AC002963D2 /* OSVMainMenuFactory.h */, CC5CC2751D2BC2AC002963D2 /* OSVMainMenuFactory.m */, - CC1B3D531D74885C00F07098 /* OSVSettingsMenuFactory.h */, - CC1B3D541D74885C00F07098 /* OSVSettingsMenuFactory.m */, ); name = Menu; sourceTree = ""; @@ -986,17 +1344,17 @@ CC1FFCD91D58A43800958B8E /* OBDLib */ = { isa = PBXGroup; children = ( - CC1FFCDA1D58A48300958B8E /* OBDService.h */, - CC1FFCDB1D58A48300958B8E /* OBDService.m */, - CC1FFCDC1D58A48300958B8E /* OBDServiceDelegate.h */, - CC1FFCDD1D58A48300958B8E /* OBDDevice.h */, - CC1FFCDE1D58A48300958B8E /* OBDDevice.m */, - CC1FFCDF1D58A48300958B8E /* OBDDevice+Internal.h */, - CC1FFCE01D58A48300958B8E /* OBDDeviceDelegate.h */, - CC1FFCE11D58A48300958B8E /* OBDSensors.h */, - CC1FFCE21D58A48300958B8E /* OBDUtils.h */, - CC1FFCE31D58A48300958B8E /* OBDUtils.m */, - CC1FFCE41D58A48300958B8E /* OBDLib.h */, + CCCDBE431DA4FFBD00F367DD /* OBDDevice.h */, + CCCDBE441DA4FFBD00F367DD /* OBDDevice.m */, + CCCDBE451DA4FFBD00F367DD /* OBDDevice+Internal.h */, + CCCDBE461DA4FFBD00F367DD /* OBDDeviceDelegate.h */, + CCCDBE471DA4FFBD00F367DD /* OBDLib.h */, + CCCDBE481DA4FFBD00F367DD /* OBDSensors.h */, + CCCDBE491DA4FFBD00F367DD /* OBDService.h */, + CCCDBE4A1DA4FFBD00F367DD /* OBDService.m */, + CCCDBE4B1DA4FFBD00F367DD /* OBDServiceDelegate.h */, + CCCDBE4C1DA4FFBD00F367DD /* OBDUtils.h */, + CCCDBE4D1DA4FFBD00F367DD /* OBDUtils.m */, ); name = OBDLib; sourceTree = ""; @@ -1014,6 +1372,8 @@ CC09AD7C1C73672100443761 /* UIDevice+Aditions.m */, CC92B0AB1D37C5D4004F7EF8 /* UIView+Additions.h */, CC92B0AC1D37C5D4004F7EF8 /* UIView+Additions.m */, + CC5CADF71E41E38A007AA999 /* UIViewController+Additions.h */, + CC5CADF81E41E38A007AA999 /* UIViewController+Additions.m */, ); name = "UIKit+Aditions"; sourceTree = ""; @@ -1027,6 +1387,46 @@ name = "SKMaps+Aditions"; sourceTree = ""; }; + CC3692BA1DDB4CF2001EAA1E /* Recording */ = { + isa = PBXGroup; + children = ( + CC92F75A1E0AD75D00427256 /* ScoreManager.swift */, + CCBE0F0E1C8DF5CF00A43F37 /* OSVVideoRecorder.h */, + CCBE0F0F1C8DF5CF00A43F37 /* OSVVideoRecorder.m */, + CC7A64031CA2FE85007C9F3B /* OSVOBDData.h */, + CC7A64041CA2FE85007C9F3B /* OSVOBDData.m */, + CC65DF831CA1674F00EC3F70 /* OSVOBDController.h */, + CC65DF841CA1674F00EC3F70 /* OSVOBDController.m */, + CC1E86711DFEB451002660F4 /* OSVTrackMatcher.h */, + CC1E86721DFEB451002660F4 /* OSVTrackMatcher.m */, + ); + name = Recording; + sourceTree = ""; + }; + CC3692BF1DDDDE74001EAA1E /* TableViewCell */ = { + isa = PBXGroup; + children = ( + CCE754331DDDEA7F007625DD /* Gamification */, + CC0167E41D2EBA5200E8297D /* WaitingCell */, + CC3937511D2D4D5100669EFC /* MyProfileCell */, + CC39372E1D2BDBC500669EFC /* MenuCell */, + CC19F3171BB05FFC006C8FCC /* OSVSequenceCell.h */, + CC19F3181BB05FFC006C8FCC /* OSVSequenceCell.m */, + CCE34A0F1BCD221000B54066 /* OSVLoadingCell.h */, + CCE34A101BCD221000B54066 /* OSVLoadingCell.m */, + CC791E5A1BF0A0E700E5CBD3 /* OSVUploadCell.h */, + CC791E5B1BF0A0E700E5CBD3 /* OSVUploadCell.m */, + CC160EA51C5A335A000185D3 /* OSVSliderCell.h */, + CC160EA61C5A335A000185D3 /* OSVSliderCell.m */, + CC06B6441C75F71C00E2B0DB /* OSVSegmentedViewCell.h */, + CC06B6451C75F71C00E2B0DB /* OSVSegmentedViewCell.m */, + CC06B6461C75F71C00E2B0DB /* OSVSegmentedViewCell.xib */, + CCD426B31DE44C870006F74B /* OSVGamificationProfileCell.h */, + CCD426B41DE44C870006F74B /* OSVGamificationProfileCell.m */, + ); + name = TableViewCell; + sourceTree = ""; + }; CC39372E1D2BDBC500669EFC /* MenuCell */ = { isa = PBXGroup; children = ( @@ -1079,6 +1479,8 @@ CC4B55301BA7034700165A74 /* Models */ = { isa = PBXGroup; children = ( + CC4F6DC41E02A9B400B4F7FD /* protoExif */, + CCF0B4831DDB38AB00D80961 /* Gamification */, CC1529781C039EF700BD29DC /* User */, CC1E50381BF2088C00BD4A1A /* Menu */, CC19F2E81BAED3F8006C8FCC /* Photo */, @@ -1089,9 +1491,38 @@ name = Models; sourceTree = ""; }; + CC4E16781DAB9F620037827E /* AnimationControllers */ = { + isa = PBXGroup; + children = ( + CC410AE11D12B9C7000220BA /* OSVFullScreenAnimationController.h */, + CC410AE21D12B9C7000220BA /* OSVFullScreenAnimationController.m */, + CC410AE51D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.h */, + CC410AE61D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m */, + CC4E16791DABA36A0037827E /* OSVRecordTransition.h */, + CC4E167A1DABA36A0037827E /* OSVRecordTransition.m */, + CC4E167D1DABEFB00037827E /* OSVDissmissRecordTransition.h */, + CC4E167E1DABEFB00037827E /* OSVDissmissRecordTransition.m */, + CC4E16811DACE7780037827E /* OSVPushTransition.h */, + CC4E16821DACE7780037827E /* OSVPushTransition.m */, + CC4E16851DAD3D570037827E /* OSVPopTransition.h */, + CC4E16861DAD3D570037827E /* OSVPopTransition.m */, + ); + name = AnimationControllers; + sourceTree = ""; + }; + CC4F6DC41E02A9B400B4F7FD /* protoExif */ = { + isa = PBXGroup; + children = ( + CC7AEBBB1E07EC5E00D587A9 /* exif_iOS.proto */, + ); + name = protoExif; + sourceTree = ""; + }; CC50D2741BA1D2370092896B /* BuisnessLogic */ = { isa = PBXGroup; children = ( + CC3692BA1DDB4CF2001EAA1E /* Recording */, + CC60EC5A1DB1121A00DCA5AA /* OSVSearch */, CC31DB221C1F0D9D00A0E83D /* OSVReachablityController.h */, CC31DB231C1F0D9D00A0E83D /* OSVReachablityController.m */, CC0167DB1D2E854100E8297D /* SensorLib */, @@ -1109,16 +1540,12 @@ CCC2C6831BA8506400A4CDEE /* OSVPersistentManager.m */, CCC2C6861BA8506400A4CDEE /* OSVUserDefaults.h */, CCC2C6871BA8506400A4CDEE /* OSVUserDefaults.m */, - CCBE0F0E1C8DF5CF00A43F37 /* OSVVideoRecorder.h */, - CCBE0F0F1C8DF5CF00A43F37 /* OSVVideoRecorder.m */, - CC65DF831CA1674F00EC3F70 /* OSVOBDController.h */, - CC65DF841CA1674F00EC3F70 /* OSVOBDController.m */, - CC7A64031CA2FE85007C9F3B /* OSVOBDData.h */, - CC7A64041CA2FE85007C9F3B /* OSVOBDData.m */, CC9458671BDA32DB00DFFD1A /* OSVUtils */, CC2573E91C0056D5000EDB3E /* SKMaps+Aditions */, CC2573E81C0055DF000EDB3E /* UIKit+Aditions */, CC92B0931D35671A004F7EF8 /* Foundation+Aditions */, + CC8A08F41DB63393002167AB /* OSVLocalNotificationsController.h */, + CC8A08F51DB63393002167AB /* OSVLocalNotificationsController.m */, ); name = BuisnessLogic; sourceTree = ""; @@ -1126,6 +1553,7 @@ CC50D2751BA1D26C0092896B /* ViewControllers */ = { isa = PBXGroup; children = ( + CC0168961D3514AF00E8297D /* Settings */, CC8960F31D2B9DF600501341 /* SideMenu */, CCC2C6901BA8507A00A4CDEE /* Camera */, CC1E50531BF3A14600BD4A1A /* MapState */, @@ -1141,15 +1569,28 @@ CC16AE361CE4892B001EA02A /* OSVVideoPlayerViewController.m */, CC39374D1D2D2CC700669EFC /* OSVMyProfileViewController.h */, CC39374E1D2D2CC700669EFC /* OSVMyProfileViewController.m */, - CCB88C761D830C15000CADD6 /* OSVLocalTracksViewController.h */, - CCB88C771D830C15000CADD6 /* OSVLocalTracksViewController.m */, - CC0168961D3514AF00E8297D /* Settings */, + CC0167E01D2EB0CF00E8297D /* OSVLocalTracksViewController.h */, + CC0167E11D2EB0CF00E8297D /* OSVLocalTracksViewController.m */, CC4C7B3F1D3D3C1200B902E8 /* OSVLayersViewController.h */, CC4C7B401D3D3C1200B902E8 /* OSVLayersViewController.m */, + CCCA969F1DA77E9100D32CE7 /* OSVSplashViewController.h */, + CCCA96A01DA77E9100D32CE7 /* OSVSplashViewController.m */, + CC3692BB1DDC9F3D001EAA1E /* OSVLeaderboardViewController.h */, + CC3692BC1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m */, + CC2794741E2D0C2E0085866F /* SummaryViewController.swift */, + CCEC8A081E38B4510049093A /* PortraitViewController.swift */, + CC59A5981E5DF42700A84996 /* LoginViewController.swift */, ); name = ViewControllers; sourceTree = ""; }; + CC60EC5A1DB1121A00DCA5AA /* OSVSearch */ = { + isa = PBXGroup; + children = ( + ); + name = OSVSearch; + sourceTree = ""; + }; CC65DF5C1CA1601400EC3F70 /* OBD2Kit */ = { isa = PBXGroup; children = ( @@ -1373,6 +1814,8 @@ CCD92BBA1BE7709E002F9341 /* OSVUtils+Image.m */, CC9458621BDA324100DFFD1A /* OSVUtils+Location.m */, CC9458651BDA32D300DFFD1A /* OSVUtils+FileManager.m */, + CC99BB251D9421B80029E58D /* OSVUtils+Device.m */, + CC2794701E2CED4F0085866F /* OSVUtils+Gamification.m */, ); name = OSVUtils; sourceTree = ""; @@ -1413,8 +1856,10 @@ CCC2C6441BA84F4A00A4CDEE /* OSVCamViewController.m */, CC12FCF81D51DA1A00EB1177 /* OSVCameraManager.h */, CC12FCF91D51DA1A00EB1177 /* OSVCameraManager.m */, - CC1B3D501D74884700F07098 /* OSVCameraMapManager.h */, - CC1B3D511D74884700F07098 /* OSVCameraMapManager.m */, + CC69145B1D671D19005B6855 /* OSVCameraMapManager.h */, + CC69145C1D671D19005B6855 /* OSVCameraMapManager.m */, + CC5CADFC1E41F0E6007AA999 /* OSVCameraGamificationManager.h */, + CC5CADFD1E41F0E6007AA999 /* OSVCameraGamificationManager.m */, ); name = Camera; sourceTree = ""; @@ -1422,59 +1867,20 @@ CCC2C6911BA850AB00A4CDEE /* Views */ = { isa = PBXGroup; children = ( + CCE7542A1DDDE9C5007625DD /* CollectionViewCell */, + CCE754291DDDE973007625DD /* PageControllers */, + CCE754281DDDE951007625DD /* Buttons */, + CC3692BF1DDDDE74001EAA1E /* TableViewCell */, + CC4E16781DAB9F620037827E /* AnimationControllers */, CC01686B1D34D6FD00E8297D /* Settings */, - CC0167E41D2EBA5200E8297D /* WaitingCell */, - CC3937511D2D4D5100669EFC /* MyProfileCell */, - CC39372E1D2BDBC500669EFC /* MenuCell */, CC7C6A381CF5E01F00C03051 /* RangeSlider */, CC97264D1C1634B20034DE96 /* KAProgressLabel */, - CC19F3171BB05FFC006C8FCC /* OSVSequenceCell.h */, - CC19F3181BB05FFC006C8FCC /* OSVSequenceCell.m */, - CCE34A0F1BCD221000B54066 /* OSVLoadingCell.h */, - CCE34A101BCD221000B54066 /* OSVLoadingCell.m */, - CC791E5A1BF0A0E700E5CBD3 /* OSVUploadCell.h */, - CC791E5B1BF0A0E700E5CBD3 /* OSVUploadCell.m */, - CC91D5CE1BFC751E003A6409 /* OSVExpandableCell.h */, - CC91D5CF1BFC751E003A6409 /* OSVExpandableCell.m */, - CC91D5D11BFDE88E003A6409 /* OSVSequenceSectionHeaderView.h */, - CC91D5D21BFDE88E003A6409 /* OSVSequenceSectionHeaderView.m */, - CC91D5D41BFDE8AA003A6409 /* OSVSequenceSectionHeaderView.xib */, - CCF822DD1C06FDAE00E607D9 /* OSVImageCollectionViewCell.h */, - CCF822DE1C06FDAE00E607D9 /* OSVImageCollectionViewCell.m */, - CCF822E01C0745B900E607D9 /* OSVButton.h */, - CCF822E11C0745B900E607D9 /* OSVButton.m */, - CCF823041C0884DD00E607D9 /* OSVRedButton.h */, - CCF823051C0884DD00E607D9 /* OSVRedButton.m */, - CCE6C45B1C102F12005DC6FF /* OSVGalleryCell.h */, - CCE6C45C1C102F12005DC6FF /* OSVGalleryCell.m */, - CCE6C45E1C105008005DC6FF /* OSVCropedLabel.h */, - CCE6C45F1C105008005DC6FF /* OSVCropedLabel.m */, - CC160EA51C5A335A000185D3 /* OSVSliderCell.h */, - CC160EA61C5A335A000185D3 /* OSVSliderCell.m */, - CC06B6441C75F71C00E2B0DB /* OSVSegmentedViewCell.h */, - CC06B6451C75F71C00E2B0DB /* OSVSegmentedViewCell.m */, - CC06B6461C75F71C00E2B0DB /* OSVSegmentedViewCell.xib */, - CCBE0F141C8F1D9D00A43F37 /* OSVFullScreenImageCell.h */, - CCBE0F151C8F1D9D00A43F37 /* OSVFullScreenImageCell.m */, - CCBE0F161C8F1D9D00A43F37 /* OSVFullScreenImageCell.xib */, - CC7A63FA1CA2CFE8007C9F3B /* OSVSettingsButtonCell.h */, - CC7A63FB1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m */, - CC6E45901CCE7577007DB5CA /* OSVTipView.xib */, - CC6E45921CCE75F4007DB5CA /* OSVTipView.h */, - CC6E45931CCE75F4007DB5CA /* OSVTipView.m */, - CCBBCFE01D1D638700B9104F /* OSVTipPageViewController.h */, - CCBBCFE11D1D638700B9104F /* OSVTipPageViewController.m */, - CCBBCFE21D1D638700B9104F /* OSVTipPageViewController.xib */, - CC410AE11D12B9C7000220BA /* OSVFullScreenAnimationController.h */, - CC410AE21D12B9C7000220BA /* OSVFullScreenAnimationController.m */, - CC410AE51D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.h */, - CC410AE61D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m */, CC225EC31D227A65000EC04C /* OSVDotedPolyline.h */, CC225EC41D227A65000EC04C /* OSVDotedPolyline.m */, - CC92B0A71D377877004F7EF8 /* OSVCloseButton.h */, - CC92B0A81D377877004F7EF8 /* OSVCloseButton.m */, CC92B0AF1D37DC74004F7EF8 /* OSVSlider.h */, CC92B0B01D37DC74004F7EF8 /* OSVSlider.m */, + CC1E866D1DFB2996002660F4 /* OSVScoreDetailsView.h */, + CC1E866E1DFB2996002660F4 /* OSVScoreDetailsView.m */, ); name = Views; sourceTree = ""; @@ -1484,6 +1890,8 @@ children = ( CCC2C6961BA850D900A4CDEE /* OSVPhoto+Relm.h */, CCC2C6971BA850D900A4CDEE /* OSVPhoto+Relm.m */, + CC7B2AD61DE3092B00025B67 /* OSVScoreHistory+Realm.h */, + CC7B2AD71DE3092B00025B67 /* OSVScoreHistory+Realm.m */, CC19F2D31BAC28C0006C8FCC /* OSVServerPhoto+Convertor.h */, CC19F2D41BAC28C0006C8FCC /* OSVServerPhoto+Convertor.m */, CC19F2D61BAC2CFF006C8FCC /* OSVServerSequence+Convertor.h */, @@ -1492,6 +1900,68 @@ name = Categories; sourceTree = ""; }; + CCE754281DDDE951007625DD /* Buttons */ = { + isa = PBXGroup; + children = ( + CCF822E01C0745B900E607D9 /* OSVButton.h */, + CCF822E11C0745B900E607D9 /* OSVButton.m */, + CC92B0A71D377877004F7EF8 /* OSVCloseButton.h */, + CC92B0A81D377877004F7EF8 /* OSVCloseButton.m */, + CCE754341DDE08EE007625DD /* OSVUnderlineButton.h */, + CCE754351DDE08EE007625DD /* OSVUnderlineButton.m */, + ); + name = Buttons; + sourceTree = ""; + }; + CCE754291DDDE973007625DD /* PageControllers */ = { + isa = PBXGroup; + children = ( + CC6E45901CCE7577007DB5CA /* OSVTipView.xib */, + CC6E45921CCE75F4007DB5CA /* OSVTipView.h */, + CC6E45931CCE75F4007DB5CA /* OSVTipView.m */, + CCBBCFE01D1D638700B9104F /* OSVTipPageViewController.h */, + CCBBCFE11D1D638700B9104F /* OSVTipPageViewController.m */, + CCBBCFE21D1D638700B9104F /* OSVTipPageViewController.xib */, + CC2794781E2E1FD10085866F /* OSVIntroViewController.h */, + CC2794791E2E1FD10085866F /* OSVIntroViewController.m */, + CC27947A1E2E1FD10085866F /* OSVIntroViewController.xib */, + ); + name = PageControllers; + sourceTree = ""; + }; + CCE7542A1DDDE9C5007625DD /* CollectionViewCell */ = { + isa = PBXGroup; + children = ( + CCF822DD1C06FDAE00E607D9 /* OSVImageCollectionViewCell.h */, + CCF822DE1C06FDAE00E607D9 /* OSVImageCollectionViewCell.m */, + CCBE0F141C8F1D9D00A43F37 /* OSVFullScreenImageCell.h */, + CCBE0F151C8F1D9D00A43F37 /* OSVFullScreenImageCell.m */, + CCBE0F161C8F1D9D00A43F37 /* OSVFullScreenImageCell.xib */, + ); + name = CollectionViewCell; + sourceTree = ""; + }; + CCE754331DDDEA7F007625DD /* Gamification */ = { + isa = PBXGroup; + children = ( + CCE7542B1DDDEA08007625DD /* OSVRankHeaderCell.h */, + CCE7542C1DDDEA08007625DD /* OSVRankHeaderCell.m */, + CCE7542F1DDDEA7A007625DD /* OSVRankCell.h */, + CCE754301DDDEA7A007625DD /* OSVRankCell.m */, + ); + name = Gamification; + sourceTree = ""; + }; + CCF0B4831DDB38AB00D80961 /* Gamification */ = { + isa = PBXGroup; + children = ( + CCF0B4841DDB38F900D80961 /* OSVScoreHistory.h */, + CCF0B4851DDB38F900D80961 /* OSVScoreHistory.m */, + CC92F75E1E0C147700427256 /* ScoreHistory.swift */, + ); + name = Gamification; + sourceTree = ""; + }; CCFD49881BA02455005B5E9A = { isa = PBXGroup; children = ( @@ -1499,17 +1969,19 @@ CC735C771BE8C2E4001E7E03 /* OpenStreetViewUITests */, CCFD49AD1BA02455005B5E9A /* OpenStreetViewTests */, CCFD49CF1BA03156005B5E9A /* Resources */, + CCFF57911E44D0960031B8BE /* OSCTests */, CCFD49BA1BA028F0005B5E9A /* Frameworks */, CCFD49921BA02455005B5E9A /* Products */, - D53B87E3951A9F6256E47AF7 /* Pods */, ); sourceTree = ""; }; CCFD49921BA02455005B5E9A /* Products */ = { isa = PBXGroup; children = ( - CCFD49911BA02455005B5E9A /* OSV.app */, - CCA16CB61C92F64B001EEB57 /* OSV.app */, + CCFD49911BA02455005B5E9A /* OSC.app */, + CCA16CB61C92F64B001EEB57 /* OSC.app */, + CC92F7501E095E5C00427256 /* OSC_ORBB_Dev.app */, + CCFF57901E44D0960031B8BE /* OSCTests.xctest */, ); name = Products; sourceTree = ""; @@ -1535,6 +2007,9 @@ CCFD49941BA02455005B5E9A /* Supporting Files */ = { isa = PBXGroup; children = ( + CC92F7531E0AD74100427256 /* OpenStreetView-Bridging-Header.h */, + CC92F7541E0AD74100427256 /* OpenStreetViewRelease-Bridging-Header.h */, + CC92F7551E0AD74100427256 /* OSC_ORBB_Dev-Bridging-Header.h */, CC38A73E1D40CC7D0027D5F1 /* oSVLogoV1.png */, CC38A73F1D40CC7D0027D5F1 /* oSVLogoV1@2x.png */, CC38A7401D40CC7D0027D5F1 /* oSVLogoV1@3x.png */, @@ -1551,11 +2026,11 @@ CCFD49AD1BA02455005B5E9A /* OpenStreetViewTests */ = { isa = PBXGroup; children = ( - CCFD49AE1BA02455005B5E9A /* Supporting Files */, CCFD49B01BA02455005B5E9A /* OpenStreetViewTests.m */, CC700FDC1BE25C3D007A646F /* OSVAPITests.m */, CC700FDE1BE25C52007A646F /* OSMAPITests.m */, CC700FE01BE25C79007A646F /* OSVPersistenceManagerTests.m */, + CCFD49AE1BA02455005B5E9A /* Supporting Files */, ); path = OpenStreetViewTests; sourceTree = ""; @@ -1571,23 +2046,24 @@ CCFD49BA1BA028F0005B5E9A /* Frameworks */ = { isa = PBXGroup; children = ( - CC42A36E1D5B464F001541DD /* Fabric.framework */, - CC42A36C1D5B4649001541DD /* Crashlytics.framework */, + CC59A57B1E5DBAAB00A84996 /* SafariServices.framework */, CC0167E91D2F9A8200E8297D /* CoreMedia.framework */, CC06B62A1C75BBD900E2B0DB /* AVFoundation.framework */, CCFD49C71BA02F07005B5E9A /* CoreGraphics.framework */, CCFD49C11BA02EEE005B5E9A /* CoreLocation.framework */, CCFD49C91BA02F0F005B5E9A /* CoreMotion.framework */, CC06B6261C75BBB700E2B0DB /* CoreTelephony.framework */, + CC12A1DD1C2404240019DB21 /* Crashlytics.framework */, + CC12A1DC1C2404240019DB21 /* Fabric.framework */, CCFD49BF1BA02EE7005B5E9A /* Foundation.framework */, CC90C5D61BFB620800F7C69D /* ImageIO.framework */, + CCFD49CD1BA02F25005B5E9A /* libc++.dylib */, + CCFD49CB1BA02F19005B5E9A /* libz.dylib */, CC7F068E1C6DEF3900441593 /* MobileCoreServices.framework */, CCFD49C31BA02EF7005B5E9A /* OpenGLES.framework */, CCFD49C51BA02EFF005B5E9A /* QuartzCore.framework */, CC06B6281C75BBC300E2B0DB /* SystemConfiguration.framework */, CCFD49BD1BA02EDA005B5E9A /* UIKit.framework */, - 53A86B025D720FA16CBA4524 /* Pods_OpenStreetView.framework */, - 0D96C56BCF2E540BBEFFA744 /* Pods_OpenStreetViewRelease.framework */, ); name = Frameworks; sourceTree = ""; @@ -1595,7 +2071,6 @@ CCFD49CF1BA03156005B5E9A /* Resources */ = { isa = PBXGroup; children = ( - CC359D9E1CC4DBF6007DBD49 /* photoShutter2.caf */, ); name = Resources; sourceTree = ""; @@ -1603,6 +2078,8 @@ CCFD4A311BA04E2A005B5E9A /* Persistence */ = { isa = PBXGroup; children = ( + CC7B2AD11DE3061900025B67 /* RLMScoreHistory.h */, + CC7B2AD21DE3061900025B67 /* RLMScoreHistory.m */, CCC2C63B1BA84F2C00A4CDEE /* RLMPhoto.h */, CCC2C63C1BA84F2C00A4CDEE /* RLMPhoto.m */, CCB56F581C285E8800FFFC39 /* RLMBoundingBox.h */, @@ -1610,39 +2087,53 @@ name = Persistence; sourceTree = ""; }; - D53B87E3951A9F6256E47AF7 /* Pods */ = { + CCFF57911E44D0960031B8BE /* OSCTests */ = { isa = PBXGroup; children = ( - 568DA0768A3FBE3F9CED9C76 /* Pods-OpenStreetView.debug.xcconfig */, - D3A9DC100926C3AD8E6C6DA0 /* Pods-OpenStreetView.release.xcconfig */, - 76EFDE20412EDAEF4D2AEAC5 /* Pods-OpenStreetView.enterprise.xcconfig */, - 918840F1F96F2026A7C60A46 /* Pods-OpenStreetView.beta.xcconfig */, - BCCC682778267DD5632A0C68 /* Pods-OpenStreetViewRelease.debug.xcconfig */, - 61065ED006F711614BE2E2D3 /* Pods-OpenStreetViewRelease.release.xcconfig */, - 244418F01B0BB9BE8E5468A5 /* Pods-OpenStreetViewRelease.enterprise.xcconfig */, - B5994CEE8F0652F6972FCE4A /* Pods-OpenStreetViewRelease.beta.xcconfig */, + CCFF579C1E44D1980031B8BE /* MatcherDataSet.json */, + CCFF57921E44D0960031B8BE /* OSCTests.m */, + CCFF57941E44D0960031B8BE /* Info.plist */, ); - name = Pods; + path = OSCTests; sourceTree = ""; }; /* End PBXGroup section */ /* Begin PBXNativeTarget section */ + CC92F6771E095E5C00427256 /* OSC_ORBB_Dev */ = { + isa = PBXNativeTarget; + buildConfigurationList = CC92F74B1E095E5C00427256 /* Build configuration list for PBXNativeTarget "OSC_ORBB_Dev" */; + buildPhases = ( + CC92F6781E095E5C00427256 /* Sources */, + CC92F71E1E095E5C00427256 /* Frameworks */, + CC92F7361E095E5C00427256 /* Resources */, + CC92F7451E095E5C00427256 /* CopyFiles */, + CC92F7461E095E5C00427256 /* Embed Frameworks */, + CC92F7481E095E5C00427256 /* Revision Number Script */, + CC92F7491E095E5C00427256 /* ShellScript */, + CC92F74A1E095E5C00427256 /* RemoveUnusedArch */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = OSC_ORBB_Dev; + productName = OpenStreetView; + productReference = CC92F7501E095E5C00427256 /* OSC_ORBB_Dev.app */; + productType = "com.apple.product-type.application"; + }; CCA16C241C92F64B001EEB57 /* OpenStreetViewRelease */ = { isa = PBXNativeTarget; buildConfigurationList = CCA16CB11C92F64B001EEB57 /* Build configuration list for PBXNativeTarget "OpenStreetViewRelease" */; buildPhases = ( - CCA1BE655A028522632548C6 /* 📦 Check Pods Manifest.lock */, CCA16C251C92F64B001EEB57 /* Sources */, CCA16C881C92F64B001EEB57 /* Frameworks */, CCA16C9E1C92F64B001EEB57 /* Resources */, CCA16CAA1C92F64B001EEB57 /* CopyFiles */, CCA16CAB1C92F64B001EEB57 /* Embed Frameworks */, CCA16CAD1C92F64B001EEB57 /* Revision Number Script */, + CCA16CAE1C92F64B001EEB57 /* ShellScript */, CCA16CB01C92F64B001EEB57 /* RemoveUnusedArch */, - 4C4043EDB8BCA142998D7A1D /* 📦 Embed Pods Frameworks */, - 6063DEECC26DDED4B8869791 /* 📦 Copy Pods Resources */, - CC42A3731D5B47C2001541DD /* ShellScript */, ); buildRules = ( ); @@ -1650,22 +2141,20 @@ ); name = OpenStreetViewRelease; productName = OpenStreetView; - productReference = CCA16CB61C92F64B001EEB57 /* OSV.app */; + productReference = CCA16CB61C92F64B001EEB57 /* OSC.app */; productType = "com.apple.product-type.application"; }; CCFD49901BA02455005B5E9A /* OpenStreetView */ = { isa = PBXNativeTarget; buildConfigurationList = CCFD49B41BA02455005B5E9A /* Build configuration list for PBXNativeTarget "OpenStreetView" */; buildPhases = ( - 4EED58DA2B525129B9BB1CD5 /* 📦 Check Pods Manifest.lock */, CCFD498D1BA02455005B5E9A /* Sources */, CCFD498E1BA02455005B5E9A /* Frameworks */, CCFD498F1BA02455005B5E9A /* Resources */, CCFD4A4A1BA05D06005B5E9A /* CopyFiles */, CC8C01331BDE3D950011BE4D /* Revision Number Script */, - A04AAF56780F19FAE1F2F2CD /* 📦 Embed Pods Frameworks */, - 7327978942410886812C037A /* 📦 Copy Pods Resources */, - CC42A3721D5B4724001541DD /* CrashlyticsRunScript */, + CC12A1DB1C23FF5A0019DB21 /* ShellScript */, + CC02D2C91D92CD16000E98BF /* Embed Frameworks */, ); buildRules = ( ); @@ -1673,25 +2162,58 @@ ); name = OpenStreetView; productName = OpenStreetView; - productReference = CCFD49911BA02455005B5E9A /* OSV.app */; + productReference = CCFD49911BA02455005B5E9A /* OSC.app */; productType = "com.apple.product-type.application"; }; + CCFF578F1E44D0960031B8BE /* OSCTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = CCFF579B1E44D0960031B8BE /* Build configuration list for PBXNativeTarget "OSCTests" */; + buildPhases = ( + CCFF578C1E44D0960031B8BE /* Sources */, + CCFF578D1E44D0960031B8BE /* Frameworks */, + CCFF578E1E44D0960031B8BE /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + CCFF57961E44D0960031B8BE /* PBXTargetDependency */, + ); + name = OSCTests; + productName = OSCTests; + productReference = CCFF57901E44D0960031B8BE /* OSCTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ CCFD49891BA02455005B5E9A /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 0710; - LastUpgradeCheck = 0730; + LastSwiftUpdateCheck = 0820; + LastUpgradeCheck = 0820; ORGANIZATIONNAME = "Bogdan Sala"; TargetAttributes = { + CC92F6771E095E5C00427256 = { + DevelopmentTeam = F86PKNGLDF; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; CCA16C241C92F64B001EEB57 = { - DevelopmentTeam = 2BF96UN6UZ; + DevelopmentTeam = F86PKNGLDF; + LastSwiftMigration = 0820; + ProvisioningStyle = Manual; }; CCFD49901BA02455005B5E9A = { CreatedOnToolsVersion = 6.4; - DevelopmentTeam = 2BF96UN6UZ; + DevelopmentTeam = F86PKNGLDF; + LastSwiftMigration = 0820; + ProvisioningStyle = Automatic; + }; + CCFF578F1E44D0960031B8BE = { + CreatedOnToolsVersion = 8.2.1; + DevelopmentTeam = F86PKNGLDF; + ProvisioningStyle = Automatic; + TestTargetID = CCFD49901BA02455005B5E9A; }; }; }; @@ -1710,29 +2232,47 @@ targets = ( CCFD49901BA02455005B5E9A /* OpenStreetView */, CCA16C241C92F64B001EEB57 /* OpenStreetViewRelease */, + CC92F6771E095E5C00427256 /* OSC_ORBB_Dev */, + CCFF578F1E44D0960031B8BE /* OSCTests */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + CC92F7361E095E5C00427256 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CC92F7371E095E5C00427256 /* oSVLogoV1.png in Resources */, + CC92F7381E095E5C00427256 /* oSVLogoV1@2x.png in Resources */, + CC2794801E2E1FD10085866F /* OSVIntroViewController.xib in Resources */, + CC92F7391E095E5C00427256 /* oSVLogoV1@3x.png in Resources */, + CC92F73D1E095E5C00427256 /* Main.storyboard in Resources */, + CC92F73E1E095E5C00427256 /* LaunchScreen.xib in Resources */, + CC92F73F1E095E5C00427256 /* Localizable.strings in Resources */, + CC92F7401E095E5C00427256 /* OSVTipView.xib in Resources */, + CC92F7411E095E5C00427256 /* OSVSegmentedViewCell.xib in Resources */, + CC92F7421E095E5C00427256 /* OSVFullScreenImageCell.xib in Resources */, + CC92F7431E095E5C00427256 /* OSVTipPageViewController.xib in Resources */, + CC92F7441E095E5C00427256 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; CCA16C9E1C92F64B001EEB57 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + CC38A7421D40CC7D0027D5F1 /* oSVLogoV1.png in Resources */, CC38A7441D40CC7D0027D5F1 /* oSVLogoV1@2x.png in Resources */, - CC359DA01CC4DC88007DBD49 /* photoShutter2.caf in Resources */, - CCA16C9F1C92F64B001EEB57 /* OSVSegmentedViewCell.xib in Resources */, - CCA16CA01C92F64B001EEB57 /* InfoEnterprise.plist in Resources */, + CC27947F1E2E1FD10085866F /* OSVIntroViewController.xib in Resources */, + CC38A7461D40CC7D0027D5F1 /* oSVLogoV1@3x.png in Resources */, CCA16CA11C92F64B001EEB57 /* Main.storyboard in Resources */, CCA16CA21C92F64B001EEB57 /* LaunchScreen.xib in Resources */, - CC38A7461D40CC7D0027D5F1 /* oSVLogoV1@3x.png in Resources */, + CCA16CA61C92F64B001EEB57 /* Localizable.strings in Resources */, CC4ACCDD1CF8DD9A009562C3 /* OSVTipView.xib in Resources */, - CCA16CA31C92F64B001EEB57 /* InfoBeta.plist in Resources */, - CCBBCFE61D1D638700B9104F /* OSVTipPageViewController.xib in Resources */, - CC38A7421D40CC7D0027D5F1 /* oSVLogoV1.png in Resources */, + CCA16C9F1C92F64B001EEB57 /* OSVSegmentedViewCell.xib in Resources */, CCA16CA51C92F64B001EEB57 /* OSVFullScreenImageCell.xib in Resources */, - CCA16CA61C92F64B001EEB57 /* Localizable.strings in Resources */, - CCA16CA71C92F64B001EEB57 /* OSVSequenceSectionHeaderView.xib in Resources */, + CCBBCFE61D1D638700B9104F /* OSVTipPageViewController.xib in Resources */, CCA16CA81C92F64B001EEB57 /* Images.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -1742,129 +2282,102 @@ buildActionMask = 2147483647; files = ( CC38A7411D40CC7D0027D5F1 /* oSVLogoV1.png in Resources */, - CCBBCFE51D1D638700B9104F /* OSVTipPageViewController.xib in Resources */, - CC06B6481C75F71C00E2B0DB /* OSVSegmentedViewCell.xib in Resources */, - CC29AD9C1BA8807700538BD3 /* InfoEnterprise.plist in Resources */, - CC359DA11CC4DC88007DBD49 /* photoShutter2.caf in Resources */, + CC27947E1E2E1FD10085866F /* OSVIntroViewController.xib in Resources */, + CC38A7431D40CC7D0027D5F1 /* oSVLogoV1@2x.png in Resources */, + CC38A7451D40CC7D0027D5F1 /* oSVLogoV1@3x.png in Resources */, CCFD49A01BA02455005B5E9A /* Main.storyboard in Resources */, - CCFD49A51BA02455005B5E9A /* LaunchScreen.xib in Resources */, - CCA16C1F1C92D1DA001EEB57 /* InfoBeta.plist in Resources */, + CC7AEBBC1E07EC5E00D587A9 /* exif_iOS.proto in Resources */, + CC4128E31D6EE39000B8AA35 /* LaunchScreen.xib in Resources */, + CCB56F551C28072D00FFFC39 /* Localizable.strings in Resources */, CC6E45911CCE7577007DB5CA /* OSVTipView.xib in Resources */, + CC06B6481C75F71C00E2B0DB /* OSVSegmentedViewCell.xib in Resources */, CCBE0F181C8F1D9D00A43F37 /* OSVFullScreenImageCell.xib in Resources */, - CCB56F551C28072D00FFFC39 /* Localizable.strings in Resources */, - CC38A7451D40CC7D0027D5F1 /* oSVLogoV1@3x.png in Resources */, - CC91D5D51BFDE8AA003A6409 /* OSVSequenceSectionHeaderView.xib in Resources */, + CCBBCFE51D1D638700B9104F /* OSVTipPageViewController.xib in Resources */, CCFD49A21BA02455005B5E9A /* Images.xcassets in Resources */, - CC38A7431D40CC7D0027D5F1 /* oSVLogoV1@2x.png in Resources */, + CCFF579E1E44D2930031B8BE /* MatcherDataSet.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; -/* End PBXResourcesBuildPhase section */ - -/* Begin PBXShellScriptBuildPhase section */ - 4C4043EDB8BCA142998D7A1D /* 📦 Embed Pods Frameworks */ = { - isa = PBXShellScriptBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - inputPaths = ( - ); - name = "📦 Embed Pods Frameworks"; - outputPaths = ( - ); - runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OpenStreetViewRelease/Pods-OpenStreetViewRelease-frameworks.sh\"\n"; - showEnvVarsInLog = 0; - }; - 4EED58DA2B525129B9BB1CD5 /* 📦 Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; + CCFF578E1E44D0960031B8BE /* Resources */ = { + isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - name = "📦 Check Pods Manifest.lock"; - outputPaths = ( + CCFF579D1E44D1980031B8BE /* MatcherDataSet.json in Resources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; }; - 6063DEECC26DDED4B8869791 /* 📦 Copy Pods Resources */ = { +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + CC12A1DB1C23FF5A0019DB21 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "📦 Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OpenStreetViewRelease/Pods-OpenStreetViewRelease-resources.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "\"${PODS_ROOT}/Fabric/run\" "; }; - 7327978942410886812C037A /* 📦 Copy Pods Resources */ = { + CC8C01331BDE3D950011BE4D /* Revision Number Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "📦 Copy Pods Resources"; + name = "Revision Number Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OpenStreetView/Pods-OpenStreetView-resources.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "#revision genereation script\nREV=`svnversion -nc | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`\necho \"REV=$REV\"\necho \"$REV\" > ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/revision.osv\n"; }; - A04AAF56780F19FAE1F2F2CD /* 📦 Embed Pods Frameworks */ = { + CC92F7481E095E5C00427256 /* Revision Number Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "📦 Embed Pods Frameworks"; + name = "Revision Number Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-OpenStreetView/Pods-OpenStreetView-frameworks.sh\"\n"; - showEnvVarsInLog = 0; + shellScript = "#revision genereation script\nREV=`svnversion -nc | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`\necho \"REV=$REV\"\necho \"$REV\" > ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/revision.osv\n"; }; - CC42A3721D5B4724001541DD /* CrashlyticsRunScript */ = { + CC92F7491E095E5C00427256 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = CrashlyticsRunScript; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Fabric/run\" c1f1517ab073bd0f7235948145e059192e8cb582 f470f12af6aba9998ff32f1b52dc7da58584fa85cf3dfef0ad54bcf55ceb12d0"; + shellScript = "\"${PODS_ROOT}/Fabric/run\" "; }; - CC42A3731D5B47C2001541DD /* ShellScript */ = { + CC92F74A1E095E5C00427256 /* RemoveUnusedArch */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); + name = RemoveUnusedArch; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${PODS_ROOT}/Fabric/run\" c1f1517ab073bd0f7235948145e059192e8cb582 f470f12af6aba9998ff32f1b52dc7da58584fa85cf3dfef0ad54bcf55ceb12d0"; + shellScript = "APP_PATH=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}\"\n\n# This script loops through the frameworks embedded in the application and\n# removes unused architectures.\nfind \"$APP_PATH\" -name '*.framework' -type d | while read -r FRAMEWORK\ndo\nFRAMEWORK_EXECUTABLE_NAME=$(defaults read \"$FRAMEWORK/Info.plist\" CFBundleExecutable)\nFRAMEWORK_EXECUTABLE_PATH=\"$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME\"\necho \"Executable is $FRAMEWORK_EXECUTABLE_PATH\"\n\nEXTRACTED_ARCHS=()\n\nfor ARCH in $ARCHS\ndo\necho \"Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME\"\nlipo -extract \"$ARCH\" \"$FRAMEWORK_EXECUTABLE_PATH\" -o \"$FRAMEWORK_EXECUTABLE_PATH-$ARCH\"\nEXTRACTED_ARCHS+=(\"$FRAMEWORK_EXECUTABLE_PATH-$ARCH\")\ndone\n\necho \"Merging extracted architectures: ${ARCHS}\"\nlipo -o \"$FRAMEWORK_EXECUTABLE_PATH-merged\" -create \"${EXTRACTED_ARCHS[@]}\"\nrm \"${EXTRACTED_ARCHS[@]}\"\n\necho \"Replacing original executable with thinned version\"\nrm \"$FRAMEWORK_EXECUTABLE_PATH\"\nmv \"$FRAMEWORK_EXECUTABLE_PATH-merged\" \"$FRAMEWORK_EXECUTABLE_PATH\"\n\ndone"; }; - CC8C01331BDE3D950011BE4D /* Revision Number Script */ = { + CCA16CAD1C92F64B001EEB57 /* Revision Number Script */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -1878,19 +2391,18 @@ shellPath = /bin/sh; shellScript = "#revision genereation script\nREV=`svnversion -nc | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`\necho \"REV=$REV\"\necho \"$REV\" > ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/revision.osv\n"; }; - CCA16CAD1C92F64B001EEB57 /* Revision Number Script */ = { + CCA16CAE1C92F64B001EEB57 /* ShellScript */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Revision Number Script"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "#revision genereation script\nREV=`svnversion -nc | /usr/bin/sed -e 's/^[^:]*://;s/[A-Za-z]//'`\necho \"REV=$REV\"\necho \"$REV\" > ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/revision.osv\n"; + shellScript = "\"${PODS_ROOT}/Fabric/run\" "; }; CCA16CB01C92F64B001EEB57 /* RemoveUnusedArch */ = { isa = PBXShellScriptBuildPhase; @@ -1906,24 +2418,187 @@ shellPath = /bin/sh; shellScript = "APP_PATH=\"${TARGET_BUILD_DIR}/${WRAPPER_NAME}\"\n\n# This script loops through the frameworks embedded in the application and\n# removes unused architectures.\nfind \"$APP_PATH\" -name '*.framework' -type d | while read -r FRAMEWORK\ndo\nFRAMEWORK_EXECUTABLE_NAME=$(defaults read \"$FRAMEWORK/Info.plist\" CFBundleExecutable)\nFRAMEWORK_EXECUTABLE_PATH=\"$FRAMEWORK/$FRAMEWORK_EXECUTABLE_NAME\"\necho \"Executable is $FRAMEWORK_EXECUTABLE_PATH\"\n\nEXTRACTED_ARCHS=()\n\nfor ARCH in $ARCHS\ndo\necho \"Extracting $ARCH from $FRAMEWORK_EXECUTABLE_NAME\"\nlipo -extract \"$ARCH\" \"$FRAMEWORK_EXECUTABLE_PATH\" -o \"$FRAMEWORK_EXECUTABLE_PATH-$ARCH\"\nEXTRACTED_ARCHS+=(\"$FRAMEWORK_EXECUTABLE_PATH-$ARCH\")\ndone\n\necho \"Merging extracted architectures: ${ARCHS}\"\nlipo -o \"$FRAMEWORK_EXECUTABLE_PATH-merged\" -create \"${EXTRACTED_ARCHS[@]}\"\nrm \"${EXTRACTED_ARCHS[@]}\"\n\necho \"Replacing original executable with thinned version\"\nrm \"$FRAMEWORK_EXECUTABLE_PATH\"\nmv \"$FRAMEWORK_EXECUTABLE_PATH-merged\" \"$FRAMEWORK_EXECUTABLE_PATH\"\n\ndone"; }; - CCA1BE655A028522632548C6 /* 📦 Check Pods Manifest.lock */ = { - isa = PBXShellScriptBuildPhase; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + CC92F6781E095E5C00427256 /* Sources */ = { + isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - ); - inputPaths = ( - ); - name = "📦 Check Pods Manifest.lock"; - outputPaths = ( + CC92F6791E095E5C00427256 /* OSVSettingsViewController.m in Sources */, + CC92F67A1E095E5C00427256 /* AVCamPreviewView.m in Sources */, + CC92F67B1E095E5C00427256 /* OSVSyncController.m in Sources */, + CC92F67C1E095E5C00427256 /* NSStreamAdditions.m in Sources */, + CC27947D1E2E1FD10085866F /* OSVIntroViewController.m in Sources */, + CC92F67D1E095E5C00427256 /* OSVLoadingCell.m in Sources */, + CC92F67E1E095E5C00427256 /* OSVTrackCell.m in Sources */, + CC92F67F1E095E5C00427256 /* UIBarButtonItem+Aditions.m in Sources */, + CC92F6801E095E5C00427256 /* OSVSectionItem.m in Sources */, + CC92F6811E095E5C00427256 /* OSVBasicMapController.m in Sources */, + CC92F6821E095E5C00427256 /* AFPropertyListRequestOperation.m in Sources */, + CC92F6831E095E5C00427256 /* OSVPhotoSyncController.m in Sources */, + CC92F6841E095E5C00427256 /* OSVLocalNotificationsController.m in Sources */, + CC92F6851E095E5C00427256 /* OBDUtils.m in Sources */, + CC2794731E2CED640085866F /* OSVUtils+Gamification.m in Sources */, + CC92F6861E095E5C00427256 /* OSVServerSequence+Convertor.m in Sources */, + CC92F6871E095E5C00427256 /* OSVButton.m in Sources */, + CC92F6881E095E5C00427256 /* OSVPolyline.m in Sources */, + CC92F6891E095E5C00427256 /* OSVSettingsSwitchCell.m in Sources */, + CC92F68A1E095E5C00427256 /* ELM327Command.m in Sources */, + CC92F68B1E095E5C00427256 /* OSVUtils+Location.m in Sources */, + CC92F68C1E095E5C00427256 /* OSVMainViewController.m in Sources */, + CC92F68D1E095E5C00427256 /* OSVDebugViewController.m in Sources */, + CC92F68E1E095E5C00427256 /* OSVPhotoData.m in Sources */, + CC92F68F1E095E5C00427256 /* OSVUserDefaults.m in Sources */, + CC92F6901E095E5C00427256 /* OSMParser.m in Sources */, + CC92F6911E095E5C00427256 /* OBDService.m in Sources */, + CC92F6921E095E5C00427256 /* OSVSequence.m in Sources */, + CC92F6931E095E5C00427256 /* OSVUtils+Device.m in Sources */, + CCEC8A0B1E38B4510049093A /* PortraitViewController.swift in Sources */, + CC92F6941E095E5C00427256 /* OSVPhotoPlayer.m in Sources */, + CC92F6951E095E5C00427256 /* OSVSequenceCell.m in Sources */, + CC92F6961E095E5C00427256 /* OSVMainMenuFactory.m in Sources */, + CC92F6971E095E5C00427256 /* OSVUploadViewController.m in Sources */, + CC5CAE001E41F0E6007AA999 /* OSVCameraGamificationManager.m in Sources */, + CC92F6981E095E5C00427256 /* OSVPopTransition.m in Sources */, + CC92F6991E095E5C00427256 /* OSVLocalTrackCell.m in Sources */, + CC92F69A1E095E5C00427256 /* OSVRankCell.m in Sources */, + CC92F69B1E095E5C00427256 /* AppDelegate.m in Sources */, + CC92F69C1E095E5C00427256 /* OSVTrackSyncController.m in Sources */, + CC92F69D1E095E5C00427256 /* OSVTipView.m in Sources */, + CC92F69E1E095E5C00427256 /* OSVDissmissFullScreenAnimationController.m in Sources */, + CC92F69F1E095E5C00427256 /* OSVServerPhoto.m in Sources */, + CC92F6A01E095E5C00427256 /* OSVAPISpeedometer.m in Sources */, + CC92F6A11E095E5C00427256 /* AFURLConnectionOperation.m in Sources */, + CC92F6A21E095E5C00427256 /* OSVLeaderboardViewController.m in Sources */, + CC92F6A31E095E5C00427256 /* UIAlertView+Blocks.m in Sources */, + CC92F6A41E095E5C00427256 /* OSVCloseButton.m in Sources */, + CC92F6A51E095E5C00427256 /* OSVSegmentedViewCell.m in Sources */, + CC92F6A61E095E5C00427256 /* OSVPushTransition.m in Sources */, + CC92F6A71E095E5C00427256 /* ConnectivityHandler.m in Sources */, + CC92F6A81E095E5C00427256 /* OSVMapViewController.m in Sources */, + CC59A59B1E5DF42700A84996 /* LoginViewController.swift in Sources */, + CC92F6A91E095E5C00427256 /* NSAttributedString+Additions.m in Sources */, + CC92F6AA1E095E5C00427256 /* OSVVideo.m in Sources */, + CC92F6AB1E095E5C00427256 /* AFJSONRequestOperation.m in Sources */, + CC2794771E2D0C2E0085866F /* SummaryViewController.swift in Sources */, + CC92F6AC1E095E5C00427256 /* OSVUtils+Image.m in Sources */, + CC92F6AD1E095E5C00427256 /* OSVSettingsMenuFactory.m in Sources */, + CC92F6AE1E095E5C00427256 /* OSVCamViewController.m in Sources */, + CC92F6AF1E095E5C00427256 /* UIColor+OSVColor.m in Sources */, + CC92F6B01E095E5C00427256 /* OSVSplashViewController.m in Sources */, + CC92F6B11E095E5C00427256 /* OSVRankHeaderCell.m in Sources */, + CC92F6B21E095E5C00427256 /* OSVAPI+Video.m in Sources */, + CC92F6B31E095E5C00427256 /* OSVBasicCell.m in Sources */, + CC92F6B41E095E5C00427256 /* OSVCameraMapManager.m in Sources */, + CC92F6B51E095E5C00427256 /* OBDDevice.m in Sources */, + CC92F6B61E095E5C00427256 /* OSVMetadata.m in Sources */, + CC92F6B71E095E5C00427256 /* KAProgressLabel.m in Sources */, + CC92F6B81E095E5C00427256 /* OSVPhoto+Relm.m in Sources */, + CC92F6B91E095E5C00427256 /* ELM327.m in Sources */, + CC92F6BA1E095E5C00427256 /* FLScanTool.m in Sources */, + CC92F6BB1E095E5C00427256 /* OSVDetailsCell.m in Sources */, + CC92F6BC1E095E5C00427256 /* OSVGamificationProfileCell.m in Sources */, + CC92F6BD1E095E5C00427256 /* FLWifiScanTool.m in Sources */, + CC92F6BE1E095E5C00427256 /* OSVGamificationInfo.m in Sources */, + CC92F6BF1E095E5C00427256 /* ELM327ResponseParser.m in Sources */, + CC92F6C01E095E5C00427256 /* OSVSectionHeaderCell.m in Sources */, + CC92F6C11E095E5C00427256 /* OSVSequenceMapController.m in Sources */, + CC92F6C21E095E5C00427256 /* OSVAPI+Mix.m in Sources */, + CC92F6C31E095E5C00427256 /* OSVVideoPlayer.m in Sources */, + CC92F6C41E095E5C00427256 /* OSVFullScreenImageViewController.m in Sources */, + CC92F6C51E095E5C00427256 /* OSVSensorLibManager.mm in Sources */, + CC92F6C61E095E5C00427256 /* UIDevice+Aditions.m in Sources */, + CC92F6C71E095E5C00427256 /* OSVMenuItem.m in Sources */, + CC92F6C81E095E5C00427256 /* OSVPhoto.m in Sources */, + CC92F6C91E095E5C00427256 /* OSVServerPhoto+Convertor.m in Sources */, + CC92F6CA1E095E5C00427256 /* OSVVideoRecorder.m in Sources */, + CC92F75D1E0AD75E00427256 /* ScoreManager.swift in Sources */, + CC92F6CB1E095E5C00427256 /* OSVScoreHistory.m in Sources */, + CC92F6CC1E095E5C00427256 /* NSFileManager+Godzippa.m in Sources */, + CC92F6CD1E095E5C00427256 /* CERangeSliderKnobLayer.m in Sources */, + CC92F6CE1E095E5C00427256 /* AFHTTPClient.m in Sources */, + CC92F6CF1E095E5C00427256 /* OSVSlider.m in Sources */, + CC92F6D01E095E5C00427256 /* AFImageRequestOperation.m in Sources */, + CC92F6D11E095E5C00427256 /* UIImageView+AFNetworking.m in Sources */, + CC92F6D21E095E5C00427256 /* RLMScoreHistory.m in Sources */, + CC92F6D31E095E5C00427256 /* OSVUtils+FileManager.m in Sources */, + CC92F6D41E095E5C00427256 /* AVCamViewController.m in Sources */, + CC92F6D51E095E5C00427256 /* OSVAPIConfigurator.m in Sources */, + CC92F6D61E095E5C00427256 /* OSVMyProfileViewController.m in Sources */, + CC92F6D71E095E5C00427256 /* OSVSettingsOptionCell.m in Sources */, + CC92F6D81E095E5C00427256 /* FLScanToolResponseParser.m in Sources */, + CC92F6D91E095E5C00427256 /* OSVSyncUtils.m in Sources */, + CC92F6DA1E095E5C00427256 /* OSVAPI+Photos.m in Sources */, + CC92F6DB1E095E5C00427256 /* FLScanToolCommand.m in Sources */, + CC92F6DC1E095E5C00427256 /* OSVAPI.m in Sources */, + CC92F6DD1E095E5C00427256 /* OSVImageCollectionViewCell.m in Sources */, + CC92F6DE1E095E5C00427256 /* OSVLocationManager.m in Sources */, + CC92F6DF1E095E5C00427256 /* OSVSettingsDetails.m in Sources */, + CC5CADFB1E41E38A007AA999 /* UIViewController+Additions.m in Sources */, + CC92F6E01E095E5C00427256 /* OSVLeftMenuViewController.m in Sources */, + CC92F6E11E095E5C00427256 /* OSVLogger.m in Sources */, + CC92F6E21E095E5C00427256 /* OSVLayersViewController.m in Sources */, + CC92F6E31E095E5C00427256 /* UIView+Additions.m in Sources */, + CC92F6E41E095E5C00427256 /* OSVTrackCache.m in Sources */, + CC92F6E51E095E5C00427256 /* OSVAPIUtils.m in Sources */, + CC92F6E61E095E5C00427256 /* OSVDissmissRecordTransition.m in Sources */, + CC92F6E71E095E5C00427256 /* OSVScoreDetailsView.m in Sources */, + CC92F6E91E095E5C00427256 /* OSVPersistentManager.m in Sources */, + CC92F6EA1E095E5C00427256 /* OSVTrackMatcher.m in Sources */, + CC92F6EB1E095E5C00427256 /* OSVBaseUser.m in Sources */, + CC92F6EC1E095E5C00427256 /* OSVInfoCell.m in Sources */, + CC92F6ED1E095E5C00427256 /* OSVAPI+Sequences.m in Sources */, + CC92F6EE1E095E5C00427256 /* OSVLocalTracksViewController.m in Sources */, + CC92F6EF1E095E5C00427256 /* NSData+Godzippa.m in Sources */, + CC92F6F01E095E5C00427256 /* OSVFullScreenImageCell.m in Sources */, + CC92F6F11E095E5C00427256 /* OSVUnderlineButton.m in Sources */, + CC92F6F21E095E5C00427256 /* CERangeSlider.m in Sources */, + CC92F7611E0C147700427256 /* ScoreHistory.swift in Sources */, + CC92F6F31E095E5C00427256 /* OSVNavigationController.m in Sources */, + CC92F6F41E095E5C00427256 /* OSVTipPageViewController.m in Sources */, + CC92F6F51E095E5C00427256 /* OSVVideoPlayerViewController.m in Sources */, + CC92F6F61E095E5C00427256 /* TPPropertyAnimation.m in Sources */, + CC92F6F71E095E5C00427256 /* OSVServerSequence.m in Sources */, + CC92F6F81E095E5C00427256 /* RLMPhoto.m in Sources */, + CC92F6F91E095E5C00427256 /* main.m in Sources */, + CC92F6FA1E095E5C00427256 /* OSVSensorsManager.m in Sources */, + CC92F6FC1E095E5C00427256 /* OSVMainMenuCell.m in Sources */, + CC92F6FD1E095E5C00427256 /* OSVSliderCell.m in Sources */, + CC92F6FE1E095E5C00427256 /* OSVRecordTransition.m in Sources */, + CC92F6FF1E095E5C00427256 /* OSVOBDData.m in Sources */, + CC92F7001E095E5C00427256 /* OSVReachablityController.m in Sources */, + CC92F7011E095E5C00427256 /* OSMAPI.m in Sources */, + CC92F7021E095E5C00427256 /* OSVMyTracksCell.m in Sources */, + CC92F7031E095E5C00427256 /* OSVLoginController.m in Sources */, + CC92F7041E095E5C00427256 /* OSVAPISerialOperation.m in Sources */, + CC92F7051E095E5C00427256 /* CALayer+XibConfiguration.m in Sources */, + CC92F7061E095E5C00427256 /* OSVUser.m in Sources */, + CC92F7071E095E5C00427256 /* NSMutableAttributedString+Additions.m in Sources */, + CC92F7081E095E5C00427256 /* AFNetworkActivityIndicatorManager.m in Sources */, + CC92F7091E095E5C00427256 /* FLECUSensor.m in Sources */, + CC92F70A1E095E5C00427256 /* OSVMyProfileCell.m in Sources */, + CC92F70B1E095E5C00427256 /* Reachability.m in Sources */, + CC92F70C1E095E5C00427256 /* AFXMLRequestOperation.m in Sources */, + CC92F70D1E095E5C00427256 /* LGSideMenuController.m in Sources */, + CC92F70E1E095E5C00427256 /* OSMUser.m in Sources */, + CC92F70F1E095E5C00427256 /* OSVUploadCell.m in Sources */, + CC92F7101E095E5C00427256 /* SKSearchResult+Aditions.m in Sources */, + CC92F7111E095E5C00427256 /* OSVScoreHistory+Realm.m in Sources */, + CC92F7131E095E5C00427256 /* OSVCameraManager.m in Sources */, + CC92F7141E095E5C00427256 /* CERangeSliderTrackLayer.m in Sources */, + CC92F7151E095E5C00427256 /* OSVTrackLogger.m in Sources */, + CC92F7161E095E5C00427256 /* AFOAuth1Client.m in Sources */, + CC92F7171E095E5C00427256 /* OSVFullScreenAnimationController.m in Sources */, + CC92F7181E095E5C00427256 /* AFHTTPRequestOperation.m in Sources */, + CC92F7191E095E5C00427256 /* OSVLogItem.m in Sources */, + CC92F71A1E095E5C00427256 /* OSVOBDController.m in Sources */, + CC92F71B1E095E5C00427256 /* OSVDotedPolyline.m in Sources */, + CC92F71C1E095E5C00427256 /* OSVUtils.m in Sources */, + CC92F71D1E095E5C00427256 /* FLScanToolResponse.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; - shellPath = /bin/sh; - shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; - showEnvVarsInLog = 0; }; -/* End PBXShellScriptBuildPhase section */ - -/* Begin PBXSourcesBuildPhase section */ CCA16C251C92F64B001EEB57 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1932,6 +2607,7 @@ CCA16C271C92F64B001EEB57 /* AVCamPreviewView.m in Sources */, CCA16C281C92F64B001EEB57 /* OSVSyncController.m in Sources */, CC4536581CA59373005C4490 /* NSStreamAdditions.m in Sources */, + CC27947C1E2E1FD10085866F /* OSVIntroViewController.m in Sources */, CCA16C2A1C92F64B001EEB57 /* OSVLoadingCell.m in Sources */, CC01672E1D2D654100E8297D /* OSVTrackCell.m in Sources */, CCA16C2B1C92F64B001EEB57 /* UIBarButtonItem+Aditions.m in Sources */, @@ -1939,7 +2615,9 @@ CCA16C2D1C92F64B001EEB57 /* OSVBasicMapController.m in Sources */, CCA16C2E1C92F64B001EEB57 /* AFPropertyListRequestOperation.m in Sources */, CCA16C2F1C92F64B001EEB57 /* OSVPhotoSyncController.m in Sources */, - CC1FFCEA1D58A48300958B8E /* OBDUtils.m in Sources */, + CC8A08F71DB63393002167AB /* OSVLocalNotificationsController.m in Sources */, + CCCA96921DA6355600D32CE7 /* OBDUtils.m in Sources */, + CC2794721E2CED630085866F /* OSVUtils+Gamification.m in Sources */, CCA16C301C92F64B001EEB57 /* OSVServerSequence+Convertor.m in Sources */, CCA16C311C92F64B001EEB57 /* OSVButton.m in Sources */, CCA16C321C92F64B001EEB57 /* OSVPolyline.m in Sources */, @@ -1951,12 +2629,18 @@ CCA16C361C92F64B001EEB57 /* OSVPhotoData.m in Sources */, CCA16C381C92F64B001EEB57 /* OSVUserDefaults.m in Sources */, CCA16C391C92F64B001EEB57 /* OSMParser.m in Sources */, + CCCA96911DA6355200D32CE7 /* OBDService.m in Sources */, CCA16C3A1C92F64B001EEB57 /* OSVSequence.m in Sources */, + CC99BB271D9421B80029E58D /* OSVUtils+Device.m in Sources */, + CCEC8A0A1E38B4510049093A /* PortraitViewController.swift in Sources */, CC410ADE1D117427000220BA /* OSVPhotoPlayer.m in Sources */, CCA16C3B1C92F64B001EEB57 /* OSVSequenceCell.m in Sources */, CC5CC2771D2BC2AC002963D2 /* OSVMainMenuFactory.m in Sources */, CCA16C3C1C92F64B001EEB57 /* OSVUploadViewController.m in Sources */, + CC5CADFF1E41F0E6007AA999 /* OSVCameraGamificationManager.m in Sources */, + CC4E16881DAD3D570037827E /* OSVPopTransition.m in Sources */, CC0167E81D2EBA8100E8297D /* OSVLocalTrackCell.m in Sources */, + CCE754321DDDEA7A007625DD /* OSVRankCell.m in Sources */, CCA16C3D1C92F64B001EEB57 /* AppDelegate.m in Sources */, CCA16C3E1C92F64B001EEB57 /* OSVTrackSyncController.m in Sources */, CC4ACCDC1CF8DD8E009562C3 /* OSVTipView.m in Sources */, @@ -1964,35 +2648,41 @@ CCA16C3F1C92F64B001EEB57 /* OSVServerPhoto.m in Sources */, CCA16C401C92F64B001EEB57 /* OSVAPISpeedometer.m in Sources */, CCA16C411C92F64B001EEB57 /* AFURLConnectionOperation.m in Sources */, - CCA16C421C92F64B001EEB57 /* OSVExpandableCell.m in Sources */, + CC3692BE1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m in Sources */, CCA16C431C92F64B001EEB57 /* UIAlertView+Blocks.m in Sources */, - CC7A63FE1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m in Sources */, CC92B0AA1D377877004F7EF8 /* OSVCloseButton.m in Sources */, CCA16C441C92F64B001EEB57 /* OSVSegmentedViewCell.m in Sources */, + CC4E16841DACE7780037827E /* OSVPushTransition.m in Sources */, CCA16C451C92F64B001EEB57 /* ConnectivityHandler.m in Sources */, CCA16C461C92F64B001EEB57 /* OSVMapViewController.m in Sources */, + CC59A59A1E5DF42700A84996 /* LoginViewController.swift in Sources */, CC92B0971D35674A004F7EF8 /* NSAttributedString+Additions.m in Sources */, CCB952E11CE60EB9006D5BBD /* OSVVideo.m in Sources */, CCA16C471C92F64B001EEB57 /* AFJSONRequestOperation.m in Sources */, + CC2794761E2D0C2E0085866F /* SummaryViewController.swift in Sources */, CCA16C491C92F64B001EEB57 /* OSVUtils+Image.m in Sources */, - CCA16C4B1C92F64B001EEB57 /* OSVSequenceSectionHeaderView.m in Sources */, + CCA16C4A1C92F64B001EEB57 /* OSVSettingsMenuFactory.m in Sources */, CCA16C4D1C92F64B001EEB57 /* OSVCamViewController.m in Sources */, CCA16C4E1C92F64B001EEB57 /* UIColor+OSVColor.m in Sources */, + CCCA96A21DA77E9100D32CE7 /* OSVSplashViewController.m in Sources */, + CCE7542E1DDDEA08007625DD /* OSVRankHeaderCell.m in Sources */, CCB952D11CE5EAD3006D5BBD /* OSVAPI+Video.m in Sources */, - CCA16C4F1C92F64B001EEB57 /* OSVGalleryCell.m in Sources */, CC0168771D34ED7F00E8297D /* OSVBasicCell.m in Sources */, + CC69145E1D671D19005B6855 /* OSVCameraMapManager.m in Sources */, + CCCA96901DA6354D00D32CE7 /* OBDDevice.m in Sources */, CCA16C501C92F64B001EEB57 /* OSVMetadata.m in Sources */, CC92B0A31D3665D9004F7EF8 /* KAProgressLabel.m in Sources */, CCA16C511C92F64B001EEB57 /* OSVPhoto+Relm.m in Sources */, CC4536541CA59363005C4490 /* ELM327.m in Sources */, CC45365A1CA5937B005C4490 /* FLScanTool.m in Sources */, CC0168731D34EC8700E8297D /* OSVDetailsCell.m in Sources */, + CCD426B61DE44C870006F74B /* OSVGamificationProfileCell.m in Sources */, CC4536571CA5936E005C4490 /* FLWifiScanTool.m in Sources */, + CCD426BA1DE46A700006F74B /* OSVGamificationInfo.m in Sources */, CC4536561CA59368005C4490 /* ELM327ResponseParser.m in Sources */, CC01686F1D34D92D00E8297D /* OSVSectionHeaderCell.m in Sources */, CCA16C521C92F64B001EEB57 /* OSVSequenceMapController.m in Sources */, CC40CEB31D1BF3E60006D619 /* OSVAPI+Mix.m in Sources */, - CCA16C531C92F64B001EEB57 /* OSVRedButton.m in Sources */, CC16AE301CE4826E001EA02A /* OSVVideoPlayer.m in Sources */, CCA16C541C92F64B001EEB57 /* OSVFullScreenImageViewController.m in Sources */, CC0167DF1D2E856100E8297D /* OSVSensorLibManager.mm in Sources */, @@ -2001,12 +2691,15 @@ CCA16C581C92F64B001EEB57 /* OSVPhoto.m in Sources */, CCA16C591C92F64B001EEB57 /* OSVServerPhoto+Convertor.m in Sources */, CCA16C5A1C92F64B001EEB57 /* OSVVideoRecorder.m in Sources */, + CC92F75C1E0AD75E00427256 /* ScoreManager.swift in Sources */, + CCF0B4871DDB38F900D80961 /* OSVScoreHistory.m in Sources */, CC40F3A91D14028D0028E488 /* NSFileManager+Godzippa.m in Sources */, CC7C6A431CF5E03700C03051 /* CERangeSliderKnobLayer.m in Sources */, CCA16C5B1C92F64B001EEB57 /* AFHTTPClient.m in Sources */, CC92B0B21D37DC74004F7EF8 /* OSVSlider.m in Sources */, CCA16C5C1C92F64B001EEB57 /* AFImageRequestOperation.m in Sources */, CCA16C5D1C92F64B001EEB57 /* UIImageView+AFNetworking.m in Sources */, + CC7B2AD41DE3061900025B67 /* RLMScoreHistory.m in Sources */, CCA16C5E1C92F64B001EEB57 /* OSVUtils+FileManager.m in Sources */, CCA16C5F1C92F64B001EEB57 /* AVCamViewController.m in Sources */, CCA16C601C92F64B001EEB57 /* OSVAPIConfigurator.m in Sources */, @@ -2020,22 +2713,26 @@ CCA16C641C92F64B001EEB57 /* OSVImageCollectionViewCell.m in Sources */, CCA16C651C92F64B001EEB57 /* OSVLocationManager.m in Sources */, CC0168901D35104B00E8297D /* OSVSettingsDetails.m in Sources */, + CC5CADFA1E41E38A007AA999 /* UIViewController+Additions.m in Sources */, CC8960FB1D2B9ECF00501341 /* OSVLeftMenuViewController.m in Sources */, CCA16C671C92F64B001EEB57 /* OSVLogger.m in Sources */, CC4C7B421D3D3C1200B902E8 /* OSVLayersViewController.m in Sources */, CC92B0AE1D37C5D4004F7EF8 /* UIView+Additions.m in Sources */, CCA16C681C92F64B001EEB57 /* OSVTrackCache.m in Sources */, CCA16C691C92F64B001EEB57 /* OSVAPIUtils.m in Sources */, - CCA16C6A1C92F64B001EEB57 /* OSVBaseUser+OSM.m in Sources */, + CC4E16801DABEFB00037827E /* OSVDissmissRecordTransition.m in Sources */, + CC1E86701DFB2996002660F4 /* OSVScoreDetailsView.m in Sources */, CCA16C6B1C92F64B001EEB57 /* OSVPersistentManager.m in Sources */, + CC1E86741DFEB451002660F4 /* OSVTrackMatcher.m in Sources */, CCA16C6C1C92F64B001EEB57 /* OSVBaseUser.m in Sources */, CC01677F1D2E4CB000E8297D /* OSVInfoCell.m in Sources */, CCA16C6D1C92F64B001EEB57 /* OSVAPI+Sequences.m in Sources */, + CC0167E31D2EB0CF00E8297D /* OSVLocalTracksViewController.m in Sources */, CC40F3A81D14028A0028E488 /* NSData+Godzippa.m in Sources */, - CCA16C6E1C92F64B001EEB57 /* OSVCropedLabel.m in Sources */, - CC1FFCE61D58A48300958B8E /* OBDService.m in Sources */, CCA16C6F1C92F64B001EEB57 /* OSVFullScreenImageCell.m in Sources */, + CCE754371DDE08EE007625DD /* OSVUnderlineButton.m in Sources */, CC7C6A421CF5E03400C03051 /* CERangeSlider.m in Sources */, + CC92F7601E0C147700427256 /* ScoreHistory.swift in Sources */, CC0168551D30235D00E8297D /* OSVNavigationController.m in Sources */, CCBBCFE41D1D638700B9104F /* OSVTipPageViewController.m in Sources */, CC16AE381CE4892B001EA02A /* OSVVideoPlayerViewController.m in Sources */, @@ -2046,9 +2743,9 @@ CCA16C761C92F64B001EEB57 /* OSVSensorsManager.m in Sources */, CC3937321D2BDBEB00669EFC /* OSVMainMenuCell.m in Sources */, CCA16C781C92F64B001EEB57 /* OSVSliderCell.m in Sources */, + CC4E167C1DABA36A0037827E /* OSVRecordTransition.m in Sources */, CC7A64061CA2FE85007C9F3B /* OSVOBDData.m in Sources */, CCA16C791C92F64B001EEB57 /* OSVReachablityController.m in Sources */, - CCB88C791D830E52000CADD6 /* OSVLocalTracksViewController.m in Sources */, CCA16C7A1C92F64B001EEB57 /* OSMAPI.m in Sources */, CC01672A1D2D647D00E8297D /* OSVMyTracksCell.m in Sources */, CC40CEB71D1BF8250006D619 /* OSVLoginController.m in Sources */, @@ -2065,6 +2762,7 @@ CCA16C7F1C92F64B001EEB57 /* OSMUser.m in Sources */, CCA16C801C92F64B001EEB57 /* OSVUploadCell.m in Sources */, CCA16C811C92F64B001EEB57 /* SKSearchResult+Aditions.m in Sources */, + CC7B2AD91DE3092B00025B67 /* OSVScoreHistory+Realm.m in Sources */, CC12FCFB1D51DA1A00EB1177 /* OSVCameraManager.m in Sources */, CC7C6A441CF5E03900C03051 /* CERangeSliderTrackLayer.m in Sources */, CCA16C831C92F64B001EEB57 /* OSVTrackLogger.m in Sources */, @@ -2075,7 +2773,6 @@ CC7A64011CA2CFF6007C9F3B /* OSVOBDController.m in Sources */, CC225EC61D227A65000EC04C /* OSVDotedPolyline.m in Sources */, CCA16C871C92F64B001EEB57 /* OSVUtils.m in Sources */, - CC1FFCE81D58A48300958B8E /* OBDDevice.m in Sources */, CC45365C1CA59380005C4490 /* FLScanToolResponse.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -2095,7 +2792,8 @@ CC1862141BCF73F900FE0F75 /* AFPropertyListRequestOperation.m in Sources */, CC7F063C1C6B6D7E00441593 /* OSVPhotoSyncController.m in Sources */, CC19F2D81BAC2CFF006C8FCC /* OSVServerSequence+Convertor.m in Sources */, - CC1FFCE91D58A48300958B8E /* OBDUtils.m in Sources */, + CC8A08F61DB63393002167AB /* OSVLocalNotificationsController.m in Sources */, + CCCDBE501DA4FFBD00F367DD /* OBDUtils.m in Sources */, CC65DF801CA1601400EC3F70 /* ELM327Command.m in Sources */, CC7C6A401CF5E01F00C03051 /* CERangeSliderKnobLayer.m in Sources */, CCF822E21C0745B900E607D9 /* OSVButton.m in Sources */, @@ -2105,15 +2803,18 @@ CC9458631BDA324100DFFD1A /* OSVUtils+Location.m in Sources */, CC65DF7B1CA1601400EC3F70 /* FLScanToolResponse.m in Sources */, CC1E50371BF2048200BD4A1A /* OSVDebugViewController.m in Sources */, - CC7A63FD1CA2CFE8007C9F3B /* OSVSettingsButtonCell.m in Sources */, CC7F064F1C6C9E4800441593 /* OSVPhotoData.m in Sources */, + CCCDBE4F1DA4FFBD00F367DD /* OBDService.m in Sources */, CC410ADD1D117427000220BA /* OSVPhotoPlayer.m in Sources */, + CC99BB261D9421B80029E58D /* OSVUtils+Device.m in Sources */, CCC2C68E1BA8506400A4CDEE /* OSVUserDefaults.m in Sources */, CC5CC2761D2BC2AC002963D2 /* OSVMainMenuFactory.m in Sources */, CC881E331C2012A40089CA0B /* OSMParser.m in Sources */, CC0167E71D2EBA8100E8297D /* OSVLocalTrackCell.m in Sources */, + CC4E16871DAD3D570037827E /* OSVPopTransition.m in Sources */, CC19F2E11BAE937B006C8FCC /* OSVSequence.m in Sources */, CC65DF791CA1601400EC3F70 /* FLScanTool.m in Sources */, + CCE754311DDDEA7A007625DD /* OSVRankCell.m in Sources */, CC19F3191BB05FFC006C8FCC /* OSVSequenceCell.m in Sources */, CC410AE71D12B9E9000220BA /* OSVDissmissFullScreenAnimationController.m in Sources */, CC5492DF1C48DA190081AC56 /* OSVUploadViewController.m in Sources */, @@ -2121,10 +2822,12 @@ CC7F06391C6B6D5100441593 /* OSVTrackSyncController.m in Sources */, CC19F2EB1BAF15A1006C8FCC /* OSVServerPhoto.m in Sources */, CC7F06921C6DF46000441593 /* OSVAPISpeedometer.m in Sources */, + CC3692BD1DDC9F3D001EAA1E /* OSVLeaderboardViewController.m in Sources */, + CC92F75B1E0AD75E00427256 /* ScoreManager.swift in Sources */, CC1862151BCF73F900FE0F75 /* AFURLConnectionOperation.m in Sources */, CC92B0A91D377877004F7EF8 /* OSVCloseButton.m in Sources */, - CC91D5D01BFC751E003A6409 /* OSVExpandableCell.m in Sources */, CC1E50521BF2986900BD4A1A /* UIAlertView+Blocks.m in Sources */, + CC4E16831DACE7780037827E /* OSVPushTransition.m in Sources */, CC06B6471C75F71C00E2B0DB /* OSVSegmentedViewCell.m in Sources */, CC92B0961D35674A004F7EF8 /* NSAttributedString+Additions.m in Sources */, CC1862301BCF76E000FE0F75 /* ConnectivityHandler.m in Sources */, @@ -2135,35 +2838,41 @@ CC1862121BCF73F900FE0F75 /* AFJSONRequestOperation.m in Sources */, CCD92BBB1BE7709E002F9341 /* OSVUtils+Image.m in Sources */, CC16AE371CE4892B001EA02A /* OSVVideoPlayerViewController.m in Sources */, + CCE7542D1DDDEA08007625DD /* OSVRankHeaderCell.m in Sources */, + CCCA96A11DA77E9100D32CE7 /* OSVSplashViewController.m in Sources */, CC65DF811CA1601400EC3F70 /* ELM327ResponseParser.m in Sources */, - CC1B3D521D74884700F07098 /* OSVCameraMapManager.m in Sources */, CC0168761D34ED7F00E8297D /* OSVBasicCell.m in Sources */, + CC1E50411BF26B1200BD4A1A /* OSVSettingsMenuFactory.m in Sources */, + CC69145D1D671D19005B6855 /* OSVCameraMapManager.m in Sources */, + CCCDBE4E1DA4FFBD00F367DD /* OBDDevice.m in Sources */, CC92B0A21D3665D9004F7EF8 /* KAProgressLabel.m in Sources */, - CC91D5D31BFDE88E003A6409 /* OSVSequenceSectionHeaderView.m in Sources */, CCC2C64A1BA84F4A00A4CDEE /* OSVCamViewController.m in Sources */, CC2573CF1C003D16000EDB3E /* UIColor+OSVColor.m in Sources */, CC0168721D34EC8700E8297D /* OSVDetailsCell.m in Sources */, + CCD426B51DE44C870006F74B /* OSVGamificationProfileCell.m in Sources */, CC7C6A3F1CF5E01F00C03051 /* CERangeSlider.m in Sources */, - CCE6C45D1C102F12005DC6FF /* OSVGalleryCell.m in Sources */, + CCD426B91DE46A700006F74B /* OSVGamificationInfo.m in Sources */, CC01686E1D34D92D00E8297D /* OSVSectionHeaderCell.m in Sources */, CC881E411C2025440089CA0B /* OSVMetadata.m in Sources */, CC40CEB21D1BF3E60006D619 /* OSVAPI+Mix.m in Sources */, CC40F3A71D13FE840028E488 /* NSFileManager+Godzippa.m in Sources */, CCC2C69A1BA850D900A4CDEE /* OSVPhoto+Relm.m in Sources */, CCF10DA21BF4A3C200A620EF /* OSVSequenceMapController.m in Sources */, - CCF823061C0884DD00E607D9 /* OSVRedButton.m in Sources */, CC0167DE1D2E856100E8297D /* OSVSensorLibManager.mm in Sources */, CC1529201C02618D00BD29DC /* OSVFullScreenImageViewController.m in Sources */, CC09AD7D1C73672100443761 /* UIDevice+Aditions.m in Sources */, CC1E503B1BF209BA00BD4A1A /* OSVMenuItem.m in Sources */, + CC2794711E2CED630085866F /* OSVUtils+Gamification.m in Sources */, CCC2C6391BA84F1A00A4CDEE /* OSVPhoto.m in Sources */, CC19F2D51BAC28C0006C8FCC /* OSVServerPhoto+Convertor.m in Sources */, + CCF0B4861DDB38F900D80961 /* OSVScoreHistory.m in Sources */, CCBE0F101C8DF5CF00A43F37 /* OSVVideoRecorder.m in Sources */, CC18620F1BCF73F900FE0F75 /* AFHTTPClient.m in Sources */, CC1862111BCF73F900FE0F75 /* AFImageRequestOperation.m in Sources */, CC92B0B11D37DC74004F7EF8 /* OSVSlider.m in Sources */, CC1862171BCF73F900FE0F75 /* UIImageView+AFNetworking.m in Sources */, CC9458661BDA32D300DFFD1A /* OSVUtils+FileManager.m in Sources */, + CC7B2AD31DE3061900025B67 /* RLMScoreHistory.m in Sources */, CCC2C6491BA84F4A00A4CDEE /* AVCamViewController.m in Sources */, CCB69D551C3E856D00832788 /* OSVAPIConfigurator.m in Sources */, CC7F06461C6B7E6A00441593 /* OSVSyncUtils.m in Sources */, @@ -2183,18 +2892,23 @@ CC92B0AD1D37C5D4004F7EF8 /* UIView+Additions.m in Sources */, CC7F06491C6B85E400441593 /* OSVTrackCache.m in Sources */, CC881E451C2025440089CA0B /* OSVAPIUtils.m in Sources */, + CC4E167F1DABEFB00037827E /* OSVDissmissRecordTransition.m in Sources */, + CC1E866F1DFB2996002660F4 /* OSVScoreDetailsView.m in Sources */, CCB952D01CE5EAD3006D5BBD /* OSVAPI+Video.m in Sources */, - CC15297B1C039F3100BD29DC /* OSVBaseUser+OSM.m in Sources */, + CC5CADF91E41E38A007AA999 /* UIViewController+Additions.m in Sources */, + CC1E86731DFEB451002660F4 /* OSVTrackMatcher.m in Sources */, CC7A64051CA2FE85007C9F3B /* OSVOBDData.m in Sources */, CC01677E1D2E4CB000E8297D /* OSVInfoCell.m in Sources */, CCC2C68C1BA8506400A4CDEE /* OSVPersistentManager.m in Sources */, + CC59A5991E5DF42700A84996 /* LoginViewController.swift in Sources */, + CC0167E21D2EB0CF00E8297D /* OSVLocalTracksViewController.m in Sources */, CC1529771C039DC500BD29DC /* OSVBaseUser.m in Sources */, - CC1B3D551D74885C00F07098 /* OSVSettingsMenuFactory.m in Sources */, + CC2794751E2D0C2E0085866F /* SummaryViewController.swift in Sources */, CC881E431C2025440089CA0B /* OSVAPI+Sequences.m in Sources */, - CC1FFCE51D58A48300958B8E /* OBDService.m in Sources */, - CCE6C4611C106288005DC6FF /* OSVCropedLabel.m in Sources */, + CCE754361DDE08EE007625DD /* OSVUnderlineButton.m in Sources */, CCBE0F171C8F1D9D00A43F37 /* OSVFullScreenImageCell.m in Sources */, CC0168541D30235D00E8297D /* OSVNavigationController.m in Sources */, + CC27947B1E2E1FD10085866F /* OSVIntroViewController.m in Sources */, CCBBCFE31D1D638700B9104F /* OSVTipPageViewController.m in Sources */, CC97264B1C1634A80034DE96 /* TPPropertyAnimation.m in Sources */, CC65DF7F1CA1601400EC3F70 /* ELM327.m in Sources */, @@ -2204,14 +2918,16 @@ CCC2C63F1BA84F2C00A4CDEE /* RLMPhoto.m in Sources */, CC3937311D2BDBEB00669EFC /* OSVMainMenuCell.m in Sources */, CCFD49971BA02455005B5E9A /* main.m in Sources */, - CCB88C781D830C15000CADD6 /* OSVLocalTracksViewController.m in Sources */, + CC4E167B1DABA36A0037827E /* OSVRecordTransition.m in Sources */, CCDEFA661C88864700A542BA /* OSVSensorsManager.m in Sources */, CC160EA71C5A335A000185D3 /* OSVSliderCell.m in Sources */, CC31DB241C1F0D9D00A0E83D /* OSVReachablityController.m in Sources */, + CC5CADFE1E41F0E6007AA999 /* OSVCameraGamificationManager.m in Sources */, CC0167291D2D647D00E8297D /* OSVMyTracksCell.m in Sources */, CC40CEB61D1BF8250006D619 /* OSVLoginController.m in Sources */, CC881E351C2012A40089CA0B /* OSMAPI.m in Sources */, CC92B09A1D356F19004F7EF8 /* CALayer+XibConfiguration.m in Sources */, + CCEC8A091E38B4510049093A /* PortraitViewController.swift in Sources */, CC3833791D395906005F228B /* OSVUser.m in Sources */, CC92B09E1D362E2A004F7EF8 /* NSMutableAttributedString+Additions.m in Sources */, CCFADD3D1BB309A500A5AAFA /* OSVAPISerialOperation.m in Sources */, @@ -2223,23 +2939,42 @@ CC881E341C2012A40089CA0B /* OSMUser.m in Sources */, CC791E5C1BF0A0E700E5CBD3 /* OSVUploadCell.m in Sources */, CC2573EC1C00570D000EDB3E /* SKSearchResult+Aditions.m in Sources */, + CC7B2AD81DE3092B00025B67 /* OSVScoreHistory+Realm.m in Sources */, CC12FCFA1D51DA1A00EB1177 /* OSVCameraManager.m in Sources */, CC65DF7A1CA1601400EC3F70 /* FLScanToolCommand.m in Sources */, CC65DF851CA1674F00EC3F70 /* OSVOBDController.m in Sources */, CC7C6A411CF5E01F00C03051 /* CERangeSliderTrackLayer.m in Sources */, CC410AE31D12B9C7000220BA /* OSVFullScreenAnimationController.m in Sources */, + CC92F75F1E0C147700427256 /* ScoreHistory.swift in Sources */, CC7F064C1C6C877500441593 /* OSVTrackLogger.m in Sources */, CC1862181BCF73F900FE0F75 /* AFOAuth1Client.m in Sources */, CC1862101BCF73F900FE0F75 /* AFHTTPRequestOperation.m in Sources */, CC225EC51D227A65000EC04C /* OSVDotedPolyline.m in Sources */, CC7F06521C6CD9D300441593 /* OSVLogItem.m in Sources */, - CC1FFCE71D58A48300958B8E /* OBDDevice.m in Sources */, CCC2C68F1BA8506400A4CDEE /* OSVUtils.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; + CCFF578C1E44D0960031B8BE /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + CCFF579F1E44D6170031B8BE /* OSVUtils.m in Sources */, + CCFF57931E44D0960031B8BE /* OSCTests.m in Sources */, + CCFF57A01E44D7000031B8BE /* OSVUtils+Location.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXSourcesBuildPhase section */ +/* Begin PBXTargetDependency section */ + CCFF57961E44D0960031B8BE /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = CCFD49901BA02455005B5E9A /* OpenStreetView */; + targetProxy = CCFF57951E44D0960031B8BE /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + /* Begin PBXVariantGroup section */ CCFD499E1BA02455005B5E9A /* Main.storyboard */ = { isa = PBXVariantGroup; @@ -2263,11 +2998,184 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ + CC92F74C1E095E5C00427256 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", + "$(inherited)", + "BUILD_ROOT=@\\\"\"$(BUILD_ROOT)\"\\\"", + "kOSCGoogleClientID=\\@\\\"\\\"", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = OpenStreetView/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OpenStreetView", + "$(PROJECT_DIR)", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); + OTHER_LIBTOOLFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OpenStreetView; + PRODUCT_MODULE_NAME = OSC; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Debug; + }; + CC92F74D1E095E5C00427256 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", + "$(inherited)", + "kOSCGoogleClientID=\\@\\\"\\\"", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = OpenStreetView/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OpenStreetView", + "$(PROJECT_DIR)", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); + OTHER_LIBTOOLFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.telenav.OpenStreetView; + PRODUCT_MODULE_NAME = OSC; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Release; + }; + CC92F74E1E095E5C00427256 /* Enterprise */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", + "$(inherited)", + "kOSCGoogleClientID=\\@\\\"\\\"", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = OpenStreetView/InfoEnterprise.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OpenStreetView", + "$(PROJECT_DIR)", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); + OTHER_LIBTOOLFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OpenStreetView; + PRODUCT_MODULE_NAME = OSC; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Enterprise; + }; + CC92F74F1E095E5C00427256 /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; + FRAMEWORK_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", + "$(inherited)", + RELEASE, + "kOSCGoogleClientID=\\@\\\"\\\"", + ); + HEADER_SEARCH_PATHS = "$(inherited)"; + INFOPLIST_FILE = OpenStreetView/InfoBeta.plist; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)/OpenStreetView", + "$(PROJECT_DIR)", + ); + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); + OTHER_LIBTOOLFLAGS = ""; + PRODUCT_BUNDLE_IDENTIFIER = com.telenav.OpenStreetView; + PRODUCT_MODULE_NAME = OSC; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h"; + SWIFT_VERSION = 3.0; + TARGETED_DEVICE_FAMILY = 1; + }; + name = Beta; + }; CCA16C1C1C92D18B001EEB57 /* Beta */ = { isa = XCBuildConfiguration; baseConfigurationReference = CCF822971C05B0C700E607D9 /* Config.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -2277,8 +3185,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: skobbler GmbH (Ent)"; @@ -2297,7 +3207,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/include"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = ""; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-objC"; @@ -2309,21 +3219,22 @@ }; CCA16C1D1C92D18B001EEB57 /* Beta */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 918840F1F96F2026A7C60A46 /* Pods-OpenStreetView.beta.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Telenav GmbH (2BF96UN6UZ)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", RELEASE, + DONT_USE_ORBB, + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/InfoBeta.plist; @@ -2333,33 +3244,39 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.telenav.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "e8ca2ea0-21cd-416b-b469-b5cdfe1f57e5"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetView-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Beta; }; CCA16CB21C92F64B001EEB57 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = BCCC682778267DD5632A0C68 /* Pods-OpenStreetViewRelease.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + DEVELOPMENT_TEAM = F86PKNGLDF; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", "BUILD_ROOT=@\\\"\"$(BUILD_ROOT)\"\\\"", + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/Info.plist; @@ -2369,32 +3286,39 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = ""; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = "6eabd413-5b5f-4afd-a9dd-d6a6a0c4fa24"; + PROVISIONING_PROFILE_SPECIFIER = OpenStreetViewEnterprise; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetViewRelease-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; CCA16CB31C92F64B001EEB57 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 61065ED006F711614BE2E2D3 /* Pods-OpenStreetViewRelease.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + DEVELOPMENT_TEAM = 2BF96UN6UZ; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/Info.plist; @@ -2404,33 +3328,38 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.telenav.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "79955e22-e9b6-445b-bdec-76c5b07289cb"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = "47af54d8-d41f-4790-bc8f-cb58ca56765c"; + PROVISIONING_PROFILE_SPECIFIER = "XC iOS: com.telenav.OpenStreetView"; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetViewRelease-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; CCA16CB41C92F64B001EEB57 /* Enterprise */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 244418F01B0BB9BE8E5468A5 /* Pods-OpenStreetViewRelease.enterprise.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: skobbler GmbH (Ent)"; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + DEVELOPMENT_TEAM = F86PKNGLDF; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/InfoEnterprise.plist; @@ -2440,34 +3369,39 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "a6602be9-6f47-4f8d-9837-a5d49b2b0043"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = "6eabd413-5b5f-4afd-a9dd-d6a6a0c4fa24"; + PROVISIONING_PROFILE_SPECIFIER = OpenStreetViewEnterprise; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetViewRelease-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Enterprise; }; CCA16CB51C92F64B001EEB57 /* Beta */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B5994CEE8F0652F6972FCE4A /* Pods-OpenStreetViewRelease.beta.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: Telenav GmbH (2BF96UN6UZ)"; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution"; + DEVELOPMENT_TEAM = 2BF96UN6UZ; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", RELEASE, + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/InfoBeta.plist; @@ -2477,13 +3411,18 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.telenav.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "79955e22-e9b6-445b-bdec-76c5b07289cb"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = "47af54d8-d41f-4790-bc8f-cb58ca56765c"; + PROVISIONING_PROFILE_SPECIFIER = "XC iOS: com.telenav.OpenStreetView"; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetViewRelease-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Beta; @@ -2492,7 +3431,9 @@ isa = XCBuildConfiguration; baseConfigurationReference = CCF822971C05B0C700E607D9 /* Config.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -2502,8 +3443,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: skobbler GmbH (Ent)"; @@ -2521,7 +3464,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/include"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = ""; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-objC"; @@ -2533,20 +3476,21 @@ }; CCC2C69D1BA86E1D00A4CDEE /* Enterprise */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 76EFDE20412EDAEF4D2AEAC5 /* Pods-OpenStreetView.enterprise.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CODE_SIGN_IDENTITY = "iPhone Developer"; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: skobbler GmbH (Ent)"; + CLANG_ENABLE_MODULES = YES; + CODE_SIGN_IDENTITY = "iPhone Distribution"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", + DONT_USE_ORBB, + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/InfoEnterprise.plist; @@ -2556,13 +3500,18 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "a6602be9-6f47-4f8d-9837-a5d49b2b0043"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetView-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Enterprise; @@ -2571,7 +3520,9 @@ isa = XCBuildConfiguration; baseConfigurationReference = CCF822971C05B0C700E607D9 /* Config.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -2581,8 +3532,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; @@ -2608,7 +3561,7 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/include"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = ""; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; @@ -2622,7 +3575,9 @@ isa = XCBuildConfiguration; baseConfigurationReference = CCF822971C05B0C700E607D9 /* Config.xcconfig */; buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = NO; ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -2632,8 +3587,10 @@ CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_SUSPICIOUS_MOVE = YES; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; @@ -2651,11 +3608,12 @@ GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = "$(SRCROOT)/include"; - IPHONEOS_DEPLOYMENT_TARGET = 7.0; + IPHONEOS_DEPLOYMENT_TARGET = 8.0; LIBRARY_SEARCH_PATHS = ""; MTL_ENABLE_DEBUG_INFO = NO; OTHER_LDFLAGS = "-objC"; SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; }; @@ -2663,21 +3621,22 @@ }; CCFD49B51BA02455005B5E9A /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 568DA0768A3FBE3F9CED9C76 /* Pods-OpenStreetView.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", "BUILD_ROOT=@\\\"\"$(BUILD_ROOT)\"\\\"", + DONT_USE_ORBB, + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/Info.plist; @@ -2687,32 +3646,40 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "f506cc43-281e-4faf-804c-83213bae87d1"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetView-Bridging-Header.h"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Debug; }; CCFD49B61BA02455005B5E9A /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = D3A9DC100926C3AD8E6C6DA0 /* Pods-OpenStreetView.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ENABLE_MODULES = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + DEVELOPMENT_TEAM = F86PKNGLDF; FRAMEWORK_SEARCH_PATHS = ( "$(inherited)", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/Pods/Crashlytics/iOS", - "$(PROJECT_DIR)/Pods/Fabric/iOS", ); GCC_PREPROCESSOR_DEFINITIONS = ( "PROJECT_DIR=@\\\"\"$PROJECT_DIR\"\\\"", "$(inherited)", + DONT_USE_ORBB, + "kOSCGoogleClientID=\\@\\\"\\\"", ); HEADER_SEARCH_PATHS = "$(inherited)"; INFOPLIST_FILE = OpenStreetView/Info.plist; @@ -2722,20 +3689,101 @@ "$(inherited)", "$(PROJECT_DIR)/OpenStreetView", "$(PROJECT_DIR)", - "$(PROJECT_DIR)/lib", ); - OTHER_LDFLAGS = "-ObjC"; + OTHER_LDFLAGS = ( + "-ObjC", + "$(inherited)", + ); OTHER_LIBTOOLFLAGS = ""; PRODUCT_BUNDLE_IDENTIFIER = com.telenav.OpenStreetView; - PRODUCT_NAME = OSV; - PROVISIONING_PROFILE = "e8ca2ea0-21cd-416b-b469-b5cdfe1f57e5"; + PRODUCT_NAME = OSC; + PROVISIONING_PROFILE = ""; + PROVISIONING_PROFILE_SPECIFIER = ""; + SWIFT_OBJC_BRIDGING_HEADER = "OpenStreetView/OpenStreetView-Bridging-Header.h"; + SWIFT_VERSION = 3.0; TARGETED_DEVICE_FAMILY = 1; }; name = Release; }; + CCFF57971E44D0960031B8BE /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = F86PKNGLDF; + INFOPLIST_FILE = OSCTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OSCTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OSC.app/OSC"; + }; + name = Debug; + }; + CCFF57981E44D0960031B8BE /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + DEVELOPMENT_TEAM = F86PKNGLDF; + INFOPLIST_FILE = OSCTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OSCTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OSC.app/OSC"; + }; + name = Release; + }; + CCFF57991E44D0960031B8BE /* Enterprise */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + DEVELOPMENT_TEAM = F86PKNGLDF; + INFOPLIST_FILE = OSCTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OSCTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OSC.app/OSC"; + }; + name = Enterprise; + }; + CCFF579A1E44D0960031B8BE /* Beta */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + DEVELOPMENT_TEAM = F86PKNGLDF; + INFOPLIST_FILE = OSCTests/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 10.2; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_BUNDLE_IDENTIFIER = com.skobbler.OSCTests; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/OSC.app/OSC"; + }; + name = Beta; + }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ + CC92F74B1E095E5C00427256 /* Build configuration list for PBXNativeTarget "OSC_ORBB_Dev" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CC92F74C1E095E5C00427256 /* Debug */, + CC92F74D1E095E5C00427256 /* Release */, + CC92F74E1E095E5C00427256 /* Enterprise */, + CC92F74F1E095E5C00427256 /* Beta */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; CCA16CB11C92F64B001EEB57 /* Build configuration list for PBXNativeTarget "OpenStreetViewRelease" */ = { isa = XCConfigurationList; buildConfigurations = ( @@ -2769,6 +3817,17 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; + CCFF579B1E44D0960031B8BE /* Build configuration list for PBXNativeTarget "OSCTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + CCFF57971E44D0960031B8BE /* Debug */, + CCFF57981E44D0960031B8BE /* Release */, + CCFF57991E44D0960031B8BE /* Enterprise */, + CCFF579A1E44D0960031B8BE /* Beta */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; /* End XCConfigurationList section */ }; rootObject = CCFD49891BA02455005B5E9A /* Project object */; diff --git a/OpenStreetView.xcodeproj/project.xcworkspace/xcshareddata/OpenStreetView.xcscmblueprint b/OpenStreetView.xcodeproj/project.xcworkspace/xcshareddata/OpenStreetView.xcscmblueprint deleted file mode 100644 index 63729da..0000000 --- a/OpenStreetView.xcodeproj/project.xcworkspace/xcshareddata/OpenStreetView.xcscmblueprint +++ /dev/null @@ -1,25 +0,0 @@ -{ - "DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "b83d054a-0364-4dbc-b21a-410ba2f1b1d5", - "DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : { - "b83d054a-0364-4dbc-b21a-410ba2f1b1d5" : { - - } - }, - "DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : { - "b83d054a-0364-4dbc-b21a-410ba2f1b1d5" : 0 - }, - "DVTSourceControlWorkspaceBlueprintIdentifierKey" : "913A63F1-3EC2-4341-846C-227865D31FB8", - "DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : { - "b83d054a-0364-4dbc-b21a-410ba2f1b1d5" : "OpenStreetViewReleaseBrach\/" - }, - "DVTSourceControlWorkspaceBlueprintNameKey" : "OpenStreetView", - "DVTSourceControlWorkspaceBlueprintVersion" : 204, - "DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "trunk\/OpenStreetView.xcodeproj", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [ - { - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "svn:\/\/bogdan.sala@svn-srv\/OpenStreetView", - "DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Subversion", - "DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "b83d054a-0364-4dbc-b21a-410ba2f1b1d5" - } - ] -} \ No newline at end of file diff --git a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OSC_ORBB_Dev.xcscheme b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OSC_ORBB_Dev.xcscheme new file mode 100644 index 0000000..9458f1b --- /dev/null +++ b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OSC_ORBB_Dev.xcscheme @@ -0,0 +1,91 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetView.xcscheme b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetView.xcscheme index f45e4f6..a1f82f9 100644 --- a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetView.xcscheme +++ b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetView.xcscheme @@ -1,6 +1,6 @@ @@ -28,12 +28,22 @@ selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" shouldUseLaunchSchemeArgsEnv = "YES"> + + + + @@ -56,7 +66,7 @@ @@ -65,7 +75,7 @@ @@ -85,7 +95,7 @@ buildConfiguration = "Debug"> diff --git a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetViewRelease.xcscheme b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetViewRelease.xcscheme index 1247b07..911afad 100644 --- a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetViewRelease.xcscheme +++ b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/OpenStreetViewRelease.xcscheme @@ -1,6 +1,6 @@ @@ -33,7 +33,7 @@ @@ -56,7 +56,7 @@ @@ -75,7 +75,7 @@ diff --git a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/xcschememanagement.plist b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/xcschememanagement.plist index 1a1278e..698a8b2 100644 --- a/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/xcschememanagement.plist +++ b/OpenStreetView.xcodeproj/xcuserdata/bogdansala.xcuserdatad/xcschemes/xcschememanagement.plist @@ -4,6 +4,11 @@ SchemeUserState + OSC_ORBB_Dev.xcscheme + + orderHint + 2 + OpenStreetView.xcscheme orderHint @@ -17,6 +22,11 @@ SuppressBuildableAutocreation + CC92F6771E095E5C00427256 + + primary + + CCA16C241C92F64B001EEB57 primary @@ -27,6 +37,11 @@ primary + CCFF578F1E44D0960031B8BE + + primary + + diff --git a/OpenStreetView.xcworkspace/contents.xcworkspacedata b/OpenStreetView.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..6334fd5 --- /dev/null +++ b/OpenStreetView.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/OpenStreetView/.pb.cc b/OpenStreetView/.pb.cc new file mode 100644 index 0000000..212224e --- /dev/null +++ b/OpenStreetView/.pb.cc @@ -0,0 +1,94 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: + +#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION +#include ".pb.h" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +// @@protoc_insertion_point(includes) + +namespace protobuf_ { + + +namespace { + + +} // namespace + +const ::google::protobuf::uint32 TableStruct::offsets[] = { ~0u }; +static const ::google::protobuf::internal::MigrationSchema* schemas = NULL; +static const ::google::protobuf::Message* const* file_default_instances = NULL; +namespace { + +void protobuf_AssignDescriptors() { + AddDescriptors(); + ::google::protobuf::MessageFactory* factory = NULL; + AssignDescriptors( + "", schemas, file_default_instances, TableStruct::offsets, factory, + NULL, NULL, NULL); +} + +void protobuf_AssignDescriptorsOnce() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &protobuf_AssignDescriptors); +} + +void protobuf_RegisterTypes(const ::std::string&) GOOGLE_ATTRIBUTE_COLD; +void protobuf_RegisterTypes(const ::std::string&) { + protobuf_AssignDescriptorsOnce(); +} + +} // namespace + +void TableStruct::Shutdown() { +} + +void TableStruct::InitDefaultsImpl() { + GOOGLE_PROTOBUF_VERIFY_VERSION; + + ::google::protobuf::internal::InitProtobufDefaults(); +} + +void InitDefaults() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &TableStruct::InitDefaultsImpl); +} +void AddDescriptorsImpl() { + InitDefaults(); + static const char descriptor[] = { + "\n\000" + }; + ::google::protobuf::DescriptorPool::InternalAddGeneratedFile( + descriptor, 2); + ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile( + "", &protobuf_RegisterTypes); + ::google::protobuf::internal::OnShutdown(&TableStruct::Shutdown); +} + +void AddDescriptors() { + static GOOGLE_PROTOBUF_DECLARE_ONCE(once); + ::google::protobuf::GoogleOnceInit(&once, &AddDescriptorsImpl); +} +// Force AddDescriptors() to be called at static initialization time. +struct StaticDescriptorInitializer { + StaticDescriptorInitializer() { + AddDescriptors(); + } +} static_descriptor_initializer; + +} // namespace protobuf_ + + +// @@protoc_insertion_point(namespace_scope) + +// @@protoc_insertion_point(global_scope) diff --git a/OpenStreetView/.pb.h b/OpenStreetView/.pb.h new file mode 100644 index 0000000..47909bb --- /dev/null +++ b/OpenStreetView/.pb.h @@ -0,0 +1,58 @@ +// Generated by the protocol buffer compiler. DO NOT EDIT! +// source: + +#ifndef PROTOBUF___INCLUDED +#define PROTOBUF___INCLUDED + +#include + +#include + +#if GOOGLE_PROTOBUF_VERSION < 3002000 +#error This file was generated by a newer version of protoc which is +#error incompatible with your Protocol Buffer headers. Please update +#error your headers. +#endif +#if 3002000 < GOOGLE_PROTOBUF_MIN_PROTOC_VERSION +#error This file was generated by an older version of protoc which is +#error incompatible with your Protocol Buffer headers. Please +#error regenerate this file with a newer version of protoc. +#endif + +#include +#include +#include +#include +#include +#include // IWYU pragma: export +#include // IWYU pragma: export +// @@protoc_insertion_point(includes) + +namespace protobuf_ { +// Internal implementation detail -- do not call these. +struct TableStruct { + static const ::google::protobuf::uint32 offsets[]; + static void InitDefaultsImpl(); + static void Shutdown(); +}; +void AddDescriptors(); +void InitDefaults(); +} // namespace protobuf_ + +// =================================================================== + + +// =================================================================== + + +// =================================================================== + +#if !PROTOBUF_INLINE_NOT_IN_HEADERS +#endif // !PROTOBUF_INLINE_NOT_IN_HEADERS + +// @@protoc_insertion_point(namespace_scope) + + +// @@protoc_insertion_point(global_scope) + +#endif // PROTOBUF___INCLUDED diff --git a/OpenStreetView/AppDelegate.m b/OpenStreetView/AppDelegate.m index d5426c5..0fba663 100644 --- a/OpenStreetView/AppDelegate.m +++ b/OpenStreetView/AppDelegate.m @@ -12,6 +12,10 @@ #import #import #import +#import +#import +#import + #import "OSVLocationManager.h" #import "OSVSyncController.h" @@ -20,19 +24,30 @@ #import "UIAlertView+Blocks.h" #import "OSVReachablityController.h" +#import "OSVLocalNotificationsController.h" #import "OSVUser.h" -@interface AppDelegate () +#import "OSVUtils.h" + +@interface AppDelegate () @end @implementation AppDelegate - - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + + UILocalNotification *localNotification = [launchOptions objectForKey:UIApplicationLaunchOptionsLocalNotificationKey]; + + if (localNotification) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [OSVLocalNotificationsController handleNotification:localNotification application:application]; + }); + } + [Fabric with:@[[Crashlytics class]]]; - NSString *username = [OSVSyncController sharedInstance].tracksController.user.name; + NSString *username = [OSVSyncController sharedInstance].tracksController.oscUser.name; if (username) { [CrashlyticsKit setUserName:username]; } @@ -43,13 +58,22 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( } }]; - SKMapsInitSettings *mapsettings = [SKMapsInitSettings mapsInitSettings]; + if ([OSVUserDefaults sharedInstance].enableMap) { + SKMapsInitSettings *mapsettings = [SKMapsInitSettings mapsInitSettings]; + mapsettings.mapStyle.resourcesFolderName = @"GrayscaleStyle"; + mapsettings.mapStyle.styleFileName = @"grayscalestyle.json"; + if ([OSVUtils isHighDensity]) { + } else { + } + + [[SKMapsService sharedInstance] initializeSKMapsWithAPIKey:@"" settings:mapsettings]; + [SKMapsService sharedInstance].tilesCacheManager.cacheLimit = 100 * 1024 * 1024; + } - [[SKMapsService sharedInstance] initializeSKMapsWithAPIKey:@"47c0589b94694c04e757f6c36157f13b21d30d051d662b7c8034bf3988bd9843" settings:mapsettings]; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingOBD]; + [[OSVSensorsManager sharedInstance] startUpdatingOBD]; if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined) { - [[SKPositionerService sharedInstance] startLocationUpdate]; + [[OSVLocationManager sharedInstance] startLocationUpdate]; } if ([OSVUserDefaults sharedInstance].isUploading && ![OSVUserDefaults sharedInstance].automaticUpload) { @@ -73,18 +97,26 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:( }]; } - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ [[OSVSyncController sharedInstance].tracksController finishUploadingEmptySequencesWithCompletionBlock:^(NSError *error) { }]; }); - + + [GIDSignIn sharedInstance].clientID = kOSCGoogleClientID; + [GIDSignIn sharedInstance].delegate = self; + + if ([[GIDSignIn sharedInstance] hasAuthInKeychain]) { + [[GIDSignIn sharedInstance] signInSilently]; + } + + [[FBSDKApplicationDelegate sharedInstance] application:application + didFinishLaunchingWithOptions:launchOptions]; + return YES; } -- (void)applicationWillResignActive:(UIApplication *)application { - // 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game. +- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notification { + [OSVLocalNotificationsController handleNotification:notification application:application]; } - (void)applicationDidEnterBackground:(UIApplication *)application { @@ -109,7 +141,7 @@ - (void)applicationWillEnterForeground:(UIApplication *)application { } }]; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingOBD]; + [[OSVSensorsManager sharedInstance] startUpdatingOBD]; if (([OSVReachablityController hasWiFiAccess] || [OSVReachablityController hasCellularAcces]) && [OSVUserDefaults sharedInstance].automaticUpload && [OSVSyncUtils hasInternetPermissions] && @@ -121,18 +153,15 @@ - (void)applicationWillEnterForeground:(UIApplication *)application { } } -- (void)applicationDidBecomeActive:(UIApplication *)application { - // 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. -} - -- (void)applicationWillTerminate:(UIApplication *)application { - // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { + return [self handleOpenURL:url forApplication:application + sourceApplication:sourceApplication annotation:annotation]; } -- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { - [[NSNotificationCenter defaultCenter] postNotificationName:kAFApplicationLaunchedWithURLNotification object:@{kAFApplicationLaunchOptionsURLKey:url}]; - - return NO; +- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { + return [self handleOpenURL:url forApplication:app + sourceApplication:options[UIApplicationOpenURLOptionsSourceApplicationKey] + annotation:options[UIApplicationOpenURLOptionsAnnotationKey]]; } - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)())completionHandler { @@ -142,5 +171,31 @@ - (void)application:(UIApplication *)application handleEventsForBackgroundURLSes - (UIInterfaceOrientationMask)application:(UIApplication *)application supportedInterfaceOrientationsForWindow:(UIWindow *)window { return [window.rootViewController supportedInterfaceOrientations]; } + +#pragma mark - GIDSignInDelegate + +- (void)signIn:(GIDSignIn *)signIn didSignInForUser:(GIDGoogleUser *)user withError:(NSError *)error { + + if (user) { + [[NSNotificationCenter defaultCenter] postNotificationName:@"kOSVGoogleSignIn" object:nil userInfo:@{@"user":user}]; + } +} + +#pragma mark - URL handle +- (BOOL)handleOpenURL:(NSURL *)url forApplication:(UIApplication *)application sourceApplication:(NSString *)sourceApplication annotation:(id)annotation { + [[NSNotificationCenter defaultCenter] postNotificationName:kAFApplicationLaunchedWithURLNotification object:@{kAFApplicationLaunchOptionsURLKey:url}]; + + BOOL facebookHandled = [[FBSDKApplicationDelegate sharedInstance] application:application + openURL:url + sourceApplication:sourceApplication + annotation:annotation]; + BOOL googleHandled = [[GIDSignIn sharedInstance] handleURL:url + sourceApplication:sourceApplication + annotation:annotation]; + BOOL osmHandled = [url.absoluteString containsString:@"osmlogin"]; + + return facebookHandled||googleHandled||osmHandled; +} + @end diff --git a/OpenStreetView/Base.lproj/LaunchScreen.xib b/OpenStreetView/Base.lproj/LaunchScreen.xib index 57c7dab..2e12a72 100644 --- a/OpenStreetView/Base.lproj/LaunchScreen.xib +++ b/OpenStreetView/Base.lproj/LaunchScreen.xib @@ -1,10 +1,11 @@ - + - + + @@ -14,13 +15,12 @@ - - + diff --git a/OpenStreetView/Base.lproj/Main.storyboard b/OpenStreetView/Base.lproj/Main.storyboard index 4bfdaf3..c87f622 100644 --- a/OpenStreetView/Base.lproj/Main.storyboard +++ b/OpenStreetView/Base.lproj/Main.storyboard @@ -1,12 +1,17 @@ - - + + + + + - + + + @@ -18,36 +23,176 @@ - + - + - - + + - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - + + @@ -75,7 +220,7 @@ - - + + - + + + + + + @@ -135,6 +285,8 @@ + + @@ -146,6 +298,8 @@ + + @@ -158,18 +312,22 @@ + + + + - + - - - + + + - - - + + - - + + - - + + - - + + - - + @@ -270,31 +428,31 @@ - - + + - - + + - - + + - - + @@ -348,9 +506,9 @@ - - - + + + @@ -369,35 +527,35 @@ - - - + + + - - + + - - + + - - + + - - + @@ -453,7 +611,7 @@ - + @@ -517,13 +675,13 @@ - - + + @@ -539,10 +697,6 @@ - - - - @@ -552,6 +706,10 @@ + + + + @@ -568,7 +726,7 @@ - + @@ -597,34 +755,34 @@ + + - - - - - + + - - + + + - - + @@ -736,14 +891,14 @@ - + - + @@ -761,8 +916,6 @@ - - @@ -771,15 +924,17 @@ + + - + @@ -793,21 +948,23 @@ - - + + + + - + @@ -819,11 +976,30 @@ + + + + + + + + + + + + + + + + + + + @@ -844,138 +1020,453 @@ + + + + + + + + + + - + - - + + - + - - + + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - + + - - - - - + + - - + + @@ -1025,7 +1516,7 @@ - + @@ -1040,7 +1531,7 @@ - @@ -1525,11 +2149,12 @@ + - + @@ -1540,28 +2165,28 @@ - + - - - + + + - - + + - + - + - + - + @@ -1578,13 +2203,13 @@ - + - + @@ -1592,7 +2217,7 @@ - + @@ -1601,18 +2226,18 @@ - + @@ -1631,21 +2256,21 @@ - + - + @@ -1667,18 +2292,18 @@ - - + + - + @@ -1731,7 +2356,7 @@ - + @@ -1742,7 +2367,7 @@ + @@ -2088,8 +2715,13 @@ + + + + + - + @@ -2100,35 +2732,35 @@ - + - - + + - + - + - - + + - + @@ -2154,11 +2786,11 @@ - + @@ -2171,7 +2803,7 @@ @@ -2199,7 +2831,7 @@ - + @@ -2210,18 +2842,18 @@ - + - + + + + + - + @@ -2330,11 +2954,35 @@ + + + + + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + @@ -2501,191 +3148,212 @@ - - - - + + - + - - @@ -2696,12 +3364,25 @@ - + - - - + + + + + + + + + + + + + + + + - - + + - - + + - - - - - - + + + + - - - - - + + - - + + - - + + - - + + - + @@ -2845,6 +3505,7 @@ + @@ -2866,108 +3527,393 @@ - - + + + + + + + + + + - - + + - + - - + + - + + + + + + + + + + + + + + + + + + + - + - + + + + + + + + + + + + + + + + + - - + + + + - - + + + + + + - + @@ -2975,39 +3921,283 @@ + + + + + + + + + + + + + + + + + + + + - - + + - + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3018,12 +4208,12 @@ - + - - - + + + @@ -3032,12 +4222,11 @@ - + - @@ -3046,8 +4235,8 @@ - - + @@ -3075,7 +4264,7 @@ - + @@ -3086,9 +4275,9 @@ - + - + @@ -3104,18 +4293,18 @@ - + - - - + + + - + - + @@ -3126,7 +4315,7 @@ - + @@ -3138,9 +4327,9 @@ @@ -3168,39 +4357,39 @@ - + - - + + - + - + - + - + - + @@ -3228,7 +4417,7 @@ - + @@ -3253,6 +4442,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -3262,12 +4486,12 @@ - + - - + + @@ -3285,8 +4509,8 @@ - - + + @@ -3301,13 +4525,13 @@ - - + + - + @@ -3316,7 +4540,7 @@ - + @@ -3329,21 +4553,18 @@ - - - @@ -3389,9 +4607,10 @@ + - - - + - + + + @@ -3428,7 +4647,7 @@ - + @@ -3438,7 +4657,7 @@ - + @@ -3451,21 +4670,29 @@ + + + + + + + + @@ -3481,8 +4708,8 @@ - - - + + + diff --git a/OpenStreetView/BuisnessLogic/OSVLocationManager.h b/OpenStreetView/BuisnessLogic/OSVLocationManager.h index 8531fe4..f5ecc3c 100644 --- a/OpenStreetView/BuisnessLogic/OSVLocationManager.h +++ b/OpenStreetView/BuisnessLogic/OSVLocationManager.h @@ -8,6 +8,7 @@ #import #import "OSVSensorsManager.h" +#import @protocol CLLocationManagerDelegate; @class CLLocation; @@ -16,14 +17,17 @@ @property (weak, nonatomic) id delegate; @property (assign, nonatomic) BOOL realPositions; -@property (strong, nonatomic) OSVSensorsManager *sensorsManager; -@property (strong, nonatomic, readonly) CLLocation *currentLocation; +@property (assign, nonatomic) SKPositionerMode positionerMode; + (instancetype)sharedInstance; -- (void)startUpdatingLocation; -- (void)startUpdatingHeading; +- (CLLocation *)currentMatchedPosition; +- (CLLocation *)currentLocation; + +- (void)startLocationUpdate; +- (void)cancelLocationUpdate; +- (void)reportGPSLocation:(CLLocation *)location; @end diff --git a/OpenStreetView/BuisnessLogic/OSVLocationManager.m b/OpenStreetView/BuisnessLogic/OSVLocationManager.m index e955b36..03f5230 100644 --- a/OpenStreetView/BuisnessLogic/OSVLocationManager.m +++ b/OpenStreetView/BuisnessLogic/OSVLocationManager.m @@ -16,7 +16,8 @@ @interface OSVLocationManager () -@property (nonatomic, strong) CLLocation *currentLocation; +@property (nonatomic, strong) CLLocation *firstLocation; +@property (nonatomic, strong) CLLocationManager *locationManager; @end @@ -38,9 +39,12 @@ - (instancetype)init { if (self) { self.realPositions = [OSVUserDefaults sharedInstance].realPositions; - [SKPositionerService sharedInstance].delegate = self; - - self.sensorsManager = [OSVSensorsManager new]; + if ([OSVUserDefaults sharedInstance].enableMap) { + [SKPositionerService sharedInstance].delegate = self; + } else { + self.locationManager = [CLLocationManager new]; + self.locationManager.delegate = self; + } } return self; @@ -51,23 +55,14 @@ - (void)positionerService:(SKPositionerService *)positionerService updatedCurren return; } - if (!self.currentLocation) { - if ([OSVUserDefaults sharedInstance].automaticDistanceUnitSystem) { - [OSVUserDefaults sharedInstance].distanceUnitSystem = [OSVUtils isUSCoordinate:currentLocation.coordinate] ? kImperialSystem : kMetricSystem; - } - self.currentLocation = currentLocation; - } - - [self.delegate locationManager:(CLLocationManager *)self didUpdateLocations:@[currentLocation]]; - - self.currentLocation = currentLocation; + + [self sendLocationToDelegate:@[currentLocation]]; } - (void)positionerService:(SKPositionerService *)positionerService updatedCurrentHeading:(CLHeading *)currentHeading { OSVLogItem *item = [OSVLogItem new]; item.heading = currentHeading; - item.timestamp = [[NSDate new] timeIntervalSince1970]; - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; + [[OSVSyncController sharedInstance].logger logItem:item]; } - (void)positionerService:(SKPositionerService *)positionerService changedGPSAccuracyToLevel:(SKGPSAccuracyLevel)level { @@ -90,24 +85,122 @@ - (void)positionerService:(SKPositionerService *)positionerService didFailToRetr } -#pragma mark - Public +#pragma mark - CllocationDelegate -- (void)startUpdatingLocation { - [[SKPositionerService sharedInstance] startLocationUpdate]; - [self refreshSimulationDelegate]; +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)newLocationArray { + [self sendLocationToDelegate:newLocationArray]; } -- (void)startUpdatingHeading { - [self refreshSimulationDelegate]; +- (void)locationManager:(CLLocationManager *)manager didUpdateHeading:(CLHeading *)newHeading { + OSVLogItem *item = [OSVLogItem new]; + item.heading = newHeading; + [[OSVSyncController sharedInstance].logger logItem:item]; } +- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { + [[NSNotificationCenter defaultCenter] postNotificationName:@"didChangeAuthorizationStatus" object:nil userInfo:@{@"status":@(status)}]; +} +#pragma mark - Public + - (void)setRealPositions:(BOOL)realPositions { _realPositions = realPositions; - [self refreshSimulationDelegate]; } -- (void)refreshSimulationDelegate { +- (CLLocation *)currentMatchedPosition { + if ([OSVUserDefaults sharedInstance].enableMap) { + SKPosition matchedPosition = [SKPositionerService sharedInstance].currentMatchedPosition; + return [[CLLocation alloc] initWithLatitude:matchedPosition.latY longitude:matchedPosition.lonX]; + } else { + return self.locationManager.location; + } +} + +- (CLLocation *)currentLocation { + if ([OSVUserDefaults sharedInstance].enableMap) { + CLLocationCoordinate2D coordinate = [SKPositionerService sharedInstance].currentCoordinate; + return [[CLLocation alloc] initWithLatitude:coordinate.latitude longitude:coordinate.longitude]; + } else { + return self.locationManager.location; + } +} + +- (void)startLocationUpdate { + if ([OSVUserDefaults sharedInstance].enableMap) { + [[SKPositionerService sharedInstance] startLocationUpdate]; + } else { + [self.locationManager startUpdatingLocation]; + } +} + +- (void)cancelLocationUpdate { + if ([OSVUserDefaults sharedInstance].enableMap) { + [[SKPositionerService sharedInstance] cancelLocationUpdate]; + } else { + [self.locationManager stopUpdatingLocation]; + } +} + +- (void)setPositionerMode:(SKPositionerMode)positionerMode { + if ([OSVUserDefaults sharedInstance].enableMap) { + [[SKPositionerService sharedInstance] setPositionerMode:positionerMode]; + } +} + +- (void)reportGPSLocation:(CLLocation *)location { + if ([OSVUserDefaults sharedInstance].enableMap) { + [[SKPositionerService sharedInstance] reportGPSLocation:location]; + } +} + +- (void)sendLocationToDelegate:(NSArray *)currentLocations { + CLLocation *currentLocation = currentLocations.lastObject; + if (!self.firstLocation && + currentLocation.coordinate.latitude != 0.0 && + currentLocation.coordinate.longitude != 0.0) { + self.firstLocation = currentLocation; + if ([OSVUserDefaults sharedInstance].automaticDistanceUnitSystem) { + [OSVUserDefaults sharedInstance].distanceUnitSystem = [OSVUtils isUSCoordinate:currentLocation.coordinate] ? kImperialSystem : kMetricSystem; + } + } + + NSInteger debugLocationAccuracy = [OSVUserDefaults sharedInstance].debugLocationAccuracy; + if (debugLocationAccuracy) { + CLLocation *debugLocation = nil; + switch (debugLocationAccuracy ) { + case 1: //high + debugLocation = [[CLLocation alloc] initWithCoordinate:currentLocation.coordinate + altitude:currentLocation.altitude + horizontalAccuracy:5 + verticalAccuracy:currentLocation.verticalAccuracy + timestamp:currentLocation.timestamp]; + + break; + case 2: // medium + debugLocation = [[CLLocation alloc] initWithCoordinate:currentLocation.coordinate + altitude:currentLocation.altitude + horizontalAccuracy:30 + verticalAccuracy:currentLocation.verticalAccuracy + timestamp:currentLocation.timestamp]; + + break; + case 3: // low + debugLocation = [[CLLocation alloc] initWithCoordinate:currentLocation.coordinate + altitude:currentLocation.altitude + horizontalAccuracy:50 + verticalAccuracy:currentLocation.verticalAccuracy + timestamp:currentLocation.timestamp]; + + break; + default: // non debug + debugLocation = currentLocation; + break; + } + [self.delegate locationManager:(CLLocationManager *)self didUpdateLocations:@[debugLocation]]; + + } else { + [self.delegate locationManager:(CLLocationManager *)self didUpdateLocations:@[currentLocation]]; + } } @end diff --git a/OpenStreetView/BuisnessLogic/OSVLogger.m b/OpenStreetView/BuisnessLogic/OSVLogger.m index 28bc783..f076848 100644 --- a/OpenStreetView/BuisnessLogic/OSVLogger.m +++ b/OpenStreetView/BuisnessLogic/OSVLogger.m @@ -33,7 +33,23 @@ + (instancetype)sharedInstance { - (id)init { self = [super init]; if (self) { + NSString *logsFolder = [[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] stringByAppendingPathComponent:kLogsFolderName]; + + NSFileManager *fm = NSFileManager.defaultManager; + NSArray *subPaths = [fm subpathsAtPath:logsFolder]; + NSDate *current = [NSDate date]; + for (NSString *path in subPaths) { + NSString *logPath = [logsFolder stringByAppendingString:[NSString stringWithFormat:@"/%@", path]]; + NSDictionary *attributes = [fm attributesOfItemAtPath:logPath error:nil]; + NSDate *lastModificationDate = [attributes objectForKey:NSFileModificationDate]; + + NSTimeInterval timeInterval = [current timeIntervalSinceDate:lastModificationDate]; + + if (fabs(timeInterval) > 3600 * 24 * 10) { + [fm removeItemAtPath:logPath error:nil]; + } + } } return self; } diff --git a/OpenStreetView/BuisnessLogic/OSVPersistentManager.h b/OpenStreetView/BuisnessLogic/OSVPersistentManager.h index 10ec575..f2e055a 100644 --- a/OpenStreetView/BuisnessLogic/OSVPersistentManager.h +++ b/OpenStreetView/BuisnessLogic/OSVPersistentManager.h @@ -9,6 +9,7 @@ #import #import "OSVPhoto.h" #import "OSVSequence.h" +#import "OSVScoreHistory.h" #import "RLMBoundingBox.h" @interface OSVPersistentManager : NSObject @@ -26,7 +27,10 @@ + (void)removeSequenceWithID:(NSInteger)sequenceID; + (void)removePhotosWithVideoIndex:(NSInteger)videoIndex localSequenceID:(NSInteger)localSequenceID; -+ (void)updatedPhoto:(OSVPhoto *)photo withAddress:(NSString *)address; ++ (void)updatedPhoto:(OSVPhoto *)photo; + (void)updatePhotosHavingLocalSequenceID:(NSInteger)sequenceID withServerID:(NSInteger)serverID; ++ (NSMutableArray *)getScoreHistoryForSequenceWithID:(NSInteger)sequenceID; ++ (void)storeScoreHistory:(OSVScoreHistory *)history; + @end diff --git a/OpenStreetView/BuisnessLogic/OSVPersistentManager.m b/OpenStreetView/BuisnessLogic/OSVPersistentManager.m index d4e6db8..fc50831 100644 --- a/OpenStreetView/BuisnessLogic/OSVPersistentManager.m +++ b/OpenStreetView/BuisnessLogic/OSVPersistentManager.m @@ -9,9 +9,12 @@ #import "OSVPersistentManager.h" #import #import "OSVPhoto+Relm.h" -#import "OSVUtils+Location.m" +#import "OSVScoreHistory+Realm.h" +#import "OSVUtils.h" #import "OSVVideo.h" +#import "OSC-Swift.h" + @implementation OSVPersistentManager + (BOOL)hasPhotos { @@ -84,7 +87,12 @@ + (void)getAllSequencesWithCompletion:(void (^)(NSArray *sequences, NSInteger ph localSeq.bottomRightCoordinate = bottomRightLocation; } - completion([dictionary allValues], results.count); + NSMutableArray *array = [[dictionary allValues] mutableCopy]; + [array sortUsingComparator:^NSComparisonResult(OSVSequence *obj1, OSVSequence *obj2) { + return [obj2.dateAdded compare:obj1.dateAdded]; + }]; + + completion(array, results.count); } + (void)getSequencesInBox:(id)box withCompletion:(void (^)(NSArray *sequences, NSInteger photosCount))completion { @@ -130,6 +138,12 @@ + (OSVSequence *)getSequenceWithID:(NSInteger)sequenceID { for (RLMPhoto *managedObject in realmResults) { OSVPhoto *photo = [OSVPhoto fromRealmObject:managedObject]; + + if (localSeq.photos.count) { + CLLocationCoordinate2D last = [localSeq.photos lastObject].photoData.location.coordinate; + localSeq.length += [OSVUtils getAirDistanceBetweenCoordinate:last andCoordinate:photo.photoData.location.coordinate]; + } + [localSeq.photos addObject:photo]; if (topLeftLocation.latitude > photo.photoData.location.coordinate.latitude ) { @@ -186,10 +200,8 @@ + (void)removePhotosWithVideoIndex:(NSInteger)videoIndex localSequenceID:(NSInte RLMRealm *realm = [RLMRealm defaultRealm]; RLMResults *realmResults = [RLMPhoto objectsWhere:[NSString stringWithFormat:@"videoIndex == %ld AND localSequenceID == %ld", (long)videoIndex,(long)localSequenceID]]; - //NSLog(@"Try remove from DB: %@",realmResults); if (realmResults.count) { [realm transactionWithBlock:^{ - //NSLog(@"Removing from DB"); [realm deleteObjects:realmResults]; }]; } @@ -220,7 +232,7 @@ + (void)updatePhotosHavingLocalSequenceID:(NSInteger)sequenceID withServerID:(NS }]; } -+ (void)updatedPhoto:(OSVPhoto *)photo withAddress:(NSString *)address { ++ (void)updatedPhoto:(OSVPhoto *)photo { RLMRealm *realm = [RLMRealm defaultRealm]; RLMPhoto *realmPhoto = [photo toRealmObject]; @@ -229,4 +241,50 @@ + (void)updatedPhoto:(OSVPhoto *)photo withAddress:(NSString *)address { }]; } +#pragma mark - OSVScoreHistory + ++ (NSMutableArray *)getScoreHistoryForSequenceWithID:(NSInteger)sequenceID { + + RLMResults *results = [RLMScoreHistory objectsWhere:[NSString stringWithFormat:@"localSequenceID == %ld", (long)sequenceID]]; + + NSMutableDictionary *scoreHistoryDict = [NSMutableDictionary dictionary]; + + for (RLMScoreHistory *managedObject in results) { + + OSVScoreHistory *history = [OSVScoreHistory fromRealmObject:managedObject]; + history.multiplier = [ScoreManager scoreForCoverage:history.coverage]; + OSVScoreHistory *sch = scoreHistoryDict[@(history.multiplier)]; + + if (!sch) { + scoreHistoryDict[@(history.multiplier)] = history; + sch = history; + } else { + sch.photos += history.photos; + sch.photosWithOBD += history.photosWithOBD; + sch.detectedSigns += history.detectedSigns; + sch.distance += history.distance; + } + + sch.points = sch.multiplier * sch.photos + sch.multiplier * 2 * sch.photosWithOBD + sch.detectedSigns; + } + + NSMutableArray *scoreHistoryArray = [NSMutableArray array]; + + for (NSNumber *number in scoreHistoryDict) { + [scoreHistoryArray addObject:scoreHistoryDict[number]]; + } + + return scoreHistoryArray; +} + ++ (void)storeScoreHistory:(OSVScoreHistory *)history { + RLMRealm *realm = [RLMRealm defaultRealm]; + RLMScoreHistory *realmScore = [history toRealmObject]; + + [realm transactionWithBlock:^{ + [realm addOrUpdateObject:realmScore]; + }]; +} + + @end diff --git a/OpenStreetView/BuisnessLogic/OSVSyncController.m b/OpenStreetView/BuisnessLogic/OSVSyncController.m index 582516b..648508e 100644 --- a/OpenStreetView/BuisnessLogic/OSVSyncController.m +++ b/OpenStreetView/BuisnessLogic/OSVSyncController.m @@ -13,7 +13,7 @@ #import "ConnectivityHandler.h" #import "OSVServerPhoto.h" #import "OSVServerSequence+Convertor.h" -#import "OSVBaseUser+OSM.h" +#import "OSVBaseUser.h" #import "UIDevice+Aditions.h" #import "OSVAPISerialOperation.h" @@ -28,7 +28,7 @@ @interface OSVSyncController () @property (nonatomic, assign) BOOL cancelGetRequests; -@property (nonatomic) NSString *basePath; + @end @implementation OSVSyncController @@ -39,9 +39,9 @@ - (instancetype)init { if (self) { OSVAPI *osvAPI = [OSVAPI new]; osvAPI.configurator = self; - self.basePath = [self createBasePath]; - self.tracksController = [[OSVTrackSyncController alloc] initWithOSVAPI:osvAPI basePath:self.basePath]; - self.logger = [[OSVTrackLogger alloc] initWithBasePath:self.basePath]; + + self.tracksController = [[OSVTrackSyncController alloc] initWithOSVAPI:osvAPI]; + self.logger = [[OSVTrackLogger alloc] initWithBasePath:[OSVUtils createOSCBasePath]]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNetworkStatusChange:) name:kReachabilityChangedNotification object:nil]; } @@ -64,35 +64,16 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (NSString *)createBasePath { - NSError *error; - NSString *photosFolderPath = [[OSVUtils getDirectoryPath] stringByAppendingString:@"/Photos/"]; - - if (![[NSFileManager defaultManager] fileExistsAtPath:photosFolderPath]) { - [[NSFileManager defaultManager] createDirectoryAtPath:photosFolderPath withIntermediateDirectories:YES attributes:nil error:&error]; - NSError *error = nil; - NSURL *URL = [NSURL fileURLWithPath:photosFolderPath]; - - BOOL success = [URL setResourceValue:[NSNumber numberWithBool:YES] - forKey:NSURLIsExcludedFromBackupKey error: &error]; - if(!success){ - NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], error); - } - } - - return photosFolderPath; -} - + (BOOL)isUploading { return [[OSVSyncController sharedInstance].tracksController isUploading]; } + (long long)sizeOnDiskForSequences { - return [OSVSyncUtils sizeOnDiskForSequencesAtPath:[OSVSyncController sharedInstance].basePath]; + return [OSVSyncUtils sizeOnDiskForSequencesAtPath:[OSVUtils createOSCBasePath]]; } + (long long)sizeOnDiskForSequence:(id)sequence { - return [OSVSyncUtils sizeOnDiskForSequence:sequence atPath:[OSVSyncController sharedInstance].basePath]; + return [OSVSyncUtils sizeOnDiskForSequence:sequence atPath:[OSVUtils createOSCBasePath]]; } + (BOOL)hasSequencesToUpload { diff --git a/OpenStreetView/BuisnessLogic/OSVUserDefaults.h b/OpenStreetView/BuisnessLogic/OSVUserDefaults.h index e3c55e9..5aae32f 100644 --- a/OpenStreetView/BuisnessLogic/OSVUserDefaults.h +++ b/OpenStreetView/BuisnessLogic/OSVUserDefaults.h @@ -28,25 +28,25 @@ //distance unit persistence; @property (nonatomic, assign) NSString *distanceUnitSystem; @property (nonatomic, assign) BOOL automaticDistanceUnitSystem; - +//server selection @property (nonatomic, strong) NSString *environment; - +//recording options @property (nonatomic, assign) BOOL hdrOption; - @property (nonatomic, assign) BOOL realPositions; - -@property (nonatomic, strong) NSString *userName; - -@property (nonatomic, assign) BOOL isFreshInstall; - -@property (nonatomic, assign) BOOL isUploading; - @property (nonatomic, assign) NSString *videoQuality; - @property (nonatomic, assign, readonly) CMVideoDimensions videoQualityDimension; +@property (nonatomic, assign) BOOL useImageRecognition; +@property (nonatomic, assign) BOOL showMapWhileRecording; +@property (nonatomic, assign) BOOL enableMap; +@property (nonatomic, assign) BOOL useGamification; +@property (nonatomic, assign) BOOL isFreshInstall; +@property (nonatomic, assign) NSInteger zoomLevel; +//OBD BLE @property (nonatomic, strong) NSString *bleDevice; - +//Upload info +@property (nonatomic, assign) BOOL isUploading; +//debug @property (nonatomic, assign) BOOL debugLogOBD; @property (nonatomic, assign) BOOL debugSLUS; @property (nonatomic, assign) float debugFrameRate; @@ -54,9 +54,9 @@ @property (nonatomic, assign) float debugBitRate; @property (nonatomic, assign) NSString *debugEncoding; @property (nonatomic, assign) BOOL debugHighDesintyOn; - -@property (nonatomic, assign) BOOL useImageRecognition; -@property (nonatomic, assign) BOOL showMapWhileRecording; +@property (nonatomic, assign) BOOL debugStabilization; +@property (nonatomic, assign) BOOL debugMatcher; +@property (nonatomic, assign) NSInteger debugLocationAccuracy; + (instancetype)sharedInstance; - (void)save; diff --git a/OpenStreetView/BuisnessLogic/OSVUserDefaults.m b/OpenStreetView/BuisnessLogic/OSVUserDefaults.m index 4bb1c8e..4f3a040 100644 --- a/OpenStreetView/BuisnessLogic/OSVUserDefaults.m +++ b/OpenStreetView/BuisnessLogic/OSVUserDefaults.m @@ -10,6 +10,7 @@ #import #import #import "UIDevice+Aditions.h" +#import "OSVAPIConfigurator.h" #define kUserNameKey @"kUserNameKey" #define kRealPositionsKey @"kRealPositionsKey" @@ -24,9 +25,14 @@ #define kHdrOptionKey @"kHdrOptionKey" #define kSLOptionKey @"kSLOptionKey" #define kMapWhileRecodingKey @"kMapWhileRecodingKey" +#define kEnableMapKey @"kEnableMapKey" +#define kZoomLevelRecordingKey @"kZoomLevelRecordingKey" + #define kisUploadingKey @"kisUploadingKey" +#define kUseGamification @"kUseGamification" + #define kDebugLogOBD @"kDebugLogOBD" #define kDebugSLUS @"kDebugSLUS" #define kDebugFrameRate @"kDebugFrameRate" @@ -34,7 +40,10 @@ #define kDebugBitRate @"kDebugBitRate" #define kDebugEncoding @"kDebugEncoding" #define kDebugHighDensityOn @"kDebugHighDensityOn" +#define kdebugStabilization @"kdebugStabilization" +#define kDebugMatcher @"kDebugMatcher" +#define kisFreshInstall @"kisFreshInstall_1.4.9" @implementation OSVUserDefaults @@ -54,31 +63,22 @@ - (instancetype)init { if (self) { if (![[NSUserDefaults standardUserDefaults] boolForKey:@"defaultOverriden"]) { - self.userName = @""; self.useCellularData = NO; self.automaticUpload = NO; self.distanceUnitSystem = kImperialSystem; self.automaticDistanceUnitSystem = YES; [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"defaultOverriden"]; - self.isFreshInstall = YES; self.videoQuality = k5MPQuality; } - if (![[NSUserDefaults standardUserDefaults] boolForKey:@"defaultOverriden1.4.2"]) { - self.showMapWhileRecording = NO; - [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"defaultOverriden1.4.2"]; + if (![[NSUserDefaults standardUserDefaults] boolForKey:@"defaultOverriden1.4.9"]) { + self.showMapWhileRecording = YES; + [[NSUserDefaults standardUserDefaults] setBool:YES forKey:@"defaultOverriden1.4.9"]; } - if (!self.environment) { -#ifdef ENABLED_DEBUG - self.environment = @"http://openstreetview.com"; - //@"http://testing.openstreetview.com" - //@"http://staging.openstreetview.com" - //@"http://openstreetview.com" -#else - self.environment = @"http://openstreetview.com"; -#endif + if (!self.environment || [self.environment containsString:@"openstreetview.com"]) { + self.environment = [OSVAPIConfigurator productionEnvironment]; } //if automatic not found then set automatic on @@ -105,9 +105,7 @@ - (instancetype)init { self.debugFrameSize = 1024.0; } - if (self.debugFrameRate <= 0) { - self.debugFrameRate = 10; - } + self.debugFrameRate = 3.0; if (self.debugBitRate <= 0) { self.debugBitRate = 1.5; @@ -117,14 +115,30 @@ - (instancetype)init { self.debugEncoding = AVVideoProfileLevelH264HighAutoLevel; } - if (![[NSUserDefaults standardUserDefaults] valueForKey:kDebugHighDensityOn]) { - self.debugHighDesintyOn = YES; - } + self.debugHighDesintyOn = NO; if (![[NSUserDefaults standardUserDefaults] valueForKey:kMapWhileRecodingKey]) { - self.showMapWhileRecording = NO; + self.showMapWhileRecording = YES; } + if (![[NSUserDefaults standardUserDefaults] valueForKey:kUseGamification]) { + self.useGamification = YES; + } + + if (![[NSUserDefaults standardUserDefaults] valueForKey:kisFreshInstall]) { + self.isFreshInstall = YES; + } + + if (![[NSUserDefaults standardUserDefaults] valueForKey:kEnableMapKey]) { + self.enableMap = YES; + } + + if (![[NSUserDefaults standardUserDefaults] valueForKey:kZoomLevelRecordingKey]) { + self.zoomLevel = 17; + } + + self.debugStabilization = NO; + [self save]; } @@ -201,7 +215,6 @@ - (CMVideoDimensions)videoQualityDimension { } else if ([self.videoQuality isEqualToString:k8MPQuality]) { dimension.width = 3264; dimension.height = 2448; - } else if ([self.videoQuality isEqualToString:k12MPQuality]) { dimension.width = 4032; dimension.height = 3024; @@ -228,6 +241,14 @@ - (BOOL)useImageRecognition { return [[NSUserDefaults standardUserDefaults] boolForKey:kSLOptionKey]; } +- (void)setEnableMap:(BOOL)enableMap { + return [[NSUserDefaults standardUserDefaults] setBool:enableMap forKey:kEnableMapKey]; +} + +- (BOOL)enableMap { + return [[NSUserDefaults standardUserDefaults] boolForKey:kEnableMapKey]; +} + - (void)setShowMapWhileRecording:(BOOL)showMapWhileRecording { return [[NSUserDefaults standardUserDefaults] setBool:showMapWhileRecording forKey:kMapWhileRecodingKey]; } @@ -260,6 +281,14 @@ - (NSString *)bleDevice { return [[NSUserDefaults standardUserDefaults] objectForKey:@"kbleDevice"]; } +- (void)setUseGamification:(BOOL)useGamification { + return [[NSUserDefaults standardUserDefaults] setBool:useGamification forKey:kUseGamification]; +} + +- (BOOL)useGamification { + return [[NSUserDefaults standardUserDefaults] boolForKey:kUseGamification]; +} + - (void)save { [[NSUserDefaults standardUserDefaults] synchronize]; } @@ -322,4 +351,46 @@ - (BOOL)debugHighDesintyOn{ return [[NSUserDefaults standardUserDefaults] boolForKey:kDebugHighDensityOn]; } +- (void)setDebugStabilization:(BOOL)debugHighDesintyOn { + return [[NSUserDefaults standardUserDefaults] setBool:debugHighDesintyOn forKey:kdebugStabilization]; +} + +- (BOOL)debugStabilization { + return [[NSUserDefaults standardUserDefaults] boolForKey:kdebugStabilization]; +} + +- (void)setIsFreshInstall:(BOOL)isFreshInstall { + return [[NSUserDefaults standardUserDefaults] setBool:isFreshInstall forKey:kisFreshInstall]; +} + +- (BOOL)isFreshInstall { + return [[NSUserDefaults standardUserDefaults] boolForKey:kisFreshInstall]; +} + +- (BOOL)debugMatcher { + return [[NSUserDefaults standardUserDefaults] boolForKey:kDebugMatcher]; +} + +- (void)setDebugMatcher:(BOOL)debugMatcher { + return [[NSUserDefaults standardUserDefaults] setBool:debugMatcher forKey:kDebugMatcher]; +} + +static NSInteger accuracy = 0; + +- (void)setDebugLocationAccuracy:(NSInteger)debugLocationAccuracy { + accuracy = debugLocationAccuracy; +} + +- (NSInteger)debugLocationAccuracy { + return accuracy; +} + +- (void)setZoomLevel:(NSInteger)zoomLevel { + return [[NSUserDefaults standardUserDefaults] setInteger:zoomLevel forKey:kZoomLevelRecordingKey]; +} + +- (NSInteger)zoomLevel { + return [[NSUserDefaults standardUserDefaults] integerForKey:kZoomLevelRecordingKey]; +} + @end diff --git a/OpenStreetView/BuisnessLogic/OSVUtils+FileManager.m b/OpenStreetView/BuisnessLogic/OSVUtils+FileManager.m index 6c52d16..b7b5cd4 100644 --- a/OpenStreetView/BuisnessLogic/OSVUtils+FileManager.m +++ b/OpenStreetView/BuisnessLogic/OSVUtils+FileManager.m @@ -14,7 +14,7 @@ @implementation OSVUtils (FileManager) -+ (NSString *)getDirectoryPath { ++ (NSString *)documentsDirectoryPath { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); return [paths objectAtIndex:0]; @@ -94,7 +94,7 @@ + (long long)sizeOfFolder:(NSString *)directoryUrl { + (long long)sizeOfFolder:(NSString *)directoryUrl containsImages:(BOOL *)contains { NSUInteger folderSize = 0; - NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey, NSURLCreationDateKey, NSURLLocalizedTypeDescriptionKey, nil]; + NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey, NSURLLocalizedTypeDescriptionKey, nil]; NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL URLWithString:directoryUrl] includingPropertiesForKeys:properties options:(NSDirectoryEnumerationSkipsHiddenFiles) error:nil]; @@ -121,6 +121,80 @@ + (long long)sizeOfFolder:(NSString *)directoryUrl containsImages:(BOOL *)contai return folderSize; } ++ (NSURL *)fileNameForTrackID:(NSInteger)trackUID { + NSString *folderPathString = [NSString stringWithFormat:@"%@%ld", [OSVUtils createOSCBasePath], (long)trackUID]; + + return [[NSURL alloc] initWithString:folderPathString]; +} + ++ (NSArray *)videoPathsFromFolder:(NSURL *)basePath { + NSMutableArray *videoFiles = [NSMutableArray array]; + + NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey, NSURLCreationDateKey, NSURLLocalizedTypeDescriptionKey, nil]; + + NSArray *array = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:basePath includingPropertiesForKeys:properties options:(NSDirectoryEnumerationSkipsHiddenFiles) error:nil]; + + for (NSURL *fileSystemItem in array) { + BOOL directory = NO; + [[NSFileManager defaultManager] fileExistsAtPath:[fileSystemItem path] isDirectory:&directory]; + if (!directory && [fileSystemItem pathExtension] && [[fileSystemItem pathExtension] isEqualToString:@"mp4"]) { + [videoFiles addObject:fileSystemItem]; + } + } + + [videoFiles sortUsingComparator:^NSComparisonResult(NSURL *obj1, NSURL *obj2) { + + return [[[obj1 lastPathComponent] stringByDeletingPathExtension] integerValue] > [[[obj2 lastPathComponent] stringByDeletingPathExtension] integerValue]; + }]; + + return videoFiles; +} + +static NSString *oscBasePath = nil; + ++ (NSString *)createOSCBasePath { + NSString *photosFolderPath = [[OSVUtils documentsDirectoryPath] stringByAppendingString:@"/Photos/"]; + + if (!oscBasePath) { + if (![[NSFileManager defaultManager] fileExistsAtPath:photosFolderPath]) { + NSError *error; + [[NSFileManager defaultManager] createDirectoryAtPath:photosFolderPath withIntermediateDirectories:YES attributes:nil error:&error]; + NSURL *URL = [NSURL fileURLWithPath:photosFolderPath]; + + NSError *errorExcluding = nil; + BOOL success = [URL setResourceValue:[NSNumber numberWithBool:YES] + forKey:NSURLIsExcludedFromBackupKey error:&errorExcluding]; + if (!success) { + NSLog(@"Error excluding %@ from backup %@", [URL lastPathComponent], errorExcluding); + } + } + oscBasePath = photosFolderPath; + } + + return oscBasePath; +} + ++ (NSString *)fileNameForVideoWithTrackID:(NSInteger)trackUID index:(NSInteger)videoIndex { + NSString *folderPathString = [NSString stringWithFormat:@"%@%ld/%ld.mp4", [OSVUtils createOSCBasePath], (long)trackUID, (long)videoIndex]; + + return folderPathString; +} + ++ (NSURL *)fileNameForTrackID:(NSInteger)trackUID videoID:(NSInteger)videoUID { + NSString *folderPathString = [NSString stringWithFormat:@"%@%ld", [OSVUtils createOSCBasePath], (long)trackUID]; + if (![[NSFileManager defaultManager] fileExistsAtPath:folderPathString]) { + NSError *error; + BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:folderPathString withIntermediateDirectories:NO attributes:NULL error:&error]; + if (!success) { + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Failed to create folder for trackID:%ld error:%@", (long)trackUID, error] withLevel:LogLevelDEBUG]; + success = [[NSFileManager defaultManager] createDirectoryAtPath:folderPathString withIntermediateDirectories:NO attributes:NULL error:&error]; + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Retry to create folder with result:%d error:%@", success, error] withLevel:LogLevelDEBUG]; + } + } + + return [NSURL fileURLWithPath:[folderPathString stringByAppendingString:[NSString stringWithFormat:@"/%ld.mp4", (long)videoUID]]]; +} + @end #undef kMB diff --git a/OpenStreetView/BuisnessLogic/OSVUtils+Location.m b/OpenStreetView/BuisnessLogic/OSVUtils+Location.m index ca68a35..034641e 100644 --- a/OpenStreetView/BuisnessLogic/OSVUtils+Location.m +++ b/OpenStreetView/BuisnessLogic/OSVUtils+Location.m @@ -70,30 +70,115 @@ + (const double)distanceBetweenStartPoint:(CGPoint)startP andEndPoint:(CGPoint)e return sqrt((startP.x - endP.x) * (startP.x - endP.x) + (startP.y - endP.y) * (startP.y - endP.y)); } -+ (CGPoint)nearestPointToPoint:(CGPoint)origin onLineSegmentPointA:(CGPoint)pointA pointB:(CGPoint)pointB distance:(double *)distance { - CGPoint dAP = CGPointMake(origin.x - pointA.x, origin.y - pointA.y); - CGPoint dAB = CGPointMake(pointB.x - pointA.x, pointB.y - pointA.y); - CGFloat dot = dAP.x * dAB.x + dAP.y * dAB.y; - CGFloat squareLength = dAB.x * dAB.x + dAB.y * dAB.y; - CGFloat param = dot / squareLength; - - CGPoint nearestPoint; - if (param < 0 || (pointA.x == pointB.x && pointA.y == pointB.y)) { - nearestPoint.x = pointA.x; - nearestPoint.y = pointA.y; - } else if (param > 1) { - nearestPoint.x = pointB.x; - nearestPoint.y = pointB.y; - } else { - nearestPoint.x = pointA.x + param * dAB.x; - nearestPoint.y = pointA.y + param * dAB.y; ++ (CLLocation *)nearestLocationToLocation:(CLLocation *)origin + onLineSegmentLocationA:(CLLocation *)pointA + locationB:(CLLocation *)pointB + distance:(double *)distance { + /*Changing to points (more compact code)*/ + CGPoint P = CGPointMake(origin.coordinate.longitude, origin.coordinate.latitude); + CGPoint A = CGPointMake(pointA.coordinate.longitude, pointA.coordinate.latitude); + CGPoint B = CGPointMake(pointB.coordinate.longitude, pointB.coordinate.latitude); + + /* Noting P' a point on AB and PP' is perpendicular on AB + Noting the slope of AB with mAB + Noting the slope of PP' with mPP' + AB equation: (X-A.x)/(B.y-A.x) = (Y-A.y)/(B.y-A.y) + Because PP' is perpendicular on AB => mAB * mPP' = -1 + mAB equation: (B.y-A.y)/(B.x-A.x) + mPP'equation: (P'.y-P.y)/(P'.x-P.x) + Because P' is on AB => (P'.x-A.x)/(B.y-A.x) = (P'.y-A.y)/(B.y-A.y) + Solving this system: + ------------------------------------------------- + | mAB * mPP' = -1 | + | (P'.x-A.x)/(B.y-A.x) = (P'.y-A.y)/(B.y-A.y) | + ------------------------------------------------- + We get P'(x,y): + Where for a more compact result we made up other variables: + ----------------------------------------------------- + | Z = (B.x - A.x)*(B.x - A.x) | + | T = (B.y - A.y)*(B.y - A.y) | + | V = (A.y - P.y)*(B.x - A.x)*(B.y - A.y) | + | P'.x = (Z * P.x + T * A.x - V)/(Z+T) | + | P'.y = (mAB/(Z+T)) * (Z * (P.x-A.x) - V) + A.y | + ----------------------------------------------------- + */ + CGFloat mAB = (B.y - A.y)/(B.x - A.x); + + CGFloat Z = (B.x - A.x)*(B.x - A.x); + CGFloat T = (B.y - A.y)*(B.y - A.y); + CGFloat V = (A.y - P.y)*(B.x - A.x)*(B.y - A.y); + + CGFloat xPrim = (Z * P.x + T * A.x - V)/(Z+T); + CGFloat yPrim = (mAB/(Z+T)) * (Z * (P.x-A.x) - V) + A.y; + + CGPoint Pprim = CGPointMake(xPrim, yPrim); + + /* case P + | + | + A-----------P'--B */ + CLLocation *nearLocation = [[CLLocation alloc] initWithLatitude:Pprim.y longitude:Pprim.x]; + + /* + Distance from A to B is dAB + Distance from A to P' is dAPprim + Distance from B to P' is dBPrim + */ + CGFloat dAB = [pointA distanceFromLocation:pointB]; + CGFloat dAPprim = [pointA distanceFromLocation:nearLocation]; + CGFloat dBPrim = [pointB distanceFromLocation:nearLocation]; + + if (dAPprim > dAB && + dAPprim > dBPrim) { + /* case: P + /| + / | + / | + A---------B---P' + we change P' with B + */ + nearLocation = pointB; + } else if (dBPrim > dAB && + dBPrim > dAPprim) { + /* case: + P + |\ + | \ + | \ + P'--A---------B + we change P' with A + */ + nearLocation = pointA; } - CGFloat dx = origin.x - nearestPoint.x; - CGFloat dy = origin.y - nearestPoint.y; - *distance = sqrtf(dx * dx + dy * dy); + *distance = [origin distanceFromLocation:nearLocation]; + + return nearLocation; +} + ++ (double)degreesBetweenLineAStart:(CLLocationCoordinate2D)pointA + lineAEnd:(CLLocationCoordinate2D)pointB + lineBStart:(CLLocationCoordinate2D)pointC + lineBEnd:(CLLocationCoordinate2D)pointD { + /*Changing to points (more compact code)*/ + CGPoint A = CGPointMake(pointA.longitude, pointA.latitude); + CGPoint B = CGPointMake(pointB.longitude, pointB.latitude); + CGPoint C = CGPointMake(pointC.longitude, pointC.latitude); + CGPoint D = CGPointMake(pointD.longitude, pointD.latitude); + + /* + mAB equation: (B.y-A.y)/(B.x-A.x) + mCD equation: (D.y-C.y)/(D.x-C.x) + Noting *phi the angle between line AB and line CD + tan(phi) = ABS((mAB-mCD)/(1+ mAB*mCD)) (formula) + => phi = atan(ABS((mAB-mCD)/(1+ mAB*mCD))) + */ + + double mAB = (B.y-A.y)/(B.x-A.x); + double mCD = (D.y-C.y)/(D.x-C.x); + double tanPHI = ABS((mAB-mCD)/(1 + mAB*mCD)); - return nearestPoint; + return ABS(atan(tanPHI) * 180.0/M_PI); } + (BOOL)isSameLocation:(CLLocationCoordinate2D)firstLocation asLocation:(CLLocationCoordinate2D)secondLocation { diff --git a/OpenStreetView/BuisnessLogic/OSVUtils.h b/OpenStreetView/BuisnessLogic/OSVUtils.h index 590cd34..f6eb418 100644 --- a/OpenStreetView/BuisnessLogic/OSVUtils.h +++ b/OpenStreetView/BuisnessLogic/OSVUtils.h @@ -36,7 +36,17 @@ /** * This method computes the distance and nereast point to a segment */ -+ (CGPoint)nearestPointToPoint:(CGPoint)origin onLineSegmentPointA:(CGPoint)pointA pointB:(CGPoint)pointB distance:(double *)distance; ++ (CLLocation *)nearestLocationToLocation:(CLLocation *)origin + onLineSegmentLocationA:(CLLocation *)pointA + locationB:(CLLocation *)pointB + distance:(double *)distance; +/** + * This method computes the angle between the two lines determined by these four points. + */ ++ (double)degreesBetweenLineAStart:(CLLocationCoordinate2D)pointA + lineAEnd:(CLLocationCoordinate2D)pointB + lineBStart:(CLLocationCoordinate2D)pointC + lineBEnd:(CLLocationCoordinate2D)pointD; + (NSArray *)metricDistanceArray:(NSInteger)meters; + (NSString *)metricDistanceFormatter:(NSInteger)meters; @@ -57,7 +67,20 @@ @interface OSVUtils (FileManager) -+ (NSString *)getDirectoryPath; +/** + Call this method to get the path to the OSC Photos folder. + If the floder does not exist it is creaded. + + @return String representing path where all OSC related files are stored. + */ ++ (NSString *)createOSCBasePath; + +/** + Convinience method for documents directory + + @return String representing path for the app documents directory + */ ++ (NSString *)documentsDirectoryPath; /** * This method will format the space in MB, GB @@ -80,7 +103,7 @@ */ + (NSString *)freeDiskSpace; /** - * This method returns a formated string representing total disk space. + * This method returns a formated string representing total used disk space. */ + (NSString *)usedDiskSpace; @@ -105,6 +128,12 @@ */ + (long long)sizeOfFolder:(NSString *)directoryUrl containsImages:(BOOL *)contains; ++ (NSURL *)fileNameForTrackID:(NSInteger)trackUID; + ++ (NSString *)fileNameForVideoWithTrackID:(NSInteger)trackUID index:(NSInteger)videoIndex; + ++ (NSURL *)fileNameForTrackID:(NSInteger)trackUID videoID:(NSInteger)videoUID; + @end /* --------------------------------------------------*/ @@ -115,6 +144,19 @@ */ + (UIImage *)rotateImage:(UIImage *)image toImageOrientation:(UIImageOrientation)orient; +@end + +@interface OSVUtils (Device) +/** + * This method returns if the screen density is high + */ ++ (BOOL)isHighDensity; + +@end + +@interface OSVUtils (Gamification) + ++ (NSString *)pointsFormatedFromPoints:(NSInteger)points; @end diff --git a/OpenStreetView/Images.xcassets/AppIcon.appiconset/Contents.json b/OpenStreetView/Images.xcassets/AppIcon.appiconset/Contents.json index 2da87cf..8d026b5 100644 --- a/OpenStreetView/Images.xcassets/AppIcon.appiconset/Contents.json +++ b/OpenStreetView/Images.xcassets/AppIcon.appiconset/Contents.json @@ -1,5 +1,15 @@ { "images" : [ + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "2x" + }, + { + "idiom" : "iphone", + "size" : "20x20", + "scale" : "3x" + }, { "size" : "29x29", "idiom" : "iphone", @@ -42,6 +52,16 @@ "filename" : "Icon-App-60x60@3x.png", "scale" : "3x" }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "1x" + }, + { + "idiom" : "ipad", + "size" : "20x20", + "scale" : "2x" + }, { "size" : "29x29", "idiom" : "ipad", diff --git a/OpenStreetView/Images.xcassets/chevroninv.imageset/Contents.json b/OpenStreetView/Images.xcassets/chevroninv.imageset/Contents.json new file mode 100644 index 0000000..7e06240 --- /dev/null +++ b/OpenStreetView/Images.xcassets/chevroninv.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "chevron.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "chevron@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "chevron@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/chevroninv.imageset/chevron.png b/OpenStreetView/Images.xcassets/chevroninv.imageset/chevron.png new file mode 100644 index 0000000000000000000000000000000000000000..153e0827d0132bfbbde60f46de8c5d07e3a91fc5 GIT binary patch literal 856 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjEa{HEjtmSN`?>!lvI6-E$sR$z z3=CCj3=9n|3=F@3LJcn%7)lKo7+xhXFj&oCU=S~uvn$Ysfq^kHGbExU!q>+tIX_n~ zF(p4KRj(qq0H}k3!KT6r$jnVGNmQuF&B-gas<2f8tFQvHLBje<3ScEA*|tg%z5xo( z`9-M;rg|oN21<5Z3JMA~MJZ`kK`w4k?LeNbQbtKhft9{~d3m{Bxv^e;QM$gNrKP35 zfswwEkuFe$ZgFK^Nn(X=Ua>O75STeGsl~}fnFS@8`FRQ;a}$&DOG|8(lt3220mPjp znP~`{@`|C}0(wv%B%^PrXP^%^8>rO=Bx>bfl$i>&8Dzelp$%9iiWt-$8-0-FNREN{ z6f6q#svVb&K0Mg$xO@(&M*;)6&eO#)#Dn*3@Ln%wM}c`e<Lq-J}?Yi5&_z zI$T9KBYv=y*>&(g5bkK@SM2D`(AlzaGlz%Ixq_GjMvS79@7%SDW;rBet{rjDWc&Sd zHTMnfzhO+7XlZbc@&5O48U6ZG5{CDQwv2KbQPU08*MG>b`lZ!=)!N=m~*p7c*nxW zOicTjeBQbS?$zz;JuIwV5L>V9`EXh{^Mmenw^Kt4?*&*nt_+#=y2PG&Q|iR5{Ry{X za?Pa#)mOEZG)1lb#<;7jr^8lgPUHK7Gau*NUiD~?pVh&D6Q8-JPFXs=r_r~E{qz<7 zW`!4gpEs=!V%B@`y#S55EyJg0~`?oH*fHe~~|PIhfaE zi&kR9a@oIfmt;G(806S79p-ww#JTJz=j*xMrb_>Unf>|}ZC8&q{&sTNs@$3GixS$5 e+5g>dlwZVDxax?QATZf8FnGH9xvXNS%G|oWRD45dJguM!v-tY$DUh!@P+6==i2z!;es5>XQ2>tmIipR1Rc zlAn~SSCLx))WN`DQ(*;U=BAb;Dpcg=|?L9&C18K8MsJ85o%LJzX3_GFab+`+I~qO8ieNxw@pxv^C)VKSLL0|BcH# za`;o7Cc1cBS=q$I@7S&%~g?eo&uDPsJkTPa>cFOs3Avd8}gf5S%QMH*f&S~E&sZ8{;|>@DPA zA@l9bnVRa3?7tf{xaQjTpNkj#nY8f>!;g1OtX3VTmqm-Xa?a^?+aDuZX&#ZqP*d-( zn9czMl)tb=R@%r? z;@{+o1xvPvJle^;j`={-TDBQ-2k)k>Pgv>NFt1Dcmu};9u2@|~og2Lo8Kdx<4Vy-Aq?v9=7e)6`c-VY&o{GuH8D4pefw9OQB^(MVp;O_e=e^8#hI1N^UrMBq_Pj z-}1w(A1TFqj>ewiW|{XWH|OR@rTQ4d{Y%*nu)f&!Z|kZ{!io-dPq+^$tomSP*5Wwl z#PhrV^iH;><>kF=zkb`q!=s9y>&*R5jd=mPvukFHe^B~-Y;DEAI!~qt!n2>{tlGCP z@4zWXmW9VGe;-_(x_tezZMS^R*>B#NbbAu(0ajI^&iTB&(QKD*zR_!8Z1-TZuDy55 z?aUEj_IQN}ambP0l+XkKPNfo; literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/chevroninv.imageset/chevron@3x.png b/OpenStreetView/Images.xcassets/chevroninv.imageset/chevron@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..31cd05c724496af2b078f49940757852cbc22e1e GIT binary patch literal 1783 zcmZ`)dsxy}82+K4O(#)W8tT(e=7pw$mzr`@Da1=@YH3(%;@ymkh(VMKl_r@@r)K%2 zDb8hRmc_Cy%Ugmg(RI-@mz86M724G4)N~E1we5Mf^E~H#=X=lhz3=y(Kh8N466|MU zgfs#Gz$Cz*5~j8Oy1C3iyM~X;{Imv|Ob#Lgz{Nu2MLJCDgYo`hK>#4I2LPc602Z{6 za0~!4T>#)kECAq70)RQY;%X=n03ea6+i6@{&=!0=i-Dmhu;LOidF=aW!xBkc>pYFqU(B4R&Wo0rj+PKQVUfLRAn$lLjl@$y|P zOJ6f#vL;9qtBNLshn3C6d{)Tiw#remlO4t3yb*V zPl-MvfB84JQ7(JF8VEcC7oU~hh5At?^)L7yHiw5sMhn{G(ukHfA6X7)dM1=Og1h=B z_vAh$stX$|G<^c~g#3qLI_h=2Il6&^C#^g>8=ko|Y~s;v#g@q;UI*I0z9K=+!$$}1 z)z=3$Hs8B-pw+OyuKuTw-1-n3Z8zRtx{O@l@cDCn5e1B=*1Pq?O0)e!OezgL<3>Dl ze#mV|J5+&Ov*t+u%Zh994wkIC@dUS}ljMRQCC5@^`&>FBMH7OW?YD5ql7r95S<-&E zFe4wPX2m9iAj$-%I%Kjwp3uyW^rZ=fq=q+3zOz^+q8`dV+8AHhwWH^nQ-di~Qi3RG zp*^D)ti}`c%Ht;URqQc~gDP_V-8M`5dKd(^7orY4yUik+MnhlXYR>=eTNG?Rko5$& z7E%%1oIU48tt4#zrl;*vrsf2Hg3PIZ1GJYv1p4f3hK{FO!sX*q!)&#c+p_&@6*f(+ zq^^o8f~ehMOGAT`wZlu&G#D9d4e?w{>m<*0v(Luo?O>z%TY;H%&y!n-b-G5vp>Ut{3@qIS*U;S)3xmvC*|_0vg>-=UJZu(Tq^$jw1t9j z8z))-gdQxVbCrWQ?mwX%rv2}d0x#^0)bRk{< z_wV!lL=uh2;I?=N6UK4yWpRCuT_B5QQaqt-QT^Pd(P;9IpEh?p8eY3J>T`P93Hr;G z#+@~6!GV@4Co`k82tmwEtC{LpL=Z$c9iiypJl>5tQ4)cVxn%{T-fVpMEFgj+BFttqb=%l|hKEwruOAlZU@_K+V?2O|ui`B^c3(v2=y% z+!-6g1yh)w-)8xIVI-b8NI=&1D#irT`}bt2Q%Su;Ml-xqiD!}_E2c`(c4gegsa)wJ zncpA~YHVZi*b0fPSj-w%kU}1IHX-$ENv`W!TWi9d;>=ZyQw`RIMKJ;TLjMMe%I$n;82N z`f2ll%*v}Rc)60QR4R*9-G!Cc_!q%VOIbkyi$$2ocC=RW>o)r8Yx?~uE<_l3yk51gm1LPkKb$AufEg70IP`|_gp>_ps#+E%x1 zC?SNZADE@Brw%&qK5~(7-tRq(c0cZM!&|mg-2b}#Of>JQORt9z4Hf=&87ho#V{L=o?Qj*v9c9EIEfA)O;>gfq3y?-Z0%YHzkTX!e7)JXRiEO# z^Uh^iF}ktSNb#^th+NV?1zeEz)urSzqFSMp@jIE$4vLkDG_`&8T$LQEH)}rH#4buw zGltqm8(Lu$Klr2c?1>%_He@0{WJ6z++EU@|0UZlptZtS*N%QIdOdPO3pun7db^I`@ zcGFx*FKNWEuC6Y%g0nb90s{e}6japW+P7IFLkfT4;0E3IbhklY{qN)R{zYQy>m7oq Wxmi;vVb|BXKPSL9m~wt&Y|fv}!2)mq literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/facebook.imageset/Contents.json b/OpenStreetView/Images.xcassets/facebook.imageset/Contents.json new file mode 100644 index 0000000..afc770f --- /dev/null +++ b/OpenStreetView/Images.xcassets/facebook.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "facebook.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "facebook@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "facebook@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/facebook.imageset/facebook.png b/OpenStreetView/Images.xcassets/facebook.imageset/facebook.png new file mode 100644 index 0000000000000000000000000000000000000000..d69ab02fbb28b37e07ec9a47ac312cf12690caf0 GIT binary patch literal 310 zcmV-60m=S}P)Px#@JU2LR5%f1V88nvb83V-}KoW!ix>J1#X!r?~{|>}|QEUVXfc%FI90Up)0x=gOBcmV?Uq?{{ zbm~TIK?n^n6t(C!GNZ^MI3E#A2n$^!x;#!k*&11Z?)OGARvd|q%=7@N`-&v+hY=JQ zNCLz%*O9BygB*?bfzDC}rJPGh?o$M^d6D=q=2al$FO)M2m;g|{2lVb1ke{&tK9~tG zn(XKp)d&khEc9sLUPx$wn;=mR9Fe^n7>K`K@i4s62)5VM6eMFg4p-~YN-!k;{#Y|>jMaO60AhKh>ewv zPv8q!*jS|y!9vpchZJ&tALN!~*`2#3!&Wme-0sfo{BFO^UXE+E60I!D0=^IL!Taz( zcoRDys-40^)g9ztz&BIojpsH70(OFlUHHs+fz)=R$$*`r@a42H-drsZFv@qvWDOI6 zfHB^K&uYL}Lj)qe2j5_#mem0dwLn#!C~zd_Zk4EYm5#* zt4v6=Z{%OY@8K^+QT+Pzr4=sv$u<2q#J2(IOL@^f#H4v?Vjy;02jd(GI2R}?4LwW2 zDkcG|9M!7DsPR?KH6P~rN zIe|Caw_K7Az*@ozhq+dGOIXeocDR28@*n?>jexCTY%4Gx8+t&1uNc0)S1>;?(Z}&T z;u%e_<%t53POd$4cmp~qv>GOFSuIP71At yNvfr!t7DQnDYP2W_tHl|#BZP8O?-O&VD}#ZBDX2|h?}(l0000Px%kx4{BRA>e5n>{ZCQ51%Eh4^X+1tK(r#7|Htgg>AWi9evx38jQeqSDYQ6iXyp zk@yKZDxJhfB2h>XU+X=?tZ;U+_s%()y_1}qyk_^@bIyI|nU9?;3I*j+E|)u?d8h^f|nCN`b7+W~RCuthF8f{I}yh_b}m6%h=)u?M;twkSe zB_z#j8A$4{7B{16D1RCmQ6s8NK)auvqefJlfOfwk9=om_n$ojlk3(Lq6nct(tCdt` z{+x`Kt4xFzTFisd7f|cV!|mw+58DrUFuG0WVd#hc0yLv_{Nk&5^ z8eK$Wl19izD~FwohI%noE+R5XBUGY0-}Zig(r5V6@7u&zotRlkoOPerMCz?W`mRF` zPr>8B06h~ZjMTs33-!=5T4t0X5eAH?5Fjfzq6~>JU_^xgS-BBqNQ40+Dg?;NjVMDR z3>Z-%Kvr%<84_W@hzbF+awE!+2m?k`2#}QAS*Yb42dvcM1=rZd2Wch{w+NH=fOSOP5;1$e@V_Nz5q^)lsc}t4axuj002ov JPDHLkV1huQKJx$o literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/google.imageset/Contents.json b/OpenStreetView/Images.xcassets/google.imageset/Contents.json new file mode 100644 index 0000000..3eb79b3 --- /dev/null +++ b/OpenStreetView/Images.xcassets/google.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "google.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "google@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "google@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/google.imageset/google.png b/OpenStreetView/Images.xcassets/google.imageset/google.png new file mode 100644 index 0000000000000000000000000000000000000000..7eaa7f31121c005a713ee935f33c8e3509db8440 GIT binary patch literal 871 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/inactivePoints.imageset/inactivePoints@3x.png b/OpenStreetView/Images.xcassets/inactivePoints.imageset/inactivePoints@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..0dde319eec6f52aa2d1836ea87a0c7184eecf830 GIT binary patch literal 6395 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard@2x.png b/OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..824703f18d505065acfc08ee808a211341ad6471 GIT binary patch literal 345 zcmV-f0jBPx$6G=otRA>e5nN1FYFc5`1=t2+T*1hcgyN#D{=Y1r>HC}>v03utL9mkESAtXae zQyL$u2Ii;ldy|xaF}Oeg1V8`;{+R%cCB7&t%gm~JWT-yu^3@o3@2| z0XX1E03+lH&^tYO2j<=gJPQ=J`$bN070Ap`yWeikZp-Kb*xHk9Xy$IJZ*7Sm^6W=| zN_k(wDcpyE*e<{UIN(Vj`4Q@z1J|;84S-S~xA}TN{OF+_0fu?0?LtHgZEUExLUnLBir_&Eh5C8!Xm;iw{nztsp1FJ)`00000NkvXXu0mjf*;|W- literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard@3x.png b/OpenStreetView/Images.xcassets/leaderboard.imageset/leaderboard@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..5a92fa3ac504a016fc12dc4d134510d9f70358b3 GIT binary patch literal 444 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!jKx9jP7LeL$-D%z%RF5iLn;{G z-uCx8>>$zh@n_dP4}sF?E$knZ;*KPDm`}*s{?G9PS7hj&O6Jd&r@1)$Q0D!KY> zu8-ROJ&{{Xmi`EGU}O~ufD<>iI=uPRQ2yONe(94nPiF)^DlM$5x?^{OveYWPU zU&p7NGv=>p^DF!0Ftc#-O?ke#ck;Kp9*dT(HZj@fTbFUHew(ktjs;9;X5=)pFfn%I z3NZB6iAUSn#2?%z1Xk|Uo6St*Kd8{-)wcfs(9|caCrCx cFtF}pER4`fSfzI`7#JN4p00i_>zopr06(RvaR2}S literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/multiplier.imageset/Contents.json b/OpenStreetView/Images.xcassets/multiplier.imageset/Contents.json new file mode 100644 index 0000000..271afa3 --- /dev/null +++ b/OpenStreetView/Images.xcassets/multiplier.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "multiplier.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "multiplier@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "multiplier@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/multiplier.imageset/multiplier.png b/OpenStreetView/Images.xcassets/multiplier.imageset/multiplier.png new file mode 100644 index 0000000000000000000000000000000000000000..980ab354bace8e759fb170a1c418cafb108662cb GIT binary patch literal 1259 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/multiplier.imageset/multiplier@3x.png b/OpenStreetView/Images.xcassets/multiplier.imageset/multiplier@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..50f0306bade8fe439dfec07a54c8ca9c8f146b36 GIT binary patch literal 5314 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/noWifi.imageset/noWifi@2x.png b/OpenStreetView/Images.xcassets/noWifi.imageset/noWifi@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..62ddbbc574e55856764cbe2910a26bfc42325aed GIT binary patch literal 4451 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/noWifi.imageset/noWifi@3x.png b/OpenStreetView/Images.xcassets/noWifi.imageset/noWifi@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..3f7bf27a875979b229ad9af9e7cb92b56c0a2407 GIT binary patch literal 8055 zcmV--ABfPy9F-b&0RCodHT?>>{#hI>q`!(G??*Rq{@fpNTR3spRAc8sw^PZlWe%}4Qn(3jZ z`}VEsp6;F=m^ugU?W(_?|2K83{`&vF3~>Ml%d#pX@2{C0k9~Bc6>gtl#e1h4hE-!F z;x)puY7!z*V_2fvFhmuH!LmfBWrz+_nC-$a+6~jyZdrJ`Dz+NFnoTbEAzQqME!b%o zM%RHlY{r4oG0SSM4)1vCq*!;;*uOuh`M6*4}fSD!u1aT{Ds`D777$=|AhvtOoN&kPv#nU@Jj;sDD)r!{)@K;5jfOk;q_2A7YWKv8UIS>l zQ`1Mv`-lPrK;Vh(cz9lKXy>;?BC-&_-Q_sY07Fce-X|)8lYj1>ddXV+j+SFP?b=lK zfB@5t$nI6Mq8*#APDHz}z?Z(pt|R3eXSAE1z(bzu84q|Tp1Tp?u*$csLX<5aI2-hC zU3O8l=Y!j@+M8C+gQ(p$!`SZePgqhh{i+q^I%||2AOHkk_qO{lO?20 z{WZ3Xrxc~rkTfMCts)WLhkwn&>cunKF04cZVv4YQT6lt}uX@uf43|$Bc#8g~>8TM$ z#Ta4w8t@NKFGL%VWECS|>-uu#_<5HbjdQmbqkNq*i_O&FU}@9GR;`o{}b z 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 FV1m$Wk*WXy literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/Contents.json b/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/Contents.json new file mode 100644 index 0000000..19bd521 --- /dev/null +++ b/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "openstreetmapLogosvg.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "openstreetmapLogosvg@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "openstreetmapLogosvg@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg.png b/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg.png new file mode 100644 index 0000000000000000000000000000000000000000..7323042f3c3fc4e2f518670864b8b45c1d9a3054 GIT binary patch literal 3258 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg@3x.png b/OpenStreetView/Images.xcassets/openstreetmapLogosvg.imageset/openstreetmapLogosvg@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..3de25f9ab63e3677d7752cc1fac75a776de50c71 GIT binary patch literal 20986 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/pointsRecording.imageset/Contents.json b/OpenStreetView/Images.xcassets/pointsRecording.imageset/Contents.json new file mode 100644 index 0000000..0533040 --- /dev/null +++ b/OpenStreetView/Images.xcassets/pointsRecording.imageset/Contents.json @@ -0,0 +1,56 @@ +{ + "images" : [ + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "tile", + "width" : 1 + }, + "cap-insets" : { + "right" : 21, + "left" : 22 + } + }, + "idiom" : "universal", + "filename" : "pointsRecording.png", + "scale" : "1x" + }, + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "tile", + "width" : 1 + }, + "cap-insets" : { + "right" : 42, + "left" : 44 + } + }, + "idiom" : "universal", + "filename" : "pointsRecording@2x.png", + "scale" : "2x" + }, + { + "resizing" : { + "mode" : "3-part-horizontal", + "center" : { + "mode" : "tile", + "width" : 1 + }, + "cap-insets" : { + "right" : 64, + "left" : 66 + } + }, + "idiom" : "universal", + "filename" : "pointsRecording@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording.png b/OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording.png new file mode 100644 index 0000000000000000000000000000000000000000..c45a69403c932a723b960b594ffb4762331d9470 GIT binary patch literal 1630 zcmV-k2BGPx*7)eAyRCodHT-$F{MHru%bGF;P-@2sTUNQ6nwqUTt_@+%8O;95ukP0d$wVIe1 zO?)*b_y>^q-~)*S67W(bF;SnY=#z#}5ko0mc%Zei6xwaww%c}Z=Q!V4zO$#>6_;N3 zgqh9m%=yllv)}joW$yD0C94Rks?wh)XPX8mQ_n4=l;)J8)+;KhRVk@a71gzhS3i_l zDWwsK(cyANui7nasM^j3Ua0l_!R48i0zy}k@w>=ByTj4UEAe!uo0A+`$vZ@z;t*hr z-f_s})K0(cbZ3=wn3Js*moxj+0}*_FVy5}mNaE9UM(KEvKM~Ka4FVFS7x(yWZ#-M? zx?1cTiz4{OtQ!30=H26oG&!9A;<>a!!m$JyolBD0l%ju=ysj3Zcm#k5mxU3(Rnoq} za+z%RSc#`hTK1B1SvuKW7x$1{dyd4CN`V|gv|b26>Fx|U$xdIn{ujJGPFK6Eul8*7e5nib68}l?@uBFk z*kbxad_I=UkiL-^iHH)5kZej^!%OtOIv20TwKAva;I+yhz4vI~SRsW95)36bGM_qw z8OGu%^3}~4iSzbWgw035CQ;J;h?hY1jiJ&m_q^Q__zbTxUPiFi=H5wOz-oDrx3k~= zHA6C@&xDwjL@aaW_SL(|4sW)~hU&UK=-soortGp&L1w&w-m=!Ay4U7H$ra=p5h|T@ znisfpqchs*1+;@7o^3)QkHxd2mX1{jHcJu*XPQrU?v zKDenkGZH;v)K(`LCNXfF3%zCNP>D9z2vupOfulZN5P>rYiA-jHe`Iz$YO50rGgK&q zp^)e;BO0Y2!(7ClQ;WKy7bfOE!3&LG=vd+OBTQnzI9CL7A@Iw1oHwW0Qk>3^PT&+Q z&4qo_jrNMXluAHZoYON0VSxNCa~uaD67J8!$AP z+RI=k21;PbPXu!#Fk;{^o>p5KY_ma=U_Dm^b0c8nFr{Q_8SJ4#lZ-b}CSr3TVB}Cy zX$^x7a%h6_Cdx!?E(GQbwJ;wQS2KN%%UpH{ZHq(zHi6v2XJOZX2Y2XmJ<-0P; z7@8yqMkLG|8#!cD{hL`B9Yu4DH&G^Hb0J{l(88oKX0xy`no#d7!=#8!ia>*bLx)TU zS!;#md$gsQ@52?r+z2$ebA@zAh2;nKbcO3W-_H{Pvz#&`)%M(OJ#(A-@M&LVllkWP z>_&OMZ+e__dxL?mi$j*aKseeA`)*MtVsjwySRl7&+Ags^&aI-2i<$${=V(HEg^jyQ zh~X0AVU`#;dpuy%)olsLr{O|l^7)YWl0{-afq*+Wk&Y@SBtXRYsJ0O4nzAz!t7H7dQ!7ucicKLJF^Akb)yQsEKa7WM`=H3uz;RfZOgAE?y z;GHfJN*e*-=-^h5#u;d8m85fBA=fq3dI^IsZ{6}fWn>C&g4^ODo{@V=h)|*kz&!JT z1~+kI&zX|RBMpIGqq<87ZgkO!-CL|(;06H?f$z(Ub#6hj5wQ|UgX_wE?z)1LQ@~k! z(AQP#p;`e&HJ1KXwlff$_6UgMmgUlOQP<+Qw&@0SGf zWdwt;x5a387)t889pQi`i9=WriS>)2Duq(I;fJsoO%lf_8PVAI^tv6R zly3@D+u+XxE-&a6k^hXiUK<29^dPi+mBFt`9A%h~%F3^KH9am#YzU4rbXeH6keyvz c?NNsR0+97=Y5VJ0)Bpeg07*qoM6N<$f|bq>J^%m! literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording@2x.png b/OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..8d8b5553621eee4f501dc2931140177a428b4d36 GIT binary patch literal 4046 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 WGDPw&%#%2v1CYun#0N#o;Qs&`VTCUM literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording@3x.png b/OpenStreetView/Images.xcassets/pointsRecording.imageset/pointsRecording@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..cc4ba99c36bb2f446555f42601a3a96a4e45f02b GIT binary patch literal 6647 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 Vu|ZpuuZRWyox{6FULkCOlZ literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/Contents.json b/OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/Contents.json new file mode 100644 index 0000000..a112ff5 --- /dev/null +++ b/OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "windyRoadLineTall.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "windyRoadLineTall@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "windyRoadLineTall@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/windyRoadLineTall.png b/OpenStreetView/Images.xcassets/windyRoadLineTall-1.imageset/windyRoadLineTall.png new file mode 100644 index 0000000000000000000000000000000000000000..89e58c276057c07d80b77640c37b10e16e3ff175 GIT binary patch literal 8655 zcmV;=Au!&FP)PyBiAh93RCodHT?vp>)w%x9?e5tJ1`uQu6l5_X3ZhBW34$oTiZB`h*+a-nQZJ_R z66=|I6<-odpH@<-^5s>MR|(~UYzl}7W}ED<4~BPs*9usXoN?7d8P-}Ceo_pZVJ^T63f4=_D_MdYZxJJo=E&qBY1pVUx7(HWw^DBTu6);|nZhQbA zv~#pee(1wlJKEbZ93Q|3?UEmK0Ao$)K88;NlvOl9-LvPFh4yYA)~l<(d07o~MQcIi zHvkjIA#lb41AOxuTlvCR3j(_Vf!hFFXaIqI041K?@W9FzTg!ED=DiDu+m=*93)}%* zoQ`0dj?!x~N-4n^?ZZT*5l=ITyo&}Kgs#Sg?+mP~AR#RYiOD!`Z@e{`<^czzA@S06Ex)M;@G7l<_Wi$oto zhSn9W^fQVUNlL;N@Oqvq)UjmY0r929wYb#s7=mx6(RS)p@fd8wg@C7E!J6HLRPVw8 z;`)U%aOV4S?0#ztiNSfJm9gD8<9-4jTDLuKG?*yZ`9R#TbObKH{07HD516Qz8#TcJ zwi%ayegyMYol1B)(BfPm9{jEkj(0qQlaQYw2rC`Py8mRsOVvA9h8?p z;w0q@=Kzr=BO+UiUC5xKYIMg|hFt)GFLKIcCjUU(u)zb-EstY+{S-my5CsIsqQ_#w zNYMhG22b7NFmGPe;>=BDmtP=mSw0lE<<=p^Q%zCrMz)#*Z{c>~LfkGqXLZI#^UEI) zUtV+%O29R^Fg?&Hv2HvYIl$l|u23w7`D@>>u@ud$^V1c+wD@rZ;on>kYPL)610;cf zZ6dWz?u*Z@M2w9GS0D(N=f0|LiH14Agy%q*{k>d{8*>N5oy*FgF}xl@INLBo+=zMP z0NVsX;Xa#1O_49hsM2g*uj<>D-j{XnFdaUg^mAsqDv zT~lxzVC)E#m(H|%Mr|(;Us*N=!r?cuJ04kZ4d4GhxqVzVqB%?h*q%mPAyxZ-L^N1Teil%P5)K_cAn9=%mM4BDb#KavF z+5v_9=1FZzZA)!zv9T72v`#23(YUi?i`&Ub+1(+vF}1aY##$hXTmR^;6I$3hj?D_! zf~B^$jzH^BEo}{nKemoEHz#LvfKP@wH!|2%zsm|bt(mOE6c}jl*qZ#TsF|CG{TzrL z_P^H(MTzWzBQ015-*Xih>~D8RmOxrNj!_#|{KOGt)CLnbn$3+xY|aNSS-kNv%!H`cW%* zty{n_TfC|GQ3Ru?3C0UhQ9dz~(}9^uGdl9=g3wg^=|&bZYX;ps?FuBRtvPf+!6aeB zeBtILA{~AgVTbvm+!UG|@DUKrH-%c{*|lBZL(b#vBmoE*ke55EJYz(x_>Hh*!l(_ZAtif4VGta*Ex`^%0H@-3yU= zxRSk%X2~9N@*w*{v&?~J(2;cK@$up(kLOE9Zy__zf!Nh>E(o)1!`_n|1(t*vV>LD= z5v4UlK$U;jSk8f>m5AM(65wtlYm3GtBHh&Ln!@A&&2Xt3jo{j!^d`IfL4R5s)Y&%4 zs^SK*lOBk4XSI7>a8_-Rx5TsyLXU(q{1eAp(i(aT2y^*AY|dENOFl zCTe{lOGhH&XT@9)rf|~+X9hi}4OG~lrGzE=RGqp}$3A^vF%W9R*>dmtww*eU?Dg#} z5|Ow_-wrG<9gN2c6d$rwmx%P0PZxyt0??_stBWRUs3lAhwp5Hd5T#Ges>F7^tmlBH zZeNx~Ws16#_X>7&~$bkZFk#yMy6+sNb~Qxa%5#mq8}QCc#Yti$q`Ek0>GFzd>i%m6VbVJ|*e;o?M-Ik?e{ zaDdhdz4+u~;TkcBTeap)6i@f%+KBuHDl$Gs9GC0zi@Ln{Vs*}?pp2_Vx?@>%$x6Vb z$6ybgnmi*n?YVy>i=*letTgYGL*e6w>JtxTrdU8FEzw2bU(QrM}9M`n~OC_c4GJ`7?IXU)9Y z(z4A+E2=onKBXrO6%u1HjtjyxjFJUQ-)+Go0(7~O)|ipni+Gw>zVd4C@*%&f&UPh5 zR&}gUlFM?32vO+b0ceRf!e^m+Xz(A@LK`~^d)qg`>EQAF66cnl83#D8#uYhUm04mA?>!dxnhbAYibulUb5P$C*nlNvK{@)+=FB-I;y1BQUFZ$E{lZ<*x&jl&NOGKimuaz+V+%M9C;7K>x2!g;xi@r3iOD z9LNFAs&V-SterJmR8M~55b!^*00>HFYm~XFNZ~{zE<(+|!|=eRsW@At86&DUQ6FB2 z57AC_C}zWOjOgV0@s{(z|GowcclN=4h!y%Zorvt7Q zM`*+-ByR*G4KIuu0$!LTDyGqU=$HV7=S$!+PC#Ui2O{yEA9@q`$s>v;U;~E(t9?-6 zFZbY`t#H@7eV{ML8F|4QgJ_{>1TLe7K%2L*C`m-_e2Ez6C4c)BfJZE@t~~ErDnKXF>G%G+!~s!Oz-;S zo&$(Mfpc~&_a$3XB7biuz^C=f%mxg@ne<$xzs!f@cyq$O%P?9TE%SA)s`umA&K7=5 zV1m$KdpR~1Anw5~8uztR4ZHe!U^k~33;H|Y&UZ?oKkuKKyzt!_>4j3Fj1p$aFWw+9 z9~3kYX}3Y#z8bY~S{2M-6Q=?jeUrjp?!lWc!2R!!Mjc1(MR9rjg0Z9GhiQ|qTWrfJ z8iZ$`{onIAPK@bNnWo$!2?8B4Fh;r*1hLy602nkv;h*Gj_A^*?{Ej5Af_IQ$qpt}V zF%*}yxbtyE3SqDA+4IuR2I(l+abkkcm%jkG*3DKP>yafO;w18D;c{C>`KgZq8b6bHbX&_R0q*%0 zK$>NpvV(`=zP4$~^o8yt9Xvx+lEh1Wq(f8apD)9>G&Gceh+T7Gj}zle6!6zi8r~{~ z^}PawS>FdX3N>+bw)qC_`xtHu-Kvs<>tzcEcxX?Jj{0&b zrewfiDCuMJs6a{{W}Nh8E#Kgg;Kgz^O<(-#@9bqD2K^9eJPA?UDr71uP`8woz~G@b zf{6b(hI6u^LO_&9@B-E@e8LbG@hyfSBnBZA4L}f|5cfkc5&(a+9o_y6IjTv0aRvzN z1FD!LlmF*4UK0$#CFER8LKbJ0b6P7AHLC;B4(N=uLr0_q+QKc+9%+Vle7E2&(JfsU z@!bR+;Z}2iC8K3-M=gUW_WPijH! zk<0K!;3S+4d3M zYN&fZux{+5#o1q!Ie;sWB2N3U)ki-E$ zjzN!i9)X7T_u*J)J&s9Jl&NSkCTU+|vP5gkvY>FeYF!hpwBT)oSSx_Y*j|{wHnE-6(={WLzPRj1QOR8(S`3&NF!96f1WNovZjbCu zb`OF;dgB_W7o`)~%^HDu;M%GQ(lcxDVyJKV2kg1{S7;2JNuL${(&&r}?Xu*;FrMg^ zskkH{dKljtDJ4NxC~)Q12m!N-UD$K)mfre}OY zDcs!uPU-oeWk3A&+&XCPN~d~?U?gdmCU3oR4TpI=Tjg;TMSf>z>&Li=D}DPy9?`Ws zhXVvs0%IxeBhyn>5__vrSnUy|;a`^+fX!#t!mbN%sYUDYqrK^LCi|}WC@$MvCod*R zB1!>_ufku&)AC5J-B}!<-JUL7P^PCn5TlL2SyAeR@)9ppmigf7@+eHL?u1GNV%#hk zFc%(e=m#&JdM)myeCI+U3T#zs!HNNakCm)JxliP{rhqs=;Oq>Bp{XqZt<9})cc1no z5K>iWV*JaoGhk9*{nL)NRvYg@1Q9WoViZ99zo`|cG48IEc&@X6IB-2`y!jL@8>>JG z`v3NZ<$0_P+XV|=IGsv>vTK%N2&-`3KP@$~>&}h?(Uv9%pZo~IXO2Vk@_7*3E`!(= z!pQ;7q)W>|=raJk1BZfd*ckAQx*i0*dwsGX<+_Rzm_G0}*l}^6G8e_HK^Y}0AC5ym z6{A}0PxkQY=C0O8?4MCx#Wh)R0K3f4vBMBJv;!jNJ~f^dE;5&lo&Xg$&j9c6YmKMF zm^D5Q|1q9xN=3@-FHPrR$)P8c^QEb{k>#6ACo7Ekp}cf3)IG1b=0+8WMBR6Gw7!T6 zP)n03bzNpS5IJ)K+W)>DqIeEF8{@nBI;fgHA3XgA8qQ`c-g-IbDiQi>?2~;KjKY++ z|2;WBI$EHK2wBvOfe5Q${$|p^O%IW%Nwo{A!TWc$v35Qd?d)#b4g79xW?sT@yfcP3pLp;f* zZg38zV+8h;PH3+SI@Q$$%{mI9bZEbA)9-8pAu&8~cqeqcxy~@}n@|esf{=3JbTmT! zu5!Z#rHknG=weA@*4&-zoY4ni!-;L^nwhSg-V)x47iIR7`Y~mV+yAl>!e>8G2Bi25 z9y|!XG+{gpziKE{RaN2WM}(G^HaK>Nd2wGd)Qc@&4gY|pBgEQ>%FQ;!7zoCmg zsbj$ZgX5|zyy`3q9^M6A#}Dh) zbj-NX@Zj7!7&CU1W;_wKWey#D4>rH@Iy5$3(2VEbw-uLpMyH)o6TPHAp|6C4s$=}J zG?vsXFq;657)oRG$B6O78$Wp)f3~%8XK#EHqiUk@JNofX0Vv#^>|F zl4bMZ_S!G21*`grD9K)X^-u8Ut#7D?lc%Tul~A+vzkqpYrlD<)27|D-qeIeXP{zWs zqd@1uPbh=5e9Vjy8QYEOUSHG7D(*_LbYFKudEoY+S!Z?wzpv-+dFxZbE^R z=B}H*C^hMkn|}rm;WCaW_p;c|Hp4?}w;Rb+{U@%HlKD!1gx;MhLA}~5_#rNRXk3Cm z^IvAb^*1DGJ4w7E1%)7<-)(PeN07BbYfCG1w0A%#q`bR_65RXsyWx7A+^89`qZw!E zAE^c9*^hOiwl87EkTDFz6?c@M!u8H44dvR4B883}Qmt)ORV93VwsMXa!R4Q})^-T^ z13-2HB~4Jm;RyIU{m_Qsr14>@nLGahTyIt%(swne(~z2n!c89&qR(H@k`#^mEH(T| zn78Vb(JT!Ekuqe}eV;*Y*t1e=lwt?P6aDR)+jrCMs)h3M2OJAto(L&2LB*El{q#$*_ zMolObg7S)Fi8^ZZ)tbpKHk|`LSUX%TA%{We-PjXk;78IES;NNII-H>F)Ckq|HVs6| z>GfdSBhbZX;Ln?C(reAQ)@D#nMetjd18NlGIT{a|F(f%jGJ0e)-2nr%uUI~CsRM$6DXV#mEcTEz_1EE@+b>$*4XQm4fyEunRaIc|<>sdZ?+cIgv%(sPiZa79qvT zQFS6x@mo9^A8GXB2P;zzZR43WsRGJZqM_4;84D^mvKcE6Wr;A~SXA9uhy{T!qT63} zqiFzho1JJHTOG-2yXZQFu8T&f%lY-s?Pu=55J|-Q>H8q(S=CLT0me8c- zqS>Uy5WgL7p;a?9zB|@%A}NU0087hCll=4?sY^c;_vpvTc_z|h-W{lold<8HZ}&Ez z*%cgyZC_Eg5a!J@HwaE4Haj3vW_2UZ;r0^Vmfri0ptklO0;0yZqW`g1sr5wQ@@i=B z$lIl~v;<02#)JF!9gs&$*ols)1|5k=sumo#@(*#@W@9Xrh5}|JqNH`r7ULO|bE?^! z@XTn|tjK@vs5dG${ty)-_%EcxH%2N$zdX8Y#po}Peli+L2MT&BBI5I~ zVC}b)12T81b1>8VJayki*`9Q{PTH)90d#~>>meyfzgCBub0hKk4~?PUhewXWs~cZe zrJU9W%TPV5va%d1Dl34xV>J-cKJ*`c_q-+uFAZkeAf%Fscf><2{*u2L5K6VdHkR62 zwQ3o8ChG-dl!YwO#*G|)Jbepv1g4_z2w6yOtt18L$$=5E9cf@S=nM59%kg8MNFBtu z>&BR-rmHIq&;H>>c<*q%X4>~|7of9Ry==`y*#t1Q2L=eU;l9UAZQ-RW(w-V@URHx$ z<8JH@@^i^b4!dSzuz=&R>92dBs!f~SlWv{}i<^ zfqk15Gh{V-?E@l}_R6v`!0?DcuECfGAX0U&ImY0|{l+9zO-)}IHhc)qqN{Nffv5OT zLH6|Nv(k*3^3pRj9N0HgfF>Lt=EM*Px#w<}v+}rI<=J18m}K0R({4IXK%_<*UoXJ; z_w8dVM-U#ECcwE7_LY$YHtLSOzL|DO!gyJ^sf{#d6!C-+zaw6-t?xVnk?J+-r~nfW zB5N(4FGW!2;oWHf7lv6o$JA^KnwSW}EIY=8sb%H{h*av%Wo2+#T#sO!ol1nZLMFB( zEkBrDzR5EXseS`4FqpDOfbuN$RpY#BzJkNSJ4ER0iy$NG4r(s>ZOCn3B^0 zKqNZ65rDBr1eB0?F?)uK9l;9xhVcy?PL4rUWNIxlpFpF9Y~ryI(M)TJ#A7lHo`Y}9 z`W~?C_K#zk8T;E^va!gP#oDy=aRlJcadqBA`54tl(G4VV2oU4^DnUh@k+=hM)u#gV zX^#8qys?T+s3v%7v65>4tb0phI&g<<+4DFCc|1~sTiASsqu7FanJpCVR!rA_!t>1##6d)OE^G0N8VE# z1LcL!r=S=+N!{AKP zTbG6yQc*q;mujf1c8#4JARZI19RfnCs&gcwobl@yPQ$f|-{YEN@@Y+1B4#HM=>`Tm z{Ql6oopN?N!R{Q1DCY(->e@=W*5E%;LiQYqbLP)RPPudJNxZ@fk%*VXQwM^On3hDY zbGRs@WW&-CsK)#o96LTBDR&y#WpQWC$SxcoMri(rSHsb*TqZ6=l5sz0R_6mT&WcS- z>1K(aqq8>drTKP&NUYh7y$LN&Z`b6Lg8~W%h;gR9wyYKpT|I`NRNna(kJFoh$k;Yq zYkdmtU%5NZjzV}B9uVVP-Lhl~MBp)W*5U3!JoQ^@0 z5tt5H)R&Y#4k7qEoO_Q$ zV2;IEcui_lOWh3cTrfL^Y=1`cP`F`SXvJYGwaPyg07*naRCodHeFvNz#g+G~p4ljAS2+MeNJt_mA)+u*fCw^11hEQ8Ad_t4JKq7m z`|R)MvxV<`_U{g3`?CRC1S^50MFIpS87vVbG6+d1pn!6gR-5BY*Y{q}&N90@q4RY2 zyxL!H&vaM4diAgF|GY}C1aM#ktRV2l%r0;oP6iR}148ry3BB>?g(7?75j#uS3-1-- z_j~|Zpq-^C0Fm$=FJfp05KWlA8H8+V`%c%TY(N>u@Y+#4VrPM8f#0P(1~PO6dcbbD zWZ6maK~mj` zdhI|RcjAF({H`irgL3_LC@YJ4N?%sSQwT62da63ItjzMe`$1FVXi#AklHX_~ywOM~ zXCk?fRp!F}<9ZY)ikpBzEC9nelCPX_>^rMXOdrLt!j01>X zgd}kxNI?YH*N;W9uCq9dO>`tl_y8cZ8br~DP&TK^x?GmvHw2gv{Z?aU^<6Xzo4JvT z08}DCJd2S?fQngh!A>Vs#O6yR$khPKYLMa8Fm3M6V3(OoM+h(>2K716EWrA!ko>O0 z=I=H5f}a%BqPkNqu@{@!Z{QpA8i?Yz*n)Hib+>b2LUbE(r}C3hz_L5ef@t(wjRZkr zGZ?~7WtY=(1w_!6_&_7aQ0R5IW!@J^mNKU?2}t3Y5dB<{Gy*JN91p4}!@Dv;fxCLKCZ%upg9iTQV zOw)d(ScVql5|}#lT@bUeKazuA5MT?@FEv$u`^BI}rr?VJQNflAyc`k3n8hi}i320a{upm8T&TegewoV)L3qwh>@L%ytbdy<-HlL>|BalH1TK zEXcMxoPQP&(3TX6XCN>92uz;0AqyICmaPadA!h4QD4%%+sOpc=8l-uHTo2i*2QTF- z@JRsiIw;D+P_|%&msHCYUHCT~?O1IyAvysqtt&2{c{BDAK7`^&IFSX* z%vl6BU?1Zzu#fS1UO#RBGr)vsH>Tw?t_4;88k;$1*)5voF#>G}2=N6d;-^ry@b$K9 z{J}B;Oo)~tY!y&G<21AgAHk;aM7uw|i}3*@#;-EQ

fae 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/windyRoadLineTall-2.imageset/windyRoadLineTall@3x.png b/OpenStreetView/Images.xcassets/windyRoadLineTall-2.imageset/windyRoadLineTall@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..81d3a7698aaa6900a0f6282b2b54e20b7895df57 GIT binary patch literal 35396 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⁡& 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 FV1kOLdXxYF literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/Contents.json b/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/Contents.json new file mode 100644 index 0000000..a112ff5 --- /dev/null +++ b/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "windyRoadLineTall.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "windyRoadLineTall@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "windyRoadLineTall@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall.png b/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall.png new file mode 100644 index 0000000000000000000000000000000000000000..c99e2dfc37c0776c229a3950d286532728aefa2c GIT binary patch literal 10413 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall@3x.png b/OpenStreetView/Images.xcassets/windyRoadLineTall.imageset/windyRoadLineTall@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..496cbf4ae144367802f89ebdf987a73ecde4d860 GIT binary patch literal 36684 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 literal 0 HcmV?d00001 diff --git a/OpenStreetView/Info.plist b/OpenStreetView/Info.plist index d341ee2..2fda4ef 100644 --- a/OpenStreetView/Info.plist +++ b/OpenStreetView/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.2 + 1.5.1 CFBundleSignature ???? CFBundleURLTypes @@ -28,13 +28,41 @@ osmLogin + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + fb + + + FacebookAppID + + FacebookDisplayName + OpenStreetCam CFBundleVersion - 2 + 4 Fabric APIKey - c1f1517ab073bd0f7235948145e059192e8cb582 + Kits @@ -52,14 +80,20 @@ NSAllowsArbitraryLoads + NSBluetoothPeripheralUsageDescription + This app needs Bluetooth access. + NSCameraUsageDescription + This app needs to access your camera. NSLocationWhenInUseUsageDescription This app needs your location + NSPhotoLibraryUsageDescription + This app need to access you Photo Library. OSMCredentials OSMKey - rBWV8Eaottv44tXfdLofdNvVemHOL62Lsutpb9tw + OSMSecret - rpmeZIp49sEjjcz91X9dsY0vD1PpEduixuPy8T6S + UIFileSharingEnabled @@ -84,5 +118,14 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + UIViewControllerBasedStatusBarAppearance + + LSApplicationQueriesSchemes + + fbapi + fb-messenger-api + fbauth2 + fbshareextension + diff --git a/OpenStreetView/InfoBeta.plist b/OpenStreetView/InfoBeta.plist index a9a545d..8de7008 100644 --- a/OpenStreetView/InfoBeta.plist +++ b/OpenStreetView/InfoBeta.plist @@ -2,6 +2,8 @@ + UIViewControllerBasedStatusBarAppearance + CFBundleDevelopmentRegion en CFBundleExecutable @@ -15,7 +17,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.2 + 1.5.1 CFBundleSignature ???? CFBundleURLTypes @@ -28,13 +30,41 @@ osmLogin + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + fb + + + FacebookAppID + + FacebookDisplayName + OpenStreetCam CFBundleVersion - 2 + 4 Fabric APIKey - c1f1517ab073bd0f7235948145e059192e8cb582 + Kits @@ -54,12 +84,18 @@ NSLocationWhenInUseUsageDescription This app needs your location + NSBluetoothPeripheralUsageDescription + This app needs Bluetooth access. + NSCameraUsageDescription + This app needs to access your camera. + NSPhotoLibraryUsageDescription + This app need to access you Photo Library. OSMCredentials OSMKey - rBWV8Eaottv44tXfdLofdNvVemHOL62Lsutpb9tw + OSMSecret - rpmeZIp49sEjjcz91X9dsY0vD1PpEduixuPy8T6S + UIFileSharingEnabled @@ -84,5 +120,12 @@ UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight + LSApplicationQueriesSchemes + + fbapi + fb-messenger-api + fbauth2 + fbshareextension + diff --git a/OpenStreetView/InfoEnterprise.plist b/OpenStreetView/InfoEnterprise.plist index 4c26db3..b669fdb 100644 --- a/OpenStreetView/InfoEnterprise.plist +++ b/OpenStreetView/InfoEnterprise.plist @@ -2,6 +2,8 @@ + UIViewControllerBasedStatusBarAppearance + UIFileSharingEnabled CFBundleDevelopmentRegion @@ -17,7 +19,7 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.4.2 + 1.5.1 CFBundleSignature ???? CFBundleURLTypes @@ -30,13 +32,47 @@ osmLogin + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + + + + + CFBundleTypeRole + Editor + CFBundleURLSchemes + + fb + + + FacebookAppID + + FacebookDisplayName + OpenStreetCam CFBundleVersion - 2 + 4 LSRequiresIPhoneOS NSLocationWhenInUseUsageDescription This app needs your location + NSBluetoothPeripheralUsageDescription + This app needs Bluetooth access. + NSCameraUsageDescription + This app needs to access your camera. + NSPhotoLibraryUsageDescription + This app need to access you Photo Library. UILaunchStoryboardName LaunchScreen UIMainStoryboardFile @@ -66,14 +102,14 @@ OSMCredentials OSMSecret - rpmeZIp49sEjjcz91X9dsY0vD1PpEduixuPy8T6S + OSMKey - rBWV8Eaottv44tXfdLofdNvVemHOL62Lsutpb9tw + Fabric APIKey - c1f1517ab073bd0f7235948145e059192e8cb582 + Kits @@ -84,5 +120,12 @@ + LSApplicationQueriesSchemes + + fbapi + fb-messenger-api + fbauth2 + fbshareextension + diff --git a/OpenStreetView/LoginViewController.swift b/OpenStreetView/LoginViewController.swift new file mode 100644 index 0000000..d2f5ab9 --- /dev/null +++ b/OpenStreetView/LoginViewController.swift @@ -0,0 +1,102 @@ +// +// LoginViewController.swift +// OpenStreetView +// +// Created by Bogdan Sala on 22/02/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +import UIKit +import FBSDKLoginKit + +class LoginViewController: UIViewController, GIDSignInUIDelegate { + + + @IBOutlet weak var titleButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + titleButton.setTitle(NSLocalizedString("Login", comment:""), for: .normal) + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + } + + @IBAction func didTapFacebookButton(_ sender: Any) { + let login = FBSDKLoginManager() + login.logIn(withReadPermissions: nil, from: nil) { (result, error) in + if error == nil { + + if((FBSDKAccessToken.current()) != nil) { + FBSDKProfile.loadCurrentProfile(completion: { (profile, error) in + if error == nil { + NotificationCenter.default.post(name: Notification.Name("kOSVDidSigninRequest"), + object: nil, + userInfo: ["success":true]) + + if let navController = self.navigationController { + navController.popViewController(animated:true) + } + + if let prof = FBSDKProfile.current() { + NotificationCenter.default.post(name: Notification.Name("kOSVFacebookSignIn"), + object: nil, + userInfo: ["user":prof]) + + } + } + }) + } + } else { + NSLog("does not log in") + } + } + } + + @IBAction func didTapGoogleButton(_ sender: Any) { + GIDSignIn.sharedInstance().uiDelegate = self + GIDSignIn.sharedInstance().signIn() + } + + @IBAction func didTapOSMButton(_ sender: Any) { + if !OSVSyncController.sharedInstance().tracksController.userIsLoggedIn() { + OSVSyncController.sharedInstance().tracksController.login(partial: { (error) in + if error != nil { + OSVSyncController.sharedInstance().tracksController.logout() + } else { + if let navController = self.navigationController { + navController.popViewController(animated:true) + } + } + }, andCompletion: { (error) in + if error != nil { + OSVSyncController.sharedInstance().tracksController.logout() + } else { + NotificationCenter.default.post(name: Notification.Name("kOSVDidSigninRequest"), + object: nil, + userInfo: ["success":true]) + } + }) + } + } + + @IBAction func didTapBackButton(_ sender: Any) { + if let navController = self.navigationController { + navController.popViewController(animated:true) + } + } + + func sign(_ signIn: GIDSignIn!, dismiss viewController: UIViewController!) { + + if let navController = self.navigationController { + navController.popViewController(animated:true) + viewController.dismiss(animated: true, completion: { + NotificationCenter.default.post(name: Notification.Name("kOSVDidSigninRequest"), + object: nil, + userInfo: ["success":true]) + + }); + } + } +} diff --git a/OpenStreetView/Models/Categories/OSVPhoto+Relm.m b/OpenStreetView/Models/Categories/OSVPhoto+Relm.m index a0ff327..04cdce4 100644 --- a/OpenStreetView/Models/Categories/OSVPhoto+Relm.m +++ b/OpenStreetView/Models/Categories/OSVPhoto+Relm.m @@ -12,43 +12,48 @@ @implementation OSVPhoto (Relm) - (RLMPhoto *)toRealmObject { - RLMPhoto *photo = [[RLMPhoto alloc] init]; - photo.latitude = self.photoData.location.coordinate.latitude; - photo.longitude = self.photoData.location.coordinate.longitude; - photo.altitude = self.photoData.location.altitude; - photo.course = self.photoData.location.course; - photo.speed = self.photoData.location.speed; + RLMPhoto *photo = [[RLMPhoto alloc] init]; + photo.latitude = self.photoData.location.coordinate.latitude; + photo.longitude = self.photoData.location.coordinate.longitude; + photo.altitude = self.photoData.location.altitude; + photo.course = self.photoData.location.course; + photo.speed = self.photoData.location.speed; photo.horizontalAccuracy = self.photoData.location.horizontalAccuracy; photo.verticalAccuracy = self.photoData.location.verticalAccuracy; - photo.sequenceIndex = self.photoData.sequenceIndex; - photo.videoIndex = self.photoData.videoIndex; + photo.sequenceIndex = self.photoData.sequenceIndex; + photo.videoIndex = self.photoData.videoIndex; - photo.timestamp = [NSDate dateWithTimeIntervalSince1970:self.photoData.timestamp]; + photo.timestamp = [NSDate dateWithTimeIntervalSince1970:self.photoData.timestamp]; if (self.photoData.addressName) { - photo.addressName = self.photoData.addressName; + photo.addressName = self.photoData.addressName; } - photo.localSequenceID = self.localSequenceId; - photo.serverSequenceID = self.serverSequenceId; - photo.localPhotoID = [@([photo.timestamp timeIntervalSince1970]) stringValue]; - photo.hasOBD = self.hasOBD; + photo.localSequenceID = self.localSequenceId; + photo.serverSequenceID = self.serverSequenceId; + photo.localPhotoID = [@([photo.timestamp timeIntervalSince1970]) stringValue]; + photo.hasOBD = self.hasOBD; return photo; } + (OSVPhoto *)fromRealmObject:(RLMPhoto *)rlmObj { - OSVPhoto *photo = [OSVPhoto new]; + OSVPhoto *photo = [OSVPhoto new]; - photo.serverSequenceId = rlmObj.serverSequenceID; - photo.localSequenceId = rlmObj.localSequenceID; - photo.hasOBD = rlmObj.hasOBD; + photo.serverSequenceId = rlmObj.serverSequenceID; + photo.localSequenceId = rlmObj.localSequenceID; + photo.hasOBD = rlmObj.hasOBD; - photo.photoData = [OSVPhotoData new]; - CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(rlmObj.latitude, rlmObj.longitude); - photo.photoData.location = [[CLLocation alloc] initWithCoordinate:coordinate altitude:rlmObj.altitude horizontalAccuracy:rlmObj.horizontalAccuracy verticalAccuracy:rlmObj.verticalAccuracy course:rlmObj.course speed:rlmObj.speed timestamp:rlmObj.timestamp]; + photo.photoData = [OSVPhotoData new]; + photo.photoData.location = [[CLLocation alloc] initWithCoordinate:CLLocationCoordinate2DMake(rlmObj.latitude, rlmObj.longitude) + altitude:rlmObj.altitude + horizontalAccuracy:rlmObj.horizontalAccuracy + verticalAccuracy:rlmObj.verticalAccuracy + course:rlmObj.course + speed:rlmObj.speed + timestamp:rlmObj.timestamp]; photo.photoData.sequenceIndex = rlmObj.sequenceIndex; photo.photoData.addressName = rlmObj.addressName; diff --git a/OpenStreetView/Models/Categories/OSVServerSequence+Convertor.m b/OpenStreetView/Models/Categories/OSVServerSequence+Convertor.m index 56a4c4a..1f43902 100644 --- a/OpenStreetView/Models/Categories/OSVServerSequence+Convertor.m +++ b/OpenStreetView/Models/Categories/OSVServerSequence+Convertor.m @@ -7,6 +7,7 @@ // #import "OSVServerSequence+Convertor.h" +#import "OSVScoreHistory.h" @implementation OSVServerSequence (Convertor) @@ -32,6 +33,8 @@ + (OSVServerSequence *)trackFromDictionary:(NSDictionary *)seqDictionary { sequence.uid = [seqDictionary[@"element_id"] hash]; } + sequence.coverage = [seqDictionary[@"coverage"] integerValue]; + return sequence; } @@ -48,6 +51,33 @@ + (OSVServerSequence *)sequenceFromDictionary:(NSDictionary *)seqDictionary { sequence.location = seqDictionary[@"location"]; sequence.previewImage = seqDictionary[@"thumb_name"]; sequence.photoCount = [seqDictionary[@"photo_no"] integerValue]; + if ([seqDictionary[@"upload_history"] isKindOfClass:[NSDictionary class]]) { + sequence.points = [seqDictionary[@"upload_history"][@"points"][@"total"] integerValue]; + sequence.scoreHistory = [NSMutableArray array]; + + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + + for (NSDictionary *coverage in seqDictionary[@"upload_history"][@"coverage"]) { + + NSInteger multi = [coverage[@"coverage_points"] integerValue]/[coverage[@"coverage_photos_count"] integerValue]; + + if (!dict[@(multi)]) { + dict[@(multi)] = [OSVScoreHistory new]; + } + + OSVScoreHistory *history = dict[@(multi)]; + history.coverage += [coverage[@"coverage_value"] integerValue]; + history.distance += [coverage[@"coverage_distance"] doubleValue]; + history.points += [coverage[@"coverage_points"] integerValue]; + history.photos += [coverage[@"coverage_photos_count"] integerValue]; + history.multiplier = history.points/history.photos; + } + + for (NSNumber *key in dict) { + [sequence.scoreHistory addObject:dict[key]]; + } + + } if ([seqDictionary[@"distance"] respondsToSelector:@selector(doubleValue)]) { sequence.length = [seqDictionary[@"distance"] doubleValue] * 1000; diff --git a/OpenStreetView/Models/OSVSequence.h b/OpenStreetView/Models/OSVSequence.h index 237e1dd..2082100 100644 --- a/OpenStreetView/Models/OSVSequence.h +++ b/OpenStreetView/Models/OSVSequence.h @@ -28,6 +28,7 @@ @property (nonatomic, assign) BOOL hasOBD; @property (nonatomic, strong) NSString *location; @property (nonatomic, strong) NSString *previewImage; +@property (nonatomic, assign) NSInteger coverage; - (BOOL)intersectWithTopLeftCoordinate:(CLLocationCoordinate2D)topLeftCoordinate andBottomRightCoordinate:(CLLocationCoordinate2D)bottomRightCoordinate; @@ -37,6 +38,8 @@ @interface OSVSequence : NSObject @property (nonatomic, assign) NSInteger uploadID; // the id used to upload a sequence of photos +@property (nonatomic, assign) NSInteger points; +@property (nonatomic, strong) NSMutableArray *scoreHistory; @property (nonatomic, strong) NSMutableDictionary *videos; @end diff --git a/OpenStreetView/Models/OSVSequence.m b/OpenStreetView/Models/OSVSequence.m index 6271dbb..a74a0b0 100644 --- a/OpenStreetView/Models/OSVSequence.m +++ b/OpenStreetView/Models/OSVSequence.m @@ -22,6 +22,7 @@ @implementation OSVSequence @synthesize hasOBD; @synthesize location; @synthesize previewImage; +@synthesize coverage; - (BOOL)intersectWithTopLeftCoordinate:(CLLocationCoordinate2D)tlCoordinate andBottomRightCoordinate:(CLLocationCoordinate2D)brCoordinate { if ((!self.topLeftCoordinate.latitude && !self.topLeftCoordinate.longitude) || (!self.bottomRightCoordinate.latitude && !self.bottomRightCoordinate.longitude)) { diff --git a/OpenStreetView/Models/OSVServerSequence.h b/OpenStreetView/Models/OSVServerSequence.h index 2267d24..5aa6bc0 100644 --- a/OpenStreetView/Models/OSVServerSequence.h +++ b/OpenStreetView/Models/OSVServerSequence.h @@ -11,9 +11,11 @@ @interface OSVServerSequence : NSObject -@property (nonatomic, strong) NSString *countryCode; -@property (nonatomic, strong) NSString *clientToken; +@property (nonatomic, strong) NSString *countryCode; +@property (nonatomic, strong) NSString *clientToken; @property (nonatomic, assign) NSInteger photoCount; +@property (nonatomic, assign) NSInteger points; +@property (nonatomic, strong) NSMutableArray *scoreHistory; @end @@ -25,4 +27,4 @@ @property (nonatomic, strong) NSString *author; @property (nonatomic, assign) NSInteger photoCount; -@end \ No newline at end of file +@end diff --git a/OpenStreetView/Models/OSVServerSequence.m b/OpenStreetView/Models/OSVServerSequence.m index 44fc761..a73ba68 100644 --- a/OpenStreetView/Models/OSVServerSequence.m +++ b/OpenStreetView/Models/OSVServerSequence.m @@ -22,6 +22,8 @@ @implementation OSVServerSequence @synthesize hasOBD; @synthesize location; @synthesize previewImage; +@synthesize coverage; +@synthesize scoreHistory; - (BOOL)intersectWithTopLeftCoordinate:(CLLocationCoordinate2D)tlCoordinate andBottomRightCoordinate:(CLLocationCoordinate2D)brCoordinate { if ((!self.topLeftCoordinate.latitude && !self.topLeftCoordinate.longitude) || (!self.bottomRightCoordinate.latitude && !self.bottomRightCoordinate.longitude)) { @@ -53,6 +55,7 @@ @implementation OSVServerSequencePart @synthesize hasOBD; @synthesize location; @synthesize previewImage; +@synthesize coverage; - (BOOL)intersectWithTopLeftCoordinate:(CLLocationCoordinate2D)tlCoordinate andBottomRightCoordinate:(CLLocationCoordinate2D)brCoordinate { if ((!self.topLeftCoordinate.latitude && !self.topLeftCoordinate.longitude) || (!self.bottomRightCoordinate.latitude && !self.bottomRightCoordinate.longitude)) { diff --git a/OpenStreetView/NSAttributedString+Additions.h b/OpenStreetView/NSAttributedString+Additions.h index 6a37826..1856be7 100644 --- a/OpenStreetView/NSAttributedString+Additions.h +++ b/OpenStreetView/NSAttributedString+Additions.h @@ -14,6 +14,9 @@ + (NSAttributedString *)attributedStringWithString:(NSString *)text withSize:(float)textSize color:(UIColor *)textColor fontName:(NSString *)textFont; + (NSAttributedString *)combineString:(NSString *)text withSize:(float)textSize color:(UIColor *)textColor fontName:(NSString *)textFont withString:(NSString *)secondtext withSize:(float)secondSize color:(UIColor *)secondColor fontName:(NSString *)sencondFont; ++ (NSAttributedString *)combineString:(NSString *)text withSize:(float)textSize color:(UIColor *)textColor fontName:(NSString *)textFont + withString:(NSString *)stext withSize:(float)secSize color:(UIColor *)secoColor fontName:(NSString *)secoFont + adjustBaseline:(BOOL)adj; - (NSMutableAttributedString *)appendString:(NSString *)aString withSize:(float)textSize color:(UIColor *)textColor fontName:(NSString *)textfont; diff --git a/OpenStreetView/NSAttributedString+Additions.m b/OpenStreetView/NSAttributedString+Additions.m index 735a670..6f831b5 100644 --- a/OpenStreetView/NSAttributedString+Additions.m +++ b/OpenStreetView/NSAttributedString+Additions.m @@ -47,6 +47,44 @@ + (NSAttributedString *)combineString:(NSString *)text withSize:(float)textSize return attSpace; } ++ (NSAttributedString *)combineString:(NSString *)text1 withSize:(float)textSize color:(UIColor *)textColor fontName:(NSString *)textFont + withString:(NSString *)text2 withSize:(float)secSize color:(UIColor *)secoColor fontName:(NSString *)secoFont + adjustBaseline:(BOOL)adjust { + if (!text1) { + text1 = @""; + } + + if (!text2) { + text2 = @""; + } + + NSRange range1 = NSMakeRange(0, [text1 length]); + NSMutableAttributedString *att1 = [[NSMutableAttributedString alloc] initWithString:text1]; + [att1 addAttribute:NSForegroundColorAttributeName value:textColor range:range1]; + UIFont *font1 = [UIFont fontWithName:textFont size:textSize]; + [att1 addAttribute:NSFontAttributeName value:font1 range:range1]; + + NSRange range2 = NSMakeRange(0, [text2 length]); + NSMutableAttributedString *att2 = [[NSMutableAttributedString alloc] initWithString:text2]; + [att2 addAttribute:NSForegroundColorAttributeName value:secoColor range:range2]; + UIFont *font2 = [UIFont fontWithName:secoFont size:secSize]; + [att2 addAttribute:NSFontAttributeName value:font2 range:range2]; + + if (adjust) { + if (font1.capHeight < font2.capHeight) { + float value = font2.capHeight - font1.capHeight; + [att1 addAttribute:NSBaselineOffsetAttributeName value:@(value/2.0) range:range1]; + } else { + float value = font1.capHeight - font2.capHeight; + [att2 addAttribute:NSBaselineOffsetAttributeName value:@(value/2.0) range:range2]; + } + } + + [att1 appendAttributedString:att2]; + + return att1; +} + - (NSMutableAttributedString *)appendString:(NSString *)aString withSize:(float)textSize color:(UIColor *)textColor fontName:(NSString *)textfont { if (!aString) { aString = @""; diff --git a/OpenStreetView/OBDDevice+Internal.h b/OpenStreetView/OBDLib/OBDDevice+Internal.h similarity index 100% rename from OpenStreetView/OBDDevice+Internal.h rename to OpenStreetView/OBDLib/OBDDevice+Internal.h diff --git a/OpenStreetView/OBDDevice.h b/OpenStreetView/OBDLib/OBDDevice.h similarity index 100% rename from OpenStreetView/OBDDevice.h rename to OpenStreetView/OBDLib/OBDDevice.h diff --git a/OpenStreetView/OBDDevice.m b/OpenStreetView/OBDLib/OBDDevice.m similarity index 98% rename from OpenStreetView/OBDDevice.m rename to OpenStreetView/OBDLib/OBDDevice.m index 6d417d8..1e98c85 100644 --- a/OpenStreetView/OBDDevice.m +++ b/OpenStreetView/OBDLib/OBDDevice.m @@ -37,7 +37,7 @@ - (id)initWithPeripheral:(CBPeripheral *)peripheral centralManager:(CBCentralMan self.internalManager = manager; self.pendingRequests = [NSMutableArray array]; } - + return self; } @@ -79,7 +79,7 @@ - (void)connect { _connected = NO; [self.pendingRequests removeAllObjects]; self.responseData = nil; - + [self.internalManager connectPeripheral:self.internalPeripheral options:nil]; } } @@ -98,9 +98,9 @@ - (void)getValueForSensor:(OBDSensor)sensor { if (!_connected) { return; } - + [self.pendingRequests addObject:@(sensor)]; - + //check if we got a response pending if (!self.responseData) { [self requestValueForSensor:sensor]; @@ -113,7 +113,7 @@ - (void)requestValueForSensor:(OBDSensor)sensor { if (!_connected) { return; } - + self.responseData = [NSMutableData data]; char buffer[5]; snprintf(buffer, 5, "%04X", sensor); @@ -133,7 +133,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverServices:(NSError *)err break; } } - + if (self.obdService) { [self.internalPeripheral discoverCharacteristics:@[[CBUUID UUIDWithString:kCharacteristicID]] forService:self.obdService]; } else { @@ -153,7 +153,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForServi if (service != self.obdService) { return; } - + //find the obd characteristic for (CBCharacteristic *characteristic in service.characteristics) { if ([characteristic.UUID isEqual:[CBUUID UUIDWithString:kCharacteristicID]]) { @@ -162,7 +162,7 @@ - (void)peripheral:(CBPeripheral *)peripheral didDiscoverCharacteristicsForServi break; } } - + if (!self.obdCharacteristic) { NSError *e = error; if (!e) { @@ -180,9 +180,9 @@ - (void)peripheral:(CBPeripheral *)peripheral didUpdateValueForCharacteristic:(C if(!self.responseData) { return; } - + [self.responseData appendData:characteristic.value]; - + //check for end of message if (strstr(self.responseData.bytes, "\r>")) { [self.responseData appendBytes:"\0" length:1]; @@ -228,7 +228,7 @@ - (void)handleDisconnection:(NSError *)error { if ([self.delegate respondsToSelector:@selector(OBDDeviceDidDisconnect:error:)]) { [self.delegate OBDDeviceDidDisconnect:self error:error]; } - + if (error.code == CBErrorConnectionTimeout) { [self connect]; } @@ -241,7 +241,7 @@ - (void)processResponse { return; } OBDSensor sensor = (OBDSensor)[self.pendingRequests[0] intValue]; - + BOOL parseSucceed = false; switch (sensor) { case OBDSensorEngineRPM: { @@ -251,7 +251,7 @@ - (void)processResponse { } } break; - + case OBDSensorVehicleSpeed: { int speed = 0; if ((parseSucceed = [OBDUtils getSpeed:&speed fromData:self.responseData]) && [self.delegate respondsToSelector:@selector(OBDDevice:didUpdateInteger:forSensor:)]) { @@ -259,12 +259,12 @@ - (void)processResponse { } } break; - + default: NSLog(@"got response for unsupported sensor"); break; } - + if (!parseSucceed && [self.delegate respondsToSelector:@selector(OBDDevice:failedToGetValueForSensor:)]) { [self.delegate OBDDevice:self failedToGetValueForSensor:sensor]; } diff --git a/OpenStreetView/OBDDeviceDelegate.h b/OpenStreetView/OBDLib/OBDDeviceDelegate.h similarity index 100% rename from OpenStreetView/OBDDeviceDelegate.h rename to OpenStreetView/OBDLib/OBDDeviceDelegate.h diff --git a/OpenStreetView/OBDLib.h b/OpenStreetView/OBDLib/OBDLib.h similarity index 100% rename from OpenStreetView/OBDLib.h rename to OpenStreetView/OBDLib/OBDLib.h diff --git a/OpenStreetView/OBDSensors.h b/OpenStreetView/OBDLib/OBDSensors.h similarity index 99% rename from OpenStreetView/OBDSensors.h rename to OpenStreetView/OBDLib/OBDSensors.h index 9d12c11..c7dade1 100644 --- a/OpenStreetView/OBDSensors.h +++ b/OpenStreetView/OBDLib/OBDSensors.h @@ -27,4 +27,4 @@ typedef NS_ENUM(uint16_t, OBDSensor) { OBDSensorMAFAirFlow = 0x0110, OBDSensorThrottlePosition = 0x0111, OBDSensorUnknown = 0xFFFF -}; \ No newline at end of file +}; diff --git a/OpenStreetView/OBDService.h b/OpenStreetView/OBDLib/OBDService.h similarity index 100% rename from OpenStreetView/OBDService.h rename to OpenStreetView/OBDLib/OBDService.h diff --git a/OpenStreetView/OBDService.m b/OpenStreetView/OBDLib/OBDService.m similarity index 86% rename from OpenStreetView/OBDService.m rename to OpenStreetView/OBDLib/OBDService.m index 55147ae..c6478d1 100644 --- a/OpenStreetView/OBDService.m +++ b/OpenStreetView/OBDLib/OBDService.m @@ -30,28 +30,29 @@ @implementation OBDService + (instancetype)sharedInstance { static OBDService *instance; - + static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ instance = [OBDService new]; }); - + return instance; } - (id)init { self = [super init]; - + if (self) { self.bluethoothQueue = dispatch_queue_create("OBDServiceBluetoothQueue", DISPATCH_QUEUE_SERIAL); if ([self backgroundBluetoothEnabled]) { - self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:self.bluethoothQueue options:@{CBCentralManagerOptionRestoreIdentifierKey : kCentralManagerRestorationID, CBCentralManagerOptionShowPowerAlertKey: @NO}]; + self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:self.bluethoothQueue options:@{CBCentralManagerOptionRestoreIdentifierKey : kCentralManagerRestorationID, + CBCentralManagerOptionShowPowerAlertKey : @NO}]; } else { - self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:self.bluethoothQueue options:@{CBCentralManagerOptionShowPowerAlertKey: @NO}]; + self.centralManager = [[CBCentralManager alloc] initWithDelegate:self queue:self.bluethoothQueue options:@{CBCentralManagerOptionShowPowerAlertKey : @NO}]; } self.devices = [NSMutableArray array]; } - + return self; } @@ -77,7 +78,9 @@ - (void)searchForDevicesOnConnection:(OBDConnectionType)connection { } - (void)stopDeviceSearch { - [self.centralManager stopScan]; + if (self.centralManager.state == CBCentralManagerStatePoweredOn) { + [self.centralManager stopScan]; + } } #pragma mark - CBCentralManagerDelegate methods @@ -95,16 +98,6 @@ - (void)centralManagerDidUpdateState:(CBCentralManager *)central { } } -- (void)centralManager:(CBCentralManager *)central willRestoreState:(NSDictionary *)dict { - NSArray *peripherals = dict[CBCentralManagerRestoredStatePeripheralsKey]; - for (CBPeripheral *p in peripherals) { - OBDDevice *device = [self deviceForPeripheral:p]; - if (device) { - device.peripheral = p; - } - } -} - - (void)centralManager:(CBCentralManager *)central didConnectPeripheral:(CBPeripheral *)peripheral { OBDDevice *device = [self deviceForPeripheral:peripheral]; if (device) { @@ -126,7 +119,10 @@ - (void)centralManager:(CBCentralManager *)central didFailToConnectPeripheral:(C } } -- (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeripheral *)peripheral advertisementData:(NSDictionary *)advertisementData RSSI:(NSNumber *)RSSI { +- (void)centralManager:(CBCentralManager *)central + didDiscoverPeripheral:(CBPeripheral *)peripheral + advertisementData:(NSDictionary *)advertisementData + RSSI:(NSNumber *)RSSI { BOOL deviceExists = false; for (OBDDevice *device in self.devices) { if ([peripheral.identifier isEqual:device.peripheral.identifier]) { @@ -134,7 +130,7 @@ - (void)centralManager:(CBCentralManager *)central didDiscoverPeripheral:(CBPeri break; } } - + if (!deviceExists) { OBDDevice *device = [[OBDDevice alloc] initWithPeripheral:peripheral centralManager:self.centralManager]; [self.devices addObject:device]; @@ -152,7 +148,7 @@ - (OBDDevice *)deviceForPeripheral:(CBPeripheral *)peripheral { return d; } } - + return nil; } @@ -163,7 +159,7 @@ - (BOOL)backgroundBluetoothEnabled { return YES; } } - + return NO; } diff --git a/OpenStreetView/OBDServiceDelegate.h b/OpenStreetView/OBDLib/OBDServiceDelegate.h similarity index 98% rename from OpenStreetView/OBDServiceDelegate.h rename to OpenStreetView/OBDLib/OBDServiceDelegate.h index 5bbf999..3ad9a29 100644 --- a/OpenStreetView/OBDServiceDelegate.h +++ b/OpenStreetView/OBDLib/OBDServiceDelegate.h @@ -12,6 +12,7 @@ typedef NS_ENUM(NSInteger, OBDConnectionType) { OBDConnectionTypeBluetoothLE = 1, }; + @class OBDService; @class OBDDevice; @@ -22,4 +23,4 @@ typedef NS_ENUM(NSInteger, OBDConnectionType) { - (void)OBDService:(OBDService *)service didDidFindDevice:(OBDDevice *)device; - (void)OBDService:(OBDService *)service unableToSearchForDevicesOnConnection:(OBDConnectionType)connection; -@end \ No newline at end of file +@end diff --git a/OpenStreetView/OBDUtils.h b/OpenStreetView/OBDLib/OBDUtils.h similarity index 100% rename from OpenStreetView/OBDUtils.h rename to OpenStreetView/OBDLib/OBDUtils.h diff --git a/OpenStreetView/OBDUtils.m b/OpenStreetView/OBDLib/OBDUtils.m similarity index 99% rename from OpenStreetView/OBDUtils.m rename to OpenStreetView/OBDLib/OBDUtils.m index 814883b..5737562 100644 --- a/OpenStreetView/OBDUtils.m +++ b/OpenStreetView/OBDLib/OBDUtils.m @@ -19,7 +19,7 @@ + (BOOL)getRPM:(int *)rpm fromData:(NSData *)data { number[2] = bytes[3]; number[3] = bytes[4]; number[4] = '\0'; - + long value = strtol(number, NULL, 16) / 4; *rpm = (int)value; return YES; @@ -39,7 +39,7 @@ + (BOOL)getSpeed:(int *)speed fromData:(NSData *)data { *speed = (int)value; return YES; } - + return NO; } @@ -55,7 +55,7 @@ + (OBDSensor)getPIDFromResponse:(NSData *)response { long value = strtol(number, NULL, 16) - 0x4000; return (OBDSensor)value; } - + return OBDSensorUnknown; } diff --git a/OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h b/OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h new file mode 100644 index 0000000..7f5f335 --- /dev/null +++ b/OpenStreetView/OSC_ORBB_Dev-Bridging-Header.h @@ -0,0 +1,21 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "OSVServerSequence.h" +#import "OSVServerPhoto.h" +#import "OSVSequence.h" +#import "OSVMetadata.h" +#import "OSVScoreHistory.h" +#import "OSVPolyline.h" +#import "OSVSyncController.h" +#import "RLMScoreHistory.h" +#import +#import +#import + +#import "OSVUtils.h" + +#import "NSAttributedString+Additions.h" +#import "NSMutableAttributedString+Additions.h" +#import "UIColor+OSVColor.h" diff --git a/OpenStreetView/OSMAPI/Models/OSMUser.h b/OpenStreetView/OSMAPI/Models/OSMUser.h index f8598a1..16f73fa 100644 --- a/OpenStreetView/OSMAPI/Models/OSMUser.h +++ b/OpenStreetView/OSMAPI/Models/OSMUser.h @@ -20,7 +20,8 @@ @property (nonatomic, assign) CLLocationCoordinate2D homeCoordinate; @property (nonatomic, strong) NSString *descriptions; -@property (nonatomic, strong) NSString *key; -@property (nonatomic, strong) NSString *secret; +@property (nonatomic, strong) NSString *providerKey; +@property (nonatomic, strong) NSString *providerSecret; +@property (nonatomic, strong) NSString *provider; @end diff --git a/OpenStreetView/OSMAPI/OSMAPI.h b/OpenStreetView/OSMAPI/OSMAPI.h index d9c69de..2800736 100644 --- a/OpenStreetView/OSMAPI/OSMAPI.h +++ b/OpenStreetView/OSMAPI/OSMAPI.h @@ -9,9 +9,8 @@ #import #import "OSMUser.h" -#define kCredentialsID @"osmLoginCredentials" -#define kOSMUsernameKey @"OSMUsernameKey" -#define kOSMUserIdKey @"OSMUserIdKey" +#define kOSCCredentialsID @"kOSCCredentialsID" +#define kOSCAuthProvider @"kOSCAuthProvider" @protocol OSMAPIDelegate; @class AFOAuth1Token; @@ -19,7 +18,6 @@ @interface OSMAPI : NSObject @property (nonatomic, copy) void (^didFinishLogin)(OSMUser *user, BOOL success); -@property (nonatomic, assign, readonly, getter = isAuthorized) BOOL authorized; #pragma mark Initialization + (instancetype)sharedInstance; @@ -29,6 +27,8 @@ - (BOOL)logout; - (void)signUp; +- (BOOL)isAuthorized; + - (OSMUser *)osmUser; - (AFOAuth1Token *)osmAccessToken; diff --git a/OpenStreetView/OSMAPI/OSMAPI.m b/OpenStreetView/OSMAPI/OSMAPI.m index 278069c..d3cdbe5 100644 --- a/OpenStreetView/OSMAPI/OSMAPI.m +++ b/OpenStreetView/OSMAPI/OSMAPI.m @@ -28,6 +28,10 @@ #define kSignUpURL @"http://openstreetmap.org/user/new" +#define kCredentialsID @"osmLoginCredentials" +#define kOSMUsernameKey @"OSMUsernameKey" +#define kOSMUserIdKey @"OSMUserIdKey" + @protocol OSMAPIDelegate; @interface OSMAPI() @@ -57,7 +61,8 @@ - (id)init { NSString *secret = credentials[kOSMSecret]; self.osmClient = [[AFOAuth1Client alloc] initWithBaseURL:[NSURL URLWithString:kOSMAPIBaseURL] key:key secret:secret]; - self.osmClient.accessToken = [AFOAuth1Token retrieveCredentialWithIdentifier:kCredentialsID]; + self.osmClient.accessToken = [AFOAuth1Token retrieveCredentialWithIdentifier:kCredentialsID]; + [self.osmClient registerHTTPOperationClass:[AFHTTPRequestOperation class]]; [AFXMLRequestOperation addAcceptableContentTypes:[NSSet setWithObjects:@"text/xml", @"application/xml", nil]]; } @@ -65,51 +70,46 @@ - (id)init { return self; } -#pragma mark - Public properties +#pragma mark - Public methods -- (BOOL)loggedIn { - return (self.osmClient.accessToken && !self.osmClient.accessToken.isExpired); +- (BOOL)isAuthorized { + return ([self userName] && + [self userID] && + [self userKey] && + [self userSecret]); } - (OSMUser *)osmUser { - OSMUser *user = [OSMUser new]; - user.userID = [self userID]; - user.name = [self userName]; - user.key = [self userKey]; - user.secret = [self userSecret]; - - return user; -} -- (NSString *)userName { - return self.osmClient.accessToken.userInfo[kOSMUsernameKey]; -} - -- (NSInteger)userID { - return ((NSNumber *)self.osmClient.accessToken.userInfo[kOSMUserIdKey]).integerValue; + if ([self isAuthorized]) { + OSMUser *user = [OSMUser new]; + user.userID = [self userID]; + user.name = [self userName]; + user.providerKey = [self userKey]; + user.providerSecret = [self userSecret]; + user.provider = @"osm"; + + return user; + } + + return nil; } -- (NSString *)userKey { - return self.osmClient.accessToken.key; -} - -- (NSString *)userSecret { - return self.osmClient.accessToken.secret; -} - -#pragma mark - Public methods - - (void)logIn { [self authorize]; } - (BOOL)logout { - BOOL couldDelete = [AFOAuth1Token deleteCredentialWithIdentifier:kCredentialsID]; - if (couldDelete) { - self.osmClient.accessToken = nil; - } - - return couldDelete; + BOOL couldDelete = [AFOAuth1Token deleteCredentialWithIdentifier:kCredentialsID]; + if (couldDelete) { + NSDictionary *infoDict = [[NSBundle mainBundle] infoDictionary]; + NSDictionary *credentials = infoDict[kOSMCredentials]; + NSString *key = credentials[kOSMKey]; + NSString *secret = credentials[kOSMSecret]; + self.osmClient = [[AFOAuth1Client alloc] initWithBaseURL:[NSURL URLWithString:kOSMAPIBaseURL] key:key secret:secret]; + } + + return couldDelete; } - (void)signUp { @@ -119,14 +119,10 @@ - (void)signUp { } } -- (BOOL)isAuthorized { - return (self.osmClient.accessToken && !self.osmClient.accessToken.isExpired); -} - - (AFOAuth1Token *)osmAccessToken { return self.osmClient.accessToken; } - + #pragma mark - Private methods - (void)authorize { @@ -152,8 +148,8 @@ - (void)requestAccountInfo{ [self.osmClient getPath:kOSMAPIUserInfoPath parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { OSMParser *parser = [[OSMParser alloc] init]; [parser parseWithData:responseObject andCompletionHandler:^(OSMUser *user) { - user.key = self.osmClient.accessToken.key; - user.secret = self.osmClient.accessToken.secret; + user.providerKey = self.osmClient.accessToken.key; + user.providerSecret = self.osmClient.accessToken.secret; if (self.didFinishLogin) { self.didFinishLogin(user, YES); @@ -168,4 +164,20 @@ - (void)requestAccountInfo{ }]; } +- (NSString *)userName { + return self.osmClient.accessToken.userInfo[kOSMUsernameKey]; +} + +- (NSInteger)userID { + return ((NSNumber *)self.osmClient.accessToken.userInfo[kOSMUserIdKey]).integerValue; +} + +- (NSString *)userKey { + return self.osmClient.accessToken.key; +} + +- (NSString *)userSecret { + return self.osmClient.accessToken.secret; +} + @end diff --git a/OpenStreetView/OSVAPI/Models/OSVMetadata.h b/OpenStreetView/OSVAPI/Models/OSVMetadata.h index e47b8e8..7043d13 100644 --- a/OpenStreetView/OSVAPI/Models/OSVMetadata.h +++ b/OpenStreetView/OSVAPI/Models/OSVMetadata.h @@ -19,5 +19,6 @@ + (OSVMetadata *)metadataError; - (BOOL)isLastPage; +- (NSInteger)totalPages; @end diff --git a/OpenStreetView/OSVAPI/Models/OSVMetadata.m b/OpenStreetView/OSVAPI/Models/OSVMetadata.m index 3a64250..04cfe3d 100644 --- a/OpenStreetView/OSVAPI/Models/OSVMetadata.m +++ b/OpenStreetView/OSVAPI/Models/OSVMetadata.m @@ -22,9 +22,11 @@ + (OSVMetadata *)metadataError { } - (BOOL)isLastPage { - NSInteger totalPages = self.totalItems / self.itemsPerPage + (self.totalItems % self.itemsPerPage != 0 ? 1 : 0); + return self.pageIndex == ([self totalPages] - 1); +} - return self.pageIndex == (totalPages-1); +- (NSInteger)totalPages { + return self.totalItems / self.itemsPerPage + (self.totalItems % self.itemsPerPage != 0 ? 1 : 0); } - (NSString *)description { diff --git a/OpenStreetView/OSVAPI/Models/OSVUser.h b/OpenStreetView/OSVAPI/Models/OSVUser.h index 36c95b9..211f237 100644 --- a/OpenStreetView/OSVAPI/Models/OSVUser.h +++ b/OpenStreetView/OSVAPI/Models/OSVUser.h @@ -7,28 +7,34 @@ // #import +#import "OSVGamificationInfo.h" @protocol OSVUser - -@property (nonatomic, assign) NSInteger userID; +//user info +@property (nonatomic, strong) NSString *userID; @property (nonatomic, strong) NSString *name; -@property (nonatomic, strong) NSString *type; - +@property (nonatomic, strong) NSString *fullName; +// @property (nonatomic, assign) double totalKM; @property (nonatomic, assign) double obdDistance; +// @property (nonatomic, assign) NSInteger totalPhotos; @property (nonatomic, assign) NSInteger totalTracks; +//rankings @property (nonatomic, assign) NSInteger weekRank; @property (nonatomic, assign) NSInteger rank; - -@property (nonatomic, strong) NSString *key; -@property (nonatomic, strong) NSString *secret; +//login credentials +@property (nonatomic, strong) NSString *providerKey; +@property (nonatomic, strong) NSString *providerSecret; +@property (nonatomic, strong) NSString *provider; @property (nonatomic, strong) NSString *accessToken; +@property (nonatomic, strong) OSVGamificationInfo *gameInfo; + @end @interface OSVUser : NSObject -@end \ No newline at end of file +@end diff --git a/OpenStreetView/OSVAPI/Models/OSVUser.m b/OpenStreetView/OSVAPI/Models/OSVUser.m index efc9928..74c8e17 100644 --- a/OpenStreetView/OSVAPI/Models/OSVUser.m +++ b/OpenStreetView/OSVAPI/Models/OSVUser.m @@ -12,12 +12,13 @@ @implementation OSVUser @synthesize userID; @synthesize name; -@synthesize type; +@synthesize fullName; @synthesize totalKM; @synthesize rank; -@synthesize key; -@synthesize secret; +@synthesize providerKey; +@synthesize providerSecret; +@synthesize provider; @synthesize accessToken; @@ -27,4 +28,6 @@ @implementation OSVUser @synthesize totalTracks; @synthesize weekRank; +@synthesize gameInfo; + @end diff --git a/OpenStreetView/OSVAPI/OSVAPI+Mix.m b/OpenStreetView/OSVAPI/OSVAPI+Mix.m index c01388c..3a3a618 100644 --- a/OpenStreetView/OSVAPI/OSVAPI+Mix.m +++ b/OpenStreetView/OSVAPI/OSVAPI+Mix.m @@ -10,8 +10,13 @@ #import "OSVUser.h" #import "OSVAPIUtils.h" -#define kAuthenticateMethod @"auth/openstreetmap/client_auth" +#define kOSVAuthenticateMethod @"auth/openstreetmap/client_auth" +#define kGoogleAuthenticateMethod @"auth/google/client_auth" +#define kFacebookAuthenticateMethod @"auth/facebook/client_auth" + #define kLeaderBoard @"user/leaderboard/" +#define kgameLeaderBoard @"gm-leaderboard" + #define kUserDetails @"user/details/" #define kVersion @"version" @@ -19,14 +24,46 @@ @implementation OSVAPI (Login) +- (void)logOut { + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], @"logout"]]; + AFHTTPRequestOperation *requestOperation = [OSVAPIUtils requestWithURL:url parameters:[NSDictionary dictionary] method:@"GET"]; + + [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + if (!operation.isCancelled) { + NSLog(@"ok"); + } + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"!!!!ok"); + }]; + + [self.requestsQueue addOperation:requestOperation]; +} + - (void)authenticateUser:(id)user withCompletion:(void (^)(NSError *_Nullable error))completion { - NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kAuthenticateMethod]]; - - NSString *request_token = user.key; - NSString *secret_token = user.secret; - - AFHTTPRequestOperation *requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(request_token, secret_token) method:@"POST"]; + + AFHTTPRequestOperation *requestOperation = nil; + if ([user.provider isEqualToString:@"osm"]) { + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kOSVAuthenticateMethod]]; + + NSString *request_token = user.providerKey; + NSString *secret_token = user.providerSecret; + + requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(request_token, secret_token) method:@"POST"]; + } else if ([user.provider isEqualToString:@"google"]) { + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kGoogleAuthenticateMethod]]; + + NSString *request_token = user.providerKey; + + requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(request_token) method:@"POST"]; + } else if ([user.provider isEqualToString:@"facebook"]) { + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kFacebookAuthenticateMethod]]; + + NSString *request_token = user.providerKey; + + requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(request_token) method:@"POST"]; + } + [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { if (!operation.isCancelled) { if (!responseObject) { @@ -36,7 +73,9 @@ - (void)authenticateUser:(id)user withCompletion:(void (^)(NSError *_Nu NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; user.accessToken = response[@"osv"][@"access_token"]; - + user.userID = response[@"osv"][@"id"]; + user.name = response[@"osv"][@"username"]; + completion(nil); } @@ -52,7 +91,7 @@ - (void)getUserInfo:(id)user withCompletion:( void (^)(id user NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@%@", [self.configurator osvBaseURL], [self.configurator osvAPIVerion], kUserDetails]]; NSString *username = user.name; - + AFHTTPRequestOperation *requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(username) method:@"POST"]; [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { @@ -66,14 +105,30 @@ - (void)getUserInfo:(id)user withCompletion:( void (^)(id user NSDictionary *userDict = response[@"osv"]; OSVUser *user = [OSVUser new]; user.name = userDict[@"username"]; + user.fullName = userDict[@"full_name"]; user.totalKM = [userDict[@"totalDistance"] doubleValue]; user.obdDistance = [userDict[@"obdDistance"] respondsToSelector:@selector(doubleValue)] ? [userDict[@"obdDistance"] doubleValue] : 0; user.rank = [userDict[@"overallRank"] integerValue]; user.weekRank = [userDict[@"weeklyRank"] integerValue]; user.totalTracks = [userDict[@"totalTracks"] integerValue]; user.totalPhotos = [userDict[@"totalPhotos"] integerValue]; - user.type = @"osv"; - + + if (userDict[@"gamification"]) { + NSDictionary *gamification = userDict[@"gamification"]; + user.gameInfo = [OSVGamificationInfo new]; + user.gameInfo.totalPoints = [gamification[@"total_user_points"] integerValue]; + user.gameInfo.totalLevelPoints = [gamification[@"level_target"] integerValue]; + user.gameInfo.levelPoints = [gamification[@"level_progress"] integerValue]; + user.gameInfo.rank = [gamification[@"rank"] integerValue]; + user.gameInfo.level = [gamification[@"level"] integerValue]; + user.gameInfo.levelName = gamification[@"levelName"]; + if ([gamification[@"region"] isKindOfClass:[NSDictionary class]]) { + user.gameInfo.regionCode = gamification[@"region"][@"country_code"]; + user.gameInfo.regionRank = [gamification[@"region"][@"rank"] integerValue]; + user.gameInfo.regionTotalPoints = [gamification[@"region"][@"points"] integerValue]; + } + } + completion(user, nil); } @@ -108,10 +163,9 @@ - (void)leaderBoardWithCompletion:(void (^)(NSArray *leaderBoard, NSError *error for (NSDictionary *userDict in osvArray) { rank += 1; OSVUser *user = [OSVUser new]; - user.userID = [userDict[@"id"] integerValue]; + user.userID = userDict[@"id"]; user.name = userDict[@"username"]; user.totalKM = [userDict[@"total_km"] doubleValue]; - user.type = @"osv"; user.rank = rank; [usersArray addObject:user]; @@ -126,6 +180,62 @@ - (void)leaderBoardWithCompletion:(void (^)(NSArray *leaderBoard, NSError *error [self.requestsQueue addOperation:requestOperation]; } +- (void)gameLeaderBoardForCountry:(NSString *)countryCode + fromDate:(NSDate *)date + withCompletion:(void (^)(NSArray *leaderBoard, NSError *error))completion { + + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kgameLeaderBoard]]; + + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; + + if (countryCode) { + dictionary[@"countryCode"] = countryCode; + } + + if (date) { + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + [formatter setDateFormat:@"yyyy-MM-dd"]; + dictionary[@"fromDate"] = [formatter stringFromDate:date]; + } + + AFHTTPRequestOperation *requestOperation = [OSVAPIUtils requestWithURL:url + parameters:dictionary + method:@"POST"]; + + [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + if (!operation.isCancelled) { + if (!responseObject) { + completion(nil, [NSError errorWithDomain:@"OSVAPI" code:1 userInfo:@{@"Response":@"NoResponse"}]); + return; + } + + NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; + NSArray *osvUsersArray = response[@"osv"][@"users"]; + + NSMutableArray *usersArray = [NSMutableArray array]; + int rank = 0; + for (NSDictionary *userDict in osvUsersArray) { + rank += 1; + OSVUser *user = [OSVUser new]; + user.userID = userDict[@"id"]; + user.name = userDict[@"username"]; + user.rank = rank; + user.gameInfo = [OSVGamificationInfo new]; + user.gameInfo.totalPoints = [userDict[@"total_user_points"] doubleValue]; + user.gameInfo.regionCode = userDict[@"country_code"]; + + [usersArray addObject:user]; + } + + completion(usersArray, nil); + } + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + completion(nil, error); + }]; + + [self.requestsQueue addOperation:requestOperation]; +} + @end @@ -162,4 +272,4 @@ - (NSURL *)getAppLink { return url; } -@end \ No newline at end of file +@end diff --git a/OpenStreetView/OSVAPI/OSVAPI+Photos.m b/OpenStreetView/OSVAPI/OSVAPI+Photos.m index 8dbbae6..7ee8eee 100644 --- a/OpenStreetView/OSVAPI/OSVAPI+Photos.m +++ b/OpenStreetView/OSVAPI/OSVAPI+Photos.m @@ -45,8 +45,13 @@ - (void)listPhotosForUser:(id)user withSequence:(OSVServerSequence *)se NSNumber *sequenceId = @(sequence.uid); NSString *access_token = user.accessToken; - - AFHTTPRequestOperation *requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(sequenceId, access_token) method:@"POST"]; + + AFHTTPRequestOperation *requestOperation = nil; + if (access_token) { + requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(sequenceId, access_token) method:@"POST"]; + } else { + requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(sequenceId) method:@"POST"]; + } [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { if (!operation.isCancelled) { diff --git a/OpenStreetView/OSVAPI/OSVAPI+Sequences.m b/OpenStreetView/OSVAPI/OSVAPI+Sequences.m index 7b65bff..b54001f 100644 --- a/OpenStreetView/OSVAPI/OSVAPI+Sequences.m +++ b/OpenStreetView/OSVAPI/OSVAPI+Sequences.m @@ -18,7 +18,7 @@ #define kNewSequneceMethod @"sequence" #define kLayersMethod @"nearby-tracks" -#define kMyListSequnceMethod @"list/my-list" +#define kMyListSequnceMethod @"my-list" #define kFinishedUploading @"sequence/finished-uploading" #define kSequncesRemoveMethod @"sequence/remove" #define kTracksMethod @"tracks" @@ -37,7 +37,12 @@ @implementation OSVAPI (Sequences) #pragma mark - Upload Requests -- (void)requestNewSequenceIdForUser:(nonnull id)user withSequence:(nonnull OSVSequence *)seq metadata:(NSDictionary *)metaDataDict withProgressBlock:(void (^)(long long tBytes, long long tBExpected))uploadProgressBlock completionBlock:(nullable void (^)(NSInteger sequenceId, NSError * _Nullable error))completionBlock { +- (void)requestNewSequenceIdForUser:(id)user + withSequence:(OSVSequence *)seq + metadata:(NSDictionary *)metaDataDict + scoreDetails:(NSString *)details + withProgressBlock:(void (^)(long long, long long))uploadProgressBlock + completionBlock:(void (^)(NSInteger, NSError * _Nullable))completionBlock { OSVPhoto *photo = nil; if (seq.photos.count) { @@ -56,6 +61,9 @@ - (void)requestNewSequenceIdForUser:(nonnull id)user withSequence:(nonn NSString *platformName = [self.configurator platformName]; NSString *currentCoordinate = [NSString stringWithFormat:@"%f,%f", photo.photoData.location.coordinate.latitude, photo.photoData.location.coordinate.longitude]; NSString *uploadSource = [self.configurator platformName]; + NSNumber *clientTotal = @(seq.points); + NSString *clientTotalDetails= details; + NSStringEncoding stringEncoding = NSUTF8StringEncoding; NSString *boundaryString = [OSVAPIUtils generateRandomBoundaryString]; @@ -63,7 +71,12 @@ - (void)requestNewSequenceIdForUser:(nonnull id)user withSequence:(nonn [urlRequest setValue:value forHTTPHeaderField:@"Content-Type"]; @autoreleasepool { - [urlRequest setHTTPBody:[OSVAPIUtils multipartFormDataQueryStringFromParameters:NSDictionaryOfVariableBindings(access_token, metaData, obdInfo, platformName, platformVersion, uploadSource, appVersion, currentCoordinate) withEncoding:stringEncoding boundary:boundaryString parametersInfo:@{@"metaData" : metaDataDict[@"metadataMime"]}]]; + [urlRequest setHTTPBody:[OSVAPIUtils multipartFormDataQueryStringFromParameters:NSDictionaryOfVariableBindings(access_token, metaData, obdInfo, platformName, + platformVersion, uploadSource, appVersion, currentCoordinate, + clientTotal, clientTotalDetails) + withEncoding:stringEncoding + boundary:boundaryString + parametersInfo:@{@"metaData" : metaDataDict[@"metadataMime"]}]]; } [urlRequest setHTTPMethod:@"POST"]; @@ -108,7 +121,7 @@ - (void)finishUploadingSequenceWithID:(NSInteger)uid forUser:(id)user w #pragma mark - List Requests - (void)listMySequncesForUser:(id)user atPage:(NSInteger)pageIndex withCompletionBlock:(void (^)(NSArray *, NSError *, OSVMetadata *))completionBlock { - NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@%@/", [self.configurator osvBaseURL], [self.configurator osvAPIVerion], kMyListSequnceMethod]]; + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kMyListSequnceMethod]]; NSNumber *ipp = @50; NSNumber *page = @(pageIndex + 1); @@ -189,7 +202,6 @@ - (NSOperation *)listTracksForUser:(id)user atPage:(NSInteger)pageIndex } else { NSLog(@"removed somethig"); } - } dispatch_async(dispatch_get_main_queue() , ^{ @@ -205,6 +217,7 @@ - (NSOperation *)listTracksForUser:(id)user atPage:(NSInteger)pageIndex completionBlock(sequenceArray, nil, meta); }); } else { + NSLog(@"operation is canceled"); completionBlock(nil, nil, nil); } }); @@ -221,6 +234,77 @@ - (NSOperation *)listTracksForUser:(id)user atPage:(NSInteger)pageIndex return requestOperation; } +- (NSOperation *)serialListTracksForUser:(id)user atPage:(NSInteger)pageIndex + inBoundingBox:(id)box + withZoom:(double)zomParam + withCompletionBlock:(void (^)(NSArray *, NSError *, OSVMetadata *))completionBlock { + + NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@%@/", [self.configurator osvBaseURL], [self.configurator osvAPIVerion], kTracksMethod]]; + + AFHTTPRequestOperation *requestOperation; + + NSNumber *ipp = @300; + NSNumber *page = @(pageIndex + 1); + //adding optional bounding box parameter + if (box) { + NSString *bbTopLeft = [NSString stringWithFormat:@"%f,%f", box.topLeftCoordinate.latitude, box.topLeftCoordinate.longitude]; + NSString *bbBottomRight = [NSString stringWithFormat:@"%f,%f", box.bottomRightCoordinate.latitude, box.bottomRightCoordinate.longitude]; + NSNumber *zoom = @(zomParam); + requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(bbTopLeft, bbBottomRight, zoom, ipp, page) method:@"POST"]; + } + + [requestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + if (!operation.isCancelled) { + if (!responseObject) { + completionBlock(nil, [NSError errorWithDomain:@"OSVAPI" code:1 userInfo:@{@"Response":@"NoResponse"}], [OSVMetadata metadataError]); + return; + } + NSDictionary *response = [NSJSONSerialization JSONObjectWithData:responseObject options:0 error:nil]; + NSArray *array = response[@"currentPageItems"]; + + NSMutableArray *sequenceArray = [NSMutableArray array]; + + for (NSDictionary *seqDictionary in array) { + OSVServerSequence *sequence = [OSVServerSequence trackFromDictionary:seqDictionary]; + if (sequence) { + [sequenceArray addObject:sequence]; + } else { + NSLog(@"removed somethig"); + } + } + + // dispatch_async(dispatch_get_main_queue() , ^{ + + OSVMetadata *meta = [OSVMetadata new]; + NSArray *totalItems = response[@"totalFilteredItems"]; + NSInteger numberOfItems = ((NSNumber *)totalItems.firstObject).integerValue; + meta.totalItems = numberOfItems; + meta.pageIndex = pageIndex; + meta.itemsPerPage = [ipp integerValue]; + meta.index = 0; + + completionBlock(sequenceArray, nil, meta); + // }); + } else { + NSLog(@"operation is canceled"); + completionBlock(nil, nil, nil); + } + }); + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + if (!operation.isCancelled) { + completionBlock(nil, error, [OSVMetadata metadataError]); + } else { + completionBlock(nil, nil, nil); + } + }]; + + [_serialQueue addOperation:requestOperation]; + + return requestOperation; +} + + - (void)getLayersFromLocation:(CLLocationCoordinate2D)coordinate radius:(double)dist withCompletion:(nullable void (^)(NSArray *_Nullable, NSError *_Nullable))completionBlock { NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@", [self.configurator osvBaseURL], kLayersMethod]]; @@ -270,7 +354,6 @@ - (void)deleteSequence:(OSVServerSequence *)sequence forUser:(id)user w NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"%@/%@%@/", [self.configurator osvBaseURL], [self.configurator osvAPIVerion], kSequncesRemoveMethod]]; NSNumber *sequenceId = @(sequence.uid); - NSString *access_token = user.accessToken; AFHTTPRequestOperation *requestOperation = [OSVAPIUtils requestWithURL:url parameters:NSDictionaryOfVariableBindings(sequenceId, access_token) method:@"POST"]; diff --git a/OpenStreetView/OSVAPI/OSVAPI+Video.m b/OpenStreetView/OSVAPI/OSVAPI+Video.m index da7cb7a..2423411 100644 --- a/OpenStreetView/OSVAPI/OSVAPI+Video.m +++ b/OpenStreetView/OSVAPI/OSVAPI+Video.m @@ -76,4 +76,4 @@ - (NSURLSessionUploadTask *)uploadVideo:(OSVVideo *)videoObj } } -@end \ No newline at end of file +@end diff --git a/OpenStreetView/OSVAPI/OSVAPI.h b/OpenStreetView/OSVAPI/OSVAPI.h index 9fc3519..7a8972a 100644 --- a/OpenStreetView/OSVAPI/OSVAPI.h +++ b/OpenStreetView/OSVAPI/OSVAPI.h @@ -43,12 +43,16 @@ - (void)getUserInfo:(nonnull id)user withCompletion:(nullable void (^)(id _Nullable user, NSError *_Nullable error))completion; +- (void)logOut; + @end @interface OSVAPI (Ranking) - (void)leaderBoardWithCompletion:(nullable void (^)(NSArray *_Nullable leaderBoard, NSError *_Nullable error))completion; - +- (void)gameLeaderBoardForCountry:(nullable NSString *)countryCode + fromDate:(nullable NSDate *)date + withCompletion:(nullable void (^)(NSArray *_Nullable leaderBoard, NSError *_Nullable error))completion; @end @interface OSVAPI (Version) @@ -91,6 +95,7 @@ withCompletionBlock:(nullable void (^)(NSError *_Nullable error))completionBlock - (void)requestNewSequenceIdForUser:(nonnull id)user withSequence:(nonnull OSVSequence *)seq metadata:(nonnull NSDictionary *)metaDataDict + scoreDetails:(nonnull NSString *)details withProgressBlock:(nullable void (^)(long long totalBytes, long long totalBytesExpected))uploadProgressBlock completionBlock:(nullable void (^)(NSInteger sequenceId, NSError * _Nullable error))completionBlock; @@ -104,6 +109,12 @@ withCompletionBlock:(nullable void (^)(NSError *_Nullable error))completionBlock inBoundingBox:(nullable id)box withZoom:(double)zoom withCompletionBlock:(nullable void (^)(NSArray *_Nullable, NSError *_Nullable, OSVMetadata *_Nullable))completionBlock; +- (nullable NSOperation *)serialListTracksForUser:(nonnull id)user + atPage:(NSInteger)pageIndex + inBoundingBox:(nullable id)box + withZoom:(double)zoom + withCompletionBlock:(nullable void (^)(NSArray *_Nullable, NSError *_Nullable, OSVMetadata *_Nullable))completionBlock; + //list layers - (void)getLayersFromLocation:(CLLocationCoordinate2D)coordinate radius:(double)distance diff --git a/OpenStreetView/OSVAPI/OSVAPIConfigurator.h b/OpenStreetView/OSVAPI/OSVAPIConfigurator.h index af80838..b27b2af 100644 --- a/OpenStreetView/OSVAPI/OSVAPIConfigurator.h +++ b/OpenStreetView/OSVAPI/OSVAPIConfigurator.h @@ -21,4 +21,8 @@ @interface OSVAPIConfigurator : NSObject ++ (nonnull NSString *)testingEnvironment; ++ (nonnull NSString *)stagingEnvironment; ++ (nonnull NSString *)productionEnvironment; + @end diff --git a/OpenStreetView/OSVAPI/OSVAPIConfigurator.m b/OpenStreetView/OSVAPI/OSVAPIConfigurator.m index 939952a..60220c1 100644 --- a/OpenStreetView/OSVAPI/OSVAPIConfigurator.m +++ b/OpenStreetView/OSVAPI/OSVAPIConfigurator.m @@ -8,22 +8,16 @@ #import "OSVAPIConfigurator.h" -//#ifdef ENABLED_DEBUG -////#define kBaseURLOSV @"http://openstreetview.com" -////#define kBaseURLOSV @"http://testing.openstreetview.com" -//#define kBaseURLOSV @"http://staging.openstreetview.com" -//#else -#define kBaseURLOSV @"http://openstreetview.com" -//#define kBaseURLOSV @"http://staging.openstreetview.com" -//#endif - #define kAPIVersion @"1.0/" -//#define kAPIVersion @"" + +#define kProductionBaseURLOSC @"http://openstreetcam.org" +#define kTstBaseURLOSC @"http://testing.openstreetcam.org" +#define kStagingBaseURLOSC @"http://staging.openstreetcam.org" @implementation OSVAPIConfigurator - (nonnull NSString *)osvBaseURL { - return kBaseURLOSV; + return kProductionBaseURLOSC; } - (nonnull NSString *)osvAPIVerion { @@ -42,4 +36,17 @@ - (nonnull NSString *)appVersion { return [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"]; } ++ (nonnull NSString *)testingEnvironment { + return kTstBaseURLOSC; +} + ++ (nonnull NSString *)stagingEnvironment { + return kStagingBaseURLOSC; +} + ++ (nonnull NSString *)productionEnvironment { + return kProductionBaseURLOSC; +} + + @end diff --git a/OpenStreetView/OSVBaseUser+OSM.h b/OpenStreetView/OSVBaseUser+OSM.h deleted file mode 100644 index 47ffb32..0000000 --- a/OpenStreetView/OSVBaseUser+OSM.h +++ /dev/null @@ -1,16 +0,0 @@ -// -// OSVBaseUser+OSM.h -// OpenStreetView -// -// Created by Bogdan Sala on 23/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVBaseUser.h" -#import "OSMUser.h" - -@interface OSVBaseUser (OSM) - -+ (instancetype)baseUserWithOSMUser:(OSMUser *)user; - -@end diff --git a/OpenStreetView/OSVBaseUser+OSM.m b/OpenStreetView/OSVBaseUser+OSM.m deleted file mode 100644 index 76dcd74..0000000 --- a/OpenStreetView/OSVBaseUser+OSM.m +++ /dev/null @@ -1,25 +0,0 @@ -// -// OSVBaseUser+OSM.m -// OpenStreetView -// -// Created by Bogdan Sala on 23/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVBaseUser+OSM.h" - -@implementation OSVBaseUser (OSM) - -+ (instancetype)baseUserWithOSMUser:(OSMUser *)user { - OSVBaseUser *baseUser = [OSVBaseUser new]; - baseUser.name = user.name; - baseUser.type = @"osm"; - baseUser.userID = user.userID; - - baseUser.key = user.key; - baseUser.secret = user.secret; - - return baseUser; -} - -@end diff --git a/OpenStreetView/OSVBaseUser.m b/OpenStreetView/OSVBaseUser.m index a677084..08d42d3 100644 --- a/OpenStreetView/OSVBaseUser.m +++ b/OpenStreetView/OSVBaseUser.m @@ -10,13 +10,14 @@ @implementation OSVBaseUser -@synthesize type; @synthesize name; +@synthesize fullName; @synthesize userID; @synthesize accessToken; -@synthesize secret; -@synthesize key; +@synthesize providerSecret; +@synthesize providerKey; +@synthesize provider; @synthesize totalKM; @@ -26,4 +27,6 @@ @implementation OSVBaseUser @synthesize weekRank; @synthesize rank; +@synthesize gameInfo; + @end diff --git a/OpenStreetView/OSVBasicMapController.m b/OpenStreetView/OSVBasicMapController.m index 8161688..88743bd 100644 --- a/OpenStreetView/OSVBasicMapController.m +++ b/OpenStreetView/OSVBasicMapController.m @@ -17,6 +17,8 @@ #import "OSVServerSequence.h" #import "OSVUserDefaults.h" +#import "OSVLocationManager.h" + @interface OSVBasicMapController () @property (nonatomic, assign) NSInteger polylineID; @@ -50,7 +52,12 @@ - (void)willChangeUIControllerFrom:(id)controller animated: self.localSeq = nil; [self addLocalSequences]; - self.viewController.bottomRightButton.hidden = NO; + if (![OSVUserDefaults sharedInstance].enableMap) { + self.viewController.bottomRightButton.hidden = YES; + } else { + self.viewController.bottomRightButton.hidden = NO; + } + [self.viewController.bottomRightButton setImage:[UIImage imageNamed:@"recenter"] forState:UIControlStateNormal]; @@ -81,10 +88,11 @@ - (void)clearAllCache{ - (void)didTapBottomRightButton { if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) { - [[SKPositionerService sharedInstance] startLocationUpdate]; + [[OSVLocationManager sharedInstance] startLocationUpdate]; } else { [self.viewController.mapView centerOnCurrentPosition]; [self.viewController.mapView animateToZoomLevel:14]; + [self reloadVisibleTracks]; } } @@ -121,10 +129,13 @@ - (void)addSequenceOnMap:(id)sequence { polyline.backgroundLineWidth = 6; polyline.coordinates = track; polyline.identifier = iii++; + if ([sequence isKindOfClass:[OSVSequence class]]) { polyline.fillColor = [UIColor blackColor]; + polyline.identifier += 20000; } else { - polyline.fillColor = self.colorPurple; + polyline.fillColor = [self.colorPurple colorWithAlphaComponent:MIN(sequence.coverage, 10.0)/10.0 + 0.01]; + polyline.strokeColor = [self.colorPurple colorWithAlphaComponent:MIN(sequence.coverage, 10.0)/10.0 + 0.01]; } polyline.isLocal = YES; @@ -160,54 +171,6 @@ - (void)zoomOnCurrentPosition { [self.viewController.mapView centerOnCurrentPosition]; } -- (OSVPolyline *)nearestPolylineLocationToCoordinate:(CLLocationCoordinate2D)coordinate index:(NSInteger *)index { -// OSVPolyline *bestPolyline = nil; -// NSInteger bestIndex = 0; -// double bestDistance = DBL_MAX; -// -// CGPoint originPoint = [self.viewController.mapView pointForCoordinate:coordinate]; - -// for (OSVPolyline *polyline in self.viewController.polylines) { -// if (!polyline.coordinates.count) { -// continue; -// } -// -// if (polyline.coordinates.count && polyline.coordinates.count < 2) { // we need at least 2 points: start and end -// CGPoint spoint = [self.viewController.mapView pointForCoordinate:((CLLocation *)polyline.coordinates[0]).coordinate]; -// CGPoint epoint = [self.viewController.mapView pointForCoordinate:coordinate]; -// double distance = [OSVUtils distanceBetweenStartPoint:spoint andEndPoint:epoint]; -// if (distance < bestDistance) { -// bestIndex = 0; -// bestDistance = distance; -// bestPolyline = polyline; -// } -// continue; -// } -// -// for (NSInteger index = 0; index < polyline.coordinates.count - 1; index++) { -// CLLocation *startCoordinate = polyline.coordinates[index]; -// CGPoint startPoint = [self.viewController.mapView pointForCoordinate:startCoordinate.coordinate]; -// CLLocation *endCoordinate = polyline.coordinates[index + 1]; -// CGPoint endPoint = [self.viewController.mapView pointForCoordinate:endCoordinate.coordinate]; -// double distance; -// [OSVUtils nearestPointToPoint:originPoint onLineSegmentPointA:startPoint pointB:endPoint distance:&distance]; -// -// if (distance < bestDistance) { -// bestDistance = distance; -// bestPolyline = polyline; -// bestIndex = index; -// } -// } -// } - -// if (bestDistance < 25) { -// *index = bestIndex; -// return bestPolyline; -// } - - return nil; -} - #pragma mark - Private - (void)requestAndDisplayAllSequencesOnMapInBoundingBox:(id)box withZoom:(double)zoom { @@ -239,6 +202,9 @@ - (void)requestAndDisplayAllSequencesOnMapInBoundingBox:(id)box [self addSequenceOnMap:sequence]; } + } completion:^(OSVMetadata *mf) { + NSLog(@"!!!!!!!!!!!!!!!!!!! o venit aici %ld %p", mf.totalPages, mf); + }]; }); } else { @@ -247,15 +213,15 @@ - (void)requestAndDisplayAllSequencesOnMapInBoundingBox:(id)box } - (void)addLocalSequences { - if (self.localSeq.count) { - for (OSVSequence *sequence in self.localSeq) { - if (!sequence) { - return; - } - // this should not caches - [self addSequenceOnMap:sequence]; - } - } else { +// if (self.localSeq.count) { +// for (OSVSequence *sequence in self.localSeq) { +// if (!sequence) { +// return; +// } +// // this should not caches +// [self addSequenceOnMap:sequence]; +// } +// } else { [self.syncController.tracksController getLocalSequencesWithCompletion:^(NSArray *sequences) { self.localSeq = sequences; for (OSVSequence *sequence in sequences) { @@ -266,7 +232,7 @@ - (void)addLocalSequences { [self addSequenceOnMap:sequence]; } }]; - } +// } } - (void)orderPhotosIntoSequence:(OSVSequence *)sequence { @@ -299,5 +265,4 @@ - (void)didFinishCreatingSequence:(NSNotification *)notification { }]; } - -@end \ No newline at end of file +@end diff --git a/OpenStreetView/OSVCameraGamificationManager.h b/OpenStreetView/OSVCameraGamificationManager.h new file mode 100644 index 0000000..49eb391 --- /dev/null +++ b/OpenStreetView/OSVCameraGamificationManager.h @@ -0,0 +1,69 @@ +// +// OSVCameraGamificationManager.h +// OpenStreetView +// +// Created by Bogdan Sala on 01/02/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import +#import +#import "OSVCameraManager.h" + +@class OSVCamViewController; + +typedef enum { + UIGamificationStateMultiplier = 1 << 0, + UIGamificationStateNoCoverageCollappsed = 1 << 1, + UIGamificationStateNoCoverage = 1 << 2, + UIGamificationStateScore = 1 << 3, + UIGamificationStateNotVisible = 1 << 4, + UIGamificationStateWillChange = 1 << 5, +}UIGamificationState; + +typedef enum { + UIGamificationAnimationStart, + UIGamificationAnimationContinue, + UIGamificationAnimationStop +}UIGamificationAnimation; + +@interface OSVCameraGamificationManager : NSObject + +@property (weak, nonatomic) IBOutlet UIImageView *multiplierTipImage; +@property (weak, nonatomic) IBOutlet UILabel *multiplierTipLabel; + +@property (weak, nonatomic) IBOutlet UIImageView *multiplierLandscapeImage; +@property (weak, nonatomic) IBOutlet UIImageView *animationImage; +@property (weak, nonatomic) IBOutlet UIImageView *pointsRecordingImage; +@property (weak, nonatomic) IBOutlet UILabel *multiplierLabel; +@property (weak, nonatomic) IBOutlet UIImageView *pointsBackgroundImage; + +@property (weak, nonatomic) IBOutlet UILabel *scoreLabel; + +@property (weak, nonatomic) IBOutlet UIView *clippingView; + +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *clippingLeading; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingMultiplierImage; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *trailingLandscapeImage; + +@property (nonatomic, strong) OSVCameraManager *cameraManager; + +@property (assign, nonatomic) BOOL animatingGamification; +@property (weak, nonatomic) IBOutlet UIView *scoreView; + +@property (weak, nonatomic) id delegate; + +- (void)prepareFirstTimeUse; +- (void)stopRecording; +- (void)changeMultiplierAnimation; +- (void)noCoverageData; +- (void)didLoadNewTracks; +- (void)expandMultiplier; +- (void)willDissmiss; + +- (void)configureUIForInterfaceOrientation:(UIInterfaceOrientation)orientation; +- (void)configureUIForDeviceOrientation:(UIDeviceOrientation)orientation; + +- (void)updateUIInfo; + +@end diff --git a/OpenStreetView/OSVCameraGamificationManager.m b/OpenStreetView/OSVCameraGamificationManager.m new file mode 100644 index 0000000..68788b1 --- /dev/null +++ b/OpenStreetView/OSVCameraGamificationManager.m @@ -0,0 +1,454 @@ +// +// OSVCameraGamificationManager.m +// OpenStreetView +// +// Created by Bogdan Sala on 01/02/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import "OSVCameraGamificationManager.h" +#import "OSVCamViewController.h" +#import "OSVUserDefaults.h" +#import "OSVLogger.h" +#import "NSAttributedString+Additions.h" +#import "OSVLocationManager.h" + +@interface OSVCameraGamificationManager () + +@property (assign, nonatomic) UIGamificationState gamificationState; + +@end + +@implementation OSVCameraGamificationManager + +- (instancetype)init { + self = [super init]; + if (self) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLoadNewTracks) name:@"kdidLoadNewBox" object:nil]; + } + return self; +} + +- (void)didLoadNewTracks { + if (![OSVUserDefaults sharedInstance].useGamification){ + return; + } + + if (self.gamificationState & UIGamificationStateNotVisible) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.scoreView.hidden = NO; + [self.delegate didReceiveUIUpdate]; + //DebugAnimation NSLog(@"set UIGamificationStateWillChange 4"); + self.gamificationState = UIGamificationStateWillChange; + //DebugAnimation NSLog(@"didLoadNewTracks A"); + [self appeareScoreWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateMultiplier 1"); + self.gamificationState = UIGamificationStateMultiplier; + } animationState:UIGamificationAnimationStart]; + }); + } else if (self.gamificationState & UIGamificationStateNoCoverage) { + dispatch_async(dispatch_get_main_queue(), ^{ + //DebugAnimation NSLog(@"set UIGamificationStateWillChange 5"); + self.gamificationState = UIGamificationStateWillChange; + //DebugAnimation NSLog(@"didLoadNewTracks B"); + [self colapseScoreWithCompletion:^{ + [self appeareScoreWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateScore 55"); + self.gamificationState = UIGamificationStateScore; + } animationState:UIGamificationAnimationStop]; + } animationState:UIGamificationAnimationStart]; + }); + } +} + +- (void)noCoverageData { + if (self.gamificationState == UIGamificationStateScore) { + //DebugAnimation NSLog(@"set UIGamificationStateWillChange 2"); + self.gamificationState = UIGamificationStateWillChange; + //DebugAnimation NSLog(@"NO DATA A"); + [self appeareNoCoverageWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateNoCoverage"); + self.gamificationState = UIGamificationStateNoCoverage; + } animationState:UIGamificationAnimationStart]; + } else if (self.gamificationState == UIGamificationStateMultiplier) { + //DebugAnimation NSLog(@"set UIGamificationStateWillChange 1"); + self.gamificationState = UIGamificationStateWillChange; + //DebugAnimation NSLog(@"NO DATA B"); + [self animateNoCoverateWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateNoCoverage"); + self.gamificationState = UIGamificationStateNoCoverage; + } animationState:UIGamificationAnimationStart]; + } +} + +- (void)expandMultiplier { + if (self.gamificationState & UIGamificationStateMultiplier) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self increaseScoreWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateScore -1"); + self.gamificationState = UIGamificationStateScore; + } animationState:UIGamificationAnimationStart]; + }); + } +} + +- (void)willDissmiss { + if (self.gamificationState & UIGamificationStateMultiplier) { + self.clippingView.hidden = YES; + } +} + +- (void)configureUIForInterfaceOrientation:(UIInterfaceOrientation)orientation { + self.clippingView.hidden = !UIInterfaceOrientationIsPortrait(orientation); + self.animationImage.hidden = !UIInterfaceOrientationIsPortrait(orientation); + self.pointsRecordingImage.hidden = UIInterfaceOrientationIsPortrait(orientation); + self.multiplierLandscapeImage.hidden = UIInterfaceOrientationIsPortrait(orientation); +} + +- (void)configureUIForDeviceOrientation:(UIDeviceOrientation)orientation { + self.clippingView.hidden = UIDeviceOrientationIsLandscape(orientation); + self.animationImage.hidden = UIDeviceOrientationIsLandscape(orientation); + self.pointsRecordingImage.hidden = !UIDeviceOrientationIsLandscape(orientation); + self.multiplierLandscapeImage.hidden = !UIDeviceOrientationIsLandscape(orientation); +} + +- (void)prepareFirstTimeUse { + self.scoreView.hidden = YES; + + if ([OSVUserDefaults sharedInstance].useGamification){ + self.multiplierTipLabel.text = NSLocalizedString(@"You will get more points when the streets have less coverage!", @""); + + //DebugAnimation NSLog(@"set UIGamificationStateNotVisible"); + self.gamificationState = UIGamificationStateNotVisible; + [self colapseScoreWithCompletion:^{} + animationState:UIGamificationAnimationStart]; + } +} + +- (void)stopRecording { + //DebugAnimation NSLog(@"set UIGamificationStateWillChange 3"); + self.gamificationState = UIGamificationStateWillChange; + [self colapseScoreWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateMultiplier 2"); + self.gamificationState = UIGamificationStateMultiplier; + } animationState:UIGamificationAnimationStart]; +} + +- (void)changeMultiplierAnimation { + if (self.gamificationState == UIGamificationStateScore) { + //DebugAnimation NSLog(@"set UIGamificationStateWillChange 22"); + self.gamificationState = UIGamificationStateWillChange; + [self enlageMultiplyerWithCompletion:^{ + [self diminishMultiplyerWithCompletion:^{ + //DebugAnimation NSLog(@"set UIGamificationStateScore 22"); + self.gamificationState = UIGamificationStateScore; + } animationState:UIGamificationAnimationStop]; + } animationState:UIGamificationAnimationStart]; + } +} + +- (void)setGamificationState:(UIGamificationState)gamificationState { + // NSLog(@"pre setGamiState:%d", _gamificationState); + // NSLog(@"post setGamiState:%d", gamificationState); + + _gamificationState = gamificationState; +} + +- (void)appeareScoreWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"appear score"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block appear score"); + + return; + } + self.animatingGamification = YES; + + [self appeareMultiplierWithCompletion:^{ + if (self.cameraManager.isRecording) { + [self increaseScoreWithCompletion:^{ + + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"EnD appear score A"); + + completion(); + } animationState:UIGamificationAnimationContinue]; + } else { + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"EnD appear score B"); + completion(); + } + } animationState:UIGamificationAnimationContinue]; +} + +- (void)appeareMultiplierWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"appear multiplier"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block appear multiplier"); + return; + } + self.animatingGamification = YES; + + self.animationImage.image = [UIImage imageNamed:@"multiplier"]; + self.multiplierLandscapeImage.image = self.animationImage.image; + self.pointsBackgroundImage.image = [UIImage imageNamed:@"pointsRecording"]; + self.pointsRecordingImage.image = self.pointsBackgroundImage.image; + self.pointsBackgroundImage.alpha = 0; + self.pointsRecordingImage.alpha = 0; + self.animationImage.alpha = 0; + self.multiplierLabel.alpha = 0; + + [UIView animateWithDuration:0.3 animations:^{ + self.multiplierLabel.alpha = 1; + self.animationImage.alpha = 1; + } completion:^(BOOL finished) { + [self enlageMultiplyerWithCompletion:^{ + [self diminishMultiplyerWithCompletion:^{ + + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"End appear multiplier"); + + completion(); + } animationState:UIGamificationAnimationContinue]; + } animationState:UIGamificationAnimationContinue]; + }]; +} + +- (void)appeareNoCoverageWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"appeareNoCoverage"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block appeareNoCoverage"); + return; + } + self.animatingGamification = YES; + + [self colapseScoreWithCompletion:^{ + [self animateNoCoverateWithCompletion:^{ + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"EnD appeareNoCoverage"); + completion(); + } animationState:UIGamificationAnimationContinue]; + } animationState:UIGamificationAnimationContinue]; +} + +- (void)animateNoCoverateWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"animateNoCoverate"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block animateNoCoverate"); + return; + } + self.animatingGamification = YES; + + self.multiplierLabel.alpha = 0; + + [UIView transitionWithView:self.scoreView duration:0.3f + options:UIViewAnimationOptionTransitionCrossDissolve animations:^{ + self.animationImage.image = [UIImage imageNamed:@"noWifi"]; + self.multiplierLandscapeImage.image = self.animationImage.image; + } completion:^(BOOL finished) { + self.pointsBackgroundImage.image = [UIImage imageNamed:@"inactivePoints"]; + self.pointsRecordingImage.image = self.pointsBackgroundImage.image; + [self enlageMultiplyerWithCompletion:^{ + [self diminishMultiplyerWithCompletion:^{ + [self increaseScoreWithCompletion:^{ + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"EnD animateNoCoverate"); + completion(); + } animationState:UIGamificationAnimationContinue]; + } animationState:UIGamificationAnimationContinue]; + } animationState:UIGamificationAnimationContinue]; + }]; +} + + +- (void)colapseScoreWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"coloapse Score"); + + if (!(self.gamificationState & (UIGamificationStateScore| + UIGamificationStateNoCoverage| + UIGamificationStateNotVisible| + UIGamificationStateWillChange))) { + + //DebugAnimation NSLog(@"block coloapse Score A"); + return; + } + + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block coloapse Score B"); + return; + } + self.animatingGamification = YES; + + self.clippingLeading.constant = self.scoreView.frame.size.height / 2.0; + [UIView animateWithDuration:0.1 animations:^{ + [self.scoreView setNeedsLayout]; + [self.scoreView layoutIfNeeded]; + + } completion:^(BOOL finished) { + [self.delegate didReceiveUIUpdate]; + self.scoreLabel.hidden = YES; + self.leadingMultiplierImage.constant = self.scoreView.frame.size.width - self.scoreView.frame.size.height; + + self.clippingLeading.constant = self.scoreView.frame.size.width - self.scoreView.frame.size.height / 2.0; + self.trailingLandscapeImage.constant = self.scoreView.frame.size.width - 44; + + [UIView animateWithDuration:0.3 animations:^{ + [self.clippingView setNeedsLayout]; + [self.clippingView layoutIfNeeded]; + [self.pointsRecordingImage setNeedsLayout]; + [self.pointsRecordingImage layoutIfNeeded]; + [self.scoreView setNeedsLayout]; + [self.scoreView layoutIfNeeded]; + } completion:^(BOOL finished) { + self.clippingLeading.constant = self.scoreView.frame.size.width; + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"EnD coloapse Score"); + completion(); + }]; + }]; +} + + +- (void)increaseScoreWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"incresee Score"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block incresee Score"); + return; + } + self.animatingGamification = YES; + + self.clippingLeading.constant = self.scoreView.frame.size.height / 2.0; + self.leadingMultiplierImage.constant = 0; + self.trailingLandscapeImage.constant = 0; + + [UIView animateWithDuration:0.6 + delay:0.0 + usingSpringWithDamping:0.3 + initialSpringVelocity:0.75 + options:UIViewAnimationOptionCurveEaseInOut animations:^{ + [self.clippingView setNeedsLayout]; + [self.clippingView layoutIfNeeded]; + [self.pointsRecordingImage setNeedsLayout]; + [self.pointsRecordingImage layoutIfNeeded]; + [self.scoreView setNeedsLayout]; + [self.scoreView layoutIfNeeded]; + } + completion:^(BOOL finished) { + self.scoreLabel.hidden = NO; + [self.delegate didReceiveUIUpdate]; + self.clippingLeading.constant = 0; + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"EnD incresee Score"); + + completion(); + }]; +} + +- (void)enlageMultiplyerWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"Enlarge"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + //DebugAnimation NSLog(@"block enlarge"); + return; + } + self.animatingGamification = YES; + + [UIView animateWithDuration:0.3 animations:^{ + self.multiplierLabel.transform = CGAffineTransformMakeScale(1.5, 1.5); + self.animationImage.transform = CGAffineTransformMakeScale(1.5, 1.5); + self.multiplierLandscapeImage.transform = CGAffineTransformMakeScale(1.5, 1.5); + } completion:^(BOOL finished) { + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"End enlarge"); + completion(); + }]; +} + +- (void)diminishMultiplyerWithCompletion:(void (^)(void))completion animationState:(UIGamificationAnimation)state { + //DebugAnimation NSLog(@"dmininish"); + if (state == UIGamificationAnimationStart && self.animatingGamification) { + + //DebugAnimation NSLog(@"blick dmininish"); + return; + } + self.animatingGamification = YES; + + [UIView animateWithDuration:0.4 + delay:0.0 + usingSpringWithDamping:0.15 + initialSpringVelocity:0.7 + options:UIViewAnimationOptionCurveLinear animations:^{ + self.multiplierLabel.transform = CGAffineTransformIdentity; + self.animationImage.transform = CGAffineTransformIdentity; + self.multiplierLandscapeImage.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + self.pointsBackgroundImage.alpha = 1; + self.pointsRecordingImage.alpha = 1; + + self.animatingGamification = state == UIGamificationAnimationContinue; + //DebugAnimation NSLog(@"End dmininish"); + completion(); + }]; +} + +- (IBAction)didTapMultiplier:(id)sender { + if (self.multiplierTipImage.hidden) { + + self.multiplierTipImage.hidden = NO; + self.multiplierTipLabel.superview.hidden = NO; + self.multiplierTipImage.alpha = 0; + self.multiplierTipLabel.superview.alpha = 0; + NSInteger i = self.multiplierTipImage.tag; + + [UIView animateWithDuration:0.4 animations:^{ + self.multiplierTipImage.alpha = 1; + self.multiplierTipLabel.superview.alpha = 1; + }]; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + if (i == self.multiplierTipImage.tag) { + [UIView animateWithDuration:0.4 animations:^{ + self.multiplierTipImage.alpha = 0; + self.multiplierTipLabel.superview.alpha = 0; + } completion:^(BOOL finished) { + self.multiplierTipImage.hidden = YES; + self.multiplierTipLabel.superview.hidden = YES; + }]; + } + }); + + } else { + self.multiplierTipImage.alpha = 1; + self.multiplierTipLabel.superview.alpha = 1; + self.multiplierTipImage.tag += 1; + + [UIView animateWithDuration:0.4 animations:^{ + self.multiplierTipImage.alpha = 0; + self.multiplierTipLabel.superview.alpha = 0; + } completion:^(BOOL finished) { + self.multiplierTipImage.hidden = YES; + self.multiplierTipLabel.superview.hidden = YES; + }]; + } +} + +- (void)updateUIInfo { + self.scoreLabel.attributedText = [NSAttributedString combineString:[NSString stringWithFormat:@"%.f", self.cameraManager.score] withSize:18.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + withString:NSLocalizedString(@" pts", nil) withSize:12.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + adjustBaseline:YES]; + + + NSAttributedString *multiplierString = [NSAttributedString combineString:NSLocalizedString(@"X ", nil) withSize:10.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + withString:[@(self.cameraManager.multiplier) stringValue] withSize:18.f color:[UIColor whiteColor] fontName:@"HelveticaNeue"adjustBaseline:YES]; + if (![self.multiplierLabel.attributedText isEqual:multiplierString]) { + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"multiplier changed:%@", multiplierString.string] withLevel:LogLevelDEBUG]; + self.multiplierLabel.attributedText = multiplierString; + [self changeMultiplierAnimation]; + } + + if (self.cameraManager.hasCoverage) { + [self didLoadNewTracks]; + } else { + [self noCoverageData]; + } +} + +@end diff --git a/OpenStreetView/OSVCameraMapManager.h b/OpenStreetView/OSVCameraMapManager.h index b56198e..501c292 100644 --- a/OpenStreetView/OSVCameraMapManager.h +++ b/OpenStreetView/OSVCameraMapManager.h @@ -8,10 +8,18 @@ #import #import +#import "OSVPolyline.h" +@class OSVTrackMatcher; @interface OSVCameraMapManager : NSObject +@property (nonatomic, strong) OSVTrackMatcher *matcher; + - (instancetype)initWithMap:(SKMapView *)view; +- (void)addPolyline:(id)sequence; +- (void)moveToMap; + + @end diff --git a/OpenStreetView/OSVCameraMapManager.m b/OpenStreetView/OSVCameraMapManager.m index 65dfb21..f1b019e 100644 --- a/OpenStreetView/OSVCameraMapManager.m +++ b/OpenStreetView/OSVCameraMapManager.m @@ -12,7 +12,8 @@ #import "UIColor+OSVColor.h" #import "OSVUtils.h" #import "OSVLocationManager.h" - +#import "OSVTrackMatcher.h" +#import "OSVUserDefaults.h" @interface OSVCameraMapManager () @@ -29,13 +30,15 @@ @interface OSVCameraMapManager () @property (assign, nonatomic) BOOL isRequestingRight; @property (strong, nonatomic) NSMutableArray *bufferV; - -@property (strong, nonatomic) NSMutableArray *bufferT; -@property (strong, nonatomic) NSMutableArray *bufferB; -@property (strong, nonatomic) NSMutableArray *bufferL; -@property (strong, nonatomic) NSMutableArray *bufferR; +@property (strong, nonatomic) NSMutableArray *bufferN; @property (strong, nonatomic) SKBoundingBox *viewBox; +@property (strong, nonatomic) SKBoundingBox *midBox; +@property (strong, nonatomic) SKBoundingBox *loadedBox; + +@property (assign, nonatomic) NSInteger bestIndex; + +@property (strong, nonnull) NSLock *lock; @end @@ -47,120 +50,93 @@ - (instancetype)initWithMap:(SKMapView *)view { self.first = YES; self.mapView = view; - self.mapView.delegate = self; + self.mapView.delegate = self; + self.mapView.clipsToBounds = YES; + + self.mapView.mapScaleView.hidden = YES; + + self.mapView.settings.showHouseNumbers = NO; + self.mapView.settings.showCompass = NO; + self.mapView.settings.displayMode = SKMapDisplayMode2D; + self.mapView.settings.showStreetNamePopUps = YES; + self.mapView.settings.osmAttributionPosition = SKOSMAttributionPositionTopLeft; + self.mapView.settings.panningEnabled = NO; + + SKMapZoomLimits zoomLimits; + zoomLimits.mapZoomLimitMax = 20; + zoomLimits.mapZoomLimitMin = 15; + self.mapView.settings.zoomLimits = zoomLimits; + + SKCoordinateRegion region; + region.zoomLevel = [OSVUserDefaults sharedInstance].zoomLevel; + region.center = [OSVLocationManager sharedInstance].currentLocation.coordinate; + self.mapView.visibleRegion = region; + self.colorPurple = [UIColor colorWithHex:0xbd10e0]; self.bufferV = [NSMutableArray array]; + self.bufferN = [NSMutableArray array]; + + self.matcher = [OSVTrackMatcher new]; + self.matcher.delegate = self; + self.lock = [NSLock new]; } return self; } - (void)mapView:(SKMapView *)mapView didChangeToRegion:(SKCoordinateRegion)region { - if (self.first) { - dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ - [self addTracksOnMapWithRegion:region]; - self.first = NO; - }); - } else { - [self addTracksOnMapWithRegion:region]; - } + [self.matcher getTracksForMap:self.mapView withRegion:region]; } - -- (void)addTracksOnMapWithRegion:(SKCoordinateRegion)region { - SKBoundingBox *box = [SKBoundingBox boundingBoxForRegion:region inMapViewWithSize:self.mapView.frame.size]; - - double diagonalTopL = [OSVUtils getAirDistanceBetweenCoordinate:box.topLeftCoordinate andCoordinate:self.viewBox.topLeftCoordinate]; - double diagonalBotR = [OSVUtils getAirDistanceBetweenCoordinate:box.bottomRightCoordinate andCoordinate:self.viewBox.bottomRightCoordinate]; - - CLLocationCoordinate2D boxTopRight = CLLocationCoordinate2DMake(box.topLeftCoordinate.latitude, box.bottomRightCoordinate.longitude); - CLLocationCoordinate2D boxBotLeft = CLLocationCoordinate2DMake(box.bottomRightCoordinate.latitude, box.topLeftCoordinate.longitude); - CLLocationCoordinate2D viewTopRight = CLLocationCoordinate2DMake(self.viewBox.topLeftCoordinate.latitude, self.viewBox.bottomRightCoordinate.longitude); - CLLocationCoordinate2D viewBotLeft = CLLocationCoordinate2DMake(self.viewBox.bottomRightCoordinate.latitude, self.viewBox.topLeftCoordinate.longitude); - - double diagonalTopR = [OSVUtils getAirDistanceBetweenCoordinate:boxTopRight andCoordinate:viewTopRight]; - double diagonalBotL = [OSVUtils getAirDistanceBetweenCoordinate:boxBotLeft andCoordinate:viewBotLeft]; - - double diagonal = [OSVUtils getAirDistanceBetweenCoordinate:self.viewBox.topLeftCoordinate andCoordinate:self.viewBox.bottomRightCoordinate]; - - if (((![self.viewBox containsLocation:box.bottomRightCoordinate] && ![self.viewBox containsLocation:box.topLeftCoordinate]) || - !self.isRequestingView) && - (diagonalTopL / diagonal < 0.4 || - diagonalBotR / diagonal < 0.4 || - diagonalTopR / diagonal < 0.4 || - diagonalBotL / diagonal < 0.4 || - ![self.viewBox containsLocation:box.topLeftCoordinate] || - ![self.viewBox containsLocation:box.bottomRightCoordinate]) ) { - - self.isRequestingView = YES; - self.viewBox = [SKBoundingBox new]; - self.viewBox.topLeftCoordinate = CLLocationCoordinate2DMake(box.topLeftCoordinate.latitude + 0.02, box.topLeftCoordinate.longitude - 0.02); - self.viewBox.bottomRightCoordinate = CLLocationCoordinate2DMake(box.bottomRightCoordinate.latitude - 0.02, box.bottomRightCoordinate.longitude + 0.02); - - [self deleteBuffer:self.bufferV]; - self.bufferV = [NSMutableArray array]; - - NSLog(@"requested view"); - - dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ - [[OSVSyncController sharedInstance].tracksController getServerTracksInBoundingBox:(id)self.viewBox withZoom:region.zoomLevel withPartialCompletion:^(id sequence, OSVMetadata *metadata, NSError *error) { - if ([metadata isLastPage] || error || !sequence) { - self.isRequestingView = NO; - } - - [self addSequenceOnMap:sequence]; - [self.bufferV addObject:@(_iii_)]; - }]; - }); - } +- (void)mapView:(SKMapView *)mapView didEndRegionChangeToRegion:(SKCoordinateRegion)region { + if (region.zoomLevel <= 20 && region.zoomLevel >= 15) { + [OSVUserDefaults sharedInstance].zoomLevel = region.zoomLevel; + [[OSVUserDefaults sharedInstance] save]; + } +} + +- (void)addPolyline:(OSVPolyline *)polyline { + [self.lock lock]; + [self.bufferN addObject:polyline]; + [self.lock unlock]; } int _iii_ = 0; -- (void)addSequenceOnMap:(id)sequence { - dispatch_async(dispatch_get_main_queue(), ^{ - NSArray *track = [self getTrackForSequence:sequence]; - OSVPolyline *polyline = [OSVPolyline new]; - polyline.lineWidth = 6; - polyline.backgroundLineWidth = 6; - polyline.coordinates = track; - if (_iii_ > 2000) { - _iii_ = 0; - } - polyline.identifier = _iii_++; - - if ([sequence isKindOfClass:[OSVSequence class]]) { - polyline.fillColor = [UIColor blackColor]; - } else { - polyline.fillColor = self.colorPurple; - } - - polyline.isLocal = YES; - [self.mapView addPolyline:polyline]; - }); -} - +- (void)moveToMap { + + [self.lock lock]; +// NSLog(@"___x___ %p - %ld, %p - %ld", self.bufferV, self.bufferV.count, self.bufferN, self.bufferN.count); -- (void)deleteBuffer:(NSMutableArray *)array { - for (NSNumber *uid in array) { + for (NSNumber *uid in self.bufferV) { [self.mapView clearOverlayWithID:(int)[uid integerValue]]; } -} - -- (NSMutableArray *)getTrackForSequence:(id)sequence { + self.bufferV = [NSMutableArray array]; - NSMutableArray *positions; - if ([sequence isKindOfClass:[OSVSequence class]] || !sequence.track.count) { - positions = [NSMutableArray array]; - for (OSVPhoto *photo in sequence.photos) { - CLLocation *location = photo.photoData.location; - [positions addObject:location]; + for (OSVPolyline *polyline in self.bufferN) { + + if (_iii_ > 3000) { + _iii_ = 0; } - } else { - positions = [sequence.track mutableCopy]; + + polyline.identifier = _iii_; + polyline.lineWidth = 6; + polyline.backgroundLineWidth = 6; + polyline.fillColor = [self.colorPurple colorWithAlphaComponent:MIN(polyline.coverage, 10.0)/10.0 + 0.01]; + polyline.strokeColor = [self.colorPurple colorWithAlphaComponent:MIN(polyline.coverage, 10.0)/10.0 + 0.01]; + + [self.bufferV addObject:@(_iii_)]; + + _iii_ += 1; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self.mapView addPolyline:polyline]; + }); } - return positions; + self.bufferN = [NSMutableArray array]; + + [self.lock unlock]; } @end diff --git a/OpenStreetView/OSVCropedLabel.h b/OpenStreetView/OSVCropedLabel.h deleted file mode 100644 index 672aabf..0000000 --- a/OpenStreetView/OSVCropedLabel.h +++ /dev/null @@ -1,14 +0,0 @@ -// -// OSVCropedLabel.h -// OpenStreetView -// -// Created by Bogdan Sala on 03/12/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import - -@interface OSVCropedLabel : UILabel - - -@end diff --git a/OpenStreetView/OSVCropedLabel.m b/OpenStreetView/OSVCropedLabel.m deleted file mode 100644 index 24e134b..0000000 --- a/OpenStreetView/OSVCropedLabel.m +++ /dev/null @@ -1,31 +0,0 @@ -// -// OSVCropedLabel.m -// OpenStreetView -// -// Created by Bogdan Sala on 03/12/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVCropedLabel.h" - -@implementation OSVCropedLabel - -- (void)drawRect:(CGRect)rect { - CGContextRef context = UIGraphicsGetCurrentContext(); - [[UIColor whiteColor] setFill]; - UIRectFill(rect); - - [super drawRect:rect]; - - CGRect holeRectIntersection = CGRectMake(CGRectGetMidX(rect) - 37.5, CGRectGetMinY(rect) - 70, 75, 75); - - if (CGRectIntersectsRect( holeRectIntersection, rect )) { - CGContextAddEllipseInRect(context, holeRectIntersection); - CGContextClip(context); - CGContextClearRect(context, holeRectIntersection); - CGContextSetFillColorWithColor( context, [UIColor clearColor].CGColor ); - CGContextFillRect( context, holeRectIntersection); - } -} - -@end diff --git a/OpenStreetView/OSVDebugViewController.m b/OpenStreetView/OSVDebugViewController.m index 3bf8765..a136fc9 100644 --- a/OpenStreetView/OSVDebugViewController.m +++ b/OpenStreetView/OSVDebugViewController.m @@ -13,15 +13,17 @@ #import #import -#define kProductionBaseURLOSV @"http://openstreetview.com" -#define kTstBaseURLOSV @"http://testing.openstreetview.com" -#define kStagingBaseURLOSV @"http://staging.openstreetview.com" +#import "OSVSequence.h" +#import "OSVPersistentManager.h" +#import "OSVUtils.h" +#import "OSVAPIConfigurator.h" @interface OSVDebugViewController () @property (weak, nonatomic) IBOutlet UILabel *revisionNumber; @property (weak, nonatomic) IBOutlet UISwitch *positionerSwitch; @property (weak, nonatomic) IBOutlet UIButton *simulatorButton; +@property (weak, nonatomic) IBOutlet UISwitch *highDensity; @property (weak, nonatomic) IBOutlet UIButton *testEnvironment; @property (weak, nonatomic) IBOutlet UIButton *stagingEnvironment; @@ -41,6 +43,13 @@ @interface OSVDebugViewController () @property (weak, nonatomic) IBOutlet UIButton *encodingMediumQ; @property (weak, nonatomic) IBOutlet UIButton *encodingLowQ; @property (weak, nonatomic) IBOutlet UIButton *encodingHighQ; +@property (weak, nonatomic) IBOutlet UISwitch *stabilization; +@property (weak, nonatomic) IBOutlet UISwitch *matcherRedering; + +@property (weak, nonatomic) IBOutlet UIButton *redGPS; +@property (weak, nonatomic) IBOutlet UIButton *yellowGPS; +@property (weak, nonatomic) IBOutlet UIButton *greenGPS; +@property (weak, nonatomic) IBOutlet UIButton *nonDebugGPS; @end @@ -55,28 +64,39 @@ - (void)viewDidLoad { self.revisionNumber.text = [NSString stringWithFormat:@"Revision %@", content]; self.simulatorButton.hidden = [OSVUserDefaults sharedInstance].realPositions; - self.testEnvironment.selected = [[OSVUserDefaults sharedInstance].environment isEqualToString:kTstBaseURLOSV]; - self.stagingEnvironment.selected = [[OSVUserDefaults sharedInstance].environment isEqualToString:kStagingBaseURLOSV]; - self.productionEnvironment.selected = [[OSVUserDefaults sharedInstance].environment isEqualToString:kProductionBaseURLOSV]; + self.testEnvironment.selected = [[OSVUserDefaults sharedInstance].environment isEqualToString:[OSVAPIConfigurator testingEnvironment]]; + self.stagingEnvironment.selected = [[OSVUserDefaults sharedInstance].environment isEqualToString:[OSVAPIConfigurator stagingEnvironment]]; + self.productionEnvironment.selected = [[OSVUserDefaults sharedInstance].environment isEqualToString:[OSVAPIConfigurator productionEnvironment]]; self.encodingLowQ.selected = [[OSVUserDefaults sharedInstance].debugEncoding isEqualToString:AVVideoProfileLevelH264BaselineAutoLevel]; self.encodingHighQ.selected = [[OSVUserDefaults sharedInstance].debugEncoding isEqualToString:AVVideoProfileLevelH264HighAutoLevel]; self.encodingMediumQ.selected = [[OSVUserDefaults sharedInstance].debugEncoding isEqualToString:AVVideoProfileLevelH264MainAutoLevel]; + self.nonDebugGPS.selected = [OSVUserDefaults sharedInstance].debugLocationAccuracy == 0; + self.greenGPS.selected = [OSVUserDefaults sharedInstance].debugLocationAccuracy == 1; + self.yellowGPS.selected = [OSVUserDefaults sharedInstance].debugLocationAccuracy == 2; + self.redGPS.selected = [OSVUserDefaults sharedInstance].debugLocationAccuracy == 3; + [self.hdrSwitch setOn:[OSVUserDefaults sharedInstance].hdrOption animated:NO]; [self.debugLogsOBD setOn:[OSVUserDefaults sharedInstance].debugLogOBD animated:NO]; [self.debugSLUS setOn:[OSVUserDefaults sharedInstance].debugSLUS animated:NO]; + + [self.stabilization setOn:[OSVUserDefaults sharedInstance].debugStabilization animated:NO]; + [self.matcherRedering setOn:[OSVUserDefaults sharedInstance].debugMatcher animated:NO]; + double value = [OSVUserDefaults sharedInstance].debugFrameRate; self.frameRateLabel.text = [NSString stringWithFormat:@"%.f frames/sec when possible", value]; value = [OSVUserDefaults sharedInstance].debugFrameSize; self.frameMaxDimensionLabel.text = [NSString stringWithFormat:@"%.f w x %.f h (landscape)\n %.f w x %.f h (portrait)", value, floorf(value/1.33), floorf(value/1.33), value]; if ([OSVUserDefaults sharedInstance].debugHighDesintyOn) { - self.hqLabel.text = @"HighQualityVideoLowDensity ON"; + self.hqLabel.text = @"HighDensity ON"; + [self.highDensity setOn:YES]; } else { - self.hqLabel.text = @"HighQualityVideoLowDensity OFF"; + self.hqLabel.text = @"HighDensity OFF"; + [self.highDensity setOn:NO]; } value = [OSVUserDefaults sharedInstance].debugBitRate; @@ -89,11 +109,11 @@ - (void)viewWillAppear:(BOOL)animated { } - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } #pragma mark - UI Actions @@ -127,16 +147,18 @@ - (IBAction)didTouchEnvironmentButton:(UIButton *)sender { if (sender == self.testEnvironment) { self.stagingEnvironment.selected = NO; self.productionEnvironment.selected = NO; - [OSVUserDefaults sharedInstance].environment = kTstBaseURLOSV; + [OSVUserDefaults sharedInstance].environment = [OSVAPIConfigurator testingEnvironment]; } else if (sender == self.stagingEnvironment) { self.testEnvironment.selected = NO; self.productionEnvironment.selected = NO; - [OSVUserDefaults sharedInstance].environment = kStagingBaseURLOSV; + [OSVUserDefaults sharedInstance].environment = [OSVAPIConfigurator stagingEnvironment]; } else if (sender == self.productionEnvironment) { self.testEnvironment.selected = NO; self.stagingEnvironment.selected = NO; - [OSVUserDefaults sharedInstance].environment = kProductionBaseURLOSV; + [OSVUserDefaults sharedInstance].environment = [OSVAPIConfigurator productionEnvironment]; } + + [[OSVUserDefaults sharedInstance] save]; } - (IBAction)didTouchEncodingButton:(UIButton *)sender { @@ -157,6 +179,32 @@ - (IBAction)didTouchEncodingButton:(UIButton *)sender { } } +- (IBAction)didTouchGPSQualityButton:(UIButton *)sender { + sender.selected = YES; + + if (sender == self.nonDebugGPS) { + self.greenGPS.selected = NO; + self.yellowGPS.selected = NO; + self.redGPS.selected = NO; + [OSVUserDefaults sharedInstance].debugLocationAccuracy = 0; + } else if (sender == self.greenGPS) { + self.nonDebugGPS.selected = NO; + self.yellowGPS.selected = NO; + self.redGPS.selected = NO; + [OSVUserDefaults sharedInstance].debugLocationAccuracy = 1; + } else if (sender == self.yellowGPS) { + self.greenGPS.selected = NO; + self.nonDebugGPS.selected = NO; + self.redGPS.selected = NO; + [OSVUserDefaults sharedInstance].debugLocationAccuracy = 2; + } else if (sender == self.redGPS) { + self.greenGPS.selected = NO; + self.yellowGPS.selected = NO; + self.nonDebugGPS.selected = NO; + [OSVUserDefaults sharedInstance].debugLocationAccuracy = 3; + } +} + - (IBAction)didChangeHDROption:(UISwitch *)sender { [OSVUserDefaults sharedInstance].hdrOption = sender.on; } @@ -191,7 +239,6 @@ - (IBAction)didChangeFrameSize:(UITextField *)sender { self.frameMaxDimensionLabel.text = [NSString stringWithFormat:@"%.f w x %.f h (landscape)\n %.f w x %.f h (portrait)", value, floorf(value/1.33), floorf(value/1.33), value]; [sender resignFirstResponder]; - } - (IBAction)didChangeBitRate:(UITextField *)sender { @@ -208,10 +255,42 @@ - (IBAction)didChangeBitRate:(UITextField *)sender { - (IBAction)didChangeHQSwitch:(UISwitch *)sender { [OSVUserDefaults sharedInstance].debugHighDesintyOn = sender.on; if (sender.on) { - self.hqLabel.text = @"HighQualityVideoLowDensity ON"; + self.hqLabel.text = @"HighDensity ON"; } else { - self.hqLabel.text = @"HighQualityVideoLowDensity OFF"; + self.hqLabel.text = @"HighDensity OFF"; } } +- (IBAction)didChangeStabilization:(UISwitch *)sender { + [OSVUserDefaults sharedInstance].debugStabilization = sender.on; +} + +- (IBAction)didChangeMatcherDebug:(UISwitch *)sender { + [OSVUserDefaults sharedInstance].debugMatcher = sender.on; + [[OSVUserDefaults sharedInstance] save]; +} + +- (IBAction)moveTrackFiles:(id)sender { + NSFileManager * fm = [[NSFileManager alloc] init]; + + [OSVPersistentManager getAllSequencesWithCompletion:^(NSArray *sequences, NSInteger photosCount) { + for (OSVSequence *track in sequences) { + NSString *pathToTrack = [self metadataForTrack:track]; + NSString *pathToMove = [[OSVUtils documentsDirectoryPath] stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld_track.txt", (long)track.uid]]; + [fm copyItemAtPath:pathToTrack toPath:pathToMove error:nil]; + } + }]; +} + +- (NSString *)metadataForTrack:(OSVSequence *)seq { + + NSString *photoPath = [[OSVUtils createOSCBasePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/track.txt", (long)seq.uid]]; + + if ([[NSFileManager defaultManager] fileExistsAtPath:photoPath]) { + return photoPath; + } + + return nil; +} + @end diff --git a/OpenStreetView/OSVDissmissFullScreenAnimationController.m b/OpenStreetView/OSVDissmissFullScreenAnimationController.m index 9d33e04..513c07b 100644 --- a/OpenStreetView/OSVDissmissFullScreenAnimationController.m +++ b/OpenStreetView/OSVDissmissFullScreenAnimationController.m @@ -31,8 +31,7 @@ - (void)animateTransition:(id)transitionCo [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:1.0 animations:^{ source.imageView.frame = self.destinationFrame; }]; - } - completion:^(BOOL finished) { + } completion:^(BOOL finished) { [transitionContext completeTransition:YES]; }]; diff --git a/OpenStreetView/OSVDissmissRecordTransition.h b/OpenStreetView/OSVDissmissRecordTransition.h new file mode 100644 index 0000000..b9f5069 --- /dev/null +++ b/OpenStreetView/OSVDissmissRecordTransition.h @@ -0,0 +1,14 @@ +// +// OSVDissmissRecordTransition.h +// OpenStreetView +// +// Created by Bogdan Sala on 10/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import +#import + +@interface OSVDissmissRecordTransition : NSObject + +@end diff --git a/OpenStreetView/OSVDissmissRecordTransition.m b/OpenStreetView/OSVDissmissRecordTransition.m new file mode 100644 index 0000000..37f7b14 --- /dev/null +++ b/OpenStreetView/OSVDissmissRecordTransition.m @@ -0,0 +1,54 @@ +// +// OSVDissmissRecordTransition.m +// OpenStreetView +// +// Created by Bogdan Sala on 10/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVDissmissRecordTransition.h" +#import "OSVCamViewController.h" + +@implementation OSVDissmissRecordTransition + +- (NSTimeInterval)transitionDuration:(id)transitionContext { + return 0.4; +} + +- (void)animateTransition:(id)transitionContext { + OSVCamViewController *source = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; + UIViewController *destination = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; + + NSTimeInterval transitionDuration = [self transitionDuration:transitionContext]; + destination.view.alpha = 0.0; + destination.view.frame = transitionContext.containerView.frame; + + [transitionContext.containerView addSubview:destination.view]; + + source.view.alpha = 1.0; + + [UIView animateKeyframesWithDuration:transitionDuration + delay:0.0 + options:UIViewKeyframeAnimationOptionCalculationModeCubic + animations:^{ + + [UIView addKeyframeWithRelativeStartTime:0.0 + relativeDuration:1.0 + animations:^{ + destination.view.alpha = 1.0; + source.view.alpha = 0.2; + }]; + + [UIView addKeyframeWithRelativeStartTime:0.0 + relativeDuration:0.7 + animations:^{ + source.sugestionLabel.frame = CGRectOffset(source.sugestionLabel.frame, 0, 40); + source.arrowImage.frame = CGRectOffset(source.arrowImage.frame, 0, 40); + }]; + } completion:^(BOOL finished) { + [source removeFromParentViewController]; + [transitionContext completeTransition:YES]; + }]; +} + +@end diff --git a/OpenStreetView/OSVExpandableCell.h b/OpenStreetView/OSVExpandableCell.h deleted file mode 100644 index 245c05a..0000000 --- a/OpenStreetView/OSVExpandableCell.h +++ /dev/null @@ -1,20 +0,0 @@ -// -// OSVExpandableCell.h -// OpenStreetView -// -// Created by Bogdan Sala on 18/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import - -@protocol OSVExpandableCellDelegate; - -@interface OSVExpandableCell : UITableViewCell - -@property (weak, nonatomic) IBOutlet UILabel *title; -@property (weak, nonatomic) IBOutlet UIView *rightImageView; - -@property (copy, nonatomic) void (^action)(OSVExpandableCell *sender); - -@end diff --git a/OpenStreetView/OSVExpandableCell.m b/OpenStreetView/OSVExpandableCell.m deleted file mode 100644 index 4cf8778..0000000 --- a/OpenStreetView/OSVExpandableCell.m +++ /dev/null @@ -1,26 +0,0 @@ -// -// OSVExpandableCell.m -// OpenStreetView -// -// Created by Bogdan Sala on 18/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVExpandableCell.h" - -@implementation OSVExpandableCell - -- (void)awakeFromNib { - [super awakeFromNib]; - UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(expandSection:)]; - tapGesture.numberOfTapsRequired = 1; - - [self.contentView addGestureRecognizer:tapGesture]; -} - - -- (void)expandSection:(id)sender { - self.action(self); -} - -@end diff --git a/OpenStreetView/OSVFullScreenAnimationController.m b/OpenStreetView/OSVFullScreenAnimationController.m index 7df7a39..a393f4d 100644 --- a/OpenStreetView/OSVFullScreenAnimationController.m +++ b/OpenStreetView/OSVFullScreenAnimationController.m @@ -8,7 +8,6 @@ #import "OSVFullScreenAnimationController.h" #import "OSVPlayer.h" -#import "OSVVideoPlayerViewController.h" #import "OSVFullScreenImageViewController.h" @implementation OSVFullScreenAnimationController diff --git a/OpenStreetView/OSVFullScreenImageViewController.m b/OpenStreetView/OSVFullScreenImageViewController.m index 580ba54..1217d59 100644 --- a/OpenStreetView/OSVFullScreenImageViewController.m +++ b/OpenStreetView/OSVFullScreenImageViewController.m @@ -9,6 +9,9 @@ #import "OSVFullScreenImageViewController.h" #import "OSVImageCollectionViewCell.h" #import "OSVSyncController.h" + +#import "OSVUtils.h" + #import "OSVFullScreenImageCell.h" #import #import @@ -54,12 +57,21 @@ - (BOOL)prefersStatusBarHidden { return YES; } +#pragma mark - Rotation + +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { + [coordinator animateAlongsideTransition:^(id context) { + [self.collectionViewFullscreen reloadData]; + } completion:^(id context) { + }]; +} + - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } #pragma mark - Actions @@ -158,7 +170,6 @@ - (void)setSelectedCellUsingCollectionView:(UICollectionView *)collectionView ov } } - #pragma mark - Overide - (void)setSelectedIndexPath:(NSIndexPath *)selectedIndexPath { @@ -172,7 +183,7 @@ - (void)setSequenceDatasource:(id)sequenceDatasource { _sequenceDatasource = sequenceDatasource; if (sequenceDatasource.photos.count && ![sequenceDatasource.photos[0] isKindOfClass:[OSVServerPhoto class]]) { - NSArray *videoPaths = [self videoPathsFromFolder:[self fileNameForTrackID:self.sequenceDatasource.uid]]; + NSArray *videoPaths = [self videoPathsFromFolder:[OSVUtils fileNameForTrackID:self.sequenceDatasource.uid]]; AVMutableComposition *mixComposition = [[AVMutableComposition alloc] init]; AVMutableCompositionTrack *videoTrack = [mixComposition addMutableTrackWithMediaType:AVMediaTypeVideo @@ -204,12 +215,6 @@ - (void)setSequenceDatasource:(id)sequenceDatasource { } } -- (NSURL *)fileNameForTrackID:(NSInteger)trackUID { - NSString *folderPathString = [NSString stringWithFormat:@"%@%ld", [OSVSyncController sharedInstance].tracksController.basePathToPhotos, (long)trackUID]; - - return [[NSURL alloc] initWithString:folderPathString]; -} - - (NSArray *)videoPathsFromFolder:(NSURL *)basePath { NSMutableArray *videoFiles = [NSMutableArray array]; diff --git a/OpenStreetView/OSVGalleryCell.h b/OpenStreetView/OSVGalleryCell.h deleted file mode 100644 index 247b9cf..0000000 --- a/OpenStreetView/OSVGalleryCell.h +++ /dev/null @@ -1,18 +0,0 @@ -// -// OSVGalleryCell.h -// OpenStreetView -// -// Created by Bogdan Sala on 03/12/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import - -@interface OSVGalleryCell : UICollectionViewCell - -@property (weak, nonatomic) IBOutlet UIImageView *imageView; -@property (weak, nonatomic) IBOutlet UIView *transparentOverlay; - -@property (assign, nonatomic) BOOL isInEditMode; - -@end diff --git a/OpenStreetView/OSVGalleryCell.m b/OpenStreetView/OSVGalleryCell.m deleted file mode 100644 index 7ae8ebd..0000000 --- a/OpenStreetView/OSVGalleryCell.m +++ /dev/null @@ -1,27 +0,0 @@ -// -// OSVGalleryCell.m -// OpenStreetView -// -// Created by Bogdan Sala on 03/12/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVGalleryCell.h" - -@implementation OSVGalleryCell - -- (void)awakeFromNib { - [super awakeFromNib]; - self.transparentOverlay.backgroundColor = [[UIColor whiteColor] colorWithAlphaComponent:0.6]; -} - -- (void)setIsInEditMode:(BOOL)isInEditMode { - _isInEditMode = isInEditMode; - self.transparentOverlay.hidden = !isInEditMode; -} - -- (void)prepareForReuse { - self.isInEditMode = NO; -} - -@end diff --git a/OpenStreetView/OSVGamificationInfo.h b/OpenStreetView/OSVGamificationInfo.h new file mode 100644 index 0000000..5d43273 --- /dev/null +++ b/OpenStreetView/OSVGamificationInfo.h @@ -0,0 +1,26 @@ +// +// OSVGamificationInfo.h +// OpenStreetView +// +// Created by Bogdan Sala on 22/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVGamificationInfo : NSObject + +@property (nonatomic, assign) double totalPoints; + +@property (nonatomic, assign) double regionTotalPoints; +@property (nonatomic, assign) NSInteger regionRank; +@property (nonatomic, strong) NSString *regionCode; + +@property (nonatomic, assign) NSInteger level; +@property (nonatomic, assign) NSInteger levelPoints; +@property (nonatomic, assign) NSInteger totalLevelPoints; +@property (nonatomic, strong) NSString *levelName; + +@property (nonatomic, assign) NSInteger rank; + +@end diff --git a/OpenStreetView/OSVGamificationInfo.m b/OpenStreetView/OSVGamificationInfo.m new file mode 100644 index 0000000..bc2cae2 --- /dev/null +++ b/OpenStreetView/OSVGamificationInfo.m @@ -0,0 +1,13 @@ +// +// OSVGamificationInfo.m +// OpenStreetView +// +// Created by Bogdan Sala on 22/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVGamificationInfo.h" + +@implementation OSVGamificationInfo + +@end diff --git a/OpenStreetView/OSVGamificationProfileCell.h b/OpenStreetView/OSVGamificationProfileCell.h new file mode 100644 index 0000000..1373970 --- /dev/null +++ b/OpenStreetView/OSVGamificationProfileCell.h @@ -0,0 +1,26 @@ +// +// OSVGamificationProfileCell.h +// OpenStreetView +// +// Created by Bogdan Sala on 22/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import +#import "KAProgressLabel.h" + +@interface OSVGamificationProfileCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *nextLevelPoints; +@property (weak, nonatomic) IBOutlet UILabel *rankLabel; +@property (weak, nonatomic) IBOutlet UILabel *scoreLabel; +@property (weak, nonatomic) IBOutlet KAProgressLabel *progressView; +@property (weak, nonatomic) IBOutlet UILabel *progressLabel; + +@property (weak, nonatomic) IBOutlet UILabel *scoreTextLabel; +@property (weak, nonatomic) IBOutlet UILabel *rankTextLabel; +@property (weak, nonatomic) IBOutlet UIView *rankView; + +@property (copy, nonatomic) void (^didTapRank)(id view); + +@end diff --git a/OpenStreetView/OSVGamificationProfileCell.m b/OpenStreetView/OSVGamificationProfileCell.m new file mode 100644 index 0000000..6adcb36 --- /dev/null +++ b/OpenStreetView/OSVGamificationProfileCell.m @@ -0,0 +1,40 @@ +// +// OSVGamificationProfileCell.m +// OpenStreetView +// +// Created by Bogdan Sala on 22/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVGamificationProfileCell.h" +#import "UIColor+OSVColor.h" + +@implementation OSVGamificationProfileCell + +- (void)awakeFromNib { + [super awakeFromNib]; + + self.progressView.trackWidth = 6; + self.progressView.borderWidth = 1; + self.progressView.trackColor = [UIColor colorWithHex:0x80cee9]; + self.progressView.borderColor = [UIColor colorWithHex:0x80cee9]; + self.progressView.progressWidth = self.progressView.trackWidth; + self.progressView.progressColor = [UIColor whiteColor]; + self.progressView.startRoundedCornersWidth = 0; + self.progressView.endRoundedCornersWidth = self.progressView.trackWidth * 3; + self.progressView.startDegree = 0; + self.progressView.endDegree = 0; + + UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapRankView)]; + tap.numberOfTapsRequired = 1; + + [self.rankView addGestureRecognizer:tap]; +} + +- (void)didTapRankView { + if (self.didTapRank) { + self.didTapRank(self.rankView); + } +} + +@end diff --git a/OpenStreetView/OSVIntroViewController.h b/OpenStreetView/OSVIntroViewController.h new file mode 100644 index 0000000..cff535b --- /dev/null +++ b/OpenStreetView/OSVIntroViewController.h @@ -0,0 +1,19 @@ +// +// OSVIntroViewController.h +// OpenStreetView +// +// Created by Bogdan Sala on 17/01/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVIntroViewController : UIViewController + +@property (weak, nonatomic) IBOutlet UILabel *tipTitleLabel; +@property (weak, nonatomic) IBOutlet UILabel *tipDescriptionLabel; +@property (weak, nonatomic) IBOutlet UIImageView *image; + +@property (assign, nonatomic) NSInteger index; + +@end diff --git a/OpenStreetView/OSVIntroViewController.m b/OpenStreetView/OSVIntroViewController.m new file mode 100644 index 0000000..d803e74 --- /dev/null +++ b/OpenStreetView/OSVIntroViewController.m @@ -0,0 +1,35 @@ +// +// OSVIntroViewController.m +// OpenStreetView +// +// Created by Bogdan Sala on 17/01/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import "OSVIntroViewController.h" + +@interface OSVIntroViewController () + +@end + +@implementation OSVIntroViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view from its nib. +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + return UIStatusBarStyleLightContent; +} + +@end diff --git a/OpenStreetView/OSVIntroViewController.xib b/OpenStreetView/OSVIntroViewController.xib new file mode 100644 index 0000000..f35daee --- /dev/null +++ b/OpenStreetView/OSVIntroViewController.xib @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/OpenStreetView/OSVLeftMenuViewController.m b/OpenStreetView/OSVLeftMenuViewController.m index 3d40d6d..cfe7864 100644 --- a/OpenStreetView/OSVLeftMenuViewController.m +++ b/OpenStreetView/OSVLeftMenuViewController.m @@ -28,8 +28,12 @@ @implementation OSVLeftMenuViewController - (void)viewDidLoad { [super viewDidLoad]; - self.menu = [OSVMainMenuFactory mainMenu]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willDisplayView) name:kLGSideMenuControllerWillShowLeftViewNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(showUploadScreen) name:@"kShowUploadScreen" object:nil]; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; } - (void)willDisplayView { @@ -38,6 +42,9 @@ - (void)willDisplayView { } else { self.titleButton.text = NSLocalizedString(@"Sign Out", @""); } + + self.menu = [OSVMainMenuFactory mainMenu]; + [self.tableView reloadData]; } - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { @@ -58,7 +65,9 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { OSVMenuItem *item = self.menu[indexPath.row]; - item.action(self.defaultViewController, nil); + if (item && item.action) { + item.action(self.defaultViewController, nil); + } if ([self.mainMenuDelegate respondsToSelector:@selector(hideLeftViewAnimated:completionHandler:)]) { [self.mainMenuDelegate hideLeftViewAnimated:YES completionHandler:^{ @@ -67,31 +76,53 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath [tableView deselectRowAtIndexPath:indexPath animated:YES]; } - - (IBAction)didTapActionView:(id)sender { - if (![[OSVSyncController sharedInstance].tracksController userIsLoggedIn]) { - [[OSVSyncController sharedInstance].tracksController loginWithCompletion:^(NSError *error) { - if (error) { - [[OSVSyncController sharedInstance].tracksController logout]; - } else { - self.titleButton.text = NSLocalizedString(@"Sign Out", @""); - } - }]; - } else { - [UIAlertView showWithTitle:@"" - message:NSLocalizedString(@"Are you sure you want to logout?", @"Preemtiv message to stop a unwanted loggout form the current online user profile") - cancelButtonTitle:NSLocalizedString(@"No", nil) - otherButtonTitles:@[NSLocalizedString(@"Yes", nil)] - tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { - if (buttonIndex == [alertView cancelButtonIndex]) { - - } else { - [[OSVSyncController sharedInstance].tracksController logout]; - self.titleButton.text = NSLocalizedString(@"Sign In", @""); - } - }]; + if ([[OSVSyncController sharedInstance].tracksController userIsLoggedIn]) { + if (![OSVSyncController isUploading]) { + [UIAlertView showWithTitle:@"" + message:NSLocalizedString(@"Are you sure you want to logout?", @"") + cancelButtonTitle:NSLocalizedString(@"No", nil) + otherButtonTitles:@[NSLocalizedString(@"Yes", nil)] + tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { + if (buttonIndex != [alertView cancelButtonIndex]) { + [[OSVSyncController sharedInstance].tracksController logout]; + self.titleButton.text = NSLocalizedString(@"Sign In", @""); + } + }]; + } else { + [UIAlertView showWithTitle:@"" + message:NSLocalizedString(@"Can not logout while uploading!", @"") + cancelButtonTitle:NSLocalizedString(@"Ok", nil) + otherButtonTitles:nil + tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { + }]; + } + } else { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLoginWithSuccess:) name:@"kOSVDidSigninRequest" object:nil]; + + [self.defaultViewController performSegueWithIdentifier:@"showLoginController" sender:nil]; + + if ([self.mainMenuDelegate respondsToSelector:@selector(hideLeftViewAnimated:completionHandler:)]) { + [self.mainMenuDelegate hideLeftViewAnimated:YES completionHandler:^{ + }]; + } + } +} +- (void)didLoginWithSuccess:(NSNotification *)notification { + NSNumber *success = notification.userInfo[@"success"]; + if ([success boolValue]) { + self.titleButton.text = NSLocalizedString(@"Sign Out", @""); + } else { + self.titleButton.text = NSLocalizedString(@"Sign In", @""); + } +} +- (void)showUploadScreen { + //TODO this is a hack + OSVMenuItem *item = self.menu[1]; + if (item && item.action) { + item.action(self.defaultViewController, nil); } } diff --git a/OpenStreetView/OSVLocalNotificationsController.h b/OpenStreetView/OSVLocalNotificationsController.h new file mode 100644 index 0000000..044f859 --- /dev/null +++ b/OpenStreetView/OSVLocalNotificationsController.h @@ -0,0 +1,18 @@ +// +// OSVLocalNotificationsController.h +// OpenStreetView +// +// Created by Bogdan Sala on 18/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVLocalNotificationsController : NSObject + ++ (void)scheduleUploadNotification; ++ (void)removeUploadNotification; + ++ (void)handleNotification:(UILocalNotification *)notification application:(UIApplication *)application; + +@end diff --git a/OpenStreetView/OSVLocalNotificationsController.m b/OpenStreetView/OSVLocalNotificationsController.m new file mode 100644 index 0000000..61112b6 --- /dev/null +++ b/OpenStreetView/OSVLocalNotificationsController.m @@ -0,0 +1,64 @@ +// +// OSVLocalNotificationsController.m +// OpenStreetView +// +// Created by Bogdan Sala on 18/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +#import "OSVLocalNotificationsController.h" + +@implementation OSVLocalNotificationsController + ++ (void)scheduleUploadNotification { + UIUserNotificationType types = (UIUserNotificationType) (UIUserNotificationTypeBadge | UIUserNotificationTypeSound | UIUserNotificationTypeAlert); + UIUserNotificationSettings *mySettings = [UIUserNotificationSettings settingsForTypes:types categories:nil]; + [[UIApplication sharedApplication] registerUserNotificationSettings:mySettings]; + + [self removeUploadNotification]; + + UILocalNotification *localNotification = [[UILocalNotification alloc] init]; + + NSDate *today = [NSDate date]; + NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian]; + [gregorian setLocale:[NSLocale currentLocale]]; + + NSDateComponents *nowComponents = [gregorian components: NSCalendarUnitMonth |NSCalendarUnitYear | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:today]; + + [nowComponents setHour:19]; + [nowComponents setMinute:0]; + + NSDate *fireDate = [gregorian dateFromComponents:nowComponents]; + + if ([today compare:fireDate] == NSOrderedDescending) { + fireDate = [fireDate dateByAddingTimeInterval:3600 * 24]; + } + + localNotification.fireDate = fireDate; + if ([localNotification respondsToSelector:@selector(alertTitle)]) { + localNotification.alertTitle = NSLocalizedString(@"Upload", @""); + } + localNotification.alertBody = NSLocalizedString(@"Hey, it seems that you have local recordings on your phone. Don't forget to upload your photos!", @""); + + [[UIApplication sharedApplication] scheduleLocalNotification:localNotification]; +} + ++ (void)removeUploadNotification { + NSArray *arrayOfLocalNotifications = [[UIApplication sharedApplication] scheduledLocalNotifications]; + + for (UILocalNotification *localNotification in arrayOfLocalNotifications) { + + if ([localNotification.alertBody isEqualToString:NSLocalizedString(@"Hey, it seems that you have local recordings on your phone. Don't forget to upload your photos!", @"")]) { + [[UIApplication sharedApplication] cancelLocalNotification:localNotification]; + } + } +} + ++ (void)handleNotification:(UILocalNotification *)notification application:(UIApplication *)application { + [[NSNotificationCenter defaultCenter] postNotificationName:@"kShowUploadScreen" object:nil]; +} + + +@end diff --git a/OpenStreetView/OSVLocalTracksViewController.m b/OpenStreetView/OSVLocalTracksViewController.m index 9107c92..8a5a2e0 100644 --- a/OpenStreetView/OSVLocalTracksViewController.m +++ b/OpenStreetView/OSVLocalTracksViewController.m @@ -20,11 +20,13 @@ #import "OSVReachablityController.h" #import "OSVUploadViewController.h" #import "OSVVideoPlayerViewController.h" +#import "OSVPushTransition.h" +#import "OSVPopTransition.h" #import "UIColor+OSVColor.h" #import "NSAttributedString+Additions.h" -@interface OSVLocalTracksViewController () +@interface OSVLocalTracksViewController () @property (weak, nonatomic) IBOutlet UIButton *tracksCount; @property (weak, nonatomic) IBOutlet UIButton *viewControllerTitle; @@ -49,17 +51,24 @@ - (void)viewWillAppear:(BOOL)animated { self.metricSystem = [[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]; [self addRightNavigationItemWithText:NSLocalizedString(@"Upload ", @"") andCount:@"-"]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + NSString *string = [OSVUtils memoryFormatter:[OSVSyncController sizeOnDiskForSequences]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self addRightNavigationItemWithText:NSLocalizedString(@"Upload ", @"") andCount:string]; + }); + }); + dispatch_async(dispatch_get_main_queue(), ^{ [[OSVSyncController sharedInstance].tracksController getLocalSequencesWithCompletion:^(NSArray *sequences) { self.dataSource = [sequences mutableCopy]; - - [self addRightNavigationItemWithText:NSLocalizedString(@"Upload ", @"") andCount:[@(self.dataSource.count) stringValue]]; [self.tableView reloadData]; }]; }); [self.uploadAll setTitle:NSLocalizedString(@"UPLOAD ALL", @"") forState:UIControlStateNormal]; self.tableView.allowsMultipleSelectionDuringEditing = NO; + self.navigationController.delegate = self; } - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { @@ -75,11 +84,11 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } #pragma mark - Private @@ -94,11 +103,16 @@ - (void)addRightNavigationItemWithText:(NSString *)text andCount:(NSString *)str self.navigationItem.rightBarButtonItems = @[[[UIBarButtonItem alloc] initWithCustomView:label]]; } - - - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { OSVSequence *sequence = self.dataSource[indexPath.row]; - [self performSegueWithIdentifier:@"videoPlayerSegueID" sender:sequence]; + [[OSVSyncController sharedInstance].tracksController getScoreHistoryForSequenceWithID:sequence.uid completion:^(NSArray *history) { + sequence.scoreHistory = [history mutableCopy]; + sequence.points = 0; + for (OSVScoreHistory *sch in history) { + sequence.points += sch.points; + } + [self performSegueWithIdentifier:@"videoPlayerSegueID" sender:sequence]; + }]; } #pragma mark - UITableViewDatasource @@ -113,7 +127,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N OSVSequence *track = self.dataSource[indexPath.row]; OSVPhoto *photo = track.photos.firstObject; - + cell.locationLabel.text = [NSString stringWithFormat:@"%@", track.location]; cell.photoCountLabel.attributedText = [NSAttributedString combineString:[@(track.photos.count) stringValue] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" withString:@" IMG" withSize:12.f color:[UIColor colorWithHex:0xb7bac5] fontName:@"HelveticaNeue"]; @@ -149,10 +163,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N if ([placemarks count] > 0) { CLPlacemark *placemark = placemarks[0]; NSArray *lines = placemark.addressDictionary[@"FormattedAddressLines"]; - NSString *addressString = [lines componentsJoinedByString:@","]; + NSString *addressString = [lines componentsJoinedByString:@", "]; photo.photoData.addressName = addressString; if ([photo isKindOfClass:[OSVPhoto class]]) { - [OSVPersistentManager updatedPhoto:photo withAddress:addressString]; + [OSVPersistentManager updatedPhoto:photo]; } cell.locationLabel.text = addressString; } @@ -177,7 +191,14 @@ - (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEd [[OSVSyncController sharedInstance].tracksController deleteSequence:self.dataSource[indexPath.row] withCompletionBlock:^(NSError *error) { [self.dataSource removeObjectAtIndex:indexPath.row]; [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; - [self addRightNavigationItemWithText:NSLocalizedString(@"Upload ", @"") andCount:[@(self.dataSource.count) stringValue]]; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + NSString *string = [OSVUtils memoryFormatter:[OSVSyncController sizeOnDiskForSequences]]; + dispatch_async(dispatch_get_main_queue(), ^{ + [self addRightNavigationItemWithText:NSLocalizedString(@"Upload ", @"") andCount:string]; + }); + }); + if (self.dataSource.count == 0) { [self.navigationController popViewControllerAnimated:YES]; } @@ -209,7 +230,9 @@ - (void)presentUploadControllerAndStartUploading:(BOOL)shouldUpload withAllert:( if (reach && hasServerAccess) { [self performSegueWithIdentifier:@"uploadViewControllerSegueID" sender:@(shouldUpload)]; } else if (reach && !hasServerAccess) { - [[OSVSyncController sharedInstance].tracksController loginWithCompletion:^(NSError *error) { + [[OSVSyncController sharedInstance].tracksController loginWithPartial:^(NSError * _Nullable error) { + + } andCompletion:^(NSError * _Nullable error) { dispatch_async(dispatch_get_main_queue(), ^{ [self performSegueWithIdentifier:@"uploadViewControllerSegueID" sender:@(shouldUpload)]; }); @@ -218,4 +241,24 @@ - (void)presentUploadControllerAndStartUploading:(BOOL)shouldUpload withAllert:( } } +#pragma mark - UINavigationControllerDelegate + +- (nullable id )navigationController:(UINavigationController *)navigationController + animationControllerForOperation:(UINavigationControllerOperation)operation + fromViewController:(UIViewController *)fromVC + toViewController:(UIViewController *)toVC { + if ([toVC isKindOfClass:[OSVUploadViewController class]]) { + + return [OSVPushTransition new]; + } else if ([fromVC isKindOfClass:[OSVUploadViewController class]]) { + + return [OSVPopTransition new]; + } else if ([toVC isKindOfClass:NSClassFromString(@"OSVMapViewController")]) { + return [[OSVPopTransition alloc] initWithoutAnimatingSource:YES]; + } + + return nil; +} + + @end diff --git a/OpenStreetView/OSVLogItem.h b/OpenStreetView/OSVLogItem.h index 981114b..8131241 100644 --- a/OpenStreetView/OSVLogItem.h +++ b/OpenStreetView/OSVLogItem.h @@ -23,6 +23,4 @@ @property (nonatomic, strong) OSVOBDData *carSensorData; -@property (nonatomic, assign) NSTimeInterval timestamp; - @end diff --git a/OpenStreetView/OSVLoginController.h b/OpenStreetView/OSVLoginController.h index 123c2de..7860fe6 100644 --- a/OpenStreetView/OSVLoginController.h +++ b/OpenStreetView/OSVLoginController.h @@ -14,20 +14,24 @@ @interface OSVLoginController : NSObject -@property (nonatomic) NSString *basePathToPhotos; -@property (nonatomic, readonly) id user; +@property (nonatomic, readonly, nullable) id oscUser; -- (instancetype)initWithOSVAPI:(OSVAPI *)api basePath:(NSString *)basePath; +- (instancetype _Nonnull)initWithOSVAPI:(OSVAPI *_Nonnull)api; -- (void)loginWithCompletion:(void (^)(NSError *error))completion; +- (void)loginWithPartial:(void (^_Nonnull)(NSError *_Nullable error))partial andCompletion:(void (^ _Nonnull)(NSError * _Nullable error))completion; - (void)logout; - (BOOL)userIsLoggedIn; -- (void)rankingWithCompletion:(void (^)(NSInteger rank, NSError *error))completion; -- (void)osvUserInfoWithCompletion:(void (^)(id user, NSError *error))completion; +- (void)rankingWithCompletion:(void (^ _Nonnull)(NSInteger rank, NSError * _Nullable error))completion; +- (void)leaderBoardWithCompletion:(void(^ _Nonnull)(NSArray * _Nullable leaderBoard, NSError * _Nullable error))completion; +- (void)gameLeaderBoardForRegion:(NSString * _Nullable)countryCode + formDate:(NSDate * _Nullable)date + withCompletion:(void (^_Nonnull)(NSArray *_Nullable, NSError * _Nullable))completion; -- (NSURL *)getAppLink; -- (void)checkForAppUpdateWithCompletion:(void (^)(BOOL response))completion; +- (void)osvUserInfoWithCompletion:(void (^_Nonnull)(id _Nullable user, NSError *_Nullable error))completion; + +- (NSURL *_Nullable)getAppLink; +- (void)checkForAppUpdateWithCompletion:(void (^_Nonnull)(BOOL response))completion; @end diff --git a/OpenStreetView/OSVLoginController.m b/OpenStreetView/OSVLoginController.m index c2ff3b4..17bae72 100644 --- a/OpenStreetView/OSVLoginController.m +++ b/OpenStreetView/OSVLoginController.m @@ -6,13 +6,24 @@ // Copyright © 2016 Bogdan Sala. All rights reserved. // + #import "OSVLoginController.h" + +#define kOSCUsernameKey @"OSCUsernameKey" +#define kOSCUserIdKey @"OSCUserIdKey" +#define kOSCTokenKey @"kOSCTokenKey" + +#define kOSVTokenKey @"kOSVTokenKey" + +#import +#import + +#import + #import "OSVAPI.h" #import "OSMAPI.h" #import "AFOAuth1Client.h" -#import "OSVBaseUser+OSM.h" - -#define kOSVTokenKey @"kOSVTokenKey" +#import "OSVBaseUser.h" @interface OSVLoginController () @@ -22,12 +33,20 @@ @interface OSVLoginController () @implementation OSVLoginController -- (instancetype)initWithOSVAPI:(OSVAPI *)api basePath:(NSString *)basePath { +- (instancetype)init { + self = [super init]; + if (self) { + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSignInWithGoogle:) name:@"kOSVGoogleSignIn" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didSignInWithFacebook:) name:@"kOSVFacebookSignIn" object:nil]; + } + return self; +} + +- (instancetype)initWithOSVAPI:(OSVAPI *)api { self = [super init]; if (self) { self.osvAPI = api; - self.basePathToPhotos = basePath; } return self; @@ -41,7 +60,7 @@ - (void)setDidFinishLogin:(void (^)(OSMUser *, BOOL))didFinishLogin { return [OSMAPI sharedInstance].didFinishLogin; } -- (void)loginWithCompletion:(void (^)(NSError *error))completion { +- (void)loginWithPartial:(void (^)(NSError *error))partial andCompletion:(void (^)(NSError *error))completion { [[OSMAPI sharedInstance] logIn]; [OSMAPI sharedInstance].didFinishLogin = ^(OSMUser *osmUser, BOOL success){ NSError *error = nil; @@ -50,16 +69,24 @@ - (void)loginWithCompletion:(void (^)(NSError *error))completion { completion(error); return; } - - OSVBaseUser *osvUser = [OSVBaseUser baseUserWithOSMUser:osmUser]; + partial(error); + + OSVBaseUser *osvUser = [self baseUserWithOSMUser:osmUser]; + [self.osvAPI authenticateUser:osvUser withCompletion:^(NSError *erro) { if (!erro) { + AFOAuth1Token *persistentToken = [[OSMAPI sharedInstance] osmAccessToken]; - persistentToken.userInfo = @{kOSMUsernameKey : osvUser.name, kOSMUserIdKey : @(osvUser.userID), kOSVTokenKey : osvUser.accessToken}; - - [AFOAuth1Token storeCredential:persistentToken withIdentifier:kCredentialsID]; - } - + persistentToken.userInfo = @{kOSCUsernameKey : osvUser.name, + kOSCUserIdKey : osvUser.userID, + kOSCTokenKey : osvUser.accessToken, + kOSCAuthProvider : @"osm"}; + + [AFOAuth1Token storeCredential:persistentToken withIdentifier:kOSCCredentialsID]; + } else { + [[OSMAPI sharedInstance] logout]; + } + completion(erro); }]; }; @@ -67,12 +94,16 @@ - (void)loginWithCompletion:(void (^)(NSError *error))completion { - (void)logout { [[OSMAPI sharedInstance] logout]; + [[GIDSignIn sharedInstance] signOut]; + [[FBSDKLoginManager new] logOut]; + [AFOAuth1Token deleteCredentialWithIdentifier:kOSCCredentialsID]; +// [self.osvAPI logOut]; } - (void)rankingWithCompletion:(void (^)(NSInteger , NSError *))completion { [self.osvAPI leaderBoardWithCompletion:^(NSArray *leaderBoard, NSError *error) { for (id user in leaderBoard) { - if ([user.name isEqualToString:self.user.name]) { + if ([user.name isEqualToString:self.oscUser.name]) { completion(user.rank, nil); return; } @@ -80,27 +111,27 @@ - (void)rankingWithCompletion:(void (^)(NSInteger , NSError *))completion { }]; } -- (void)osvUserInfoWithCompletion:(void (^)(id user, NSError *error))completion { - [self.osvAPI getUserInfo:self.user withCompletion:^(id user, NSError *error) { - completion(user, error); - }]; +- (void)leaderBoardWithCompletion:(void (^)(NSArray *, NSError *))completion { + [self.osvAPI leaderBoardWithCompletion:completion]; } -- (id)user { - OSMUser *osmUser = [[OSMAPI sharedInstance] osmUser]; - OSVBaseUser *osvUser = [OSVBaseUser baseUserWithOSMUser:osmUser]; - osvUser.accessToken = [self osvAccessToken]; +- (void)gameLeaderBoardForRegion:(NSString *)countryCode + formDate:(NSDate *)date + withCompletion:(void (^)(NSArray *, NSError *))completion { -// TODO remove this after the authentication is enabled on server - if (!osvUser.accessToken) { - osvUser.accessToken = @""; - } - - return osvUser; + [self.osvAPI gameLeaderBoardForCountry:countryCode + fromDate:date + withCompletion:completion]; } -- (NSString *)osvAccessToken { - return [[OSMAPI sharedInstance] osmAccessToken].userInfo[kOSVTokenKey]; +- (void)osvUserInfoWithCompletion:(void (^)(id user, NSError *error))completion { + id osvuser = self.oscUser; + + if (osvuser) { + [self.osvAPI getUserInfo:osvuser withCompletion:^(id user, NSError *error) { + completion(user, error); + }]; + } } - (NSURL *)getAppLink { @@ -114,15 +145,117 @@ - (void)checkForAppUpdateWithCompletion:(void (^)(BOOL response))completion { } }]; } - + - (BOOL)userIsLoggedIn { - id user = [self user]; - return user != nil && - user.userID != 0 && - user.name != nil && - ![user.name isEqualToString:@""] && - user.accessToken != nil && - ![user.accessToken isEqualToString:@""]; + return [self oscUser] != nil; +} + +- (void)didSignInWithGoogle:(NSNotification *)notification { + if ([self userIsLoggedIn]) { + return; + } + + GIDGoogleUser *googleUser = notification.userInfo[@"user"]; + OSVBaseUser *user = [self baseUserWithGoogleUser:googleUser]; + + if (user) { + [self.osvAPI authenticateUser:user withCompletion:^(NSError * _Nullable error) { + if (!error) { + AFOAuth1Token *persistentToken = [AFOAuth1Token new]; + persistentToken.userInfo = @{kOSCUsernameKey : user.name, + kOSCUserIdKey : user.userID, + kOSCTokenKey : user.accessToken, + kOSCAuthProvider : @"google"}; + + [AFOAuth1Token storeCredential:persistentToken withIdentifier:kOSCCredentialsID]; + } else { + [[GIDSignIn sharedInstance] signOut]; + } + }]; + } +} + +- (void)didSignInWithFacebook:(NSNotification *)notification { + if ([self userIsLoggedIn]) { + return; + } + + FBSDKProfile *profile = notification.userInfo[@"user"]; + OSVBaseUser *user = [self baseUserWithFacebookProfile:profile]; + + if (user) { + [self.osvAPI authenticateUser:user withCompletion:^(NSError * _Nullable error) { + if (!error) { + AFOAuth1Token *persistentToken = [AFOAuth1Token new]; + persistentToken.userInfo = @{kOSCUsernameKey : user.name, + kOSCUserIdKey : user.userID, + kOSCTokenKey : user.accessToken, + kOSCAuthProvider : @"facebook"}; + + [AFOAuth1Token storeCredential:persistentToken withIdentifier:kOSCCredentialsID]; + } else { + [[FBSDKLoginManager new] logOut]; + } + }]; + } +} + +- (OSVBaseUser *)oscUser { + AFOAuth1Token *thirdPartyAuth = [AFOAuth1Token retrieveCredentialWithIdentifier:kOSCCredentialsID]; + + OSVBaseUser *user = [OSVBaseUser new]; + user.userID = thirdPartyAuth.userInfo[kOSCUserIdKey]; + user.name = thirdPartyAuth.userInfo[kOSCUsernameKey]; + user.provider = thirdPartyAuth.userInfo[kOSCAuthProvider]; + user.accessToken = thirdPartyAuth.userInfo[kOSCTokenKey]; + + if ([self validOSCUser:user]) { + return user; + } + + OSMUser *oldOSMAuth = [OSMAPI sharedInstance].osmUser; + user.userID = [@(oldOSMAuth.userID) stringValue]; + user.name = oldOSMAuth.name; + user.provider = oldOSMAuth.provider; + user.accessToken = [OSMAPI sharedInstance].osmAccessToken.userInfo[kOSVTokenKey]; + + if ([[OSMAPI sharedInstance] isAuthorized]) { + return user; + } + + return nil; +} + +- (BOOL)validOSCUser:(id)user { + return user.userID && ![user.userID isEqualToString:@""] && + user.name && ![user.name isEqualToString:@""] && + user.provider && ![user.provider isEqualToString:@""] && + user.accessToken && ![user.accessToken isEqualToString:@""]; +} + +- (OSVBaseUser *)baseUserWithOSMUser:(OSMUser *)osmUser { + OSVBaseUser *osvUser = [OSVBaseUser new]; + osvUser.providerKey = osmUser.providerKey; + osvUser.providerSecret = osmUser.providerSecret; + osvUser.provider = @"osm"; + + return osvUser; +} + +- (OSVBaseUser *)baseUserWithGoogleUser:(GIDGoogleUser *)googleUser { + OSVBaseUser *osvUser = [OSVBaseUser new]; + osvUser.providerKey = googleUser.authentication.accessToken; + osvUser.provider = @"google"; + + return osvUser; +} + +- (OSVBaseUser *)baseUserWithFacebookProfile:(FBSDKProfile *)profile { + OSVBaseUser *osvUser = [OSVBaseUser new]; + osvUser.provider = @"facebook"; + osvUser.providerKey = [FBSDKAccessToken currentAccessToken].tokenString; + + return osvUser; } @end diff --git a/OpenStreetView/OSVMainMenuFactory.m b/OpenStreetView/OSVMainMenuFactory.m index 7426aae..6b8bbaf 100644 --- a/OpenStreetView/OSVMainMenuFactory.m +++ b/OpenStreetView/OSVMainMenuFactory.m @@ -17,11 +17,23 @@ @implementation OSVMainMenuFactory + (NSArray *)mainMenu { - NSArray *array = @[[self myProfileItem], [self localTracksItem], [self settingsItem]]; + NSArray *array; + if ([OSVUserDefaults sharedInstance].useGamification) { + array = @[[self myProfileItem], + [self localTracksItem], + [self leaderboardItem], + [self settingsItem]]; + } else { + array = @[[self myProfileItem], + [self localTracksItem], + [self settingsItem]]; + } + return array; } +//TODO check version from 07/02/2017 + (OSVMenuItem *)myProfileItem { OSVMenuItem *item = [OSVMenuItem new]; item.title = NSLocalizedString(@"My Profile", @""); @@ -29,18 +41,7 @@ + (OSVMenuItem *)myProfileItem { item.action = ^(UIViewController *sender, id info) { if (![[OSVSyncController sharedInstance].tracksController userIsLoggedIn]) { - [[OSVSyncController sharedInstance].tracksController loginWithCompletion:^(NSError *error) { - if (error) { - [UIAlertView showWithTitle:@"" message:@"Failed to login. Please retry." cancelButtonTitle:@"Ok" otherButtonTitles:nil tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { - - }]; - } else { - - dispatch_async(dispatch_get_main_queue(), ^{ - [sender performSegueWithIdentifier:@"showMyProfile" sender:info]; - }); - } - }]; + [sender performSegueWithIdentifier:@"showLoginController" sender:info]; } else { [sender performSegueWithIdentifier:@"showMyProfile" sender:info]; } @@ -49,30 +50,16 @@ + (OSVMenuItem *)myProfileItem { return item; } +//TODO check version from 07/02/2017 + (OSVMenuItem *)localTracksItem { OSVMenuItem *item = [OSVMenuItem new]; item.title = NSLocalizedString(@"Upload", @""); item.additional = @{@"icon":[UIImage imageNamed:@"tracks"]}; - item.action = ^(UIViewController * sender, id info) { + item.action = ^(UIViewController *sender, id info) { if ([OSVSyncController hasSequencesToUpload]) { if ([OSVUserDefaults sharedInstance].isUploading) { - if (![[OSVSyncController sharedInstance].tracksController userIsLoggedIn]) { - [[OSVSyncController sharedInstance].tracksController loginWithCompletion:^(NSError *error) { - if (error) { - [UIAlertView showWithTitle:@"" message:@"Failed to login. Please retry." cancelButtonTitle:@"Ok" otherButtonTitles:nil tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { - - }]; - } else { - - dispatch_async(dispatch_get_main_queue(), ^{ - [sender performSegueWithIdentifier:@"showUploading" sender:info]; - }); - } - }]; - } else { - [sender performSegueWithIdentifier:@"showUploading" sender:info]; - } + [sender performSegueWithIdentifier:@"showUploading" sender:info]; } else { [sender performSegueWithIdentifier:@"showLocalTracks" sender:info]; } @@ -86,12 +73,24 @@ + (OSVMenuItem *)localTracksItem { return item; } ++ (OSVMenuItem *)leaderboardItem { + OSVMenuItem *item = [OSVMenuItem new]; + item.title = NSLocalizedString(@"Leaderboard", @""); + item.additional = @{@"icon":[UIImage imageNamed:@"leaderboard"]}; + + item.action = ^(UIViewController *sender, id info) { + [sender performSegueWithIdentifier:@"showLeaderboard" sender:info]; + }; + + return item; +} + + (OSVMenuItem *)settingsItem { OSVMenuItem *item = [OSVMenuItem new]; item.title = NSLocalizedString(@"Settings", @""); item.additional = @{@"icon":[UIImage imageNamed:@"settings"]}; - item.action = ^(UIViewController * sender, id info) { + item.action = ^(UIViewController *sender, id info) { [sender performSegueWithIdentifier:@"showSettings" sender:info]; }; diff --git a/OpenStreetView/OSVMyProfileViewController.m b/OpenStreetView/OSVMyProfileViewController.m index 4403b36..ddf6c1b 100644 --- a/OpenStreetView/OSVMyProfileViewController.m +++ b/OpenStreetView/OSVMyProfileViewController.m @@ -9,12 +9,14 @@ #import "OSVMyProfileViewController.h" #import "OSVVideoPlayerViewController.h" +#import "OSVPopTransition.h" + #import "OSVSyncController.h" #import "OSVServerSequence.h" #import "UIColor+OSVColor.h" #import "OSVMyTracksCell.h" -#import "OSVMyProfileCell.h" +#import "OSVGamificationProfileCell.h" #import "OSVTrackCell.h" #import "OSVInfoCell.h" #import "OSVUser.h" @@ -24,7 +26,11 @@ #import "NSAttributedString+Additions.h" -@interface OSVMyProfileViewController () +#define kFirstCellHeight 250 +#define kSecondCellHeight 90 +#define kThirdCellHeight 60 + +@interface OSVMyProfileViewController () @property (strong, nonatomic) UIColor *previousBarTintColor; @property (strong, nonatomic) UIImage *previousShadowImage; @@ -38,10 +44,11 @@ @interface OSVMyProfileViewController () currentUser; @property (assign, nonatomic) NSInteger localRank; -@property (assign, nonatomic) NSInteger totalNumberOfTracks; @property (assign, nonatomic) BOOL didShowNoInternet; +@property (assign, nonatomic) BOOL useGamification; + @end @implementation OSVMyProfileViewController @@ -50,7 +57,12 @@ - (void)viewDidLoad { [super viewDidLoad]; self.currentPage = 0; - self.datasource = [NSMutableArray arrayWithArray:@[@"", @"", @""]]; + if ([OSVUserDefaults sharedInstance].useGamification) { + self.datasource = [NSMutableArray arrayWithArray:@[@"", @"", @""]]; + } else { + self.datasource = [NSMutableArray arrayWithArray:@[@"", @""]]; + } + [self loadCurrentPageShowReset:NO]; [self.tableView setScrollEnabled:NO]; } @@ -63,18 +75,25 @@ - (void)viewWillAppear:(BOOL)animated { self.navigationController.navigationBar.barTintColor = [UIColor hex019ED3]; self.navigationController.navigationBar.translucent = NO; - + self.navigationController.delegate = self; + self.navigationController.navigationBar.shadowImage = [UIImage new]; [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; - - NSString *title = [NSString stringWithFormat:NSLocalizedString(@"Hey %@", @""), [OSVSyncController sharedInstance].tracksController.user.name]; - [self.userName setTitle:title forState:UIControlStateNormal]; - - self.userName.frame = CGRectInset(self.userName.frame, -40, 0); - + + + if (self.currentUser.fullName) { + NSString *title = [NSString stringWithFormat:NSLocalizedString(@"Hey %@", @""), self.currentUser.fullName]; + [self.userName setTitle:title forState:UIControlStateNormal]; + } else { + NSString *title = [NSString stringWithFormat:NSLocalizedString(@"Hey -", @"")]; + [self.userName setTitle:title forState:UIControlStateNormal]; + } + self.tableView.delegate = self; self.tableView.dataSource = self; self.tableView.backgroundColor = [UIColor hex1B1C1F]; + + self.useGamification = [OSVUserDefaults sharedInstance].useGamification; } - (void)viewWillDisappear:(BOOL)animated { @@ -99,11 +118,15 @@ - (IBAction)backButtonPressed:(id)sender { #pragma mark - Orientation - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + return UIStatusBarStyleLightContent; } #pragma mark - UITableViewDatasource @@ -114,81 +137,60 @@ - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { UITableViewCell *cell; + BOOL isGamificationON = [OSVUserDefaults sharedInstance].useGamification; - if (indexPath.row == 0) { - OSVMyProfileCell *mycell = [tableView dequeueReusableCellWithIdentifier:@"topCell"]; + if (isGamificationON && indexPath.row == 0) { + cell = [self configureGamificationInfoCell:indexPath]; - mycell.globalRankTitle.text = NSLocalizedString(@"Overall ranking", @""); - mycell.localRankTitle.text = NSLocalizedString(@"This week", @""); + } else if ((isGamificationON && indexPath.row == 1) || + (!isGamificationON && indexPath.row == 0)) { + cell = [self configureUserInfoCell:indexPath]; - if (self.currentUser) { - if (self.currentUser.rank) { - mycell.globalRank.text = [@(self.currentUser.rank) stringValue]; - } else { - mycell.globalRank.text = @"-"; - } - - if (self.currentUser.weekRank) { - mycell.localRank.text = [@(self.currentUser.weekRank) stringValue]; - } else { - mycell.localRank.text = @"-"; - } - } else { - mycell.globalRank.text = @"-"; - mycell.localRank.text = @"-"; - [[OSVSyncController sharedInstance].tracksController osvUserInfoWithCompletion:^(id user, NSError *error) { - if (!error) { - self.currentUser = user; - [tableView reloadData]; - } - }]; - } + } else if ((isGamificationON && indexPath.row == 2) || + (!isGamificationON && indexPath.row == 1)) { + cell = [tableView dequeueReusableCellWithIdentifier:@"titleCell"]; - cell = mycell; - } else if (indexPath.row == 1) { - OSVInfoCell *infoCell = [tableView dequeueReusableCellWithIdentifier:@"midCell"]; - if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { - NSString *metricArray = [OSVUtils metricDistanceFormatter:self.currentUser.totalKM * 1000]; - infoCell.distanceInfo.attributedText = [NSAttributedString combineString:@"Distance: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" - withString:metricArray withSize:12.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; - } else { - NSString *imperialArray = [OSVUtils imperialDistanceFormatter:self.currentUser.totalKM * 1000]; - infoCell.distanceInfo.attributedText = [NSAttributedString combineString:@"Distance: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" - withString:imperialArray withSize:12.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; - } - infoCell.tracksInfo.attributedText = [NSAttributedString combineString:@"Tracks: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" - withString:[@(self.totalNumberOfTracks) stringValue] withSize:12.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; - - if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { - NSString *metricArray = [OSVUtils metricDistanceFormatter:self.currentUser.obdDistance * 1000]; - infoCell.OBDInfo.attributedText = [NSAttributedString combineString:@"OBD: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" - withString:metricArray withSize:12.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; - - } else { - NSString *imperialArray = [OSVUtils imperialDistanceFormatter:self.currentUser.obdDistance * 1000]; - infoCell.OBDInfo.attributedText = [NSAttributedString combineString:@"OBD: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" - withString:imperialArray withSize:12.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; - - } - - NSString *imagesString = [NSString stringWithFormat:@"%ld", (long)self.currentUser.totalPhotos]; - infoCell.imagesInfo.attributedText = [NSAttributedString combineString:@"Images: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" - withString:imagesString withSize:12.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; - - cell = infoCell; - - } else if (indexPath.row == 2) { - OSVMyTracksCell *titleCell = [tableView dequeueReusableCellWithIdentifier:@"titleCell"]; - - cell = titleCell; } else { OSVServerSequence *track = self.datasource[indexPath.row]; OSVTrackCell *trackCell = [tableView dequeueReusableCellWithIdentifier:@"trackCell"]; - [[OSVSyncController sharedInstance].tracksController loadPreviewForTrack:track intoImageView:trackCell.previewImage withCompletion:^(UIImage *image, NSError *error) { + [[OSVSyncController sharedInstance].tracksController loadPreviewForTrack:track + intoImageView:trackCell.previewImage + withCompletion:^(UIImage *image, NSError *error) { + float x = image.size.height / image.size.width; + if (fabs(x - 4.0/3.0) > 0.1 && fabs(x - 3.0/4.0) > 0.1) { + trackCell.previewImage.contentMode = UIViewContentModeScaleAspectFill; + } else { + trackCell.previewImage.contentMode = UIViewContentModeScaleAspectFit; + } }]; - trackCell.locationLabel.text = [NSString stringWithFormat:@"%@", track.location]; + + if (!track.location || + ![track.location isKindOfClass:[NSString class]] || + [track.location isEqualToString:@""]) { + trackCell.locationLabel.text = @"-"; + } else { + NSArray *array = [track.location componentsSeparatedByString:@","]; + NSString *street; + NSString *broadLocation; + + if (array.count) { + street = array[0]; + broadLocation = [track.location stringByReplacingOccurrencesOfString:street withString:@""]; + trackCell.locationLabel.attributedText = [NSAttributedString combineString:street + withSize:12.f + color:[UIColor whiteColor] + fontName:@"HelveticaNeue" + withString:broadLocation withSize:12.f + color:[UIColor colorWithHex:0x6e707b] + fontName:@"HelveticaNeue"]; + + } else { + trackCell.locationLabel.text = [NSString stringWithFormat:@"%@", track.location]; + } + } + trackCell.photoCountLabel.attributedText = [NSAttributedString combineString:[@(track.photoCount) stringValue] withSize:12.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" withString:@" IMG" withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { @@ -201,6 +203,34 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N withString:imperialArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; } + NSString *pointsString = [@(track.points) stringValue]; + if (track.points > 9999) { + pointsString = [NSString stringWithFormat:@"%ldK", track.points/1000]; + } + + NSRange range = NSMakeRange(0, [pointsString length]); + NSMutableAttributedString *attSpace = [[NSMutableAttributedString alloc] initWithString:pointsString]; + [attSpace addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range]; + [attSpace addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue" size:16.f] range:range]; + + range = NSMakeRange(0, [@"\n" length]); + NSMutableAttributedString *att1 = [[NSMutableAttributedString alloc] initWithString:@"\n"]; + [att1 addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range]; + [att1 addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue" size:1.f] range:range]; + + NSString *ptsString = NSLocalizedString(@"pts", @""); + range = NSMakeRange(0, [ptsString length]); + NSMutableAttributedString *att2 = [[NSMutableAttributedString alloc] initWithString:ptsString]; + [att2 addAttribute:NSForegroundColorAttributeName value:[UIColor whiteColor] range:range]; + [att2 addAttribute:NSFontAttributeName value:[UIFont fontWithName:@"HelveticaNeue" size:10.f] range:range]; + + [attSpace appendAttributedString:att1]; + [attSpace appendAttributedString:att2]; + + trackCell.pointsLabel.attributedText = attSpace; + trackCell.pointsLabel.hidden = !self.useGamification; + trackCell.pointsImage.hidden = !self.useGamification; + NSDateFormatter *formatter = [NSDateFormatter new]; [formatter setDateFormat:@"MM.dd.YY "]; NSString *dString = [formatter stringFromDate:track.dateAdded]; @@ -224,19 +254,24 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N #pragma mark - UITableViewDelegate - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.row > 2) { + if ((indexPath.row > 2 && self.useGamification)|| + (!self.useGamification && indexPath.row > 1)) { [self performSegueWithIdentifier:@"showPlayer" sender:indexPath]; [self.tableView deselectRowAtIndexPath:indexPath animated:NO]; } } - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath { - if (indexPath.row == 0) { - return 156; - } else if (indexPath.row == 1) { - return 90; - } else if (indexPath.row == 2) { - return 60; + BOOL isGamificationON = self.useGamification; + + if (isGamificationON && indexPath.row == 0) { + return kFirstCellHeight; + } else if ((isGamificationON && indexPath.row == 1) || + (!isGamificationON && indexPath.row == 0)) { + return kSecondCellHeight; + } else if ((isGamificationON && indexPath.row == 2) || + (!isGamificationON && indexPath.row == 1)) { + return kThirdCellHeight; } else { return (tableView.frame.size.width - 24) * 3/4 + 80 ; } @@ -249,12 +284,85 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { } else { self.tableView.backgroundColor = [UIColor hex1B1C1F]; } + + if (!self.tableView.visibleCells.count) { + return; + } + + BOOL isGamificationON = self.useGamification; + + if (isGamificationON && scrollView.contentOffset.y < 10) { + OSVGamificationProfileCell *cell = self.tableView.visibleCells[0]; + cell.rankLabel.alpha = 1; + cell.rankLabel.superview.alpha = 1; + cell.rankTextLabel.alpha = 1; + cell.scoreTextLabel.alpha = 1; + cell.scoreLabel.alpha = 1; + cell.progressView.alpha = 1; + cell.progressLabel.alpha = 1; + cell.nextLevelPoints.alpha = 1; + + float rawr = self.tableView.contentOffset.y; + cell.frame = CGRectMake(cell.frame.origin.x, rawr, cell.frame.size.width, kFirstCellHeight-rawr); + float scale = 1.0f + fabs(scrollView.contentOffset.y) / scrollView.frame.size.width; + + //Cap the scaling between zero and 1 + scale = MAX(0.0f, scale * scale); + + cell.progressLabel.transform = CGAffineTransformMakeScale(scale, scale); + + } else if ((!isGamificationON && scrollView.contentOffset.y < 10) || + (isGamificationON && scrollView.contentOffset.y < kFirstCellHeight)) { + + OSVInfoCell *infoCell; + if (isGamificationON) { + OSVGamificationProfileCell *cell = self.tableView.visibleCells[0]; + float ratio = scrollView.contentOffset.y/(kFirstCellHeight/1.8); + cell.rankLabel.alpha = 0.8 - ratio; + cell.rankLabel.superview.alpha = 0.8 - ratio; + cell.rankTextLabel.alpha = 0.8 - ratio; + cell.scoreTextLabel.alpha = 0.8 - ratio; + cell.scoreLabel.alpha = 0.8 - ratio; + cell.progressView.alpha = 0.8 - ratio; + cell.progressLabel.alpha = 0.8 - ratio; + cell.nextLevelPoints.alpha = 0.8 - ratio; + + infoCell = self.tableView.visibleCells[1]; + float rawr = self.tableView.contentOffset.y; + cell.frame = CGRectMake(cell.frame.origin.x, rawr, cell.frame.size.width, kFirstCellHeight-rawr); + + float scale = 1.0f + fabs(scrollView.contentOffset.y) / scrollView.frame.size.width; + + //Cap the scaling between zero and 1 + scale = MAX(0.0f, 1.0 / (scale * scale)); + + cell.progressLabel.transform = CGAffineTransformMakeScale(scale, scale); + } else { + infoCell = self.tableView.visibleCells[0]; + } + + infoCell.distanceInfo.alpha = 1; + infoCell.tracksInfo.alpha = 1; + infoCell.OBDInfo.alpha = 1; + infoCell.imagesInfo.alpha = 1; + + } else if (((isGamificationON && scrollView.contentOffset.y < kFirstCellHeight + kSecondCellHeight)|| + (!isGamificationON && scrollView.contentOffset.y < kFirstCellHeight) ) + && [self.tableView.visibleCells[0] isKindOfClass:[OSVInfoCell class]]) { + + OSVInfoCell *infoCell = self.tableView.visibleCells[0]; + infoCell.distanceInfo.alpha = 0.9 - (scrollView.contentOffset.y - infoCell.frame.origin.y)/46; + infoCell.tracksInfo.alpha = 0.9 - (scrollView.contentOffset.y - infoCell.frame.origin.y)/46; + infoCell.OBDInfo.alpha = 0.9 - (scrollView.contentOffset.y - infoCell.frame.origin.y)/46; + infoCell.imagesInfo.alpha = 0.9 - (scrollView.contentOffset.y - infoCell.frame.origin.y)/46; + } } #pragma mark - Private - (void)loadCurrentPageShowReset:(BOOL)reset { - [[OSVSyncController sharedInstance].tracksController getMyServerSequencesAtPage:self.currentPage withCompletion:^(NSArray *tracks, OSVMetadata *metadata, NSError *error) { + [[OSVSyncController sharedInstance].tracksController getMyServerSequencesAtPage:self.currentPage + withCompletion:^(NSArray *tracks, OSVMetadata *metadata, NSError *error) { if (error && !self.didShowNoInternet) { self.didShowNoInternet = YES; @@ -264,7 +372,16 @@ - (void)loadCurrentPageShowReset:(BOOL)reset { } if (reset) { - self.datasource = [NSMutableArray arrayWithArray:tracks]; + NSMutableArray *mutableArray; + if (self.useGamification) { + mutableArray = [@[@"", @"", @""] mutableCopy]; + } else { + mutableArray = [@[@"", @""] mutableCopy]; + } + + [mutableArray addObjectsFromArray:tracks]; + + self.datasource = mutableArray; } else { [self.datasource addObjectsFromArray:tracks]; } @@ -273,7 +390,6 @@ - (void)loadCurrentPageShowReset:(BOOL)reset { [self.tableView setScrollEnabled:YES]; } - self.totalNumberOfTracks = metadata.totalItems; if (metadata.totalItems >= self.datasource.count) { dispatch_async(dispatch_get_main_queue(), ^{ [self.tableView reloadData]; @@ -282,5 +398,121 @@ - (void)loadCurrentPageShowReset:(BOOL)reset { }]; } +#pragma mark - Navigation Controler Delegate + +- (nullable id )navigationController:(UINavigationController *)navigationController + animationControllerForOperation:(UINavigationControllerOperation)operation + fromViewController:(UIViewController *)fromVC + toViewController:(UIViewController *)toVC { + if ([toVC isKindOfClass:NSClassFromString(@"OSVMapViewController")]) { + return [[OSVPopTransition alloc] initWithoutAnimatingSource:YES]; + } + + return nil; +} + +#pragma mark - TableView Cell Creation + +- (UITableViewCell *)configureGamificationInfoCell:(NSIndexPath *)indexPath { + OSVGamificationProfileCell *mycell = [self.tableView dequeueReusableCellWithIdentifier:@"topGameCell"]; + + mycell.rankTextLabel.text = NSLocalizedString(@"Rank", @""); + mycell.scoreTextLabel.text = NSLocalizedString(@"Score", @""); + + mycell.rankLabel.text = @"-"; + mycell.didTapRank = ^(id view) { + [self performSegueWithIdentifier:@"showLeaderboardRank" sender:self]; + }; + + NSInteger levelProgress = self.currentUser.gameInfo.levelPoints; + NSInteger levelTotalPoints = self.currentUser.gameInfo.totalLevelPoints; + NSInteger userTotalPoints = self.currentUser.gameInfo.totalPoints; + NSInteger currentLevelDiference = levelTotalPoints - (userTotalPoints - levelProgress); + if (levelProgress && levelTotalPoints) { + [mycell.progressView setProgress:((double)levelProgress)/((double)currentLevelDiference) + timing:TPPropertyAnimationTimingEaseOut + duration:1 + delay:0]; + mycell.nextLevelPoints.text = [NSString stringWithFormat:@"%@ points to next level", [OSVUtils pointsFormatedFromPoints:levelTotalPoints - userTotalPoints]]; + } else { + mycell.nextLevelPoints.text = [NSString stringWithFormat:@"- points to next level"]; + } + + if (userTotalPoints) { + mycell.scoreLabel.text = [OSVUtils pointsFormatedFromPoints:userTotalPoints]; + } + + NSString *levelTitle = NSLocalizedString(@"LEVEL\n", @""); + NSString *level = self.currentUser.gameInfo.level ? [NSString stringWithFormat:@"%ld", self.currentUser.gameInfo.level] : @"-"; + NSAttributedString *progress = [NSAttributedString combineString:levelTitle + withSize:12.f + color:[UIColor whiteColor] + fontName:@"HelveticaNeue" + withString:level + withSize:60.f + color:[UIColor whiteColor] + fontName:@"HelveticaNeue"]; + mycell.progressLabel.attributedText = progress; + + if (self.currentUser) { + if (self.currentUser.rank) { + mycell.rankLabel.text = [@(self.currentUser.gameInfo.rank) stringValue]; + } + } else { + [[OSVSyncController sharedInstance].tracksController osvUserInfoWithCompletion:^(id user, NSError *error) { + if (!error) { + self.currentUser = user; + NSString *name = self.currentUser.fullName; + if (!name) { + name = self.currentUser.name; + } + + NSString *title = [NSString stringWithFormat:NSLocalizedString(@"Hey %@", @""), name]; + [self.userName setTitle:title forState:UIControlStateNormal]; + [self.tableView reloadData]; + } + }]; + } + mycell.progressView.progressColor = [UIColor whiteColor]; + + return mycell; +} + +- (UITableViewCell *)configureUserInfoCell:(NSIndexPath *)indexPath { + OSVInfoCell *infoCell = [self.tableView dequeueReusableCellWithIdentifier:@"midCell"]; + if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { + NSString *metricArray = [OSVUtils metricDistanceFormatter:self.currentUser.totalKM * 1000]; + infoCell.distanceInfo.attributedText = [NSAttributedString combineString:@"Distance: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" + withString:metricArray withSize:16.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; + } else { + NSString *imperialArray = [OSVUtils imperialDistanceFormatter:self.currentUser.totalKM * 1000]; + infoCell.distanceInfo.attributedText = [NSAttributedString combineString:@"Distance: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" + withString:imperialArray withSize:16.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; + } + infoCell.tracksInfo.attributedText = [NSAttributedString combineString:@"Tracks: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" + withString:[@(self.currentUser.totalTracks) stringValue] withSize:16.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; + + if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { + NSString *metricArray = [OSVUtils metricDistanceFormatter:self.currentUser.obdDistance * 1000]; + infoCell.OBDInfo.attributedText = [NSAttributedString combineString:@"OBD: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" + withString:metricArray withSize:16.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; + + } else { + NSString *imperialArray = [OSVUtils imperialDistanceFormatter:self.currentUser.obdDistance * 1000]; + infoCell.OBDInfo.attributedText = [NSAttributedString combineString:@"OBD: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" + withString:imperialArray withSize:16.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; + + } + + NSString *imagesString = [NSString stringWithFormat:@"%ld", (long)self.currentUser.totalPhotos]; + infoCell.imagesInfo.attributedText = [NSAttributedString combineString:@"Images: " withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue" + withString:imagesString withSize:16.f color:[UIColor colorWithHex:0x1b1c1f] fontName:@"HelveticaNeue"]; + + return infoCell; +} + +#undef kFirstCellHeight +#undef kSecondCellHeight +#undef kThirdCellHeight @end diff --git a/OpenStreetView/OSVNavigationController.m b/OpenStreetView/OSVNavigationController.m index a5bff79..92cd90c 100644 --- a/OpenStreetView/OSVNavigationController.m +++ b/OpenStreetView/OSVNavigationController.m @@ -7,9 +7,26 @@ // #import "OSVNavigationController.h" +#import "OSVSplashViewController.h" @implementation OSVNavigationController + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + UIStoryboard *sb = [UIStoryboard storyboardWithName:@"Main" bundle:nil]; + OSVSplashViewController *vc = [sb instantiateViewControllerWithIdentifier:@"splashScreenID"]; + vc.view.frame = self.view.frame; + [self.view addSubview:vc.view]; + [vc animateLogo]; + }); + +} + - (BOOL)prefersStatusBarHidden { return self.topViewController ? [self.topViewController prefersStatusBarHidden] : [super prefersStatusBarHidden]; } @@ -22,5 +39,8 @@ - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return self.topViewController ? [self.topViewController supportedInterfaceOrientations] : [super supportedInterfaceOrientations]; } +- (UIStatusBarStyle)preferredStatusBarStyle { + return self.topViewController ? [self.topViewController preferredStatusBarStyle] : [super preferredStatusBarStyle]; +} @end diff --git a/OpenStreetView/OSVOBDController.m b/OpenStreetView/OSVOBDController.m index addef10..bc3ac74 100644 --- a/OpenStreetView/OSVOBDController.m +++ b/OpenStreetView/OSVOBDController.m @@ -22,6 +22,8 @@ #import #import +#import "UIAlertView+Blocks.h" + @interface OSVOBDController () @property (strong, nonatomic) ELM327 *obdScanner; @@ -81,7 +83,10 @@ - (instancetype)initWithHandler:(OSVOBDHandler)handler { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(currentStatus) name:@"kOBDStatus" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNetworkStatusChange:) name:kReachabilityChangedNotification object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveNewDatasourceItem:) name:@"BLEDatasource" object:nil]; - + +// [[OSVLogger sharedInstance] createNewLogFile]; +// [self diagnostics]; + } return self; @@ -237,6 +242,34 @@ - (void)checkForNewData { } } +- (void)diagnostics { + NSTimeInterval timePassed = [[NSDate new] timeIntervalSinceDate:self.lastReceivedDataTimestamp]; + + if (!self.isConnected && !self.isConnectedBLE) { + [self performSelector:@selector(diagnostics) withObject:nil afterDelay:1.0/10.0]; + return; + } + + if (timePassed > 4.0) { + [[OSVLogger sharedInstance] logMessage:@" Drop > 4 s" withLevel:LogLevelWARNING]; + NSLog(@"Drop > 4 s"); + [UIAlertView showWithTitle:@"Stop Recording!" message:@"Unusable OBD data" cancelButtonTitle:@"OK" otherButtonTitles:@[] tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { + + }]; + } else { + + if (timePassed > 1.0) { + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Drop > 1s => %f", timePassed] withLevel:LogLevelWARNING]; + NSLog(@"Drop > 1s => %f", timePassed); + } else if (timePassed > 1.0/10.0 ) { + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Drop > 1/10s => %f", timePassed] withLevel:LogLevelWARNING]; + NSLog(@"Drop > 1/10s => %f", timePassed); + } + } + + [self performSelector:@selector(diagnostics) withObject:nil afterDelay:1.0/10.0]; +} + - (void)reconnect { [[OSVLogger sharedInstance] logMessage:@"is reconnecting" withLevel:LogLevelDEBUG]; diff --git a/OpenStreetView/OSVPhotoSyncController.h b/OpenStreetView/OSVPhotoSyncController.h index 3bb506a..1306f64 100644 --- a/OpenStreetView/OSVPhotoSyncController.h +++ b/OpenStreetView/OSVPhotoSyncController.h @@ -21,7 +21,7 @@ //Save photo //localy -- (void)savePhoto:(OSVPhoto *)photo withImageData:(NSData *)data; +- (void)savePhoto:(OSVPhoto *)photo; //delete photo localy/server - (void)deletePhoto:(id)photo withCompletionBlock:(void (^)(NSError *error))completionBlock; diff --git a/OpenStreetView/OSVPhotoSyncController.m b/OpenStreetView/OSVPhotoSyncController.m index c6ff7fa..8dc825c 100644 --- a/OpenStreetView/OSVPhotoSyncController.m +++ b/OpenStreetView/OSVPhotoSyncController.m @@ -9,10 +9,14 @@ #import "OSVPhotoSyncController.h" #import "OSVPersistentManager.h" #import "OSVSyncUtils.h" +#import "OSVUtils.h" + #import "OSVAPI.h" + #import -@import ImageIO; + +#import @interface OSVPhotoSyncController () @@ -22,7 +26,7 @@ @interface OSVPhotoSyncController () @implementation OSVPhotoSyncController -- (void)savePhoto:(OSVPhoto *)photo withImageData:(NSData *)data { +- (void)savePhoto:(OSVPhoto *)photo { dispatch_async(dispatch_get_main_queue(), ^{ [OSVPersistentManager storePhoto:photo]; }); @@ -30,12 +34,17 @@ - (void)savePhoto:(OSVPhoto *)photo withImageData:(NSData *)data { #pragma mark - load image data method -- (void)loadImageDataForPhoto:(id)photo intoImageView:(UIImageView *)imageView withCompletion:(void (^)(idphoto, NSError *error))completion { +- (void)loadImageDataForPhoto:(id)photo + intoImageView:(UIImageView *)imageView + withCompletion:(void (^)(idphoto, NSError *error))completion { if ([photo isKindOfClass:[OSVServerPhoto class]]) { NSURL *imageURL = [self.osvAPI imageURLForPhoto:photo]; SDWebImageManager *manager = [SDWebImageManager sharedManager]; - [manager downloadImageWithURL:imageURL options:SDWebImageLowPriority progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + [manager downloadImageWithURL:imageURL + options:SDWebImageLowPriority + progress:nil + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { if (!image) { photo.image = photo.thumbnail; } else { @@ -50,7 +59,7 @@ - (void)loadImageDataForPhoto:(id)photo intoImageView:(UIImageView *)i } else { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ - NSString *photoPath = [self.basePathToPhotos stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/%@", (long)((OSVPhoto *)photo).localSequenceId, photo.imageName]]; + NSString *photoPath = [[OSVUtils createOSCBasePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/%@", (long)((OSVPhoto *)photo).localSequenceId, photo.imageName]]; @autoreleasepool { NSData *imageData = [NSData dataWithContentsOfFile:photoPath]; @@ -89,15 +98,13 @@ - (void)loadPreviewForTrack:(id)track intoImageView:(UIImageView *) } } - - (void)deletePhoto:(id)photo withCompletionBlock:(void (^)(NSError *error))completionBlock { if ([photo isKindOfClass:[OSVServerPhoto class]]) { - [self.osvAPI deletePhoto:photo forUser:self.user withCompletionBlock:completionBlock]; + [self.osvAPI deletePhoto:photo forUser:self.oscUser withCompletionBlock:completionBlock]; } else { [OSVPersistentManager removePhoto:photo]; completionBlock(nil); } } - @end diff --git a/OpenStreetView/OSVPolyline.h b/OpenStreetView/OSVPolyline.h index bbe5038..1b2732d 100644 --- a/OpenStreetView/OSVPolyline.h +++ b/OpenStreetView/OSVPolyline.h @@ -10,6 +10,7 @@ @interface OSVPolyline : SKPolyline -@property (nonatomic, assign) BOOL isLocal; +@property (nonatomic, assign) BOOL isLocal; +@property (nonatomic, assign) NSInteger coverage; @end diff --git a/OpenStreetView/OSVPolyline.m b/OpenStreetView/OSVPolyline.m index aa581b2..34ffecc 100644 --- a/OpenStreetView/OSVPolyline.m +++ b/OpenStreetView/OSVPolyline.m @@ -10,5 +10,13 @@ @implementation OSVPolyline +- (instancetype)init +{ + self = [super init]; + if (self) { + self.coverage = 0; + } + return self; +} @end diff --git a/OpenStreetView/OSVPopTransition.h b/OpenStreetView/OSVPopTransition.h new file mode 100644 index 0000000..ca7da9e --- /dev/null +++ b/OpenStreetView/OSVPopTransition.h @@ -0,0 +1,17 @@ +// +// OSVPopTransition.h +// OpenStreetView +// +// Created by Bogdan Sala on 11/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import +#import + +@interface OSVPopTransition : NSObject + +- (instancetype)initWithoutAnimatingSource:(BOOL)animatingSource; + + +@end diff --git a/OpenStreetView/OSVPopTransition.m b/OpenStreetView/OSVPopTransition.m new file mode 100644 index 0000000..fde5e56 --- /dev/null +++ b/OpenStreetView/OSVPopTransition.m @@ -0,0 +1,121 @@ +// +// OSVPopTransition.m +// OpenStreetView +// +// Created by Bogdan Sala on 11/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVPopTransition.h" + +@interface OSVPopTransition () + +@property (nonatomic, assign) BOOL animatingSource; + +@end + +@implementation OSVPopTransition + +- (instancetype)initWithoutAnimatingSource:(BOOL)animatingSource { + self = [super init]; + if (self) { + self.animatingSource = animatingSource; + } + return self; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.animatingSource = NO; + } + return self; +} + +- (NSTimeInterval)transitionDuration:(id)transitionContext { + return 0.5; +} + +- (void)animateTransition:(id)transitionContext { + UIViewController *source = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; + UIViewController *destination = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; + + UIView *container = transitionContext.containerView; + + destination.view.frame = CGRectMake(source.view.frame.origin.x, source.view.frame.origin.y, source.view.frame.size.width, source.view.frame.size.height-40); + [container insertSubview:destination.view belowSubview:source.view]; + + UIView *imag = [[UIView alloc] initWithFrame:CGRectMake(0, 0, source.navigationController.navigationBar.frame.size.width, CGRectGetMaxY(source.navigationController.navigationBar.frame))]; + imag.clipsToBounds = YES; + + UIImage *navImage = [self imageWithView:destination.navigationController.navigationBar]; + UIImageView *nav = [[UIImageView alloc] initWithImage:navImage]; + nav.frame = source.navigationController.navigationBar.frame; + imag.backgroundColor = [self getColorFromImage:navImage]; + + [imag addSubview:nav]; + + UIWindow *currentWindow = [UIApplication sharedApplication].keyWindow; + [currentWindow addSubview:imag]; + + float origin = CGRectGetMaxY(source.navigationController.navigationBar.frame); + + CGRect frameOriginal = CGRectMake(source.view.frame.origin.x, origin, source.view.frame.size.width, [UIScreen mainScreen].bounds.size.height - origin); + + if (!self.animatingSource) { + destination.view.frame = CGRectMake(destination.view.frame.origin.x, 300, destination.view.frame.size.width, destination.view.frame.size.height); + source.navigationController.navigationBar.frame = CGRectOffset(source.navigationController.navigationBar.frame, 0, -60); + + } + + NSTimeInterval transitionDuration = [self transitionDuration:transitionContext]; + + [UIView animateKeyframesWithDuration:transitionDuration delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{ + [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.7 animations:^{ + source.view.frame = CGRectOffset(source.view.frame, 0, source.view.frame.size.height); + imag.frame = CGRectOffset(imag.frame, 0, -imag.frame.size.height); + }]; + [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.7 animations:^{ + destination.view.frame = frameOriginal; + }]; + [UIView addKeyframeWithRelativeStartTime:0.2 relativeDuration:0.9 animations:^{ + if (!self.animatingSource) { + source.navigationController.navigationBar.frame = CGRectOffset(source.navigationController.navigationBar.frame, 0, 60); + } + }]; + + } completion:^(BOOL finished) { + + source.view.frame = CGRectOffset(source.view.frame, 0, -source.view.frame.size.height); + + [imag removeFromSuperview]; + [transitionContext completeTransition:finished]; + }]; +} + +- (UIImage *)imageWithView:(UIView *)view { + UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f); + [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; + UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return snapshotImage; +} + +- (UIColor *)getColorFromImage:(UIImage *)image { + + CFDataRef pixelData = CGDataProviderCopyData(CGImageGetDataProvider(image.CGImage)); + const UInt8* data = CFDataGetBytePtr(pixelData); + + int pixelInfo = ((image.size.width * 1) + 1 ) * 4; // The image is png + + UInt8 red = data[pixelInfo + 2]; // If you need this info, enable it + UInt8 green = data[(pixelInfo + 1)]; // If you need this info, enable it + UInt8 blue = data[pixelInfo]; // If you need this info, enable it + UInt8 alpha = data[pixelInfo + 3]; // I need only this info for my maze game + CFRelease(pixelData); + + return [UIColor colorWithRed:red/255.0f green:green/255.0f blue:blue/255.0f alpha:alpha/255.0f]; // The pixel color info +} + +@end diff --git a/OpenStreetView/OSVPushTransition.h b/OpenStreetView/OSVPushTransition.h new file mode 100644 index 0000000..5cda923 --- /dev/null +++ b/OpenStreetView/OSVPushTransition.h @@ -0,0 +1,16 @@ +// +// OSVPushTransition.h +// OpenStreetView +// +// Created by Bogdan Sala on 11/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import +#import + +@interface OSVPushTransition : NSObject + +- (instancetype)initWithoutAnimatingSource:(BOOL)animatingSource; + +@end diff --git a/OpenStreetView/OSVPushTransition.m b/OpenStreetView/OSVPushTransition.m new file mode 100644 index 0000000..590a62a --- /dev/null +++ b/OpenStreetView/OSVPushTransition.m @@ -0,0 +1,100 @@ +// +// OSVPushTransition.m +// OpenStreetView +// +// Created by Bogdan Sala on 11/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVPushTransition.h" +#import "OSVLocalTracksViewController.h" + +@interface OSVPushTransition () + +@property (nonatomic, assign) BOOL animatingSource; + +@end + +@implementation OSVPushTransition + +- (instancetype)initWithoutAnimatingSource:(BOOL)animatingSource { + self = [super init]; + if (self) { + self.animatingSource = animatingSource; + } + return self; +} + +- (instancetype)init { + self = [super init]; + if (self) { + self.animatingSource = NO; + } + return self; +} + + +- (NSTimeInterval)transitionDuration:(id)transitionContext { + return 0.5; +} + +- (void)animateTransition:(id)transitionContext { + + UIViewController *source = [transitionContext viewControllerForKey:UITransitionContextFromViewControllerKey]; + UIViewController *destination = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; + UIView *container = transitionContext.containerView; + + UIImageView *screenShot = [[UIImageView alloc] initWithImage:[self imageWithView:source.navigationController.navigationBar]]; + screenShot.frame = source.navigationController.navigationBar.frame; + + UIView *imag = [[UIView alloc] initWithFrame:CGRectMake(0, 0, source.navigationController.navigationBar.frame.size.width, CGRectGetMaxY(source.navigationController.navigationBar.frame))]; + imag.clipsToBounds = YES; + + [container addSubview:imag]; + + [container addSubview:destination.view]; + [destination beginAppearanceTransition:YES animated:YES]; + [destination.view setNeedsLayout]; + [destination.view layoutIfNeeded]; + + float origin = CGRectGetMaxY(source.navigationController.navigationBar.frame); + CGRect frameOriginal = CGRectMake(source.view.frame.origin.x, origin, source.view.frame.size.width, [UIScreen mainScreen].bounds.size.height - origin); + + destination.view.frame = CGRectOffset(destination.view.frame, 0, destination.view.frame.size.height); + source.navigationController.navigationBar.frame = CGRectOffset(source.navigationController.navigationBar.frame, 0, -60); + NSTimeInterval transitionDuration = [self transitionDuration:transitionContext]; + + [UIView animateKeyframesWithDuration:transitionDuration delay:0.0 options:UIViewKeyframeAnimationOptionCalculationModeCubic animations:^{ + [UIView addKeyframeWithRelativeStartTime:0.0 relativeDuration:0.4 animations:^{ + if (!self.animatingSource) { + source.view.frame = CGRectOffset(source.view.frame, 0, 200); + imag.frame = CGRectOffset(imag.frame, 0, -imag.frame.size.height-20); + } + }]; + [UIView addKeyframeWithRelativeStartTime:0.4 relativeDuration:0.7 animations:^{ + destination.view.frame = frameOriginal; + }]; + [UIView addKeyframeWithRelativeStartTime:0.2 relativeDuration:0.9 animations:^{ + source.navigationController.navigationBar.frame = CGRectOffset(source.navigationController.navigationBar.frame, 0, 60); + }]; + + } completion:^(BOOL finished) { + if (!self.animatingSource) { + source.view.frame = CGRectOffset(source.view.frame, 0, -200); + } + [imag removeFromSuperview]; + [destination endAppearanceTransition]; + [transitionContext completeTransition:finished]; + }]; +} + +- (UIImage *)imageWithView:(UIView *)view { + UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, 0.0f); + [view drawViewHierarchyInRect:view.bounds afterScreenUpdates:NO]; + UIImage * snapshotImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return snapshotImage; +} + +@end diff --git a/OpenStreetView/OSVRecordTransition.h b/OpenStreetView/OSVRecordTransition.h new file mode 100644 index 0000000..f39703b --- /dev/null +++ b/OpenStreetView/OSVRecordTransition.h @@ -0,0 +1,15 @@ +// +// OSVRecordTransition.h +// OpenStreetView +// +// Created by Bogdan Sala on 10/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import +#import + +@interface OSVRecordTransition : NSObject + + +@end diff --git a/OpenStreetView/OSVRecordTransition.m b/OpenStreetView/OSVRecordTransition.m new file mode 100644 index 0000000..26f376e --- /dev/null +++ b/OpenStreetView/OSVRecordTransition.m @@ -0,0 +1,65 @@ +// +// OSVRecordTransition.m +// OpenStreetView +// +// Created by Bogdan Sala on 10/10/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVRecordTransition.h" +#import "OSVCamViewController.h" + +@implementation OSVRecordTransition + +- (NSTimeInterval)transitionDuration:(id)transitionContext { + return 0.5; +} + +- (void)animateTransition:(id)transitionContext { + OSVCamViewController *destination = [transitionContext viewControllerForKey:UITransitionContextToViewControllerKey]; + + UIView *container = transitionContext.containerView; + + [destination beginAppearanceTransition:YES animated:YES]; + + destination.view.alpha = 0.0; + destination.view.frame = container.frame; + [container addSubview:destination.view]; + NSTimeInterval transitionDuration = [self transitionDuration:transitionContext]; + [destination.view setNeedsLayout]; + [destination.view layoutIfNeeded]; + + destination.sugestionLabel.frame = CGRectOffset(destination.sugestionLabel.frame, 0, 40); + destination.arrowImage.frame = CGRectOffset(destination.arrowImage.frame, 0, 40); + + [UIView animateKeyframesWithDuration:transitionDuration + delay:0.0 + options:UIViewKeyframeAnimationOptionCalculationModeCubic + animations:^{ + + [UIView addKeyframeWithRelativeStartTime:0.0 + relativeDuration:0.7 + animations:^{ + destination.view.alpha = 1; + }]; + + [UIView addKeyframeWithRelativeStartTime:0.0 + relativeDuration:0.5 + animations:^{ + destination.sugestionLabel.frame = CGRectOffset(destination.sugestionLabel.frame, 0, -48); + destination.arrowImage.frame = CGRectOffset(destination.arrowImage.frame, 0, -48); + }]; + + [UIView addKeyframeWithRelativeStartTime:0.5 + relativeDuration:1.0 + animations:^{ + destination.sugestionLabel.frame = CGRectOffset(destination.sugestionLabel.frame, 0, 8); + destination.arrowImage.frame = CGRectOffset(destination.arrowImage.frame, 0, 8); + }]; + } completion:^(BOOL finished) { + [destination endAppearanceTransition]; + [transitionContext completeTransition:finished]; + }]; +} + +@end diff --git a/OpenStreetView/OSVRedButton.h b/OpenStreetView/OSVRedButton.h deleted file mode 100644 index 48b9840..0000000 --- a/OpenStreetView/OSVRedButton.h +++ /dev/null @@ -1,13 +0,0 @@ -// -// OSVRedButton.h -// OpenStreetView -// -// Created by Bogdan Sala on 27/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import - -@interface OSVRedButton : UIButton - -@end diff --git a/OpenStreetView/OSVRedButton.m b/OpenStreetView/OSVRedButton.m deleted file mode 100644 index b355d20..0000000 --- a/OpenStreetView/OSVRedButton.m +++ /dev/null @@ -1,24 +0,0 @@ -// -// OSVRedButton.m -// OpenStreetView -// -// Created by Bogdan Sala on 27/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVRedButton.h" -#import "UIColor+OSVColor.h" - -@implementation OSVRedButton - -- (void)setHighlighted:(BOOL)highlighted { - [super setHighlighted:highlighted]; - - if (highlighted) { - self.backgroundColor = [UIColor whiteColor]; - } else { - self.backgroundColor = [UIColor hexF44336]; - } -} - -@end diff --git a/OpenStreetView/OSVScoreDetailsView.h b/OpenStreetView/OSVScoreDetailsView.h new file mode 100644 index 0000000..00ed22f --- /dev/null +++ b/OpenStreetView/OSVScoreDetailsView.h @@ -0,0 +1,47 @@ +// +// OSVScoreDetailsView.h +// OpenStreetView +// +// Created by Bogdan Sala on 09/12/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVScoreDetailsView : UIView + +@property (weak, nonatomic) IBOutlet UILabel *totalPointsLabel; +@property (weak, nonatomic) IBOutlet UILabel *disclosureLabel; + +@property (weak, nonatomic) IBOutlet UILabel *distanceTitle; +@property (weak, nonatomic) IBOutlet UILabel *multiplierTitle; +@property (weak, nonatomic) IBOutlet UILabel *pointsTitle; + +@property (weak, nonatomic) IBOutlet UILabel *distance1Label; +@property (weak, nonatomic) IBOutlet UILabel *distance2Label; +@property (weak, nonatomic) IBOutlet UILabel *distance3Label; +@property (weak, nonatomic) IBOutlet UILabel *distance4Label; +@property (weak, nonatomic) IBOutlet UILabel *distance5Label; +@property (weak, nonatomic) IBOutlet UILabel *distance6Label; + +@property (strong, nonatomic) NSArray *distanceLabels; + +@property (weak, nonatomic) IBOutlet UILabel *multiplier1Label; +@property (weak, nonatomic) IBOutlet UILabel *multiplier2Label; +@property (weak, nonatomic) IBOutlet UILabel *multiplier3Label; +@property (weak, nonatomic) IBOutlet UILabel *multiplier4Label; +@property (weak, nonatomic) IBOutlet UILabel *multiplier5Label; +@property (weak, nonatomic) IBOutlet UILabel *multiplier6Label; + +@property (strong, nonatomic) NSArray *multiplierLabels; + +@property (weak, nonatomic) IBOutlet UILabel *points1Label; +@property (weak, nonatomic) IBOutlet UILabel *points2Label; +@property (weak, nonatomic) IBOutlet UILabel *points3Label; +@property (weak, nonatomic) IBOutlet UILabel *points4Label; +@property (weak, nonatomic) IBOutlet UILabel *points5Label; +@property (weak, nonatomic) IBOutlet UILabel *points6Label; + +@property (strong, nonatomic) NSArray *pointsLabels; + +@end diff --git a/OpenStreetView/OSVScoreDetailsView.m b/OpenStreetView/OSVScoreDetailsView.m new file mode 100644 index 0000000..d93acf5 --- /dev/null +++ b/OpenStreetView/OSVScoreDetailsView.m @@ -0,0 +1,61 @@ +// +// OSVScoreDetailsView.m +// OpenStreetView +// +// Created by Bogdan Sala on 09/12/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVScoreDetailsView.h" + +@implementation OSVScoreDetailsView + +- (void)awakeFromNib { + [super awakeFromNib]; + + self.multiplier1Label.hidden = YES; + self.multiplier2Label.hidden = YES; + self.multiplier3Label.hidden = YES; + self.multiplier4Label.hidden = YES; + self.multiplier5Label.hidden = YES; + self.multiplier6Label.hidden = YES; + + self.distance1Label.hidden = YES; + self.distance2Label.hidden = YES; + self.distance3Label.hidden = YES; + self.distance4Label.hidden = YES; + self.distance5Label.hidden = YES; + self.distance6Label.hidden = YES; + + self.points1Label.hidden = YES; + self.points2Label.hidden = YES; + self.points3Label.hidden = YES; + self.points4Label.hidden = YES; + self.points5Label.hidden = YES; + self.points6Label.hidden = YES; + + self.disclosureLabel.hidden = YES; + + self.distanceLabels = @[self.distance1Label, + self.distance2Label, + self.distance3Label, + self.distance4Label, + self.distance5Label, + self.distance6Label]; + self.multiplierLabels = @[ self.multiplier1Label, + self.multiplier2Label, + self.multiplier3Label, + self.multiplier4Label, + self.multiplier5Label, + self.multiplier6Label]; + self.pointsLabels = @[ self.points1Label, + self.points2Label, + self.points3Label, + self.points4Label, + self.points5Label, + self.points6Label]; +} + + + +@end diff --git a/OpenStreetView/OSVScoreHistory+Realm.h b/OpenStreetView/OSVScoreHistory+Realm.h new file mode 100644 index 0000000..a7deeca --- /dev/null +++ b/OpenStreetView/OSVScoreHistory+Realm.h @@ -0,0 +1,17 @@ +// +// OSVScoreHistory+Realm.h +// OpenStreetView +// +// Created by Bogdan Sala on 21/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVScoreHistory.h" +#import "RLMScoreHistory.h" + +@interface OSVScoreHistory (Realm) + +- (RLMScoreHistory *)toRealmObject; ++ (OSVScoreHistory *)fromRealmObject:(RLMScoreHistory *)historyObject; + +@end diff --git a/OpenStreetView/OSVScoreHistory+Realm.m b/OpenStreetView/OSVScoreHistory+Realm.m new file mode 100644 index 0000000..5820d2b --- /dev/null +++ b/OpenStreetView/OSVScoreHistory+Realm.m @@ -0,0 +1,46 @@ +// +// OSVScoreHistory+Realm.m +// OpenStreetView +// +// Created by Bogdan Sala on 21/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVScoreHistory+Realm.h" +#import "RLMScoreHistory.h" + +@interface OSVScoreHistory () + +@property (nonatomic, strong) NSString *scoreHistoryID; + +@end + +@implementation OSVScoreHistory (Realm) + +- (RLMScoreHistory *)toRealmObject { + + RLMScoreHistory *history = [[RLMScoreHistory alloc] init]; + history.scoreHistoryID = self.scoreHistoryID; + history.localSequenceID = self.localSequenceID; + history.coverage = self.coverage; + history.photos = self.photos; + history.photosWithOBD = self.photosWithOBD; + history.detectedSigns = self.detectedSigns; + + return history; +} + ++ (OSVScoreHistory *)fromRealmObject:(RLMScoreHistory *)historyObject { + OSVScoreHistory *history = [OSVScoreHistory new]; + history.scoreHistoryID = historyObject.scoreHistoryID; + history.localSequenceID = historyObject.localSequenceID; + history.coverage = historyObject.coverage; + history.photos = historyObject.photos; + history.photosWithOBD = historyObject.photosWithOBD; + history.detectedSigns = historyObject.detectedSigns; + + return history; +} + + +@end diff --git a/OpenStreetView/OSVScoreHistory.h b/OpenStreetView/OSVScoreHistory.h new file mode 100644 index 0000000..d0194f5 --- /dev/null +++ b/OpenStreetView/OSVScoreHistory.h @@ -0,0 +1,26 @@ +// +// OSVScoreHistory.h +// OpenStreetView +// +// Created by Bogdan Sala on 15/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVScoreHistory : NSObject + +@property (nonatomic, assign) NSInteger localSequenceID; +@property (nonatomic, assign) NSInteger coverage; +@property (nonatomic, assign) NSInteger photos; +@property (nonatomic, assign) NSInteger photosWithOBD; +@property (nonatomic, assign) NSInteger detectedSigns; +@property (nonatomic, assign) double multiplier; +@property (nonatomic, assign) double distance; +@property (nonatomic, assign) NSInteger points; + +- (nonnull instancetype)initForCoverage:(NSInteger)coverage withLocalSequenceID:(NSInteger)seqID; + +- (nonnull NSDictionary *)jsonDictionary; + +@end diff --git a/OpenStreetView/OSVScoreHistory.m b/OpenStreetView/OSVScoreHistory.m new file mode 100644 index 0000000..0511f21 --- /dev/null +++ b/OpenStreetView/OSVScoreHistory.m @@ -0,0 +1,40 @@ +// +// OSVScoreHistory.m +// OpenStreetView +// +// Created by Bogdan Sala on 15/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVScoreHistory.h" + +@interface OSVScoreHistory () + +@property (nonatomic, strong) NSString *scoreHistoryID; + +@end + +@implementation OSVScoreHistory + +- (instancetype)initForCoverage:(NSInteger)coverage withLocalSequenceID:(NSInteger)seqID { + self = [super init]; + if (self) { + self.localSequenceID = seqID; + self.coverage = coverage; + self.scoreHistoryID = [NSString stringWithFormat:@"%ld%ld", seqID, coverage]; + self.photos = 0; + self.photosWithOBD = 0; + self.detectedSigns = 0; + } + + return self; +} + +- (NSDictionary *)jsonDictionary { + return @{@"coverage" : @(self.coverage), + @"photo" : @(self.photos), + @"obdPhoto" : @(self.photosWithOBD), + @"detectedSigns" : @(self.detectedSigns)}; +} + +@end diff --git a/OpenStreetView/OSVSensorLibManager.h b/OpenStreetView/OSVSensorLibManager.h index b5be4ef..2b6529e 100644 --- a/OpenStreetView/OSVSensorLibManager.h +++ b/OpenStreetView/OSVSensorLibManager.h @@ -10,6 +10,7 @@ #import #import + @interface OSVSensorLibManager : NSObject @property (strong, nonatomic) UIImage *debugFrame; @@ -23,4 +24,9 @@ - (UIImage *)imageForSpeedLimit:(NSString *)speedLimit; +- (void)createNewTrackWithInfo:(NSDictionary *)info trackID:(NSInteger)trackID; +- (void)addPhotoWithInfo:(NSDictionary *)info withFrameIndex:(NSInteger)frameIndex; + +- (void)read; + @end diff --git a/OpenStreetView/OSVSensorLibManager.mm b/OpenStreetView/OSVSensorLibManager.mm index 1761ead..ffc3906 100644 --- a/OpenStreetView/OSVSensorLibManager.mm +++ b/OpenStreetView/OSVSensorLibManager.mm @@ -6,22 +6,30 @@ // Copyright © 2016 Bogdan Sala. All rights reserved. // + #import "OSVSensorLibManager.h" #import #import "OSVUserDefaults.h" #import "OSVUtils.h" -#import +#import "OSVLocationManager.h" #import "OSVLogger.h" +#import "OSVUtils.h" + + @interface OSVSensorLibManager () -@property(strong, nonatomic) dispatch_queue_t imageProcessingQueue; +@property(strong, nonatomic) dispatch_queue_t imageProcessingQueue; +@property (strong, nonatomic) NSString *basePath; @end + + + @implementation OSVSensorLibManager + (instancetype)sharedInstance { @@ -39,22 +47,7 @@ - (instancetype)init { self = [super init]; if (self) { - self.imageProcessingQueue = dispatch_queue_create("ImageProcessQueue", DISPATCH_QUEUE_SERIAL); - - __weak typeof(self) welf = self; - - dispatch_async(self.imageProcessingQueue, ^{ - if ([OSVUtils isUSCoordinate:[SKPositionerService sharedInstance].currentCoordinate] || - [OSVUserDefaults sharedInstance].debugSLUS) { - NSLog(@"is US"); - //initialize a library to detect signs for US - } else { - NSLog(@"is EU"); - //initialize a library to detect signs for EU - } - //some other settup for the library - welf.isProcessing = NO; - }); + } return self; @@ -62,41 +55,7 @@ - (instancetype)init { - (void)speedLimitsFromSampleBuffer:(CMSampleBufferRef)sampleBuffer withCompletion:(void (^)(NSArray *, CVImageBufferRef pixelsBuffer))completion { - - if (self.isProcessing) { - return; - } - - self.isProcessing = YES; - CVImageBufferRef imageBuffer = CMSampleBufferGetImageBuffer(sampleBuffer); - CVBufferRetain(imageBuffer); - - NSMutableArray *signs = [NSMutableArray array]; - - CVPixelBufferLockBaseAddress(imageBuffer, 0); - - // Processing here - const int buffer_width = static_cast(CVPixelBufferGetWidth(imageBuffer)); - const int buffer_height = - static_cast(CVPixelBufferGetHeight(imageBuffer)); - - unsigned char *pixel = - static_cast(CVPixelBufferGetBaseAddress(imageBuffer)); - - // put buffer in open cv, no memory copied - __weak typeof(self) welf = self; - - dispatch_async(self.imageProcessingQueue, ^{ - @autoreleasepool { - CVPixelBufferUnlockBaseAddress(imageBuffer, 0); - //Process image buffer in order to get the signs - - completion(signs, imageBuffer); - welf.isProcessing = NO; - CVBufferRelease(imageBuffer); - } - }); - + } - (UIImage *)imageForSpeedLimit:(NSString *)speedLimit { @@ -108,113 +67,26 @@ - (UIImage *)imageForSpeedLimit:(NSString *)speedLimit { return [UIImage imageNamed:imagename]; } -#pragma mark - private +- (void)createNewTrackWithInfo:(NSDictionary *)info trackID:(NSInteger)trackID { + + self.basePath = [OSVUtils fileNameForTrackID:trackID].absoluteString; + -- (UIImage *)UIImageFromPixelBuffer:(CVPixelBufferRef)imageBuffer { - CVPixelBufferLockBaseAddress(imageBuffer, 0); - - void *bufferAddress; - size_t width; - size_t height; - size_t bytesPerRow; - - bufferAddress = CVPixelBufferGetBaseAddress(imageBuffer); - width = CVPixelBufferGetWidth(imageBuffer); - height = CVPixelBufferGetHeight(imageBuffer); - bytesPerRow = CVPixelBufferGetBytesPerRow(imageBuffer); - - CGColorSpaceRef colorSpaceOrig; - CGImage *origImage; - - colorSpaceOrig = CGColorSpaceCreateDeviceRGB(); - - CGContextRef origContext = CGBitmapContextCreate( - bufferAddress, width, height, 8, bytesPerRow, colorSpaceOrig, - kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); - - origImage = CGBitmapContextCreateImage(origContext); - - CGColorSpaceRelease(colorSpaceOrig); - CGContextRelease(origContext); - - UIImage *originalUIImage = [UIImage imageWithCGImage:origImage]; - - CGImageRelease(origImage); - - // Cleanup and free the buffers - CVPixelBufferUnlockBaseAddress(imageBuffer, 0); - - return originalUIImage; } + -//- (UIImage *)UIImageFromCVMat:(cv::Mat)cvMat { -// NSData *data = -// [NSData dataWithBytes:cvMat.data length:cvMat.elemSize() * cvMat.total()]; -// CGColorSpaceRef colorSpace; -// -// if (cvMat.elemSize() == 1) { -// colorSpace = CGColorSpaceCreateDeviceGray(); -// } else { -// colorSpace = CGColorSpaceCreateDeviceRGB(); -// } -// -// CGDataProviderRef provider = -// CGDataProviderCreateWithCFData((__bridge CFDataRef)data); -// -// // Creating CGImage from cv::Mat -// CGImageRef imageRef = CGImageCreate( -// cvMat.cols, // width -// cvMat.rows, // height -// 8, // bits per component -// 8 * cvMat.elemSize(), // bits per pixel -// cvMat.step[0], // bytesPerRow -// colorSpace, // colorspace -// kCGImageAlphaNone | kCGBitmapByteOrderDefault, // bitmap info -// provider, // CGDataProviderRef -// NULL, // decode -// false, // should interpolate -// kCGRenderingIntentDefault // intent -// ); -// -// // Getting UIImage from CGImage -// UIImage *finalImage = [UIImage imageWithCGImage:imageRef]; -// CGImageRelease(imageRef); -// CGDataProviderRelease(provider); -// CGColorSpaceRelease(colorSpace); -// -// return finalImage; -//} -// -//- (cv::Mat)cvMatWithImage:(CGImage *)image format:(int)format { -// BOOL alphaExist = NO; -// cv::Mat m; -// CGFloat cols = CGImageGetWidth(image); -// CGFloat rows = CGImageGetHeight(image); -// -// CGColorSpaceRef colorSpace = CGImageGetColorSpace(image); -// CGColorSpaceRetain(colorSpace); -// -// CGContextRef contextRef; -// CGBitmapInfo bitmapInfo = kCGImageAlphaPremultipliedLast; -// if (CGColorSpaceGetModel(colorSpace) == 0) { -// m.create(rows, cols, format); // 8 bits per component, 1 channel -// bitmapInfo = kCGImageAlphaNone; -// if (!alphaExist) -// bitmapInfo = kCGImageAlphaNone; -// contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8, m.step[0], -// colorSpace, bitmapInfo); -// } else { -// m.create(rows, cols, format); // 8 bits per component, 4 channels -// if (!alphaExist) -// bitmapInfo = kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little; -// contextRef = CGBitmapContextCreate(m.data, m.cols, m.rows, 8, m.step[0], -// colorSpace, bitmapInfo); -// } -// CGContextDrawImage(contextRef, CGRectMake(0, 0, cols, rows), image); -// CGContextRelease(contextRef); -// CGColorSpaceRelease(colorSpace); -// -// return m; -//} + +- (void)addPhotoWithInfo:(NSDictionary *)info withFrameIndex:(NSInteger)frameIndex { + +} + +- (void)read { + + +} + + + + @end diff --git a/OpenStreetView/OSVSensorsManager.h b/OpenStreetView/OSVSensorsManager.h index c359382..29fe7c4 100644 --- a/OpenStreetView/OSVSensorsManager.h +++ b/OpenStreetView/OSVSensorsManager.h @@ -15,6 +15,11 @@ @property (weak, nonatomic) id delegate; ++ (instancetype)sharedInstance; + +- (void)startAllSensors; +- (void)stopAllSensors; + - (void)startLoggingSensors; - (void)stopLoggingSensors; @@ -44,4 +49,4 @@ - (void)manager:(OSVSensorsManager *)manager didUpdateOBDData:(OSVOBDData *)data withError:(NSError *)error; -@end \ No newline at end of file +@end diff --git a/OpenStreetView/OSVSensorsManager.m b/OpenStreetView/OSVSensorsManager.m index 91ea8c0..34fa89d 100644 --- a/OpenStreetView/OSVSensorsManager.m +++ b/OpenStreetView/OSVSensorsManager.m @@ -19,9 +19,9 @@ @interface OSVSensorsManager () @property (nonatomic, strong) CMAltimeter *altimeter; @property (nonatomic, strong) OSVOBDController *OBD; -@property (nonatomic, strong) NSOperationQueue *accelerometerQueue; -@property (nonatomic, strong) NSOperationQueue *gyroQueue; -@property (nonatomic, strong) NSOperationQueue *magnetometerQueue; +//@property (nonatomic, strong) NSOperationQueue *accelerometerQueue; +//@property (nonatomic, strong) NSOperationQueue *gyroQueue; +//@property (nonatomic, strong) NSOperationQueue *magnetometerQueue; @property (nonatomic, strong) NSOperationQueue *deviceMotionQueue; @property (nonatomic, strong) NSOperationQueue *altimeterQueue; @@ -31,20 +31,31 @@ @interface OSVSensorsManager () @implementation OSVSensorsManager ++ (instancetype)sharedInstance { + static id sharedInstance; + + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + sharedInstance = [[self alloc] init]; + }); + + return sharedInstance; +} + - (instancetype)init { self = [super init]; if (self) { - self.accelerometerQueue = [NSOperationQueue new]; - self.gyroQueue = [NSOperationQueue new]; - self.magnetometerQueue = [NSOperationQueue new]; +// self.accelerometerQueue = [NSOperationQueue new]; +// self.gyroQueue = [NSOperationQueue new]; +// self.magnetometerQueue = [NSOperationQueue new]; self.deviceMotionQueue = [NSOperationQueue new]; self.altimeterQueue = [NSOperationQueue new]; self.motionManager = [CMMotionManager new]; - self.motionManager.accelerometerUpdateInterval = 0.1; - self.motionManager.gyroUpdateInterval = 0.1; - self.motionManager.magnetometerUpdateInterval = 0.1; - self.motionManager.deviceMotionUpdateInterval = 0.1; +// self.motionManager.accelerometerUpdateInterval = 0.04; +// self.motionManager.gyroUpdateInterval = 0.04; +// self.motionManager.magnetometerUpdateInterval = 0.04; + self.motionManager.deviceMotionUpdateInterval = 0.04; self.OBD = [[OSVOBDController alloc] initWithHandler:^(OSVOBDData *obdData) { @@ -59,8 +70,7 @@ - (instancetype)init { if (obdData && obdData.speed != NSNotFound) { OSVLogItem *item = [OSVLogItem new]; item.carSensorData = obdData; - item.timestamp = obdData.timestamp; - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; + [[OSVSyncController sharedInstance].logger logItem:item]; } }]; @@ -70,57 +80,52 @@ - (instancetype)init { } - (void)startUpdatingAccelerometer { - [self.motionManager startAccelerometerUpdatesToQueue:self.accelerometerQueue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { - OSVLogItem *item = [OSVLogItem new]; - item.sensorData = accelerometerData; - item.timestamp = [[NSDate new] timeIntervalSince1970]; - if (self.shouldLog) { - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; - } - }]; +// [self.motionManager startAccelerometerUpdatesToQueue:self.accelerometerQueue withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { +// OSVLogItem *item = [OSVLogItem new]; +// item.sensorData = accelerometerData; +// if (self.shouldLog) { +// [[OSVSyncController sharedInstance].logger logItem:item]; +// } +// }]; } - (void)startUpdatingGyro { - [self.motionManager startGyroUpdatesToQueue:self.gyroQueue withHandler:^(CMGyroData *gyroData, NSError *error) { - OSVLogItem *item = [OSVLogItem new]; - item.sensorData = gyroData; - item.timestamp = [[NSDate new] timeIntervalSince1970]; - if (self.shouldLog) { - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; - } - }]; +// [self.motionManager startGyroUpdatesToQueue:self.gyroQueue withHandler:^(CMGyroData *gyroData, NSError *error) { +// OSVLogItem *item = [OSVLogItem new]; +// item.sensorData = gyroData; +// if (self.shouldLog) { +// [[OSVSyncController sharedInstance].logger logItem:item]; +// } +// }]; } - (void)startUpdatingMagnetometer { - [self.motionManager startMagnetometerUpdatesToQueue:self.magnetometerQueue withHandler:^(CMMagnetometerData * magnetometerData, NSError *error) { - OSVLogItem *item = [OSVLogItem new]; - item.sensorData = magnetometerData; - item.timestamp = [[NSDate new] timeIntervalSince1970]; - if (self.shouldLog) { - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; - } - }]; +// [self.motionManager startMagnetometerUpdatesToQueue:self.magnetometerQueue withHandler:^(CMMagnetometerData * magnetometerData, NSError *error) { +// OSVLogItem *item = [OSVLogItem new]; +// item.sensorData = magnetometerData; +// if (self.shouldLog) { +// [[OSVSyncController sharedInstance].logger logItem:item]; +// } +// }]; } - (void)startUpdatingAltitude { [self.altimeter startRelativeAltitudeUpdatesToQueue:self.altimeterQueue withHandler:^(CMAltitudeData *altitudeData, NSError *error) { OSVLogItem *item = [OSVLogItem new]; item.sensorData = altitudeData; - item.timestamp = [[NSDate new] timeIntervalSince1970]; if (self.shouldLog) { - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; + [[OSVSyncController sharedInstance].logger logItem:item]; } }]; } - (void)startUpdatingDeviceMotion { self.OBD.isRecordingMode = YES; - [self.motionManager startDeviceMotionUpdatesToQueue:self.altimeterQueue withHandler:^(CMDeviceMotion * _Nullable motion, NSError * _Nullable error) { + [self.motionManager startDeviceMotionUpdatesToQueue:self.altimeterQueue withHandler:^(CMDeviceMotion *motion, NSError *error) { OSVLogItem *item = [OSVLogItem new]; item.sensorData = motion; - item.timestamp = [[NSDate new] timeIntervalSince1970]; if (self.shouldLog) { - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; + [[OSVSyncController sharedInstance].logger logItem:item]; } }]; } @@ -134,15 +139,15 @@ - (void)startBLEOBDScan { } - (void)stopUpdatingAccelerometer { - [self.motionManager stopAccelerometerUpdates]; +// [self.motionManager stopAccelerometerUpdates]; } - (void)stopUpdatingGyro { - [self.motionManager stopGyroUpdates]; +// [self.motionManager stopGyroUpdates]; } - (void)stopUpdatingMagnetometer { - [self.motionManager stopMagnetometerUpdates]; +// [self.motionManager stopMagnetometerUpdates]; } - (void)stopUpdatingAltitude { @@ -170,4 +175,22 @@ - (void)reconnectOBD { [self.OBD reconnect]; } +- (void)stopAllSensors { + [self stopLoggingSensors]; + [self stopUpdatingAccelerometer]; + [self stopUpdatingGyro]; + [self stopUpdatingMagnetometer]; + [self stopUpdatingAltitude]; + [self stopUpdatingDeviceMotion]; +} + +- (void)startAllSensors { + [self startLoggingSensors]; + [self startUpdatingDeviceMotion]; + [self startUpdatingAccelerometer]; + [self startUpdatingGyro]; + [self startUpdatingMagnetometer]; + [self startUpdatingAltitude]; +} + @end diff --git a/OpenStreetView/OSVSequenceSectionHeaderView.h b/OpenStreetView/OSVSequenceSectionHeaderView.h deleted file mode 100644 index f4a21ea..0000000 --- a/OpenStreetView/OSVSequenceSectionHeaderView.h +++ /dev/null @@ -1,23 +0,0 @@ -// -// OSVSequenceSectionHeaderView.h -// OpenStreetView -// -// Created by Bogdan Sala on 19/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import - -@interface OSVSequenceSectionHeaderView : UITableViewHeaderFooterView - -@property (copy, nonatomic) BOOL (^action)(OSVSequenceSectionHeaderView *sender, BOOL open); -@property (weak, nonatomic) IBOutlet UILabel *title; -@property (weak, nonatomic) IBOutlet UILabel *details; -@property (weak, nonatomic) IBOutlet NSLayoutConstraint *leadingSeparatorConstrain; - -@property (strong, nonatomic) id modelObject; - -- (void)open; -- (void)close; - -@end diff --git a/OpenStreetView/OSVSequenceSectionHeaderView.m b/OpenStreetView/OSVSequenceSectionHeaderView.m deleted file mode 100644 index ea4aa6d..0000000 --- a/OpenStreetView/OSVSequenceSectionHeaderView.m +++ /dev/null @@ -1,71 +0,0 @@ -// -// OSVSequenceSectionHeaderView.m -// OpenStreetView -// -// Created by Bogdan Sala on 19/11/15. -// Copyright © 2015 Bogdan Sala. All rights reserved. -// - -#import "OSVSequenceSectionHeaderView.h" - -@interface OSVSequenceSectionHeaderView () - -@property (nonatomic, strong) IBOutlet UIButton *disclosureButton; - -@end - -@implementation OSVSequenceSectionHeaderView - -- (void)awakeFromNib { - [super awakeFromNib]; - UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self - action:@selector(toggleOpen:)]; - [self addGestureRecognizer:tapGesture]; - -} - -- (IBAction)toggleOpen:(id)sender { - - [self toggleOpenWithUserAction:YES]; -} - -- (void)toggleOpenWithUserAction:(BOOL)userAction { - - BOOL shouldAct = YES; - // if this was a user action, send the delegate the appropriate message - if (userAction) { - shouldAct = self.action(self, !self.disclosureButton.selected); - } - - if (!shouldAct) { - return; - } - - // toggle the disclosure button state - if (self.disclosureButton.selected) { - [self open]; - } else { - [self close]; - } -} - -- (void)open { -// self.leadingSeparatorConstrain.constant = 50; - self.disclosureButton.selected = YES; - [self setNeedsDisplay]; - [self setNeedsUpdateConstraints]; - [self setNeedsLayout]; -} - -- (void)close { -// self.leadingSeparatorConstrain.constant = 0; - self.disclosureButton.selected = NO; - [self setNeedsDisplay]; - [self setNeedsUpdateConstraints]; - [self setNeedsLayout]; -} - -- (void)prepareForReuse { - self.modelObject = nil; -} -@end diff --git a/OpenStreetView/OSVSequenceSectionHeaderView.xib b/OpenStreetView/OSVSequenceSectionHeaderView.xib deleted file mode 100644 index 03750b7..0000000 --- a/OpenStreetView/OSVSequenceSectionHeaderView.xib +++ /dev/null @@ -1,73 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/OpenStreetView/OSVSettingsDetails.m b/OpenStreetView/OSVSettingsDetails.m index 2f63146..ef77ed4 100644 --- a/OpenStreetView/OSVSettingsDetails.m +++ b/OpenStreetView/OSVSettingsDetails.m @@ -35,11 +35,11 @@ - (void)dealloc { #pragma mark - Orientation - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } #pragma mark - TableView DataSource diff --git a/OpenStreetView/OSVSettingsMenuFactory.h b/OpenStreetView/OSVSettingsMenuFactory.h index 6e2248c..b2517bb 100644 --- a/OpenStreetView/OSVSettingsMenuFactory.h +++ b/OpenStreetView/OSVSettingsMenuFactory.h @@ -13,11 +13,10 @@ @interface OSVSettingsMenuFactory : NSObject -+ (NSArray *)settingsMenuWithWiFiOBDStatus:(int)connectionStatus BLEStatus:(int)bleStat; ++ (NSArray *)settingsMenuWithWiFiOBDStatus:(int)connectionStatus + BLEStatus:(int)bleStat + enableSecretMenu:(BOOL)secretMenu; -+ (OSVSectionItem *)defaultUserFunctionalitySection; + (OSVSectionItem *)settingsSection; -+ (OSVMenuItem *)myStreetViewItem; - @end diff --git a/OpenStreetView/OSVSettingsMenuFactory.m b/OpenStreetView/OSVSettingsMenuFactory.m index 4d78c82..c2465da 100644 --- a/OpenStreetView/OSVSettingsMenuFactory.m +++ b/OpenStreetView/OSVSettingsMenuFactory.m @@ -22,47 +22,56 @@ #import #import "UIDevice+Aditions.h" +#import "OSC-Swift.h" + +#import +#import @implementation OSVSettingsMenuFactory #pragma mark - Menu Factory -+ (NSArray *)settingsMenuWithWiFiOBDStatus:(int)connectionStatus BLEStatus:(int)bleStat { - -// Enable debug for all builds for now. -#ifdef ENABLED_DEBUG - NSArray *array = @[[self settingsSection], - [self obdSectionWithWiFiStatus:connectionStatus BLEStatus:bleStat], - [self feedbackSection], - [self aboutSection], - [self debugSection]]; -#else - NSArray *array = @[[self settingsSection], - [self obdSectionWithWiFiStatus:connectionStatus BLEStatus:bleStat], - [self feedbackSection], - [self aboutSection]]; -#endif - return array; ++ (NSArray *)settingsMenuWithWiFiOBDStatus:(int)connectionStatus + BLEStatus:(int)bleStat + enableSecretMenu:(BOOL)secretMenu { + + if (secretMenu) { + return @[[self settingsSection], + [self obdSectionWithWiFiStatus:connectionStatus BLEStatus:bleStat], + [self feedbackSection], + [self aboutSection], + [self debugSection]]; + } else { + return @[[self settingsSection], + [self obdSectionWithWiFiStatus:connectionStatus BLEStatus:bleStat], + [self feedbackSection], + [self aboutSection]]; + } } #pragma mark - Sections Factory -+ (OSVSectionItem *)defaultUserFunctionalitySection { - OSVSectionItem *section1 = [OSVSectionItem new]; - section1.rowItems = [@[[self loginItem]]mutableCopy]; - section1.title = NSLocalizedString(@"Account", nil); - - return section1; -} - + (OSVSectionItem *)settingsSection { OSVSectionItem *settingsSection = [OSVSectionItem new]; - settingsSection.rowItems = [@[[self wifiItem], - [self autoUploadItem], - [self metricItem], - [self videoQualityItem], - [self showMapItem], - [self signDetectionItem]] mutableCopy]; + if (![OSVUserDefaults sharedInstance].enableMap) { + settingsSection.rowItems = [@[[self wifiItem], + [self autoUploadItem], + [self metricItem], + [self videoQualityItem], + [self enableMapItem], + [self signDetectionItem], + [self gamificationItem]] mutableCopy]; + } else { + settingsSection.rowItems = [@[[self wifiItem], + [self autoUploadItem], + [self metricItem], + [self videoQualityItem], + [self enableMapItem], + [self showMapItem], + [self signDetectionItem], + [self gamificationItem]] mutableCopy]; + } + settingsSection.title = NSLocalizedString(@"GENERAL", nil); return settingsSection; @@ -71,6 +80,7 @@ + (OSVSectionItem *)settingsSection { + (OSVSectionItem *)feedbackSection { OSVSectionItem *feedbackItem = [OSVSectionItem new]; feedbackItem.rowItems = [@[[self feedbackItem], + [self tipsItem], [self walkthrough]] mutableCopy]; feedbackItem.title = NSLocalizedString(@"IMPROVE", nil); @@ -80,6 +90,8 @@ + (OSVSectionItem *)feedbackSection { + (OSVSectionItem *)aboutSection { OSVSectionItem *aboutItem = [OSVSectionItem new]; aboutItem.rowItems = [@[[self appVersion], + [self termsConditions], + [self privacyPolicy], [self copyRight]] mutableCopy]; aboutItem.title = NSLocalizedString(@"ABOUT", nil); @@ -118,70 +130,6 @@ + (OSVSectionItem *)debugSection { return settingsSection; } -#pragma mark - User Functions Item Factory - -+ (OSVMenuItem *)loginItem { - OSVMenuItem *login = [OSVMenuItem new]; - if (![[OSVSyncController sharedInstance].tracksController userIsLoggedIn]) { - login.title = NSLocalizedString(@"Login with OSM" , nil); - login.action = ^(OSVSettingsViewController *sender, id indexPath) { - if ([OSVReachablityController checkReachablility]) { - [[OSVSyncController sharedInstance].tracksController loginWithCompletion:^(NSError *error) { - if (error) { - [[OSVSyncController sharedInstance].tracksController logout]; - } - - [sender reloadData]; - }]; - } - }; - } else { - NSString *name = [[OSVSyncController sharedInstance].tracksController user].name; - if (!name) { - name = @"-"; - } - login.title = [NSString stringWithFormat:NSLocalizedString(@"Logout (%@)", nil), name]; - login.action = ^(OSVSettingsViewController *sender, id indexPath) { - [UIAlertView showWithTitle:@"" - message:NSLocalizedString(@"Are you sure you want to logout?", @"Preemtiv message to stop a unwanted loggout form the current online user profile") - cancelButtonTitle:NSLocalizedString(@"No", nil) - otherButtonTitles:@[NSLocalizedString(@"Yes", nil)] - tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { - if (buttonIndex == [alertView cancelButtonIndex]) { - [sender reloadData]; - } else { - [[OSVSyncController sharedInstance].tracksController logout]; - [sender reloadData]; - } - }]; - }; - } - - login.type = OSVMenuItemAction; - - return login; -} - -+ (OSVMenuItem *)myStreetViewItem { - OSVMenuItem *myStreetView = [OSVMenuItem new]; - myStreetView.title = NSLocalizedString(@"My Recordings", @"Recordings of the User that is logged in"); - myStreetView.type = OSVMenuItemAction; - myStreetView.key = @""; - myStreetView.action = ^(UIViewController *sender, id indexPath) { - [sender performSegueWithIdentifier:@"myStreetViewSegue" sender:indexPath]; - }; - - return myStreetView; -} - -+ (OSVMenuItem *)progressItem { - OSVMenuItem *progress = [OSVMenuItem new]; - progress.title = NSLocalizedString(@"Upload Local Recordings", @"Upload all local recordings in the context of the user Profile overview"); - progress.type = OSVMenuItemUpload; - - return progress; -} - #pragma mark Settins Item Factory + (OSVMenuItem *)wifiItem { @@ -303,11 +251,13 @@ + (OSVSectionItem *)resolutionDatasource { } if (has12MP) { - item.rowItems = [@[[self smallResolution], + item.rowItems = [@[[self smallerResolution], + [self smallResolution], [self mediumResolution], [self highResolution]] mutableCopy]; } else { - item.rowItems = [@[[self smallResolution], + item.rowItems = [@[[self smallerResolution], + [self smallResolution], [self mediumResolution]] mutableCopy]; } } @@ -320,13 +270,15 @@ + (NSDictionary *)resolutionDictionaryFormArray:(NSArray *)array { if ([UIDevice isLessTheniPhone6]) { resolutionsDictionary = @{k2MPQuality : array[0]}; } else { - if ([array count] == 3) { - resolutionsDictionary = @{k5MPQuality : array[0], - k8MPQuality : array[1], - k12MPQuality: array[2]}; + if ([array count] == 4) { + resolutionsDictionary = @{k2MPQuality : array[0], + k5MPQuality : array[1], + k8MPQuality : array[2], + k12MPQuality: array[3]}; } else { - resolutionsDictionary = @{k5MPQuality : array[0], - k8MPQuality : array[1]}; + resolutionsDictionary = @{k2MPQuality : array[0], + k5MPQuality : array[1], + k8MPQuality : array[2]}; } } @@ -369,6 +321,40 @@ + (OSVMenuItem *)highResolution { return item; } ++ (OSVMenuItem *)enableMapItem { + OSVMenuItem *item = [OSVMenuItem new]; + item.title = NSLocalizedString(@"Enable map", @""); + item.subtitle = NSLocalizedString(@"Maps use more resources and it may decrease performace.", @""); + item.type = OSVMenuItemSwitch; + item.key = @"enableMap"; + + item.action = ^(OSVSettingsViewController *sender, NSNumber *value) { + if ([OSVUserDefaults sharedInstance].enableMap) { + //init the map so it will not crash the application when trying to access SKPositioner.currentLocation + SKMapsInitSettings *mapsettings = [SKMapsInitSettings mapsInitSettings]; + mapsettings.mapStyle.resourcesFolderName = @"GrayscaleStyle"; + mapsettings.mapStyle.styleFileName = @"grayscalestyle.json"; + [[SKMapsService sharedInstance] initializeSKMapsWithAPIKey:@"" settings:mapsettings]; + } + + [UIAlertView showWithTitle:NSLocalizedString(@"", @"") + message:NSLocalizedString(@"The app has to be restarted for this to take place", @"") + cancelButtonTitle:NSLocalizedString(@"Ok", @"") + otherButtonTitles:@[NSLocalizedString(@"Not now", @"")] + tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { + if (buttonIndex == [alertView cancelButtonIndex]) { + exit(0); + } else { + [OSVUserDefaults sharedInstance].enableMap = ![OSVUserDefaults sharedInstance].enableMap; + [sender reloadData]; + } + }]; + }; + + + return item; +} + + (OSVMenuItem *)showMapItem { OSVMenuItem *item = [OSVMenuItem new]; item.title = NSLocalizedString(@"Display map while recording", @""); @@ -389,6 +375,16 @@ + (OSVMenuItem *)signDetectionItem { return video; } ++ (OSVMenuItem *)gamificationItem { + OSVMenuItem *video = [OSVMenuItem new]; + video.title = NSLocalizedString(@"Points", @""); + video.subtitle = NSLocalizedString(@"Compete with other users and improve your ranking.", @""); + video.type = OSVMenuItemSwitch; + video.key = @"useGamification"; + + return video; +} + #pragma mark - Feedback Item Factory + (OSVMenuItem *)feedbackItem { @@ -399,9 +395,17 @@ + (OSVMenuItem *)feedbackItem { item.action = ^(OSVSettingsViewController *sender, id indexPath) { NSURL *url = [NSURL URLWithString:@"https://github.com/openstreetview/ios/issues"]; - if (![[UIApplication sharedApplication] openURL:url]) { - + if ([[SFSafariViewController alloc] respondsToSelector:@selector(initWithURL:)]) { + UIViewController *vc = [[SFSafariViewController alloc] initWithURL:url]; + + [sender presentViewController:vc animated:YES completion:^{ + + }]; + + } else { + [[UIApplication sharedApplication] openURL:url]; } + [sender reloadData]; }; @@ -410,13 +414,14 @@ + (OSVMenuItem *)feedbackItem { #pragma mark - About Item Factory -+ (OSVMenuItem *)walkthrough { ++ (OSVMenuItem *)tipsItem { OSVMenuItem *item = [OSVMenuItem new]; item.title = NSLocalizedString(@"Tips", nil); item.subtitle = NSLocalizedString(@"See how to improve your recordings. \n", nil); item.type = OSVMenuItemDetails; item.action = ^(OSVSettingsViewController *sender, id indexPath) { OSVTipView *tipview = [[[NSBundle mainBundle] loadNibNamed:@"OSVTipView" owner:self options:nil] objectAtIndex:0]; + [tipview configureViews]; [sender.navigationController.view addSubview:tipview]; tipview.frame = sender.navigationController.view.frame; @@ -426,6 +431,35 @@ + (OSVMenuItem *)walkthrough { return item; } ++ (OSVMenuItem *)walkthrough { + OSVMenuItem *item = [OSVMenuItem new]; + item.title = NSLocalizedString(@"Walkthrough", nil); + item.subtitle = NSLocalizedString(@"What OpenStreetCam is about. \n", nil); + item.type = OSVMenuItemDetails; + item.action = ^(OSVSettingsViewController *sender, id indexPath) { + OSVTipView *tipView = [[[NSBundle mainBundle] loadNibNamed:@"OSVTipView" owner:self options:nil] objectAtIndex:0]; + [tipView prepareIntro]; + [tipView configureViews]; + + PortraitViewController *vc = [PortraitViewController new]; + vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + + tipView.willDissmiss = ^() { + [vc dismissViewControllerAnimated:YES completion:^{}]; + return YES; + }; + + [sender presentViewController:vc animated:NO completion:^{ + [vc.view addSubview:tipView]; + }]; + + tipView.frame = sender.navigationController.view.frame; + [sender reloadData]; + }; + + return item; +} + + (OSVMenuItem *)appVersion { OSVMenuItem *item = [OSVMenuItem new]; item.type = OSVMenuItemAction; @@ -439,10 +473,54 @@ + (OSVMenuItem *)appVersion { return item; } ++ (OSVMenuItem *)termsConditions { + OSVMenuItem *item = [OSVMenuItem new]; + item.type = OSVMenuItemDetails; + item.title = NSLocalizedString(@"Terms & Conditions", @""); + + item.action = ^(OSVSettingsViewController *sender, id indexPath) { + NSURL *url = [NSURL URLWithString:@"http://openstreetcam.org/terms/"]; + if ([[SFSafariViewController alloc] respondsToSelector:@selector(initWithURL:)]) { + UIViewController *vc = [[SFSafariViewController alloc] initWithURL:url]; + + [sender presentViewController:vc animated:YES completion:^{ + + }]; + + } else { + [[UIApplication sharedApplication] openURL:url]; + } + }; + + return item; +} + ++ (OSVMenuItem *)privacyPolicy { + OSVMenuItem *item = [OSVMenuItem new]; + item.type = OSVMenuItemDetails; + item.title = NSLocalizedString(@"Privacy Policy", @""); + + item.action = ^(OSVSettingsViewController *sender, id indexPath) { + NSURL *url = [NSURL URLWithString:@"http://www.telenav.com/legal/policies.html#privacy-policy"]; + if ([[SFSafariViewController alloc] respondsToSelector:@selector(initWithURL:)]) { + UIViewController *vc = [[SFSafariViewController alloc] initWithURL:url]; + + [sender presentViewController:vc animated:YES completion:^{ + + }]; + + } else { + [[UIApplication sharedApplication] openURL:url]; + } + }; + + return item; +} + + (OSVMenuItem *)copyRight { OSVMenuItem *item = [OSVMenuItem new]; - item.type = OSVMenuItemBasic; - item.title = NSLocalizedString(@"Copyright 2016 Telenav GmbH", @""); + item.type = OSVMenuItemAction; + item.title = NSLocalizedString(@"Copyright 2017 Telenav GmbH", @""); return item; } @@ -456,7 +534,7 @@ + (OSVMenuItem *)obdDisconnected { item.type = OSVMenuItemButton; item.action = ^(OSVSettingsViewController *sender, id indexPath) { sender.obdWIFIConnectionStatus = 1; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingOBD]; + [[OSVSensorsManager sharedInstance] startUpdatingOBD]; [sender reloadData]; }; @@ -478,7 +556,7 @@ + (OSVMenuItem *)obdConnected { item.type = OSVMenuItemButton; item.action = ^(OSVSettingsViewController *sender, id indexPath) { sender.obdWIFIConnectionStatus = 2; - [[OSVLocationManager sharedInstance].sensorsManager stopUpdatingOBD]; + [[OSVSensorsManager sharedInstance] stopUpdatingOBD]; [sender reloadData]; }; @@ -491,7 +569,7 @@ + (OSVMenuItem *)obdBLEDisconnected { item.type = OSVMenuItemDetails; item.action = ^(OSVSettingsViewController *sender, id indexPath) { sender.obdBLEConnectionStatus = 1; - [[OSVLocationManager sharedInstance].sensorsManager startBLEOBDScan]; + [[OSVSensorsManager sharedInstance] startBLEOBDScan]; OSVSectionItem *dataItem = [self obdBLE]; dataItem.key = @"bleDevice"; [sender performSegueWithIdentifier:@"showSettingsDetails" sender:dataItem]; @@ -514,7 +592,7 @@ + (OSVMenuItem *)obdBLEConnected { item.type = OSVMenuItemButton; item.action = ^(OSVSettingsViewController *sender, id indexPath) { sender.obdBLEConnectionStatus = 2; - [[OSVLocationManager sharedInstance].sensorsManager stopUpdatingOBD]; + [[OSVSensorsManager sharedInstance] stopUpdatingOBD]; [sender reloadData]; }; diff --git a/OpenStreetView/OSVSplashViewController.h b/OpenStreetView/OSVSplashViewController.h new file mode 100644 index 0000000..ffa076c --- /dev/null +++ b/OpenStreetView/OSVSplashViewController.h @@ -0,0 +1,15 @@ +// +// OSVSplashViewController.h +// OpenStreetView +// +// Created by Bogdan Sala on 07/10/16. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVSplashViewController : UIViewController + +- (void)animateLogo; + +@end diff --git a/OpenStreetView/OSVSplashViewController.m b/OpenStreetView/OSVSplashViewController.m new file mode 100644 index 0000000..5cd4ca8 --- /dev/null +++ b/OpenStreetView/OSVSplashViewController.m @@ -0,0 +1,60 @@ +// +// OSVSplashViewController.m +// OpenStreetView +// +// Created by Bogdan Sala on 07/10/16. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVSplashViewController.h" + +@interface OSVSplashViewController () + +@property (weak, nonatomic) IBOutlet UIImageView *splashImage; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *centerYConstraint; + +@end + +@implementation OSVSplashViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +- (void)animateLogo { + [self.view setNeedsLayout]; + [self.view layoutIfNeeded]; + + self.centerYConstraint.constant = -self.view.frame.size.height/5.0; + + [UIView animateWithDuration:0.45 animations:^{ + [self.view setNeedsLayout]; + [self.view layoutIfNeeded]; + + self.view.alpha = 0; + } completion:^(BOOL finished) { + [self.view removeFromSuperview]; + }]; +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/OpenStreetView/OSVSyncUtils.h b/OpenStreetView/OSVSyncUtils.h index f03247b..ef70a65 100644 --- a/OpenStreetView/OSVSyncUtils.h +++ b/OpenStreetView/OSVSyncUtils.h @@ -16,8 +16,6 @@ + (BOOL)hasInternetPermissions; -+ (void)correctImageDataForPhoto:(OSVPhoto *)photo; - + (long long)sizeOnDiskForSequence:(id)sequence atPath:(NSString *)path; + (long long)sizeOnDiskForSequence:(id)sequence atPath:(NSString *)path containsImages:(BOOL *)contains; + (long long)sizeOnDiskForPhoto:(id)photo atPath:(NSString *)path; diff --git a/OpenStreetView/OSVSyncUtils.m b/OpenStreetView/OSVSyncUtils.m index 3236c0d..9054404 100644 --- a/OpenStreetView/OSVSyncUtils.m +++ b/OpenStreetView/OSVSyncUtils.m @@ -8,8 +8,7 @@ #import "OSVSyncUtils.h" #import "OSVUserDefaults.h" -#import "OSVUtils+Image.m" -#import "OSVBaseUser+OSM.h" +#import "OSVUtils.h" #import "ConnectivityHandler.h" #import "OSVPhoto.h" #import "OSVServerPhoto.h" @@ -19,20 +18,14 @@ @implementation OSVSyncUtils + (BOOL)hasInternetPermissions { - if ([ConnectivityHandler sharedInstance].isConnectionViaWWAN && ![OSVUserDefaults sharedInstance].useCellularData) { + if ([ConnectivityHandler sharedInstance].isConnectionViaWWAN && + ![OSVUserDefaults sharedInstance].useCellularData) { return NO; } return YES; } -+ (void)correctImageDataForPhoto:(OSVPhoto *)photo { - if (photo.image && photo.correctionOrientation != UIImageOrientationUp) { - photo.image = [OSVUtils rotateImage:photo.image toImageOrientation:photo.correctionOrientation]; - photo.correctionOrientation = UIImageOrientationUp; - } -} - + (long long)sizeOnDiskForSequence:(id)sequence atPath:(NSString *)path { if ([sequence isKindOfClass:[OSVServerSequence class]]) { diff --git a/OpenStreetView/OSVTipPageViewController.h b/OpenStreetView/OSVTipPageViewController.h index 1105739..3a25df1 100644 --- a/OpenStreetView/OSVTipPageViewController.h +++ b/OpenStreetView/OSVTipPageViewController.h @@ -10,8 +10,8 @@ @interface OSVTipPageViewController : UIViewController -@property (weak, nonatomic) IBOutlet UILabel *tipTitleLabel; -@property (weak, nonatomic) IBOutlet UILabel *tipDescriptionLabel; +@property (weak, nonatomic) IBOutlet UILabel *tipTitleLabel; +@property (weak, nonatomic) IBOutlet UILabel *tipDescriptionLabel; @property (assign, nonatomic) NSInteger index; diff --git a/OpenStreetView/OSVTipPageViewController.xib b/OpenStreetView/OSVTipPageViewController.xib index 92d8a45..31af009 100644 --- a/OpenStreetView/OSVTipPageViewController.xib +++ b/OpenStreetView/OSVTipPageViewController.xib @@ -1,9 +1,13 @@ - - + + + + + - + + @@ -15,23 +19,23 @@ - + - - + diff --git a/OpenStreetView/OSVTipView.xib b/OpenStreetView/OSVTipView.xib index e641829..779edde 100644 --- a/OpenStreetView/OSVTipView.xib +++ b/OpenStreetView/OSVTipView.xib @@ -1,22 +1,26 @@ - - + + + + + - + + - + - + - + - + diff --git a/OpenStreetView/OSVTrackCell.h b/OpenStreetView/OSVTrackCell.h index d3966c5..075f6e4 100644 --- a/OpenStreetView/OSVTrackCell.h +++ b/OpenStreetView/OSVTrackCell.h @@ -14,7 +14,9 @@ @property (weak, nonatomic) IBOutlet UILabel *photoCountLabel; @property (weak, nonatomic) IBOutlet UILabel *distanceLabel; @property (weak, nonatomic) IBOutlet UILabel *dateLabel; +@property (weak, nonatomic) IBOutlet UILabel *pointsLabel; +@property (weak, nonatomic) IBOutlet UIImageView *pointsImage; @property (weak, nonatomic) IBOutlet UIImageView *previewImage; @end diff --git a/OpenStreetView/OSVTrackCell.m b/OpenStreetView/OSVTrackCell.m index 9c71457..e813ad9 100644 --- a/OpenStreetView/OSVTrackCell.m +++ b/OpenStreetView/OSVTrackCell.m @@ -10,7 +10,7 @@ #import "UIColor+OSVColor.h" @interface OSVTrackCell () -@property (weak, nonatomic) IBOutlet UIView *backgroundPaternView; +@property (weak, nonatomic) IBOutlet UIView *backgroundPaternView; @end diff --git a/OpenStreetView/OSVTrackLogger.h b/OpenStreetView/OSVTrackLogger.h index 73ab927..56e8cbb 100644 --- a/OpenStreetView/OSVTrackLogger.h +++ b/OpenStreetView/OSVTrackLogger.h @@ -16,7 +16,7 @@ - (instancetype)initWithBasePath:(NSString *)string; - (void)createNewLogFileForSequenceID:(NSInteger)uid; -- (void)logItems:(NSArray *)trackLogItems inFileForSequenceID:(NSInteger)uid; +- (void)logItem:(OSVLogItem *)trackLogItem; - (void)closeLoggFileForSequenceID:(NSInteger)uid; @end diff --git a/OpenStreetView/OSVTrackLogger.m b/OpenStreetView/OSVTrackLogger.m index a65a23e..3a1eee5 100644 --- a/OpenStreetView/OSVTrackLogger.m +++ b/OpenStreetView/OSVTrackLogger.m @@ -11,6 +11,7 @@ #import "Godzippa.h" #import "UIDevice+Aditions.h" #import "OSVLogger.h" +#import @interface OSVTrackLogger () @@ -19,6 +20,12 @@ @interface OSVTrackLogger () @property (nonatomic) NSString *basePath; @property (nonatomic, assign) NSInteger currentID; +@property (nonatomic, strong) dispatch_queue_t serialDispatchQueue; +@property (nonatomic, assign) long count; +@property (nonatomic, strong) NSMutableString *flushMessage; + +@property (nonatomic, assign) NSTimeInterval offsetTime; + @end @implementation OSVTrackLogger @@ -28,17 +35,24 @@ - (instancetype)initWithBasePath:(NSString *)string { if (self) { self.createLock = [NSLock new]; self.basePath = string; + + self.serialDispatchQueue = dispatch_queue_create("trackLoggingQueue", DISPATCH_QUEUE_SERIAL); } return self; } - (void)createNewLogFileForSequenceID:(NSInteger)uid { + // Get NSTimeInterval of uptime i.e. the delta: now - bootTime + self.offsetTime = [[NSDate date] timeIntervalSince1970] - [NSProcessInfo processInfo].systemUptime; + if (self.currentID) { [self closeLoggFileForSequenceID:self.currentID]; } - + self.currentID = uid; + self.flushMessage = [NSMutableString string]; + self.count = 0; NSString *logsFileName = [self fileNameForTrackID:uid]; @@ -58,7 +72,11 @@ - (void)createNewLogFileForSequenceID:(NSInteger)uid { self.currentLogFileHandle = [NSFileHandle fileHandleForWritingAtPath:logsFileName]; if (self.currentLogFileHandle) { - NSString *metainfo = [NSString stringWithFormat:@"%@;%@;1.1;%@(%@)\n", [UIDevice modelString], [UIDevice osVersion], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]; + NSString *metainfo = [NSString stringWithFormat:@"%@;%@;1.1.5;%@(%@)\n", + [UIDevice modelString], + [UIDevice osVersion], + [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"], + [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"]]; [self safeWriteString:metainfo]; } } @@ -73,51 +91,82 @@ - (NSString *)fileNameForTrackID:(NSInteger)uid { return [folderPathString stringByAppendingString:@"/track.txt"]; } -- (void)logItems:(NSArray *)trackLogItems inFileForSequenceID:(NSInteger)uid { +- (void)logItem:(OSVLogItem *)item { if (!self.currentLogFileHandle || self.currentID == 0) { return; } - NSMutableString *logMessage = [NSMutableString new]; - NSString *rowMessage = @""; - // @"timestamp;longitude;latitude;elevation;horizontal_accuracy;GPSspeed;yaw;pitch;roll;accelerationX;accelerationY;accelerationZ;pressure;compass;videoIndex;tripFrameIndex;gravityX;gravityY;gravityZ;OBD2speed\n"; - for (OSVLogItem *item in trackLogItems) { - if (item.photodata){ - CLLocation *location = item.photodata.location; - rowMessage = [NSString stringWithFormat:@"%f;%f;%f;%f;%f;%f;;;;;;;;;%ld;%ld;;;;\n", item.photodata.timestamp, location.coordinate.longitude, location.coordinate.latitude, location.altitude, location.horizontalAccuracy, location.speed, (long)item.photodata.videoIndex, (long)item.photodata.sequenceIndex]; - } else if (item.location) { - CLLocation *location = item.location; - rowMessage = [NSString stringWithFormat:@"%f;%f;%f;%f;%f;%f;;;;;;;;;;;;;;\n", [location.timestamp timeIntervalSince1970], location.coordinate.longitude, location.coordinate.latitude, location.altitude, location.horizontalAccuracy, location.speed]; - } else if (item.heading) { - rowMessage = [NSString stringWithFormat:@"%f;;;;;;;;;;;;;%f;;;;;;\n", item.timestamp, item.heading.trueHeading]; - } else if ([item.sensorData isKindOfClass:[CMAltitudeData class]]) { - CMAltitudeData *altitudeData = (CMAltitudeData *)item.sensorData; - rowMessage = [NSString stringWithFormat:@"%f;;;;;;;;;;;;%f;;;;;;;\n", item.timestamp, [altitudeData.pressure doubleValue]]; - } else if ([item.sensorData isKindOfClass:[CMDeviceMotion class]]) { - CMDeviceMotion *deviceMotionData = (CMDeviceMotion *)item.sensorData; - rowMessage = [NSString stringWithFormat:@"%f;;;;;;%f;%f;%f;%f;%f;%f;;;;;%f;%f;%f;\n", item.timestamp, deviceMotionData.attitude.yaw, deviceMotionData.attitude.pitch, deviceMotionData.attitude.roll, deviceMotionData.userAcceleration.x, deviceMotionData.userAcceleration.y, deviceMotionData.userAcceleration.z, deviceMotionData.gravity.x, deviceMotionData.gravity.y, deviceMotionData.gravity.z]; - } else if (item.carSensorData) { - rowMessage = [rowMessage stringByAppendingFormat:@"%f;;;;;;;;;;;;;;;;;;;%f\n", item.timestamp, item.carSensorData.speed]; - } - [logMessage appendString:rowMessage]; + + NSString *rowMessage = nil; + + if (item.photodata){ + rowMessage = [NSString stringWithFormat:@"%f;;;;;;;;;;;;;;%ld;%ld;;;;;\n", + item.photodata.timestamp, + (long)item.photodata.videoIndex, + (long)item.photodata.sequenceIndex]; + } else if (item.location) { + CLLocation *location = item.location; + rowMessage = [NSString stringWithFormat:@"%f;%f;%f;%f;%f;%f;;;;;;;;;;;;;;;%f\n", + [location.timestamp timeIntervalSince1970], + location.coordinate.longitude, + location.coordinate.latitude, + location.altitude, + location.horizontalAccuracy, + location.speed, + location.verticalAccuracy]; + } else if (item.heading) { + rowMessage = [NSString stringWithFormat:@"%f;;;;;;;;;;;;;%f;;;;;;;\n", + [item.heading.timestamp timeIntervalSince1970], + [self adjustHeadingToOrientation:item.heading.trueHeading]]; + } else if ([item.sensorData isKindOfClass:[CMAltitudeData class]]) { + CMAltitudeData *altitudeData = (CMAltitudeData *)item.sensorData; + rowMessage = [NSString stringWithFormat:@"%f;;;;;;;;;;;;%f;;;;;;;;\n", + altitudeData.timestamp + self.offsetTime, + [altitudeData.pressure doubleValue]]; + } else if ([item.sensorData isKindOfClass:[CMDeviceMotion class]]) { + CMDeviceMotion *deviceMotionData = (CMDeviceMotion *)item.sensorData; + rowMessage = [NSString stringWithFormat:@"%f;;;;;;%f;%f;%f;%f;%f;%f;;;;;%f;%f;%f;;\n", + deviceMotionData.timestamp + self.offsetTime, + deviceMotionData.attitude.yaw, + deviceMotionData.attitude.pitch, + deviceMotionData.attitude.roll, + deviceMotionData.userAcceleration.x, + deviceMotionData.userAcceleration.y, + deviceMotionData.userAcceleration.z, + deviceMotionData.gravity.x, + deviceMotionData.gravity.y, + deviceMotionData.gravity.z]; + } else if (item.carSensorData) { + rowMessage = [NSString stringWithFormat:@"%f;;;;;;;;;;;;;;;;;;;%f;\n", + item.carSensorData.timestamp, + item.carSensorData.speed]; } - if (self.currentLogFileHandle) { - [self safeWriteString:logMessage]; + if (self.currentLogFileHandle && rowMessage != nil) { + [self safeWriteString:rowMessage]; } } - (void)safeWriteString:(NSString *)string { - int i = 0; - while (![self retryToWriteString:string] && i < 5) { - i++; - } + dispatch_async(self.serialDispatchQueue, ^{ + int i = 0; + self.count++; + [self.flushMessage appendString:string]; + + if (self.flushMessage.length > 1700) { + while (![self retryToWriteString:self.flushMessage] && i < 5) { + i++; + } + [self.flushMessage setString:@""]; + } + }); } - (BOOL)retryToWriteString:(NSString *)string { @try { - [self.currentLogFileHandle seekToEndOfFile]; NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; [self.currentLogFileHandle writeData:data]; + [self.currentLogFileHandle synchronizeFile]; + } @catch (NSException *exception) { return NO; } @@ -126,8 +175,14 @@ - (BOOL)retryToWriteString:(NSString *)string { } - (void)closeLoggFileForSequenceID:(NSInteger)uid { - [self.currentLogFileHandle closeFile]; - self.currentLogFileHandle = nil; + dispatch_async(self.serialDispatchQueue, ^{ + if (self.flushMessage.length > 0) { + [self retryToWriteString:self.flushMessage]; + } + [self retryToWriteString:@"DONE"]; + [self.currentLogFileHandle closeFile]; + self.currentLogFileHandle = nil; + }); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ NSString *txtfile = [NSString stringWithFormat:@"%@%ld/track.txt", self.basePath, (long)uid]; NSString *zipfile = [NSString stringWithFormat:@"%@%ld/track.txt.gz", self.basePath, (long)uid]; @@ -137,4 +192,24 @@ - (void)closeLoggFileForSequenceID:(NSInteger)uid { }); } +- (double)adjustHeadingToOrientation:(double)heading { + double value = heading; + + switch ([[UIDevice currentDevice] orientation]) { + case UIDeviceOrientationLandscapeLeft: + value = fmod((heading + 90), 359.0); + break; + case UIDeviceOrientationLandscapeRight: + value = fmod((heading + 270), 359.0); + break; + case UIDeviceOrientationPortraitUpsideDown: + value = fmod((heading + 180), 359.0); + break; + default: + break; + } + + return value; +} + @end diff --git a/OpenStreetView/OSVTrackMatcher.h b/OpenStreetView/OSVTrackMatcher.h new file mode 100644 index 0000000..49262b4 --- /dev/null +++ b/OpenStreetView/OSVTrackMatcher.h @@ -0,0 +1,22 @@ +// +// OSVTrackMatcher.h +// OpenStreetView +// +// Created by Bogdan Sala on 12/12/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import +#import "OSVCameraMapManager.h" + +@interface OSVTrackMatcher : NSObject + +@property (strong, nonatomic) OSVCameraMapManager * _Nullable delegate; + +- (void)getTracksForMap:(SKMapView * _Nonnull)mapView withRegion:(SKCoordinateRegion)region; +- (void)getTracks; + +- (BOOL)hasCoverage; +- (OSVPolyline * _Nonnull)nearestPolylineToLocation:(CLLocation * _Nonnull)coordinate; + +@end diff --git a/OpenStreetView/OSVTrackMatcher.m b/OpenStreetView/OSVTrackMatcher.m new file mode 100644 index 0000000..1ed5368 --- /dev/null +++ b/OpenStreetView/OSVTrackMatcher.m @@ -0,0 +1,361 @@ +// +// OSVTrackMatcher.m +// OpenStreetView +// +// Created by Bogdan Sala on 12/12/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVTrackMatcher.h" +#import +#import "OSVLocationManager.h" +#import "OSVSyncController.h" +#import "OSVUserDefaults.h" +#import "OSVUtils.h" +#import "OSVServerSequence.h" + +#import "UIColor+OSVColor.h" + +#import "OSVLogger.h" + +typedef struct { + //noting Pn the point to that was matched on segment AB + // distance from point Pn to AB + double distance; + // angle between the line defined by Pn and Pn-1 and the line AB + double historycalAngle; + + CLLocationCoordinate2D start; + CLLocationCoordinate2D end; +} MatchingParameters; + +@interface OSVTrackMatcher () + +@property (strong, nonatomic) SKBoundingBox *midBox; +@property (strong, nonatomic) SKBoundingBox *loadedBox; + +@property (strong, nonatomic) NSMutableArray *bufferV; +@property (strong, nonatomic) NSMutableArray *bufferM; + +@property (strong, nonatomic) NSLock *lock; + +@property (assign, atomic) BOOL isMakingRequest; + +@property (strong, nonatomic) SKMapView *mapView; +@property (strong, nonatomic) OSVPolyline *bestPolyline; + +@property (strong, nonatomic) CLLocation *prevLocation; + +@end + +@implementation OSVTrackMatcher + +- (instancetype)init { + self = [super init]; + if (self) { + self.lock = [NSLock new]; + self.bufferV = [NSMutableArray array]; + self.bufferM = [NSMutableArray array]; + self.isMakingRequest = NO; + } + return self; +} + +#pragma mark - Public + +- (void)getTracksForMap:(SKMapView *)mapView withRegion:(SKCoordinateRegion)region { + + CLLocationCoordinate2D coordinate = [OSVLocationManager sharedInstance].currentMatchedPosition.coordinate; + SKBoundingBox *box = [SKBoundingBox boundingBoxForRegion:region inMapViewWithSize:mapView.frame.size]; + + self.mapView = mapView; + + [self getTracksForCoordinate:coordinate withBox:box]; +} + +- (void)getTracks { + + CLLocationCoordinate2D coordinate = [OSVLocationManager sharedInstance].currentMatchedPosition.coordinate; + SKBoundingBox *box = [self boxAroundCoordinate:coordinate withDistance:500]; + + [self getTracksForCoordinate:coordinate withBox:box]; +} + +- (OSVPolyline *)nearestPolylineToLocation:(CLLocation *)coordinate { + OSVPolyline *bestPolyline = nil; + double bestDistance = MAXFLOAT; + + CLLocation *originPoint = coordinate; + [self.lock lock]; + for (OSVPolyline *polyline in self.bufferM) { + + if (polyline.coordinates.count == 1) { + // we need at least 1 point + + CLLocation *spoint = polyline.coordinates[0]; + CLLocation *epoint = coordinate; + double distance = [spoint distanceFromLocation:epoint]; + if (distance < bestDistance) { + bestDistance = distance; + bestPolyline = polyline; + } + continue; + } + + for (NSInteger index = 0; index < polyline.coordinates.count - 1; index++) { + CLLocation *startCoordinate = polyline.coordinates[index]; + CLLocation *endCoordinate = polyline.coordinates[index + 1]; + + double distance; + [OSVUtils nearestLocationToLocation:originPoint onLineSegmentLocationA:startCoordinate locationB:endCoordinate distance:&distance]; + + if (distance < bestDistance) { + bestDistance = distance; + bestPolyline = polyline; + } + } + } + [self.lock unlock]; + + if (bestPolyline && bestDistance < 25) { + + [self debugReder:bestPolyline]; + + return bestPolyline; + } + + return [OSVPolyline new]; +} + +//- (OSVPolyline *)nearestPolylineToLocation:(CLLocation *)coordinate { +// OSVPolyline *bestPolyline = nil; +// OSVPolyline *secBestPolyline = nil; +// +// MatchingParameters bestPolylineParam; +// bestPolylineParam.distance = MAXFLOAT; +// bestPolylineParam.historycalAngle = 90; +// +// MatchingParameters secBestPolylineParam; +// secBestPolylineParam.distance = MAXFLOAT; +// secBestPolylineParam.historycalAngle = 90; +// +// CLLocation *originPoint = coordinate; +// CLLocation *prevOriginPoint = self.prevLocation; +// +// [self.lock lock]; +// for (OSVPolyline *polyline in self.bufferM) { +// +// if (polyline.coordinates.count == 1) { +// // we need at least 1 point +// +// CLLocation *spoint = polyline.coordinates[0]; +// CLLocation *epoint = coordinate; +// double distance = [spoint distanceFromLocation:epoint]; +// +// if (distance < bestPolylineParam.distance) { +// secBestPolylineParam.distance = bestPolylineParam.distance; +// secBestPolylineParam.historycalAngle = 90; +// secBestPolyline = bestPolyline; +// +// bestPolylineParam.distance = distance; +// bestPolylineParam.historycalAngle = 90; +// bestPolyline = polyline; +// } +// +// continue; +// } +// +// for (NSInteger index = 0; index < polyline.coordinates.count - 1; index++) { +// CLLocation *startCoordinate = polyline.coordinates[index]; +// CLLocation *endCoordinate = polyline.coordinates[index + 1]; +// +// double distance; +// [OSVUtils nearestLocationToLocation:originPoint +// onLineSegmentLocationA:startCoordinate +// locationB:endCoordinate +// distance:&distance]; +// +// +// if (distance < bestPolylineParam.distance) { +// if (bestPolyline && bestPolyline != polyline) { +// secBestPolylineParam.distance = bestPolylineParam.distance; +// secBestPolylineParam.start = bestPolylineParam.start; +// secBestPolylineParam.end = bestPolylineParam.end; +// secBestPolylineParam.historycalAngle = 90; +// secBestPolyline = bestPolyline; +// } +// +// bestPolylineParam.distance = distance; +// bestPolylineParam.start = startCoordinate.coordinate; +// bestPolylineParam.end = endCoordinate.coordinate; +// bestPolylineParam.historycalAngle = 90; +// bestPolyline = polyline; +// } +// } +// } +// [self.lock unlock]; +// +// if (!self.prevLocation || +// [self.prevLocation distanceFromLocation:originPoint] > 20) { +// self.prevLocation = originPoint; +// } +// +// if (bestPolyline && bestPolylineParam.distance < 25) { +// +// if (prevOriginPoint && +// secBestPolyline != bestPolyline) { +// if (bestPolylineParam.start.latitude != 0.0) { +// bestPolylineParam.historycalAngle = [OSVUtils degreesBetweenLineAStart:bestPolylineParam.start +// lineAEnd:bestPolylineParam.end +// lineBStart:prevOriginPoint.coordinate +// lineBEnd:originPoint.coordinate]; +// +// } +// +// if (secBestPolylineParam.start.latitude != 0.0) { +// secBestPolylineParam.historycalAngle = [OSVUtils degreesBetweenLineAStart:secBestPolylineParam.start +// lineAEnd:secBestPolylineParam.end +// lineBStart:prevOriginPoint.coordinate +// lineBEnd:originPoint.coordinate]; +// } +// } +// +// if (secBestPolyline && +// secBestPolylineParam.distance < 25 && +// bestPolylineParam.historycalAngle > secBestPolylineParam.historycalAngle + 10) { +// //compare the angle of the most closest two polylines +// //if the second most closes polyline is smaller then the best polyline with +// //more then 30 degrees => second best polyline is more paralel +// //=> bestPolyline is the second best polyline. +// bestPolyline = secBestPolyline; +// } +// +// [self debugReder:bestPolyline]; +// +// return bestPolyline; +// } +// +// return [OSVPolyline new]; +//} + +- (BOOL)hasCoverage { + CLLocationCoordinate2D coordinate = [OSVLocationManager sharedInstance].currentMatchedPosition.coordinate; + if (!self.loadedBox) { + return NO; + } + + return [self.loadedBox containsLocation:coordinate]; +} + +#pragma mark - Private + +- (void)getTracksForCoordinate:(CLLocationCoordinate2D)coordinate withBox:(SKBoundingBox *)box { + BOOL hasCoverage = self.hasCoverage; + BOOL midContainsTop = [self.midBox containsLocation:box.topLeftCoordinate]; + BOOL midContainsBot = [self.midBox containsLocation:box.bottomRightCoordinate]; +// NSLog(@"___x___ will send request"); + if ((!hasCoverage || + !midContainsTop || + !midContainsBot) && + !self.isMakingRequest) { + + self.midBox = [self boxAroundCoordinate:coordinate withDistance:1500]; + SKBoundingBox *loadedBox = [self boxAroundCoordinate:coordinate withDistance:2000]; + + self.isMakingRequest = YES; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + self.isMakingRequest = NO; + }); + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ +// NSLog(@"___x___ %@", [NSString stringWithFormat:@"requested Box:%p h:%d, mt:%d mb:%d", loadedBox, hasCoverage, midContainsTop, midContainsBot]); + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"requested Box:%p h:%d, mt:%d mb:%d", loadedBox, hasCoverage, midContainsTop, midContainsBot] withLevel:LogLevelDEBUG]; + __block NSError *e; + + [self.lock lock]; + self.bufferV = [NSMutableArray array]; + [self.lock unlock]; + + [[OSVSyncController sharedInstance].tracksController getSerialServerTracksInBoundingBox:(id)loadedBox withZoom:16 withPartialCompletion:^(id sequence, OSVMetadata *metadata, NSError *error) { +// NSLog(@"___x___ tracks pages - %ld loaded metadataPageIndex %p",metadata.pageIndex, metadata); + + if (error) { +// NSLog(@"___x___ receiverd error"); + e = error; + } + + if (!sequence) { +// NSLog(@"___x___ receiverd no sequence"); + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"received no sequence in box:%p error:%@", loadedBox, error] withLevel:LogLevelDEBUG]; + return; + } + + NSArray *track = [sequence.track mutableCopy]; + OSVPolyline *polyline = [OSVPolyline new]; + polyline.coordinates = track; + polyline.coverage = sequence.coverage; + + if ([OSVUserDefaults sharedInstance].showMapWhileRecording) { +// NSLog(@"___x___ add Sequ"); + [self.delegate addPolyline:polyline]; + } + + [self.lock lock]; + [self.bufferV addObject:polyline]; + [self.lock unlock]; + } completion:^(OSVMetadata *mf) { +// NSLog(@"___x___ receiverd completion block, %ld", mf.totalPages); + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"received completion for Box:%p", loadedBox] withLevel:LogLevelDEBUG]; + + if (!e && self.loadedBox != loadedBox) { + self.isMakingRequest = NO; + + [self.delegate moveToMap]; + + self.bufferM = self.bufferV; + + self.loadedBox = loadedBox; +// NSLog(@"___x___ receiverd no erorr will render loadded box"); + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"received Box:%p", loadedBox] withLevel:LogLevelDEBUG]; + } + }]; + }); + } +} + +- (SKBoundingBox *)boxAroundCoordinate:(CLLocationCoordinate2D)coordinate withDistance:(double)meters { + + SKBoundingBox *box = [SKBoundingBox new]; + box.topLeftCoordinate = CLLocationCoordinate2DMake(coordinate.latitude + [self metersToDecimal:meters], coordinate.longitude - [self metersToDecimal:meters]); + box.bottomRightCoordinate = CLLocationCoordinate2DMake(coordinate.latitude - [self metersToDecimal:meters], coordinate.longitude + [self metersToDecimal:meters]); + + return box; +} + +- (double)metersToDecimal:(double)meters { + return meters / 110000; +} + +- (void)setLoadedBox:(SKBoundingBox *)loadedBox { + _loadedBox = loadedBox; + [[NSNotificationCenter defaultCenter] postNotificationName:@"kdidLoadNewBox" object:nil userInfo:@{}]; +} + +- (void)debugReder:(OSVPolyline *)bestPolyline { + if ([OSVUserDefaults sharedInstance].debugMatcher && self.bestPolyline != bestPolyline) { + if (self.bestPolyline) { + UIColor *purpleColor = [UIColor colorWithHex:0xbd10e0]; + self.bestPolyline.fillColor = [purpleColor colorWithAlphaComponent:MIN(self.bestPolyline.coverage, 10.0)/10.0 + 0.01]; + self.bestPolyline.strokeColor = [purpleColor colorWithAlphaComponent:MIN(self.bestPolyline.coverage, 10.0)/10.0 + 0.01]; + [self.mapView addPolyline:self.bestPolyline]; + } + + bestPolyline.fillColor = [UIColor redColor]; + bestPolyline.strokeColor = [UIColor redColor]; + + [self.mapView addPolyline:bestPolyline]; + self.bestPolyline = bestPolyline; + } +} + +@end diff --git a/OpenStreetView/OSVTrackSyncController.h b/OpenStreetView/OSVTrackSyncController.h index b4d3aed..d6d9805 100644 --- a/OpenStreetView/OSVTrackSyncController.h +++ b/OpenStreetView/OSVTrackSyncController.h @@ -13,6 +13,8 @@ #import "OSVTrackCache.h" #import "OSVTrackLogger.h" +#import "OSVScoreHistory.h" + @class OSVAPI; @interface OSVTrackSyncController : OSVPhotoSyncController @@ -30,7 +32,17 @@ //tracks - (void)getServerTracksInBoundingBox:(id)box withZoom:(double)zoom - withPartialCompletion:(void (^)(id sequence, OSVMetadata *metadata, NSError *error))partComp; + withPartialCompletion:(void (^)(id sequence, OSVMetadata *metadata, NSError *error))partComp + completion:(void (^)(OSVMetadata *mf))complet; + +- (void)getSerialServerTracksInBoundingBox:(id)box + withZoom:(double)zoom + withPartialCompletion:(void (^)(id sequence, OSVMetadata *metadata, NSError *error))partComp + completion:(void (^)(OSVMetadata *mf))complet; + +- (void)getScoreHistoryForSequenceWithID:(NSInteger)uid + completion:(void (^)(NSArray *history))completion; +- (void)storeScoreHistory:(OSVScoreHistory *)history; //server - (void)cancelGetServerSequences; @@ -45,6 +57,7 @@ - (void)getLayersFromLocation:(CLLocationCoordinate2D)coordinate withCompletion:(void (^)(NSArray *, NSError *))completion; + //Delete methods - (void)deleteSequence:(id)sequence withCompletionBlock:(void (^)(NSError *error))completionBlock; diff --git a/OpenStreetView/OSVTrackSyncController.m b/OpenStreetView/OSVTrackSyncController.m index e31732d..f1a13d6 100644 --- a/OpenStreetView/OSVTrackSyncController.m +++ b/OpenStreetView/OSVTrackSyncController.m @@ -9,11 +9,15 @@ #import "OSVTrackSyncController.h" #import "OSVAPI.h" #import "OSVSyncUtils.h" +#import "OSVUtils.h" #import "OSVAPISerialOperation.h" #import "OSVPersistentManager.h" #import "OSVLogger.h" #import "OSVUserDefaults.h" #import "OSVVideo.h" +#import "OSVLocalNotificationsController.h" + +#import @interface OSVTrackSyncController () @@ -32,8 +36,7 @@ @interface OSVTrackSyncController () @property (nonatomic) NSMutableDictionary<__kindof NSString *, __kindof NSOperation *> *imageUploadingOperatios; -@property (strong, nonatomic) NSTimer *stayAliveTimer; - +@property (strong, nonatomic) NSTimer *stayAliveTimer; @end @@ -41,12 +44,11 @@ @interface OSVTrackSyncController () @implementation OSVTrackSyncController -- (instancetype)initWithOSVAPI:(OSVAPI *)api basePath:(NSString *)basePath { +- (instancetype)initWithOSVAPI:(OSVAPI *)api { self = [super init]; if (self) { self.osvAPI = api; - self.basePathToPhotos = basePath; self.listSequencesQueue = [NSOperationQueue new]; self.listSequencesQueue.maxConcurrentOperationCount = 1; @@ -73,34 +75,105 @@ - (instancetype)initWithOSVAPI:(OSVAPI *)api basePath:(NSString *)basePath { #pragma mark - Getter methods -- (void)getServerTracksInBoundingBox:(id)box withZoom:(double)zoom withPartialCompletion:(void (^)(id sequence, OSVMetadata *metadata, NSError *error))partComp { +- (void)getSerialServerTracksInBoundingBox:(id)box + withZoom:(double)zoom + withPartialCompletion:(void (^)(id sequence, OSVMetadata *metadata, NSError *error))partComp + completion:(void (^)(OSVMetadata *mf))complet { + __weak typeof(self) welf = self; + __block int responeses = 0; + [welf.osvAPI listTracksForUser:self.oscUser atPage:0 inBoundingBox:box withZoom:zoom withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { +// NSLog(@"___x___ page 0 loaded"); + responeses++; + + if (!sequences && !error && !metadata) { + return; + } + + if (!sequences.count) { + partComp(nil, metadata, error); + complet(metadata); + return; + } + + for (id sequence in sequences) { + partComp(sequence, metadata, error); + } + + if (metadata.totalPages == responeses) { + NSLog(@"did send completion00"); + complet(metadata); + return; + } + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ + for (int i = 1; i < metadata.totalPages; i++) { + [self.osvAPI listTracksForUser:self.oscUser atPage:i inBoundingBox:box withZoom:zoom withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { +// NSLog(@"___x___ page %d loaded metadataPageIndex - %ld tp - %ld", i, metadata.pageIndex, totalPages - 1); + responeses++; + + for (id sequence in sequences) { + partComp(sequence, metadata, error); + } + + if (metadata.totalPages == responeses) { + NSLog(@"%p did send completion11 %ld", self, [metadata totalPages]); + complet(metadata); + } + }]; + } + }); + }]; +} + +- (void)getServerTracksInBoundingBox:(id)box + withZoom:(double)zoom + withPartialCompletion:(void (^)(id sequence, OSVMetadata *metadata, NSError *error))partComp + completion:(void (^)(OSVMetadata *mf))complet { [self cancelGetServerTracks]; __weak typeof(self) welf = self; - NSMutableArray *allIDs = [NSMutableArray array]; - [self.listTracksOpetations addObject:[welf.osvAPI listTracksForUser:self.user atPage:0 inBoundingBox:box withZoom:zoom withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { + [self.listTracksOpetations addObject:[welf.osvAPI listTracksForUser:self.oscUser atPage:0 inBoundingBox:box withZoom:zoom withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { + // NSLog(@"___x___ page 0 loaded"); + if (!sequences && !error && !metadata) { + return; + } + if (!sequences.count) { partComp(nil, metadata, error); + complet(metadata); + return; } for (id sequence in sequences) { - [allIDs addObject:@(sequence.uid)]; partComp(sequence, metadata, error); } NSInteger totalPages = metadata.totalItems / metadata.itemsPerPage + (metadata.totalItems % metadata.itemsPerPage != 0 ? 1 : 0); - + + if (metadata.isLastPage) { + NSLog(@"did send completion0"); + complet(metadata); + return; + } + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{ for (int i = 1; i < totalPages; i++) { - [welf.listTracksOpetations addObject:[welf.osvAPI listTracksForUser:self.user atPage:i inBoundingBox:box withZoom:zoom withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { + [welf.listTracksOpetations addObject:[welf.osvAPI listTracksForUser:self.oscUser atPage:i inBoundingBox:box withZoom:zoom withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { + // NSLog(@"___x___ page %d loaded metadataPageIndex - %ld tp - %ld", i, metadata.pageIndex, totalPages - 1); + for (id sequence in sequences) { - [allIDs addObject:@(sequence.uid)]; partComp(sequence, metadata, error); } + + if (metadata.isLastPage) { + NSLog(@"%p did send completion1 %ld", self, [metadata totalPages]); + complet(metadata); + } }]]; } }); }]]; } + - (void)getLayersFromLocation:(CLLocationCoordinate2D)coordinate withCompletion:(void (^)(NSArray *, NSError *))completion { __weak typeof(self) welf = self; [welf.osvAPI getLayersFromLocation:coordinate radius:50 withCompletion:^(NSArray *array, NSError *error) { @@ -113,7 +186,7 @@ - (void)getMyServerSequencesAtPage:(NSInteger)index withCompletion:(void (^)(NSA completion(nil, [OSVMetadata metadataError], [NSError errorWithDomain:@"OSMAPI" code:1 userInfo:@{@"Authentication":@"UserAutenticationRequired"}]); return; } - [self.osvAPI listMySequncesForUser:self.user atPage:index withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { + [self.osvAPI listMySequncesForUser:self.oscUser atPage:index withCompletionBlock:^(NSArray *sequences, NSError *error, OSVMetadata *metadata) { if (error) { completion(nil, nil, error); return; @@ -121,11 +194,10 @@ - (void)getMyServerSequencesAtPage:(NSInteger)index withCompletion:(void (^)(NSA completion(sequences, metadata, error); }]; - } - (void)getPhotosForTrack:(id)seq withCompletionBlock:(void (^)(idseq , NSError *error))completion { - [self.osvAPI listPhotosForUser:self.user withSequence:seq completionBlock:^(NSMutableArray> *photos, NSError *error) { + [self.osvAPI listPhotosForUser:self.oscUser withSequence:seq completionBlock:^(NSMutableArray> *photos, NSError *error) { seq.photos = photos; seq.dateAdded = [NSDate dateWithTimeIntervalSince1970:photos.firstObject.photoData.timestamp]; completion(seq, error); @@ -232,7 +304,7 @@ - (void)uploadAllSequencesWithCompletion:(void (^)(NSError *error))completion pa __block long long totalBytesExpectedToUpload = 0; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ - totalBytesExpectedToUpload = [OSVSyncUtils sizeOnDiskForSequencesAtPath:self.basePathToPhotos]; + totalBytesExpectedToUpload = [OSVSyncUtils sizeOnDiskForSequencesAtPath:[OSVUtils createOSCBasePath]]; }); __weak typeof(self) welf = self; @@ -249,6 +321,10 @@ - (void)uploadAllSequencesWithCompletion:(void (^)(NSError *error))completion pa for (OSVSequence *seq in sequences) { if (!(seq.uploadID > 0)) { NSDictionary *metaDict = [self metadataForTrack:seq]; + if (!metaDict) { + continue; + } + OSVAPISerialOperation *requestID = [OSVAPISerialOperation new]; //request sequence ID and upload sequence [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"request new sq ID operation:%p", requestID] withLevel:LogLevelDEBUG]; @@ -257,10 +333,24 @@ - (void)uploadAllSequencesWithCompletion:(void (^)(NSError *error))completion pa if (wop.isCancelled) { return; } + + NSString *details = @"[]"; + if (!seq.points) { + NSMutableArray *detailsArray = [NSMutableArray array]; + NSArray *historyArray = [OSVPersistentManager getScoreHistoryForSequenceWithID:seq.uid]; + for (OSVScoreHistory *sch in historyArray) { + seq.points += sch.points; + [detailsArray addObject:[sch jsonDictionary]]; + } + + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:detailsArray options:NSJSONWritingPrettyPrinted error:nil]; + details = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding]; + } + OSVMetadata *uploadingMeta = [OSVMetadata new]; uploadingMeta.uploadingMetadata = YES; - [welf.osvAPI requestNewSequenceIdForUser:self.user withSequence:seq metadata:metaDict withProgressBlock:^(long long tBytes, long long tBytesExpect) { + [welf.osvAPI requestNewSequenceIdForUser:self.oscUser withSequence:seq metadata:metaDict scoreDetails:details withProgressBlock:^(long long tBytes, long long tBytesExpect) { NSDictionary *progress = @{@"progress" :@(totalProgress + tBytes), @"totalSize":@(totalBytesExpectedToUpload), @@ -390,6 +480,8 @@ - (void)uploadAllSequencesWithCompletion:(void (^)(NSError *error))completion pa [self.stayAliveTimer invalidate]; self.stayAliveTimer = nil; [wfinishUploadingAll asyncTaskDone]; + [OSVLocalNotificationsController removeUploadNotification]; + if (taskIndentifier) { [[UIApplication sharedApplication] endBackgroundTask:taskIndentifier]; taskIndentifier = UIBackgroundTaskInvalid; @@ -429,7 +521,7 @@ - (void)uploadVideos:(OSVSequence *)sequence withProgress:(void (^)(long long tB }]; for (OSVVideo *video in sorted) { - video.videoPath = [self fileNameForVideoWithTrackID:sequence.uid index:video.videoIndex]; + video.videoPath = [OSVUtils fileNameForVideoWithTrackID:sequence.uid index:video.videoIndex]; OSVAPISerialOperation *operation = [OSVAPISerialOperation new]; [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"create Upload Video operation:%p", operation] withLevel:LogLevelDEBUG]; @@ -444,7 +536,7 @@ - (void)uploadVideos:(OSVSequence *)sequence withProgress:(void (^)(long long tB video.uid = sequence.uploadID; } //upload video - wOperation.taskObject = [self.osvAPI uploadVideo:video forUser:self.user withProgressBlock:^(long long totalBytesSent, long long totalBytesExpected) { + wOperation.taskObject = [self.osvAPI uploadVideo:video forUser:self.oscUser withProgressBlock:^(long long totalBytesSent, long long totalBytesExpected) { tbsCache = totalBytesSent; uploadProgressBlock(totalBytesSentInVideos + tbsCache, totalBytesExpected); @@ -517,7 +609,7 @@ - (void)uploadVideos:(OSVSequence *)sequence withProgress:(void (^)(long long tB if (succesfullRequests == numberOfVideos) { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"will send finishSeq operation:%p localUID:%ld", wfinishedRequest, (long)localID] withLevel:LogLevelDEBUG]; - [self.osvAPI finishUploadingSequenceWithID:uploadID forUser:self.user withCompletionBlock:^(NSError * _Nullable error) { + [self.osvAPI finishUploadingSequenceWithID:uploadID forUser:self.oscUser withCompletionBlock:^(NSError * _Nullable error) { if (!error) { completion(error); [self deleteLocalTrackWithID:localID]; @@ -551,28 +643,24 @@ - (void)uploadVideos:(OSVSequence *)sequence withProgress:(void (^)(long long tB [self.videoUploadQueue addOperation:finishedRequest]; } - -- (NSString *)fileNameForVideoWithTrackID:(NSInteger)trackUID index:(NSInteger)videoIndex { - NSString *folderPathString = [NSString stringWithFormat:@"%@%ld/%ld.mp4", self.basePathToPhotos, (long)trackUID, (long)videoIndex]; - - return folderPathString; -} - - - (void)finishUploadingEmptySequencesWithCompletionBlock:(void (^)(NSError *error))completionBlock { + if (![self userIsLoggedIn]) { + return; + } + [[OSVLogger sharedInstance] createNewLogFile]; - NSMutableArray *allfolders = [[OSVSyncUtils getFolderNamesAtPath:self.basePathToPhotos] mutableCopy]; + NSMutableArray *allfolders = [[OSVSyncUtils getFolderNamesAtPath:[OSVUtils createOSCBasePath]] mutableCopy]; [OSVPersistentManager getAllSequencesWithCompletion:^(NSArray *sequences, NSInteger photosCount) { for (OSVSequence *track in sequences) { NSString *trackID = [NSString stringWithFormat:@"%ld", (long)track.uid]; [allfolders removeObject:trackID]; BOOL containsImages = NO; - [OSVSyncUtils sizeOnDiskForSequence:track atPath:self.basePathToPhotos containsImages:&containsImages]; + [OSVSyncUtils sizeOnDiskForSequence:track atPath:[OSVUtils createOSCBasePath] containsImages:&containsImages]; if (!containsImages) { [[OSVLogger sharedInstance] logMessage:@"DB contains Photos that are not present in videos.This is a bug!" withLevel:LogLevelDEBUG]; [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Will Finish uploading seqID:%ld", (long)track.uploadID] withLevel:LogLevelDEBUG]; - [self.osvAPI finishUploadingSequenceWithID:track.uploadID forUser:self.user withCompletionBlock:^(NSError * _Nullable error) { + [self.osvAPI finishUploadingSequenceWithID:track.uploadID forUser:self.oscUser withCompletionBlock:^(NSError * _Nullable error) { if (!error) { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Success Finish uploading seqID:%ld", (long)track.uploadID] withLevel:LogLevelDEBUG]; if (taskIndentifier) { @@ -592,7 +680,7 @@ - (void)finishUploadingEmptySequencesWithCompletionBlock:(void (^)(NSError *erro // remove all folders that do not appare in DB; for (NSString *emptyFolderName in allfolders) { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Will try to remove empty folder:%@", emptyFolderName] withLevel:LogLevelDEBUG]; - [OSVSyncUtils removeTrackWithID:[emptyFolderName integerValue] atPath:self.basePathToPhotos]; + [OSVSyncUtils removeTrackWithID:[emptyFolderName integerValue] atPath:[OSVUtils createOSCBasePath]]; } }]; } @@ -605,10 +693,25 @@ - (void)getLocalSequencesWithCompletion:(void (^)(NSArray *sequences))completion }); } -- (void)getLocalSequenceWithID:(NSInteger)uid completion:(void (^)(OSVSequence *seq))completion { +- (void)getLocalSequenceWithID:(NSInteger)uid + completion:(void (^)(OSVSequence *seq))completion { completion([OSVPersistentManager getSequenceWithID:uid]); } +- (void)getScoreHistoryForSequenceWithID:(NSInteger)uid + completion:(void (^)(NSArray *history))completion { + id scoreHistory = [OSVPersistentManager getScoreHistoryForSequenceWithID:uid]; + + + completion(scoreHistory); +} + +- (void)storeScoreHistory:(OSVScoreHistory *)history { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_LOW, 0), ^{ + [OSVPersistentManager storeScoreHistory:history]; + }); +} + - (BOOL)isUploading { return self.imageUploadingOperatios.allKeys.count > 0 && !self.videoUploadQueue.suspended; } @@ -621,7 +724,7 @@ - (BOOL)isPaused { - (void)deleteSequence:(id)sequence withCompletionBlock:(void (^)(NSError *error))completionBlock { if ([sequence isKindOfClass:[OSVServerSequence class]]) { - [self.osvAPI deleteSequence:sequence forUser:self.user withCompletionBlock:completionBlock]; + [self.osvAPI deleteSequence:sequence forUser:self.oscUser withCompletionBlock:completionBlock]; } else { for (OSVPhoto *photo in sequence.photos) { [OSVPersistentManager removePhoto:photo]; @@ -632,7 +735,7 @@ - (void)deleteSequence:(id)sequence withCompletionBlock:(void (^)(N } - (void)deleteLocalTrackWithID:(NSInteger)uid { - if ([OSVSyncUtils removeTrackWithID:uid atPath:self.basePathToPhotos]) { + if ([OSVSyncUtils removeTrackWithID:uid atPath:[OSVUtils createOSCBasePath]]) { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"deleted folder with success:%ld", (long)uid] withLevel:LogLevelDEBUG]; } else { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"failed to delete folder:%ld", (long)uid] withLevel:LogLevelDEBUG]; @@ -644,19 +747,41 @@ - (void)deleteLocalTrackWithID:(NSInteger)uid { - (NSDictionary *)metadataForTrack:(OSVSequence *)seq { NSDictionary *metadataMime = @{@"contentType" : @"application/x-gzip", @"format" : @"gz"}; - NSString *photoPath = [self.basePathToPhotos stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/track.txt.gz", (long)seq.uid]]; + NSString *photoPath = [[OSVUtils createOSCBasePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/track.txt.gz", (long)seq.uid]]; BOOL fileExists = [[NSFileManager defaultManager] fileExistsAtPath:photoPath]; if (!fileExists) { - photoPath = [self.basePathToPhotos stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/track.txt", (long)seq.uid]]; + photoPath = [[OSVUtils createOSCBasePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"/%ld/track.txt", (long)seq.uid]]; metadataMime = @{@"contentType" : @"text/plain", @"format" : @"txt"}; + + fileExists = [[NSFileManager defaultManager] fileExistsAtPath:photoPath]; + } + + if (!fileExists) { + NSArray *properties = [NSArray arrayWithObjects: NSURLLocalizedNameKey, NSURLLocalizedTypeDescriptionKey, nil]; + + NSArray *arra1y = [[NSFileManager defaultManager] contentsOfDirectoryAtURL:[NSURL URLWithString:[[OSVUtils createOSCBasePath] stringByAppendingPathComponent:[NSString stringWithFormat:@"%ld", (long)seq.uid]]] + includingPropertiesForKeys:properties + options:(NSDirectoryEnumerationSkipsHiddenFiles) + error:nil]; + + NSMutableString *longString = [@"" mutableCopy]; + + for (NSString *fileName in arra1y) { + [longString appendString:[NSString stringWithFormat:@" %@", [fileName lastPathComponent]]]; + } + + [Answers logCustomEventWithName:@"fileCrashAvoided" customAttributes:@{@"Files":longString}]; + + return nil; } NSData *data = [NSData dataWithContentsOfFile:photoPath]; - NSDictionary *dictionary = NSDictionaryOfVariableBindings(metadataMime, data); + NSDictionary *dictionary = @{ @"metadataMime" : metadataMime, + @"data" : data}; return dictionary; } diff --git a/OpenStreetView/OSVUploadViewController.m b/OpenStreetView/OSVUploadViewController.m index d669af0..381923a 100644 --- a/OpenStreetView/OSVUploadViewController.m +++ b/OpenStreetView/OSVUploadViewController.m @@ -13,13 +13,17 @@ #import "UIColor+OSVColor.h" #import "UIAlertView+Blocks.h" #import "OSVUserDefaults.h" +#import "OSVPopTransition.h" #import #import "NSAttributedString+Additions.h" #import "NSMutableAttributedString+Additions.h" #import "UIColor+OSVColor.h" +#import "UIDevice+Aditions.h" -@interface OSVUploadViewController () +#import "OSVLocationManager.h" + +@interface OSVUploadViewController () @property (weak, nonatomic) IBOutlet KAProgressLabel *progressView; @property (weak, nonatomic) IBOutlet UIButton *stopButton; @@ -86,7 +90,7 @@ - (void)viewWillAppear:(BOOL)animated { self.navigationController.navigationBar.barStyle = UIBarStyleBlack; if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) { - [[SKPositionerService sharedInstance] cancelLocationUpdate]; + [[OSVLocationManager sharedInstance] cancelLocationUpdate]; } if ([OSVSyncController sharedInstance].tracksController.isPaused) { self.isPaused = YES; @@ -102,7 +106,7 @@ - (void)viewWillDisappear:(BOOL)animated { self.navigationController.navigationBar.barStyle = UIBarStyleDefault; if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) { - [[SKPositionerService sharedInstance] startLocationUpdate]; + [[OSVLocationManager sharedInstance] startLocationUpdate]; } } @@ -110,25 +114,18 @@ - (void)dealloc { [[NSNotificationCenter defaultCenter] removeObserver:self]; } -- (BOOL)shouldAutorotate { - return NO; +- (UIStatusBarStyle)preferredStatusBarStyle { + return UIStatusBarStyleLightContent; } -- (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; +#pragma mark - Orientation + +- (BOOL)shouldAutorotate { + return YES; } -- (void)addRightNavigationItemWithText:(NSString *)text andCount:(NSString *)stringCount { - - if (!self.status) { - CGRect rect = CGRectMake(0, 0, self.view.frame.size.width/1.5, 40); - self.status = [[UILabel alloc] initWithFrame:rect]; - self.status.textAlignment = NSTextAlignmentRight; - self.navigationItem.rightBarButtonItems = @[[[UIBarButtonItem alloc] initWithCustomView:self.status]]; - } - - self.status.attributedText = [NSAttributedString combineString:text withSize:22.f color:[UIColor hex6E707B] fontName:@"HelveticaNeue-Light" - withString:stringCount withSize:22.f color:[UIColor whiteColor] fontName:@"HelveticaNeue-Light"]; +- (UIInterfaceOrientationMask)supportedInterfaceOrientations { + return UIInterfaceOrientationMaskAll; } #pragma mark - Actions @@ -149,7 +146,8 @@ - (IBAction)didTapStopButton:(id)sender { } - (IBAction)didTapBack:(id)sender { - [self.navigationController popViewControllerAnimated:YES]; + self.navigationController.delegate = self; + [self didFinishUploadingAllSequncesWitError:nil]; } #pragma mark - Uploading notifications @@ -271,13 +269,23 @@ - (void)setProgressWithTotalSize:(double)totalSize currentProgress:(double)curre NSString *progString =[NSString stringWithFormat:@"%.0f%%", currentProgress/totalSize * 100]; - progressAttributedString = [NSMutableAttributedString mutableAttributedStringWithString:progString withSize:80 color:[UIColor whiteColor] fontName:@"HelveticaNeue-UltraLight"]; + float progressFontSize = [UIDevice isLessTheniPhone6]?60:80; + progressAttributedString = [NSMutableAttributedString mutableAttributedStringWithString:progString + withSize:progressFontSize + color:[UIColor whiteColor] + fontName:@"HelveticaNeue-UltraLight"]; + NSString *cProgress = [NSString stringWithFormat:@"\n%@ ", [OSVUtils memoryFormatter:currentProgress]]; - NSAttributedString *curentProgAttributed = [NSAttributedString attributedStringWithString:cProgress withSize:12.f color:[UIColor whiteColor] fontName:@"HelveticaNeue"]; + NSAttributedString *curentProgAttributed = [NSAttributedString attributedStringWithString:cProgress + withSize:12.f + color:[UIColor whiteColor] + fontName:@"HelveticaNeue"]; NSString *tSize = [NSString stringWithFormat:@"| %@", [OSVUtils memoryFormatter:totalSize]]; - - NSAttributedString *totalAttributed = [NSAttributedString attributedStringWithString:tSize withSize:12.f color:[UIColor hex6E707B] fontName:@"HelveticaNeue"]; + NSAttributedString *totalAttributed = [NSAttributedString attributedStringWithString:tSize + withSize:12.f + color:[UIColor hex6E707B] + fontName:@"HelveticaNeue"]; [progressAttributedString appendAttributedString:curentProgAttributed]; [progressAttributedString appendAttributedString:totalAttributed]; @@ -334,4 +342,29 @@ - (NSString *)stringForSpeed:(float)speed { return [NSString stringWithFormat:@"%.1f %@/s", speed, unitString]; } +- (nullable id )navigationController:(UINavigationController *)navigationController + animationControllerForOperation:(UINavigationControllerOperation)operation + fromViewController:(UIViewController *)fromVC + toViewController:(UIViewController *)toVC { + if ([toVC isKindOfClass:NSClassFromString(@"OSVMapViewController")]) { + return [[OSVPopTransition alloc] initWithoutAnimatingSource:YES]; + } + + return nil; +} + +- (void)addRightNavigationItemWithText:(NSString *)text andCount:(NSString *)stringCount { + + if (!self.status) { + CGRect rect = CGRectMake(0, 0, self.view.frame.size.width/1.5, 40); + self.status = [[UILabel alloc] initWithFrame:rect]; + self.status.textAlignment = NSTextAlignmentRight; + self.navigationItem.rightBarButtonItems = @[[[UIBarButtonItem alloc] initWithCustomView:self.status]]; + } + + self.status.attributedText = [NSAttributedString combineString:text withSize:22.f color:[UIColor hex6E707B] fontName:@"HelveticaNeue-Light" + withString:stringCount withSize:22.f color:[UIColor whiteColor] fontName:@"HelveticaNeue-Light"]; +} + + @end diff --git a/OpenStreetView/OSVUtils+Device.m b/OpenStreetView/OSVUtils+Device.m new file mode 100644 index 0000000..d90fa49 --- /dev/null +++ b/OpenStreetView/OSVUtils+Device.m @@ -0,0 +1,24 @@ +// +// OSVUtils+Device.m +// OpenStreetView +// +// Created by Bogdan Sala on 22/09/16. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVUtils.h" +#import + +@implementation OSVUtils (Device) + ++ (BOOL)isHighDensity { + CGFloat scale = [UIScreen mainScreen].scale; + if (scale > 2.9) { + return YES; + } + + return NO; +} + + +@end diff --git a/OpenStreetView/OSVUtils+Gamification.m b/OpenStreetView/OSVUtils+Gamification.m new file mode 100644 index 0000000..adea22a --- /dev/null +++ b/OpenStreetView/OSVUtils+Gamification.m @@ -0,0 +1,37 @@ +// +// OSVUtils_Gamification.h +// OpenStreetView +// +// Created by Bogdan Sala on 16/01/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import "OSVUtils.h" + +@implementation OSVUtils (Gamification) + ++ (NSString *)pointsFormatedFromPoints:(NSInteger)points { + NSString *formated = @""; + if (points > 9999) { + + while (points > 1000) { + NSInteger grup = points % 1000; + points = points/1000; + if (formated.length > 0) { + formated = [NSString stringWithFormat:@"%03ld %@", (long)grup, formated]; + } else { + formated = [NSString stringWithFormat:@"%03ld", (long)grup]; + } + } + + NSInteger grup = points % 1000; + formated = [[@(grup) stringValue] stringByAppendingFormat:@" %@", formated]; + + } else { + formated = [@(points) stringValue]; + } + + return formated; +} + +@end diff --git a/OpenStreetView/OSVVideoRecorder.h b/OpenStreetView/OSVVideoRecorder.h index ef98806..105bc14 100644 --- a/OpenStreetView/OSVVideoRecorder.h +++ b/OpenStreetView/OSVVideoRecorder.h @@ -19,7 +19,7 @@ @property (weak, nonatomic) id delegate; -- (instancetype)initWithVideoSize:(CMVideoDimensions)size encoding:(NSString *)encod bitrate:(NSInteger)bitrate; +//- (instancetype)initWithVideoSize:(CMVideoDimensions)size encoding:(NSString *)encod bitrate:(NSInteger)bitrate; - (instancetype)initWithVideoSize:(CMVideoDimensions)size; - (BOOL)createRecordingWithURL:(NSURL *)url orientation:(AVCaptureVideoOrientation)orientaton; diff --git a/OpenStreetView/OSVVideoRecorder.m b/OpenStreetView/OSVVideoRecorder.m index 774d997..b81d8ea 100644 --- a/OpenStreetView/OSVVideoRecorder.m +++ b/OpenStreetView/OSVVideoRecorder.m @@ -30,24 +30,23 @@ @interface OSVVideoRecorder() @implementation OSVVideoRecorder -- (instancetype)initWithVideoSize:(CMVideoDimensions)size encoding:(NSString *)encod bitrate:(NSInteger)bitrate { - self = [super init]; - if (self) { - self.size = size; - self.videoEncoding = encod; - self.bitrate = bitrate; - } - - return self; -} - +//- (instancetype)initWithVideoSize:(CMVideoDimensions)size encoding:(NSString *)encod bitrate:(NSInteger)bitrate { +// self = [super init]; +// if (self) { +// self.size = size; +// self.videoEncoding = encod; +// self.bitrate = bitrate; +// } +// +// return self; +//} - (instancetype)initWithVideoSize:(CMVideoDimensions)size { self = [super init]; if (self) { self.size = size; self.videoEncoding = AVVideoProfileLevelH264HighAutoLevel; - self.bitrate = 40000000; + self.bitrate = 80000000; } return self; @@ -60,10 +59,9 @@ - (BOOL)createRecordingWithURL:(NSURL *)url orientation:(AVCaptureVideoOrientati self.videoWriter = [[AVAssetWriter alloc] initWithURL:self.videoURL fileType:AVFileTypeMPEG4 error:&error]; NSParameterAssert(self.videoWriter); - NSDictionary *videoCompressionProps = [NSDictionary - dictionaryWithObjectsAndKeys: - [NSNumber numberWithInteger:self.bitrate], AVVideoAverageBitRateKey, // 40 Mbps - self.videoEncoding, AVVideoProfileLevelKey, // profiles... + NSDictionary *videoCompressionProps = [NSDictionary dictionaryWithObjectsAndKeys: + [NSNumber numberWithInteger:self.bitrate], AVVideoAverageBitRateKey, // 40 Mbps + self.videoEncoding, AVVideoProfileLevelKey, // profiles... nil]; CMVideoDimensions videoSize; @@ -76,18 +74,20 @@ - (BOOL)createRecordingWithURL:(NSURL *)url orientation:(AVCaptureVideoOrientati } NSDictionary *videoSettings = [NSDictionary dictionaryWithObjectsAndKeys: - AVVideoCodecH264, AVVideoCodecKey, - [NSNumber numberWithInt:videoSize.height], AVVideoHeightKey, - [NSNumber numberWithInt:videoSize.width], AVVideoWidthKey, - videoCompressionProps, AVVideoCompressionPropertiesKey, + AVVideoCodecH264, AVVideoCodecKey, + [NSNumber numberWithInt:videoSize.height], AVVideoHeightKey, + [NSNumber numberWithInt:videoSize.width], AVVideoWidthKey, + videoCompressionProps, AVVideoCompressionPropertiesKey, nil]; - self.videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo outputSettings:videoSettings]; + self.videoWriterInput = [AVAssetWriterInput assetWriterInputWithMediaType:AVMediaTypeVideo + outputSettings:videoSettings]; NSParameterAssert(self.videoWriterInput); self.videoWriterInput.expectsMediaDataInRealTime = YES; NSDictionary *bufferAttributes = [NSDictionary dictionaryWithObjectsAndKeys: - [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, nil]; + [NSNumber numberWithInt:kCVPixelFormatType_32BGRA], kCVPixelBufferPixelFormatTypeKey, + nil]; self.avAdaptor = [AVAssetWriterInputPixelBufferAdaptor assetWriterInputPixelBufferAdaptorWithAssetWriterInput:self.videoWriterInput sourcePixelBufferAttributes:bufferAttributes]; diff --git a/OpenStreetView/OpenStreetView-Bridging-Header.h b/OpenStreetView/OpenStreetView-Bridging-Header.h new file mode 100644 index 0000000..ac2abee --- /dev/null +++ b/OpenStreetView/OpenStreetView-Bridging-Header.h @@ -0,0 +1,22 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// + +#import "OSVServerSequence.h" +#import "OSVServerPhoto.h" +#import "OSVSequence.h" +#import "OSVMetadata.h" +#import "OSVScoreHistory.h" +#import "OSVPolyline.h" +#import "OSVSyncController.h" +#import "RLMScoreHistory.h" + +#import +#import +#import + +#import "OSVUtils.h" + +#import "NSAttributedString+Additions.h" +#import "NSMutableAttributedString+Additions.h" +#import "UIColor+OSVColor.h" diff --git a/OpenStreetView/OpenStreetViewRelease-Bridging-Header.h b/OpenStreetView/OpenStreetViewRelease-Bridging-Header.h new file mode 100644 index 0000000..c5940f5 --- /dev/null +++ b/OpenStreetView/OpenStreetViewRelease-Bridging-Header.h @@ -0,0 +1,20 @@ +// +// Use this file to import your target's public headers that you would like to expose to Swift. +// +#import "OSVServerSequence.h" +#import "OSVServerPhoto.h" +#import "OSVSequence.h" +#import "OSVMetadata.h" +#import "OSVScoreHistory.h" +#import "OSVPolyline.h" +#import "OSVSyncController.h" +#import "RLMScoreHistory.h" +#import +#import +#import + +#import "OSVUtils.h" + +#import "NSAttributedString+Additions.h" +#import "NSMutableAttributedString+Additions.h" +#import "UIColor+OSVColor.h" diff --git a/OpenStreetView/PortraitViewController.swift b/OpenStreetView/PortraitViewController.swift new file mode 100644 index 0000000..215b920 --- /dev/null +++ b/OpenStreetView/PortraitViewController.swift @@ -0,0 +1,30 @@ +// +// PortraitViewController.swift +// OpenStreetView +// +// Created by Bogdan Sala on 25/01/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +import UIKit + +class PortraitViewController: UIViewController,UIViewControllerTransitioningDelegate { + + override func viewDidLoad() { + super.viewDidLoad() + // Do any additional setup after loading the view. + } + + override func didReceiveMemoryWarning() { + super.didReceiveMemoryWarning() + // Dispose of any resources that can be recreated. + } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + override var supportedInterfaceOrientations: UIInterfaceOrientationMask { + return .portrait + } +} diff --git a/OpenStreetView/RLMScoreHistory.h b/OpenStreetView/RLMScoreHistory.h new file mode 100644 index 0000000..e0e6be5 --- /dev/null +++ b/OpenStreetView/RLMScoreHistory.h @@ -0,0 +1,22 @@ +// +// RLMScoreHistory.h +// OpenStreetView +// +// Created by Bogdan Sala on 21/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface RLMScoreHistory : RLMObject + +@property (nonatomic, strong) NSString *scoreHistoryID; + +@property (nonatomic, assign) NSInteger localSequenceID; + +@property (nonatomic, assign) NSInteger coverage; +@property (nonatomic, assign) NSInteger photos; +@property (nonatomic, assign) NSInteger photosWithOBD; +@property (nonatomic, assign) NSInteger detectedSigns; + +@end diff --git a/OpenStreetView/RLMScoreHistory.m b/OpenStreetView/RLMScoreHistory.m new file mode 100644 index 0000000..c286f55 --- /dev/null +++ b/OpenStreetView/RLMScoreHistory.m @@ -0,0 +1,17 @@ +// +// RLMScoreHistory.m +// OpenStreetView +// +// Created by Bogdan Sala on 21/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "RLMScoreHistory.h" + +@implementation RLMScoreHistory + ++ (NSString *)primaryKey { + return @"scoreHistoryID"; +} + +@end diff --git a/OpenStreetView/ScoreHistory.swift b/OpenStreetView/ScoreHistory.swift new file mode 100644 index 0000000..0441c62 --- /dev/null +++ b/OpenStreetView/ScoreHistory.swift @@ -0,0 +1,70 @@ +//// +//// ScoreHistory.swift +//// OpenStreetView +//// +//// Created by Bogdan Sala on 22/12/2016. +//// Copyright © 2016 Bogdan Sala. All rights reserved. +//// +// +//import Foundation +// +//@objc class ScoreHistory : NSObject { +// fileprivate var scoreHistoryID : String +// +// var localSequenceID : Int +// var photosWithOBD : Int +// var detectedSigns : Int +// var multiplier : Int +// var distance : Double +// var coverage : Int +// var photos : Int +// var points : Int +// +// override convenience init() { +// self.init(coverage:0, localSequenceID:0) +// } +// +// init(coverage:Int, localSequenceID:Int) { +// self.localSequenceID = localSequenceID +// self.coverage = coverage +// +// self.photos = 0 +// self.points = 0 +// +// self.scoreHistoryID = String(self.localSequenceID) + String(self.coverage) +// self.photosWithOBD = 0 +// self.detectedSigns = 0 +// self.multiplier = 1; +// self.distance = 0.0; +// +// super.init() +// } +//} +// +//extension ScoreHistory { +// +// func toRealmObject() -> RLMScoreHistory { +// let history = RLMScoreHistory(); +// history.scoreHistoryID = self.scoreHistoryID; +// history.localSequenceID = self.localSequenceID; +// history.coverage = self.coverage; +// history.photos = self.photos; +// history.photosWithOBD = self.photosWithOBD; +// history.detectedSigns = self.detectedSigns; +// +// return history; +// } +// +// class func fromRealmObject(historyObject:RLMScoreHistory) -> ScoreHistory { +// let history = ScoreHistory(); +// history.scoreHistoryID = historyObject.scoreHistoryID; +// history.localSequenceID = historyObject.localSequenceID; +// history.coverage = historyObject.coverage; +// history.photos = historyObject.photos; +// history.photosWithOBD = historyObject.photosWithOBD; +// history.detectedSigns = historyObject.detectedSigns; +// +// return history; +// +// } +//} diff --git a/OpenStreetView/ScoreManager.swift b/OpenStreetView/ScoreManager.swift new file mode 100644 index 0000000..eaa0a99 --- /dev/null +++ b/OpenStreetView/ScoreManager.swift @@ -0,0 +1,105 @@ +// +// ScoreManager.swift +// OpenStreetView +// +// Created by Bogdan Sala on 21/12/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +import Foundation + +@objc class ScoreManager: NSObject { + private static let coverageScore = [-1: 0.0, 0 : 10.0, 1 : 5.0, 2 : 5.0, 3 : 3.0, 4 : 3.0, 5 : 2.0, 6 : 2.0, 7 : 2.0, 8 : 2.0, 9 : 2.0, 10 : 1.0] + private var localSequenceID : Int + private var historyCoverage : Dictionary + + var score : Double + var multiplier : Double + + override init() { + self.localSequenceID = 0 + self.historyCoverage = Dictionary() + + self.score = 0 + self.multiplier = 1 + } + + func startHistorySession(forSequenceID:Int) -> Void { + self.localSequenceID = forSequenceID + self.resetMetrics() + } + + func stopHistorySession() -> Void { + self.resetMetrics() + } + + func detectedRoadSign(onSegment:OSVPolyline) -> Void { + let captCoverage = min(onSegment.coverage, 10) + if let coverageHistory = self.historyCoverage[captCoverage] { + coverageHistory.detectedSigns += 1; + } + + self.score += 1; + } + + func madePhoto(onSegment:OSVPolyline, withOBD:Bool) -> Void { + + let captCoverage = min(onSegment.coverage, 10) + let coverageHistory = self.historyCoverage[captCoverage]; + coverageHistory?.photos += 1; + coverageHistory?.photosWithOBD += withOBD ? 1 : 0; + + OSVSyncController.sharedInstance().tracksController.store(coverageHistory) + + if let photoScore = ScoreManager.coverageScore[captCoverage] { + self.multiplier = withOBD ? photoScore * 2.0 : photoScore + } else { + self.multiplier = 1 + } + + self.score += self.multiplier + } + + func madePhoto(withOBD:Bool) -> Void { + if let coverageHistory = self.historyCoverage[-1] { + coverageHistory.photos += 1; + coverageHistory.photosWithOBD += withOBD ? 1 : 0; + OSVSyncController.sharedInstance().tracksController.store(coverageHistory) + } + + self.score += 0; + } + + func updateMultiplier(onSegment:OSVPolyline, withOBD:Bool) -> Void { + let captCoverage = min(onSegment.coverage, 10) + + if let locationScore = ScoreManager.coverageScore[captCoverage] { + self.multiplier = withOBD ? locationScore * 2.0 : locationScore + } else { + self.multiplier = withOBD ? 1 * 2.0 : 1; + } + } + + func resetMetrics() -> Void { + self.score = 0; + + self.historyCoverage = Dictionary(); + + for coverage in -1...10 { + let history = OSVScoreHistory(forCoverage:coverage, withLocalSequenceID:self.localSequenceID) + if let photoScore = ScoreManager.coverageScore[coverage] { + history.multiplier = photoScore + } + self.historyCoverage[coverage] = history + } + } + + class func scoreFor(coverage:Int) -> Double { + if let photoScore = ScoreManager.coverageScore[coverage] { + return photoScore + } + + return 0.0; + } + +} diff --git a/OpenStreetView/SummaryViewController.swift b/OpenStreetView/SummaryViewController.swift new file mode 100644 index 0000000..21eeea1 --- /dev/null +++ b/OpenStreetView/SummaryViewController.swift @@ -0,0 +1,79 @@ +// +// SummaryViewController.swift +// OpenStreetView +// +// Created by Bogdan Sala on 16/01/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +import UIKit + +class SummaryViewController: UIViewController { + + var sequence: OSVSequence? + public var willDissmiss: (()->Void)? + + @IBOutlet weak var congratsTitle: UILabel! + + @IBOutlet weak var estimatedPointsLabel: UILabel! + @IBOutlet weak var estimatedPointsTitle: UILabel! + + @IBOutlet weak var diskSizeTitle: UILabel! + @IBOutlet weak var diskSizeLabel: UILabel! + + @IBOutlet weak var distanceCoveredTitle: UILabel! + @IBOutlet weak var distanceCoveredLabel: UILabel! + + @IBOutlet weak var imagesTakenTitle: UILabel! + @IBOutlet weak var imagesTakenLabel: UILabel! + + @IBOutlet weak var okButton: UIButton! + + override func viewDidLoad() { + super.viewDidLoad() + + congratsTitle.text = NSLocalizedString("Well done!", comment:"") + estimatedPointsTitle.attributedText = NSAttributedString.combineString("Points ", withSize:32, color:UIColor.init(hex:0x6e707b), fontName:"HelveticaNeue", with:"(estimated)", withSize:17, color:UIColor.init(hex:0x6e707b), fontName: "HelveticaNeue"); + + if let estimatePoints = sequence?.points { + estimatedPointsLabel.text = String(estimatePoints) + } else { + estimatedPointsLabel.text = "-" + } + + diskSizeTitle.text = NSLocalizedString("Disk size", comment: ""); + distanceCoveredLabel.text = "-" + DispatchQueue.main.async { + self.diskSizeLabel.text = OSVUtils.memoryFormatter(OSVSyncController.sizeOnDisk(for: self.sequence)) + } + distanceCoveredTitle.text = NSLocalizedString("Distance", comment: "") + if let distance = sequence?.length { + distanceCoveredLabel.text = OSVUtils.metricDistanceFormatter(Int(distance)) + } else { + distanceCoveredLabel.text = "-" + } + + imagesTakenTitle.text = NSLocalizedString("Photos", comment: "") + if let count = sequence?.photos.count { + imagesTakenLabel.text = String(count) + } else { + imagesTakenLabel.text = "-" + } + } + + override func viewWillDisappear(_ animated: Bool) { + if let callback = self.willDissmiss { + callback() + } + } + + override var preferredStatusBarStyle: UIStatusBarStyle { + return .lightContent + } + + @IBAction func didTapOkButton(_ sender: Any) { + self.dismiss(animated: true, completion: { + + }); + } +} diff --git a/OpenStreetView/ThirdParty/SideMenu/LGSideMenuController.m b/OpenStreetView/ThirdParty/SideMenu/LGSideMenuController.m index a7c18a7..7318c17 100755 --- a/OpenStreetView/ThirdParty/SideMenu/LGSideMenuController.m +++ b/OpenStreetView/ThirdParty/SideMenu/LGSideMenuController.m @@ -267,7 +267,7 @@ - (void)setupDefaults // ----- - _rootViewStyleView = [UIView new]; +// _rootViewStyleView = [UIView new]; _rootViewStyleView.hidden = YES; _rootViewStyleView.backgroundColor = [UIColor blackColor]; _rootViewStyleView.layer.masksToBounds = NO; diff --git a/OpenStreetView/UIDevice+Aditions.m b/OpenStreetView/UIDevice+Aditions.m index ba9a393..e99d1ef 100644 --- a/OpenStreetView/UIDevice+Aditions.m +++ b/OpenStreetView/UIDevice+Aditions.m @@ -52,6 +52,10 @@ + (NSString *)modelString { @"iPhone7,2" : @"iPhone6", @"iPhone8,1" : @"iPhone6S", @"iPhone8,2" : @"iPhone6SPlus", + @"iPhone9,1" : @"iPhone7", + @"iPhone9,3" : @"iPhone7", + @"iPhone9,2" : @"iPhone7Plus", + @"iPhone9,4" : @"iPhone7Plus", @"iPad1,1" : @"iPad", @"iPad2,1" : @"iPad2", @"iPad2,2" : @"iPad2", @@ -91,7 +95,7 @@ + (NSString *)modelString { deviceModel = [dictionary objectForKey:result]; if (!deviceModel) { - deviceModel = @"unknown"; + deviceModel = result; } }); diff --git a/OpenStreetView/UIView+Additions.h b/OpenStreetView/UIView+Additions.h index 24a3877..8835cb2 100644 --- a/OpenStreetView/UIView+Additions.h +++ b/OpenStreetView/UIView+Additions.h @@ -9,6 +9,7 @@ #import @interface UIView (Additions) + - (void)setColorPatternWithImageName:(NSString *)imageName; @end diff --git a/OpenStreetView/UIViewController+Additions.h b/OpenStreetView/UIViewController+Additions.h new file mode 100644 index 0000000..74106a8 --- /dev/null +++ b/OpenStreetView/UIViewController+Additions.h @@ -0,0 +1,15 @@ +// +// UIViewController+Additions.h +// OpenStreetView +// +// Created by Bogdan Sala on 01/02/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import + +@interface UIViewController (Additions) + ++ (void)addMapView:(UIView *)firstView toView:(UIView *)secView; + +@end diff --git a/OpenStreetView/UIViewController+Additions.m b/OpenStreetView/UIViewController+Additions.m new file mode 100644 index 0000000..bf80db7 --- /dev/null +++ b/OpenStreetView/UIViewController+Additions.m @@ -0,0 +1,117 @@ +// +// UIViewController+Additions.m +// OpenStreetView +// +// Created by Bogdan Sala on 01/02/2017. +// Copyright © 2017 Bogdan Sala. All rights reserved. +// + +#import "UIViewController+Additions.h" +#import "OSVUserDefaults.h" + +@implementation UIViewController (Additions) + ++ (void)addMapView:(UIView *)firstView toView:(UIView *)secView { + if ([OSVUserDefaults sharedInstance].enableMap) { + firstView.translatesAutoresizingMaskIntoConstraints = NO; + NSLayoutConstraint *trailing = [NSLayoutConstraint + constraintWithItem:firstView + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeTrailing + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *leading = [NSLayoutConstraint + constraintWithItem:firstView + attribute:NSLayoutAttributeLeading + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeLeading + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *bottom = [NSLayoutConstraint + constraintWithItem:firstView + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeBottom + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *top = [NSLayoutConstraint + constraintWithItem:firstView + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeTop + multiplier:1.0f + constant:0.f]; + [secView addSubview:firstView]; + + [secView addConstraints:@[trailing, leading, bottom, top]]; + } else { + UIImageView *imageView = [UIImageView new]; + imageView.image = [UIImage imageNamed:@"splashscreen_background"]; + imageView.translatesAutoresizingMaskIntoConstraints = NO; + + imageView.contentMode = UIViewContentModeScaleAspectFill; + UIImageView *logo = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"oSVLogoV1"]]; + logo.translatesAutoresizingMaskIntoConstraints = NO; + + [secView addSubview:imageView]; + [secView addSubview:logo]; + + NSLayoutConstraint *trailing = [NSLayoutConstraint + constraintWithItem:imageView + attribute:NSLayoutAttributeTrailing + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeTrailing + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *leading = [NSLayoutConstraint + constraintWithItem:imageView + attribute:NSLayoutAttributeLeading + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeLeading + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *bottom = [NSLayoutConstraint + constraintWithItem:imageView + attribute:NSLayoutAttributeBottom + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeBottom + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *top = [NSLayoutConstraint + constraintWithItem:imageView + attribute:NSLayoutAttributeTop + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeTop + multiplier:1.0f + constant:0.f]; + + NSLayoutConstraint *centerX = [NSLayoutConstraint + constraintWithItem:logo + attribute:NSLayoutAttributeCenterX + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeCenterX + multiplier:1.0f + constant:0.f]; + NSLayoutConstraint *centerY = [NSLayoutConstraint + constraintWithItem:logo + attribute:NSLayoutAttributeCenterY + relatedBy:NSLayoutRelationEqual + toItem:secView + attribute:NSLayoutAttributeCenterY + multiplier:1.0f + constant:0.f]; + [secView addConstraints:@[trailing,leading,bottom,top,centerX,centerY]]; + } +} + +@end diff --git a/OpenStreetView/ViewControllers/AVCamViewController.h b/OpenStreetView/ViewControllers/AVCamViewController.h index e2a286c..7eb72de 100644 --- a/OpenStreetView/ViewControllers/AVCamViewController.h +++ b/OpenStreetView/ViewControllers/AVCamViewController.h @@ -14,6 +14,12 @@ + (void)setFlashMode:(AVCaptureFlashMode)flashMode forDevice:(AVCaptureDevice *)device; -- (void)focusWithMode:(AVCaptureFocusMode)focusMode exposeWithMode:(AVCaptureExposureMode)exposureMode atDevicePoint:(CGPoint)point monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange; + +- (void)focusWithMode:(AVCaptureFocusMode)focusMode + exposeWithMode:(AVCaptureExposureMode)exposureMode + atDevicePoint:(CGPoint)point +monitorSubjectAreaChange:(BOOL)monitorSubjectAreaChange; + +- (void)animateFocusAtPoint:(CGPoint)point withGesture:(UIGestureRecognizer *)sender; @end diff --git a/OpenStreetView/ViewControllers/AVCamViewController.m b/OpenStreetView/ViewControllers/AVCamViewController.m index bcda54a..56098b7 100644 --- a/OpenStreetView/ViewControllers/AVCamViewController.m +++ b/OpenStreetView/ViewControllers/AVCamViewController.m @@ -2,16 +2,17 @@ #import "AVCamViewController.h" #import "AVCamPreviewView.h" #import "OSVUserDefaults.h" +#import "UIColor+OSVColor.h" -static void *CapturingStillImageContext = &CapturingStillImageContext; - -@interface AVCamViewController () +@interface AVCamViewController () // Session management. @property (nonatomic) dispatch_queue_t sessionQueue; // Communicate with the session and other session objects on this queue. @property (nonatomic) AVCaptureSession *session; @property (nonatomic) AVCaptureDeviceInput *videoDeviceInput; @property (nonatomic) AVCaptureStillImageOutput *stillImageOutput; +@property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput; + // Utilities. @property (nonatomic) UIBackgroundTaskIdentifier backgroundRecordingID; @property (nonatomic, readonly, getter = isSessionRunningAndDeviceAuthorized) BOOL sessionRunningAndDeviceAuthorized; @@ -60,13 +61,21 @@ - (void)viewDidLoad { [welf configureActiveFormat]; - AVCaptureStillImageOutput *stillImageOutput = [[AVCaptureStillImageOutput alloc] init]; - if ([session canAddOutput:stillImageOutput]) { - [stillImageOutput setOutputSettings:@{(id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}]; - [session addOutput:stillImageOutput]; - [self setStillImageOutput:stillImageOutput]; - } - + AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init] ; + [output setAlwaysDiscardsLateVideoFrames:YES]; + [output setVideoSettings:@{(id)kCVPixelBufferPixelFormatTypeKey:@(kCVPixelFormatType_32BGRA)}]; + + if ([self.session canAddOutput:output]) { + [self.session addOutput:output]; + self.videoOutput = output; + } + + AVCaptureConnection *avc = [welf.videoOutput connectionWithMediaType:AVMediaTypeVideo]; + if ([OSVUserDefaults sharedInstance].debugStabilization && avc.isVideoStabilizationSupported) { + avc.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeStandard; + } else { + avc.preferredVideoStabilizationMode = AVCaptureVideoStabilizationModeOff; + } }); } @@ -84,7 +93,6 @@ - (void)viewWillAppear:(BOOL)animated { if (dim.width != requestedDim.width && dim.height != requestedDim.height) { [welf configureActiveFormat]; } - [welf addObserver:welf forKeyPath:@"stillImageOutput.capturingStillImage" options:(NSKeyValueObservingOptionOld | NSKeyValueObservingOptionNew) context:CapturingStillImageContext]; [[NSNotificationCenter defaultCenter] addObserver:welf selector:@selector(subjectAreaDidChange:) name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[welf videoDeviceInput] device]]; [welf setRuntimeErrorHandlingObserver:[[NSNotificationCenter defaultCenter] addObserverForName:AVCaptureSessionRuntimeErrorNotification object:[welf session] queue:nil usingBlock:^(NSNotification *note) { @@ -106,8 +114,6 @@ - (void)viewDidDisappear:(BOOL)animated { [[NSNotificationCenter defaultCenter] removeObserver:self name:AVCaptureDeviceSubjectAreaDidChangeNotification object:[[self videoDeviceInput] device]]; [[NSNotificationCenter defaultCenter] removeObserver:[self runtimeErrorHandlingObserver]]; - - [self removeObserver:self forKeyPath:@"stillImageOutput.capturingStillImage" context:CapturingStillImageContext]; }); } @@ -132,18 +138,6 @@ - (UIInterfaceOrientationMask)supportedInterfaceOrientations { return UIInterfaceOrientationMaskAll; } -- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { - if (context == CapturingStillImageContext) { - BOOL isCapturingStillImage = [change[NSKeyValueChangeNewKey] boolValue]; - - if (isCapturingStillImage) { - [self runStillImageCaptureAnimation]; - } - } else { - [super observeValueForKeyPath:keyPath ofObject:object change:change context:context]; - } -} - #pragma mark Actions - (void)subjectAreaDidChange:(NSNotification *)notification { @@ -151,30 +145,47 @@ - (void)subjectAreaDidChange:(NSNotification *)notification { [self focusWithMode:AVCaptureFocusModeContinuousAutoFocus exposeWithMode:AVCaptureExposureModeContinuousAutoExposure atDevicePoint:devicePoint monitorSubjectAreaChange:NO]; } -#pragma mark File Output Delegate - -- (void)captureOutput:(AVCaptureFileOutput *)captureOutput didFinishRecordingToOutputFileAtURL:(NSURL *)outputFileURL fromConnections:(NSArray *)connections error:(NSError *)error { - if (error) { - NSLog(@"%@", error); +- (void)animateFocusAtPoint:(CGPoint)point withGesture:(UIGestureRecognizer *)sender { + + UIView *previousView = self.previewView.focusView; + if (previousView) { + [UIView animateWithDuration:0 animations:^{ + previousView.alpha = 0; + } completion:^(BOOL finished) { + [previousView removeFromSuperview]; + }]; + previousView = nil; } - - [self setLockInterfaceRotation:NO]; - - // Note the backgroundRecordingID for use in the ALAssetsLibrary completion handler to end the background task associated with this recording. This allows a new recording to be started, associated with a new UIBackgroundTaskIdentifier, once the movie file output's -isRecording is back to NO — which happens sometime after this method returns. - UIBackgroundTaskIdentifier backgroundRecordingID = [self backgroundRecordingID]; - [self setBackgroundRecordingID:UIBackgroundTaskInvalid]; - - [[[ALAssetsLibrary alloc] init] writeVideoAtPathToSavedPhotosAlbum:outputFileURL completionBlock:^(NSURL *assetURL, NSError *error) { - if (error) { - NSLog(@"%@", error); - } - - [[NSFileManager defaultManager] removeItemAtURL:outputFileURL error:nil]; - - if (backgroundRecordingID != UIBackgroundTaskInvalid) { - [[UIApplication sharedApplication] endBackgroundTask:backgroundRecordingID]; + + self.previewView.focusView = nil; + + UIView *aview = nil; + if (!self.previewView.focusView) { + aview = [[UIView alloc] initWithFrame:CGRectMake(point.x - 35, point.y - 35, 70, 70)]; + aview.center = point; + aview.layer.borderWidth = 3; + aview.layer.borderColor = [UIColor whiteColor].CGColor; + aview.layer.cornerRadius = aview.frame.size.width/2; + if ([sender isKindOfClass:[UILongPressGestureRecognizer class]]) { + UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake((aview.frame.size.width/2.0)-30, -30, 60, 30)]; + label.text = NSLocalizedString(@"Locked", @"Camera focus and exposure locked."); + label.textColor = [UIColor hex007AFF]; + aview.layer.borderColor = [UIColor hex007AFF].CGColor; + [aview addSubview:label]; } - }]; + [self.previewView addSubview:aview]; + + self.previewView.focusView = aview; + } + + if (![sender isKindOfClass:[UILongPressGestureRecognizer class]] || ([sender isKindOfClass:[UILongPressGestureRecognizer class]] && sender.state == UIGestureRecognizerStateEnded)) { + aview.alpha = 1; + [UIView animateWithDuration:1.5 animations:^{ + aview.alpha = 0; + } completion:^(BOOL finished) { + [aview removeFromSuperview]; + }]; + } } #pragma mark Device Configuration @@ -310,19 +321,6 @@ + (AVCaptureDevice *)deviceWithMediaType:(NSString *)mediaType preferringPositio #pragma mark UI -- (void)runStillImageCaptureAnimation { - dispatch_async(dispatch_get_main_queue(), ^{ - static SystemSoundID soundID = 0; - - if (soundID == 0) { - NSString *path = [[NSBundle mainBundle] pathForResource:@"photoShutter2" ofType:@"caf"]; - NSURL *filePath = [NSURL fileURLWithPath:path isDirectory:NO]; - AudioServicesCreateSystemSoundID((__bridge CFURLRef)filePath, &soundID); - } - AudioServicesPlaySystemSound(soundID); - }); -} - - (void)checkDeviceAuthorizationStatus { NSString *mediaType = AVMediaTypeVideo; diff --git a/OpenStreetView/ViewControllers/OSVCamViewController.h b/OpenStreetView/ViewControllers/OSVCamViewController.h index ac47490..f82ec63 100644 --- a/OpenStreetView/ViewControllers/OSVCamViewController.h +++ b/OpenStreetView/ViewControllers/OSVCamViewController.h @@ -8,6 +8,16 @@ #import "AVCamViewController.h" +@class SKMapView; + @interface OSVCamViewController : AVCamViewController +@property (weak, nonatomic) IBOutlet UILabel *sugestionLabel; +@property (weak, nonatomic) IBOutlet UIImageView *arrowImage; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *topSugestion; +@property (weak, nonatomic) IBOutlet NSLayoutConstraint *centerSugestion; + + +- (void)updateUIInfo; + @end diff --git a/OpenStreetView/ViewControllers/OSVCamViewController.m b/OpenStreetView/ViewControllers/OSVCamViewController.m index 10ee2c1..c6bce88 100644 --- a/OpenStreetView/ViewControllers/OSVCamViewController.m +++ b/OpenStreetView/ViewControllers/OSVCamViewController.m @@ -17,10 +17,13 @@ #import "OSVUserDefaults.h" #import "OSVLocationManager.h" #import "OSVUtils.h" +#import "UIDevice+Aditions.h" +#import "UIViewController+Additions.h" #import "OSVSequence.h" #import "OSVSyncController.h" +#import "OSVUser.h" #import "UIAlertView+Blocks.h" @@ -42,15 +45,24 @@ #import "NSMutableAttributedString+Additions.h" #import "NSAttributedString+Additions.h" +#import "OSVTrackMatcher.h" + +#import "OSVCameraGamificationManager.h" + +#import "OSC-Swift.h" + @interface OSVCamViewController () // Communicate with the session and other session objects on this queue. @property (nonatomic) dispatch_queue_t sessionQueue; @property (nonatomic) AVCaptureSession *session; @property (nonatomic) AVCaptureStillImageOutput *stillImageOutput; +@property (nonatomic, strong) AVCaptureVideoDataOutput *videoOutput; + //interface builder elements @property (weak, nonatomic) IBOutlet UIButton *startCapture; @property (weak, nonatomic) IBOutlet UIButton *cancelButton; +@property (weak, nonatomic) IBOutlet UIButton *infoButton; //OBD @property (weak, nonatomic) IBOutlet UILabel *obdSpeed; @property (weak, nonatomic) IBOutlet UIView *obdStatus; @@ -61,7 +73,6 @@ @interface OSVCamViewController () 1) { + shouldDissmissAll = array[1]; + } + [[OSVSyncController sharedInstance].tracksController getLocalSequenceWithID:[seqID integerValue] completion:^(OSVSequence *sequence) { + [[OSVSyncController sharedInstance].tracksController getScoreHistoryForSequenceWithID:sequence.uid completion:^(NSArray *history) { + sequence.scoreHistory = [history mutableCopy]; + sequence.points = 0; + for (OSVScoreHistory *sch in history) { + sequence.points += sch.points; + } + SummaryViewController *vc = segue.destinationViewController; + vc.sequence = sequence; + if ([shouldDissmissAll boolValue]) { + vc.willDissmiss = ^{ + [self dismissViewControllerAnimated:YES completion:^{ + + }]; + }; + } + }]; + }]; + } } #pragma mark - Actions @@ -201,14 +261,26 @@ - (IBAction)didLongPressOnPreview:(UILongPressGestureRecognizer *)sender { } - (IBAction)didTapOnInfoView:(id)sender { - CLLocation *localtion = [[CLLocation alloc] initWithCoordinate:[[SKPositionerService sharedInstance] currentCoordinate] altitude:0 horizontalAccuracy:0 verticalAccuracy:0 timestamp:[NSDate new]]; + CLLocation *localtion = [[CLLocation alloc] initWithCoordinate:[[OSVLocationManager sharedInstance] currentLocation].coordinate + altitude:0 + horizontalAccuracy:1000 + verticalAccuracy:1000 + timestamp:[NSDate new]]; [self.cameraManager makeStillCaptureWithLocation:localtion]; } -- (IBAction)didTapStartCapture:(id)sender { - if (!self.cameraManager.isSnapping) { +- (IBAction)didTapStartCapture:(UIButton *)sender { + if (!self.cameraManager.isRecording) { [self startNewSequence]; } else { + if (self.cameraManager.score > 10) { + sender.userInteractionEnabled = NO; + NSInteger sequenceID = self.cameraManager.currentSequence; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self performSegueWithIdentifier:@"showSummary" sender:@[@(sequenceID), @(NO)]]; + sender.userInteractionEnabled = YES; + }); + } [self stopSequence]; } } @@ -223,9 +295,9 @@ - (IBAction)didTapOnMap:(UIGestureRecognizer *)sender { } } completion:^(BOOL finished) { if (self.mapFullScreen) { - [self.topContainer insertSubview:self.mapView aboveSubview:self.previewView]; + [self.topContainer insertSubview:self.mapViewPlaceholder aboveSubview:self.previewView]; } else { - [self.topContainer insertSubview:self.previewView aboveSubview:self.mapView]; + [self.topContainer insertSubview:self.previewView aboveSubview:self.mapViewPlaceholder]; } self.mapFullScreen = !self.mapFullScreen; sender.enabled = YES; @@ -237,9 +309,10 @@ - (void)animateFullScreen { self.topMap.constant = -self.mapContainer.frame.origin.y; self.leadingMap.constant = -10; self.trailingMap.constant = self.topContainer.frame.size.width - CGRectGetMaxX(self.mapContainer.frame); + if (UIInterfaceOrientationIsPortrait([UIApplication sharedApplication].statusBarOrientation)) { self.bottomMap.constant = 10; - + self.bottomPreview.constant = 10; self.topPreview.constant = self.mapContainer.frame.origin.y; self.leadingPreview.constant = 10; @@ -253,8 +326,12 @@ - (void)animateFullScreen { self.trailingPreview.constant = self.topContainer.frame.size.width - CGRectGetMaxX(self.mapContainer.frame); } - self.mapView.frame = self.topContainer.frame; + self.mapViewPlaceholder.frame = self.topContainer.frame; + self.mapView.frame = self.topContainer.bounds; + self.previewView.frame = self.mapContainer.frame; + self.previewView.layer.cornerRadius = 3; + self.previewView.clipsToBounds = YES; } - (void)animateNormalSize { @@ -262,13 +339,16 @@ - (void)animateNormalSize { self.bottomMap.constant = 0; self.topMap.constant = 0; self.trailingMap.constant = 0; - self.mapView.frame = self.mapContainer.frame; + self.mapViewPlaceholder.frame = self.mapContainer.frame; + self.mapView.frame = self.mapContainer.bounds; self.topPreview.constant = 0; self.leadingPreview.constant = 0; self.trailingPreview.constant = 0; self.bottomPreview.constant = 0; self.previewView.frame = self.topContainer.frame; + self.previewView.layer.cornerRadius = 0; + self.previewView.clipsToBounds = NO; } - (void)startNewSequence { @@ -288,82 +368,56 @@ - (void)startNewSequence { self.infoView.alpha = 1; }]; - [self startNavigation]; + self.mapView.settings.followUserPosition = YES; if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorizedWhenInUse) { [self.cameraManager startHighResolutionCapure]; - [self.cameraManager startLowResolutionCapture]; [self updateUIInfo]; - [[OSVLocationManager sharedInstance].sensorsManager startLoggingSensors]; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingAccelerometer]; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingGyro]; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingMagnetometer]; - [[OSVLocationManager sharedInstance].sensorsManager startUpdatingAltitude]; + [[OSVSensorsManager sharedInstance] startAllSensors]; + + self.startCapture.selected = YES; + + [self.gamificationManager expandMultiplier]; - [self updateUIwithState:YES]; } else if ([CLLocationManager authorizationStatus] == kCLAuthorizationStatusNotDetermined) { - [[SKPositionerService sharedInstance] startLocationUpdate]; + [[OSVLocationManager sharedInstance] startLocationUpdate]; [[NSNotificationCenter defaultCenter ] addObserver:self selector:@selector(didChangeAuthorizationStatus:) name:@"didChangeAuthorizationStatus" object:nil]; } else { [UIAlertView showWithTitle:NSLocalizedString(@"No Location Services access", nil) message:NSLocalizedString(@"Please allow access to Location Services from Settings before starting a recording", @"") cancelButtonTitle:NSLocalizedString(@"Ok", nil) otherButtonTitles:nil tapBlock:^(UIAlertView *alertView, NSInteger buttonIndex) { - [self.navigationController popViewControllerAnimated:YES]; + [self dismissViewControllerAnimated:YES completion:^{ + + }]; }]; } } -- (void)resetValues { - [self.cameraManager resetValues]; - - [self updateUIInfo]; -} - -- (void)startNavigation { - self.mapView.settings.followUserPosition = YES; - - [SKPositionerService sharedInstance].positionerMode = SKPositionerModeRealPositions; - SKNavigationSettings *navSettings = [SKNavigationSettings new]; - navSettings.showStreetNamePopUpsOnRoute = YES; - navSettings.navigationType = SKNavigationTypeReal; - navSettings.transportMode = SKTransportCar; - - [[SKRoutingService sharedInstance] startNavigationWithSettings:navSettings]; -} - - (void)stopSequence { self.hadGPS = NO; self.hadOBD = NO; + [UIView animateWithDuration:0.3 animations:^{ self.infoView.alpha = 0; } completion:^(BOOL finished) { self.infoView.alpha = 0; }]; - - [[SKRoutingService sharedInstance] stopNavigation]; - NSLog(@"did finish navigation"); - [self.cameraManager stopHighResolutionCapture]; - [self.cameraManager stopLowResolutionCapture]; - [[OSVLocationManager sharedInstance].sensorsManager stopLoggingSensors]; - [[OSVLocationManager sharedInstance].sensorsManager stopUpdatingAccelerometer]; - [[OSVLocationManager sharedInstance].sensorsManager stopUpdatingGyro]; - [[OSVLocationManager sharedInstance].sensorsManager stopUpdatingMagnetometer]; - [[OSVLocationManager sharedInstance].sensorsManager stopUpdatingAltitude]; + [self.cameraManager stopHighResolutionCapture]; + [[OSVSensorsManager sharedInstance] stopAllSensors]; - [self updateUIwithState:NO]; -// [[NSNotificationCenter defaultCenter] postNotificationName:@"didFinishCreatingSequence" object:nil userInfo:@{@"sequenceID":@(self.currentSequence)}]; - - if ([OSVUserDefaults sharedInstance].automaticUpload && ([OSVReachablityController hasWiFiAccess] || ([OSVReachablityController hasCellularAcces] && [OSVUserDefaults sharedInstance].useCellularData))) { -// //TODO upload current sequence to server. - } + self.startCapture.selected = NO; [self resetValues]; + + [self.gamificationManager stopRecording]; } -- (void)updateUIwithState:(BOOL)value { - self.startCapture.selected = value; +- (void)resetValues { + [self.cameraManager resetValues]; + + [self updateUIInfo]; } - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { @@ -372,6 +426,8 @@ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id context) { if (self.mapFullScreen) { [self animateFullScreen]; @@ -382,8 +438,19 @@ - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id 10) { + NSInteger sequenceID = self.cameraManager.currentSequence; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.6 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self performSegueWithIdentifier:@"showSummary" sender:@[@(sequenceID),@(YES)]]; + }); + [self stopSequence]; + } else { + [self stopSequence]; + [self dismissViewControllerAnimated:YES + completion:^{}]; + } } - (BOOL)prefersStatusBarHidden { @@ -397,8 +464,8 @@ - (void)setDeviceAuthorized:(BOOL)deviceAuthorized { if (deviceAuthorized) { SKCoordinateRegion region; - region.zoomLevel = 12; - region.center = [SKPositionerService sharedInstance].currentCoordinate; + region.zoomLevel = [OSVUserDefaults sharedInstance].zoomLevel; + region.center = [OSVLocationManager sharedInstance].currentLocation.coordinate; self.mapView.visibleRegion = region; } } @@ -408,28 +475,32 @@ - (void)setDeviceAuthorized:(BOOL)deviceAuthorized { - (OSVTipView *)tipView { if (!_tipView) { _tipView = [[[NSBundle mainBundle] loadNibNamed:@"OSVTipView" owner:self options:nil] objectAtIndex:0]; + [_tipView configureViews]; } return _tipView; } - (void)updateUIInfo { - if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { - NSArray *metricArray = [OSVUtils metricDistanceArray:self.cameraManager.distanceCoverd]; - self.distanceLabel.attributedText = [NSAttributedString combineString:metricArray[0] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" - withString:metricArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; - } else { - NSArray *imperialArray = [OSVUtils imperialDistanceArray:self.cameraManager.distanceCoverd]; - self.distanceLabel.attributedText = [NSAttributedString combineString:imperialArray[0] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" - withString:imperialArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; - } - - self.photosCountLabel.attributedText = [NSAttributedString combineString:[@(self.cameraManager.frameCount) stringValue] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" - withString:@" IMG" withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; - - NSArray *memoryArray = [OSVUtils arrayFormatedFromByteCount:self.cameraManager.usedMemory]; - self.storageUsedLabel.attributedText = [NSAttributedString combineString:memoryArray[0] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" - withString:memoryArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; + dispatch_async(dispatch_get_main_queue(), ^{ + if ([[OSVUserDefaults sharedInstance].distanceUnitSystem isEqualToString:kMetricSystem]) { + NSArray *metricArray = [OSVUtils metricDistanceArray:self.cameraManager.distanceCoverd]; + self.distanceLabel.attributedText = [NSAttributedString combineString:metricArray[0] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + withString:metricArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; + } else { + NSArray *imperialArray = [OSVUtils imperialDistanceArray:self.cameraManager.distanceCoverd]; + self.distanceLabel.attributedText = [NSAttributedString combineString:imperialArray[0] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + withString:imperialArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; + } + + self.photosCountLabel.attributedText = [NSAttributedString combineString:[@(self.cameraManager.frameCount) stringValue] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + withString:@" IMG" withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; + + NSArray *memoryArray = [OSVUtils arrayFormatedFromByteCount:self.cameraManager.usedMemory]; + self.storageUsedLabel.attributedText = [NSAttributedString combineString:memoryArray[0] withSize:16.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" + withString:memoryArray[1] withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; + [self.gamificationManager updateUIInfo]; + }); } - (void)didChangeAuthorizationStatus:(NSNotification *)notification { @@ -444,47 +515,26 @@ - (void)didChangeAuthorizationStatus:(NSNotification *)notification { } } -- (void)animateFocusAtPoint:(CGPoint)point withGesture:(UIGestureRecognizer *)sender { - UIView *previousView = self.previewView.focusView; - if (previousView) { - [UIView animateWithDuration:0 animations:^{ - previousView.alpha = 0; - } completion:^(BOOL finished) { - [previousView removeFromSuperview]; - }]; - previousView = nil; - } - - self.previewView.focusView = nil; - - UIView *aview = nil; - if (!self.previewView.focusView) { - aview = [[UIView alloc] initWithFrame:CGRectMake(point.x - 35, point.y - 35, 70, 70)]; - aview.center = point; - aview.layer.borderWidth = 3; - aview.layer.borderColor = [UIColor whiteColor].CGColor; - aview.layer.cornerRadius = aview.frame.size.width/2; - if ([sender isKindOfClass:[UILongPressGestureRecognizer class]]) { - UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake((aview.frame.size.width/2.0)-30, -30, 60, 30)]; - label.text = @"Locked"; - label.textColor = [UIColor hex007AFF]; - aview.layer.borderColor = [UIColor hex007AFF].CGColor; - [aview addSubview:label]; - } - [self.previewView addSubview:aview]; - - self.previewView.focusView = aview; - } - - if (![sender isKindOfClass:[UILongPressGestureRecognizer class]] || ([sender isKindOfClass:[UILongPressGestureRecognizer class]] && sender.state == UIGestureRecognizerStateEnded)) { - NSLog(@"tap"); - aview.alpha = 1; - [UIView animateWithDuration:1.5 animations:^{ - aview.alpha = 0; - } completion:^(BOOL finished) { - [aview removeFromSuperview]; - }]; - } +- (void)animateInfoButton { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [UIView animateWithDuration:0.15 animations:^{ + self.infoButton.transform = CGAffineTransformMakeScale(1.2, 1.2); + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.2 animations:^{ + self.infoButton.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.15 animations:^{ + self.infoButton.transform = CGAffineTransformMakeScale(1.15, 1.15); + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.5 + delay:0.0 + usingSpringWithDamping:0.15 + initialSpringVelocity:0.2 + options:UIViewAnimationOptionCurveLinear + animations:^{ + self.infoButton.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) {}]; }]; }]; }]; + }); } #pragma mark - OSVCameraManagerDelegate @@ -526,7 +576,7 @@ - (void)didChangeOBDInfo:(double)value withError:(NSError *)error { } } -- (void)showOBD:(BOOL)value { +- (void)hideOBD:(BOOL)value { self.obdStatus.hidden = value; } diff --git a/OpenStreetView/ViewControllers/OSVCameraManager.h b/OpenStreetView/ViewControllers/OSVCameraManager.h index ad5af5a..1e1624f 100644 --- a/OpenStreetView/ViewControllers/OSVCameraManager.h +++ b/OpenStreetView/ViewControllers/OSVCameraManager.h @@ -11,6 +11,8 @@ #import @class CLLocation; +@class OSVCameraMapManager; +@class OSVTrackMatcher; @protocol OSVCameraManagerDelegate @@ -18,7 +20,7 @@ - (void)shouldDisplayTraficSign:(UIImage *)traficSign; - (void)didChangeGPSStatus:(UIImage *)gpsStatus; - (void)didChangeOBDInfo:(double)speed withError:(NSError *)error; -- (void)showOBD:(BOOL)value; +- (void)hideOBD:(BOOL)value; // TODO change naming to something more explicit - (void)didAddNewLocation:(CLLocation *)location; @@ -26,30 +28,36 @@ @end -@interface OSVCameraManager : NSObject +@interface OSVCameraManager : NSObject -@property (assign, nonatomic) BOOL isSnapping; +@property (assign, nonatomic) BOOL isRecording; @property (assign, atomic ) NSInteger frameCount; -@property (assign, nonatomic) NSInteger usedMemory; +@property (assign, nonatomic, readonly) NSInteger usedMemory; @property (assign, nonatomic) NSInteger distanceCoverd; @property (weak, nonatomic) id delegate; @property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundRenderingID; +@property (weak, nonatomic) OSVCameraMapManager *cameraMapManager; +@property (nonatomic, strong) OSVTrackMatcher *matcher; +@property (nonatomic, assign, readonly) NSInteger currentSequence; -- (instancetype)initWithOutput:(AVCaptureStillImageOutput *)stillOutput + +- (instancetype)initWithOutput:(AVCaptureVideoDataOutput *)stillOutput preview:(AVCaptureVideoPreviewLayer *)layer deviceFromat:(AVCaptureDeviceFormat *)deviceFormat queue:(dispatch_queue_t)sessionQueue; - (void)makeStillCaptureWithLocation:(CLLocation *)location; -- (void)startLowResolutionCapture; - (void)startHighResolutionCapure; -- (void)stopLowResolutionCapture; - (void)stopHighResolutionCapture; - (void)resetValues; - (void)badGPSHandling; +- (double)score; +- (double)multiplier; +- (BOOL)hasCoverage; + @end diff --git a/OpenStreetView/ViewControllers/OSVCameraManager.m b/OpenStreetView/ViewControllers/OSVCameraManager.m index 2b55dc6..5bda0e0 100644 --- a/OpenStreetView/ViewControllers/OSVCameraManager.m +++ b/OpenStreetView/ViewControllers/OSVCameraManager.m @@ -1,3 +1,4 @@ + // // OSVCameraManager.m // OpenStreetView @@ -12,6 +13,8 @@ #import "OSVVideoRecorder.h" #import "OSVSensorLibManager.h" +#import "OSVCameraMapManager.h" + #import "OSVLocationManager.h" #import @@ -20,10 +23,18 @@ #import "OSVLogger.h" #import "OSVSyncUtils.h" #import "OSVUtils.h" +#import "OSVLocalNotificationsController.h" #import "UIAlertView+Blocks.h" #import +#import + +#import "OSC-Swift.h" + +#import "OSVTrackMatcher.h" + +#define kMediumGPSQuality 40 @interface OSVCameraManager () @@ -50,20 +61,31 @@ @interface OSVCameraManager () [OSVUtils freeDiskSpaceBytes]) { - self.isSnapping = NO; + self.isRecording = NO; [self.delegate willStopCapturing]; return; } + self.lastPhotoLocation = photoLocation; + + self.shouldMakePhoto = YES; +} + +- (double)score { + return self.scoreManager.score; +} + +- (double)multiplier { + return self.scoreManager.multiplier; +} + +#pragma mark - AVCaptureVideoDataOutputSampleBufferDelegate + +- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection { __weak typeof(self) welf = self; - NSTimeInterval dateLocation = [[NSDate new] timeIntervalSince1970]; - dispatch_async([welf sessionQueue], ^{ - if (!welf.isSnapping) { - return; - } - // Update the orientation on the still image output video connection before capturing. - AVCaptureVideoOrientation orientation = [[welf.previewLayer connection] videoOrientation]; - [[welf.stillOutput connectionWithMediaType:AVMediaTypeVideo] setVideoOrientation:orientation]; - - AVCaptureConnection *connection = [welf.stillOutput connectionWithMediaType:AVMediaTypeVideo]; + CLLocation *location = welf.lastPhotoLocation; + + if (self.isHighFrequency) { + location = welf.currentLocation; + } + + if (location.coordinate.latitude == 0.0 || location.coordinate.longitude == 0.0) { + location = nil; + } + + if (self.isRecording && + (self.isHighFrequency || self.shouldMakePhoto) && + !self.isBussyRecording && + location) { - welf.stillImageRequests++; - // Capture a still image. - [welf.stillOutput captureStillImageAsynchronouslyFromConnection:connection - completionHandler:^(CMSampleBufferRef imageDataSampleBuffer, NSError *error) { - - if (error) { - welf.stillImageRequests--; - return; - } - - CVPixelBufferRef pixelsBuffer = CVPixelBufferRetain(CMSampleBufferGetImageBuffer(imageDataSampleBuffer)); - - NSInteger rotation = kRotate0DegreesClockwise; - if (orientation == AVCaptureVideoOrientationPortrait) { - rotation = kRotate90DegreesClockwise; - } if (orientation == AVCaptureVideoOrientationLandscapeLeft) { - rotation = kRotate180DegreesClockwise; - } else if (orientation == AVCaptureVideoOrientationLandscapeRight) { - rotation = kRotate0DegreesClockwise; - } - + self.isBussyRecording = YES; + self.shouldMakePhoto = NO; + AVCaptureVideoOrientation orientation = [[self.previewLayer connection] videoOrientation]; + NSTimeInterval dateLocation = [[NSDate new] timeIntervalSince1970]; + @autoreleasepool { + CVPixelBufferRef pixelsBuffer = CVPixelBufferRetain(CMSampleBufferGetImageBuffer(sampleBuffer)); + CFDictionaryRef dictionaryRef = (CFDictionaryRef)CMGetAttachment(sampleBuffer, kCGImagePropertyExifDictionary, NULL); + NSDictionary *currentListing = (__bridge NSDictionary *) dictionaryRef; + if (pixelsBuffer) { + + NSInteger rotation = kRotate0DegreesClockwise; + if (orientation == AVCaptureVideoOrientationPortrait) { + rotation = kRotate90DegreesClockwise; + } if (orientation == AVCaptureVideoOrientationLandscapeLeft) { + rotation = kRotate180DegreesClockwise; + } else if (orientation == AVCaptureVideoOrientationLandscapeRight) { + rotation = kRotate0DegreesClockwise; + } + [welf.videoRecorder addPixelBuffer:pixelsBuffer withRotation:rotation completion:^(BOOL success) { welf.isValidVideo = YES; OSVPhoto *photo = [OSVPhoto new]; - welf.stillImageRequests--; if (success) { photo.photoData = [OSVPhotoData new]; - photo.photoData.location = photoLocation; + photo.photoData.location = location; photo.photoData.timestamp = dateLocation; photo.photoData.sequenceIndex = welf.frameCount; photo.photoData.videoIndex = welf.videoIndex; photo.localSequenceId = welf.currentSequence; - photo.hasOBD = welf.hadOBD; + photo.hasOBD = welf.hasOBD; welf.frameCount++; - + OSVLogItem *item = [OSVLogItem new]; item.photodata = photo.photoData; - item.timestamp = photo.photoData.timestamp; - - [[OSVSyncController sharedInstance].tracksController savePhoto:photo withImageData:nil]; - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:welf.currentSequence]; - welf.distanceCoverd += welf.realDistance; + + [[OSVSyncController sharedInstance].tracksController savePhoto:photo]; + [[OSVSyncController sharedInstance].logger logItem:item]; + +// if (welf.frameCount == 1) { +// [[OSVSensorLibManager sharedInstance] createNewTrackWithInfo:currentListing trackID:welf.currentSequence]; +// } else { +// [[OSVSensorLibManager sharedInstance] addPhotoWithInfo:currentListing +// withFrameIndex:welf.frameCount]; +// } + + OSVTrackMatcher *matcher = welf.matcher; + if (!welf.matcher) { + matcher = welf.cameraMapManager.matcher; + } + + if (matcher.hasCoverage) { + OSVPolyline *polyline = [matcher nearestPolylineToLocation:location]; + [welf.scoreManager madePhotoOnSegment:polyline withOBD:welf.hasOBD]; + [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"madePhoto - coverage:%ld", polyline.coverage] withLevel:LogLevelDEBUG]; + } else { + [[OSVLogger sharedInstance] logMessage:@"madePhoto - missing coverage data" withLevel:LogLevelDEBUG]; + [welf.scoreManager madePhotoWithOBD:welf.hasOBD]; + } + [welf.delegate didReceiveUIUpdate]; } - + if (welf.backgroundRenderingID == UIBackgroundTaskInvalid && photo.photoData.sequenceIndex != 0 && (photo.photoData.sequenceIndex + 1) % 50 == 0) { welf.videoIndex++; [welf.videoRecorder completeRecordingSessionWithBlock:^(BOOL success, NSError *error) { - + if (!success) { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Failed to Write Video error:%@", error] withLevel:LogLevelDEBUG]; } - + AVCaptureVideoOrientation orientation = [[welf.previewLayer connection] videoOrientation]; - welf.usedMemory += [welf.videoRecorder currentVideoSize]; + welf.memoryUsedUntilNow += [welf.videoRecorder currentVideoSize]; - [welf.videoRecorder createRecordingWithURL:[welf fileNameForTrackID:welf.currentSequence videoID:welf.videoIndex] orientation:orientation]; + [welf.videoRecorder createRecordingWithURL:[OSVUtils fileNameForTrackID:welf.currentSequence videoID:welf.videoIndex] + orientation:orientation]; welf.isValidVideo = NO; + if (self.isHighFrequency) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(welf.frequency * NSEC_PER_SEC)), welf.sessionQueue, ^{ + welf.isBussyRecording = NO; + }); + } else { + welf.isBussyRecording = NO; + } }]; + } else { + if (self.isHighFrequency) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(welf.frequency * NSEC_PER_SEC)), welf.sessionQueue, ^{ + welf.isBussyRecording = NO; + }); + } else { + welf.isBussyRecording = NO; + } } }]; } else { - welf.stillImageRequests--; + if (self.isHighFrequency) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(welf.frequency * NSEC_PER_SEC)), welf.sessionQueue, ^{ + welf.isBussyRecording = NO; + }); + } else { + welf.isBussyRecording = NO; + } } CVPixelBufferRelease(pixelsBuffer); - }]; - }); -} - -- (void)lowResolutionCapure { - float interval = 0.25; -#ifdef ENABLED_DEBUG - interval = 1.0/[OSVUserDefaults sharedInstance].debugFrameRate; -#endif - - self.stillImageRequests = 0; - - if ([OSVUserDefaults sharedInstance].useImageRecognition) { - dispatch_queue_t timerQueue = dispatch_queue_create("timer queue",DISPATCH_QUEUE_SERIAL); - // Create dispatch source that submits the event handler block based on a timer. - self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, - 0, // unused - DISPATCH_TIMER_STRICT, - timerQueue); - // Set the event handler block for the timer dispatch source. - dispatch_source_set_event_handler(self.timer, ^{ - // This block will attempt to capture a new still image each time it is called. - // Captured requested number of images? - if (self.stillImageRequests >= MaxStillImageRequests) { - // Don't capture another image if the maximum - // number of outstanding still image requests has - // been exceeded. - } else { - self.stillImageRequests++; - AVCaptureConnection *connection = [self.stillOutput connectionWithMediaType:AVMediaTypeVideo]; - - [self.stillOutput captureStillImageAsynchronouslyFromConnection:connection - completionHandler:^(CMSampleBufferRef sampleBuffer, NSError *error) { - if (error) { - NSLog(@"erorare"); - self.stillImageRequests--; - } else if (sampleBuffer) { - NSLog(@"working"); - - NSTimeInterval curretTimeFrame = [[NSDate new] timeIntervalSince1970]; - if (self.previousTimeFrame == 0) { - self.previousTimeFrame = curretTimeFrame; - } - - NSTimeInterval dif = curretTimeFrame - self.previousTimeFrame; - self.previousTimeFrame = curretTimeFrame; - - AVCaptureVideoOrientation orientation = [[self.previewLayer connection] videoOrientation]; - NSInteger rotation = kRotate0DegreesClockwise; - if (orientation == AVCaptureVideoOrientationPortrait) { - rotation = kRotate90DegreesClockwise; - } if (orientation == AVCaptureVideoOrientationLandscapeLeft) { - rotation = kRotate180DegreesClockwise; - } else if (orientation == AVCaptureVideoOrientationLandscapeRight) { - rotation = kRotate0DegreesClockwise; - } - - if (![OSVUserDefaults sharedInstance].useImageRecognition) { - CVPixelBufferRef pixelsBuffer = CVPixelBufferRetain(CMSampleBufferGetImageBuffer(sampleBuffer)); - - [self.smallVideoRecorder addPixelBuffer:pixelsBuffer - withRotation:rotation - withDuration:CMTimeMake(dif*1000, 1000) - completion:^(BOOL success) { - NSLog(@"adding stuff %d", success); - }]; - CVPixelBufferRelease(pixelsBuffer); - self.stillImageRequests--; - } else { - [self.sensorLib speedLimitsFromSampleBuffer:sampleBuffer - withCompletion:^(NSArray *detections, CVImageBufferRef pixelsBuffer) { - - [self.smallVideoRecorder addPixelBuffer:pixelsBuffer - withRotation:rotation - withDuration:CMTimeMake(dif*1000, 1000) - completion:^(BOOL success) { - NSLog(@"adding stuff %d", success); - }]; - - UIImage *image = [self.sensorLib imageForSpeedLimit:detections.firstObject]; - if (image) { - dispatch_async(dispatch_get_main_queue(), ^{ - [self startDecayForSign]; - [self.delegate shouldDisplayTraficSign:image]; - }); - } - self.stillImageRequests--; - }]; - } - } else { - self.stillImageRequests--; - } - }]; - } - }); - - // Set timer start time and interval. - dispatch_source_set_timer(self.timer, - dispatch_time(DISPATCH_TIME_NOW, 0), // start time - interval * NSEC_PER_SEC, // interval - 0.001 * NSEC_PER_SEC); // leeway - dispatch_resume(self.timer); - } -} - -- (void)initSensorLib { - if ([OSVUserDefaults sharedInstance].useImageRecognition) { - NSLog(@"merge acuma"); - self.sensorLib = [OSVSensorLibManager sharedInstance]; - } -} - -- (NSURL *)fileNameForTrackID:(NSInteger)trackUID videoID:(NSInteger)videoUID { - NSString *folderPathString = [NSString stringWithFormat:@"%@%ld", [OSVSyncController sharedInstance].tracksController.basePathToPhotos, (long)trackUID]; - if (![[NSFileManager defaultManager] fileExistsAtPath:folderPathString]) { - NSError *error; - BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:folderPathString withIntermediateDirectories:NO attributes:NULL error:&error]; - if (!success) { - [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Failed to create folder for trackID:%ld error:%@", trackUID, error] withLevel:LogLevelDEBUG]; - success = [[NSFileManager defaultManager] createDirectoryAtPath:folderPathString withIntermediateDirectories:NO attributes:NULL error:&error]; - [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Retry to create folder with result:%d error:%@", success, error] withLevel:LogLevelDEBUG]; } } - return [NSURL fileURLWithPath:[folderPathString stringByAppendingString:[NSString stringWithFormat:@"/%ld.mp4", (long)videoUID]]]; -} - -- (NSURL *)fileNameForLowResTrackID:(NSInteger)trackUID videoID:(NSInteger)videoUID { - NSString *folderPathString = [NSString stringWithFormat:@"%@%ld", [OSVSyncController sharedInstance].tracksController.basePathToPhotos, (long)trackUID]; - if (![[NSFileManager defaultManager] fileExistsAtPath:folderPathString]) { - NSError *error; - BOOL success = [[NSFileManager defaultManager] createDirectoryAtPath:folderPathString withIntermediateDirectories:NO attributes:NULL error:&error]; - if (!success) { - [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Fail create folder trackID:%ld error:%@", trackUID, error] withLevel:LogLevelDEBUG]; - success = [[NSFileManager defaultManager] createDirectoryAtPath:folderPathString withIntermediateDirectories:NO attributes:NULL error:&error]; - [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Retry create folder error:%@ withResult:%d", error, success] withLevel:LogLevelDEBUG]; - } + if (!self.isBussyRecording && + [OSVUserDefaults sharedInstance].useImageRecognition && + !self.isBussyDetecting) { + + self.isBussyDetecting = YES; + [self.sensorLib speedLimitsFromSampleBuffer:sampleBuffer + withCompletion:^(NSArray *detections, CVImageBufferRef pixelsBuffer) { + + UIImage *image = [welf.sensorLib imageForSpeedLimit:detections.firstObject]; + if (image) { + dispatch_async(dispatch_get_main_queue(), ^{ + [welf startDecayForSign]; + [welf.delegate shouldDisplayTraficSign:image]; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.20 * NSEC_PER_SEC)), welf.sessionQueue, ^{ + welf.isBussyDetecting = NO; + }); + }); + } else { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.20 * NSEC_PER_SEC)), welf.sessionQueue, ^{ + welf.isBussyDetecting = NO; + }); + } + }]; } - - return [NSURL fileURLWithPath:[folderPathString stringByAppendingString:[NSString stringWithFormat:@"/%ld_low.mp4", (long)videoUID]]]; -} - -- (NSInteger)usedMemory { - return _usedMemory + [self.videoRecorder currentVideoSize] + [self.smallVideoRecorder currentVideoSize]; } #pragma mark - Location Manager -- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)newLocation { - self.currentLocation = [newLocation firstObject]; - - if (self.currentLocation.horizontalAccuracy < 0) { - [self badGPSHandling]; - } else { - if (self.currentLocation.horizontalAccuracy <= 15) { - [self.delegate didChangeGPSStatus:[UIImage imageNamed:@"gPSOK"]]; - self.hadGPS = YES; - [self.badGPSTimer invalidate]; - self.badGPSTimer = nil; - } else if (self.currentLocation.horizontalAccuracy <= 40) { - [self.delegate didChangeGPSStatus:[UIImage imageNamed:@"gPSMedium"]]; - self.hadGPS = YES; - [self.badGPSTimer invalidate]; - self.badGPSTimer = nil; - } else { - [self badGPSHandling]; +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)newLocationArray { + [self computeGPSQualityForLocation:[newLocationArray firstObject]]; + + if (!self.isRecording) { + OSVTrackMatcher *matcher = self.matcher; + if (!self.matcher) { + matcher = self.cameraMapManager.matcher; } - } - - if (!self.isSnapping) { + + if (matcher.hasCoverage) { + OSVPolyline *poly = [matcher nearestPolylineToLocation:[newLocationArray firstObject]]; + [self.scoreManager updateMultiplierOnSegment:poly withOBD:self.hasOBD]; + [self.delegate didReceiveUIUpdate]; + } + return; } - SKPosition matchedPosition = [SKPositionerService sharedInstance].currentMatchedPosition; - CLLocation *matchedLocation = [[CLLocation alloc] initWithLatitude:matchedPosition.latY longitude:matchedPosition.lonX]; + self.currentLocation = [newLocationArray firstObject]; + [self computeDistanceWithLocation:[newLocationArray firstObject]]; + + CLLocation *matchedLocation = [OSVLocationManager sharedInstance].currentMatchedPosition; [self.delegate didAddNewLocation:matchedLocation]; OSVLogItem *item = [OSVLogItem new]; item.location = self.currentLocation; - [[OSVSyncController sharedInstance].logger logItems:@[item] inFileForSequenceID:0]; + [[OSVSyncController sharedInstance].logger logItem:item]; if (!self.lastPhotoLocation || (self.lastPhotoLocation.coordinate.latitude == 0 && self.lastPhotoLocation.coordinate.longitude == 0)) { self.lastPhotoLocation = self.currentLocation; @@ -483,14 +419,35 @@ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray double distance = [self.lastPhotoLocation distanceFromLocation:self.currentLocation]; - self.distanceBetweenPhotos = [self distanceBetweenPhotosWithLocation:self.lastPhotoLocation nextLocation:self.currentLocation]; + self.distanceBetweenPhotos = [self distanceBetweenPhotosWithLocation:self.lastPhotoLocation + nextLocation:self.currentLocation]; if (self.distanceBetweenPhotos > 0 && distance >= self.distanceBetweenPhotos) { - self.realDistance = distance; if (self.currentOBDSpeed < 0) { self.lastPhotoLocation = self.currentLocation; [self makeStillCaptureWithLocation:self.currentLocation]; - NSLog(@"made snap with normal"); + } + } + + [self.matcher getTracks]; +} + +- (void)computeGPSQualityForLocation:(CLLocation *)newLocation { + if (newLocation.horizontalAccuracy < 0) { + [self badGPSHandling]; + } else { + if (newLocation.horizontalAccuracy <= 15) { + [self.delegate didChangeGPSStatus:[UIImage imageNamed:@"gPSOK"]]; + self.hadGPS = YES; + [self.badGPSTimer invalidate]; + self.badGPSTimer = nil; + } else if (newLocation.horizontalAccuracy <= kMediumGPSQuality) { + [self.delegate didChangeGPSStatus:[UIImage imageNamed:@"gPSMedium"]]; + self.hadGPS = YES; + [self.badGPSTimer invalidate]; + self.badGPSTimer = nil; + } else { + [self badGPSHandling]; } } } @@ -498,7 +455,9 @@ - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray - (void)badGPSHandling { [self.delegate didChangeGPSStatus:[UIImage imageNamed:@"gPSLow"]]; - if (self.hadOBD && !(self.currentOBDSpeed < 0)) { + if (!self.isRecording && + self.hadOBD && + !(self.currentOBDSpeed < 0)) { return; } @@ -509,86 +468,31 @@ - (void)badGPSHandling { } } -- (void)shouldRemoveCurrentSign { - [self.timerSign invalidate]; - self.timerSign = nil; - [self.delegate shouldDisplayTraficSign:nil]; -} - - (void)badGPSShapshot { - NSLog(@"made snap with bad"); if (!self.lastPhotoLocation) { - CLLocation *localtion = [[CLLocation alloc] initWithCoordinate:[[SKPositionerService sharedInstance] currentCoordinate] altitude:0 horizontalAccuracy:1000 verticalAccuracy:0 timestamp:[NSDate new]]; + CLLocation *localtion = [[CLLocation alloc] initWithCoordinate:[[OSVLocationManager sharedInstance] currentLocation].coordinate + altitude:0 + horizontalAccuracy:1000 + verticalAccuracy:0 + timestamp:[NSDate new]]; [self makeStillCaptureWithLocation:localtion]; } else { - [self makeStillCaptureWithLocation:[[CLLocation alloc] initWithCoordinate:self.lastPhotoLocation.coordinate altitude:0 horizontalAccuracy:1000 verticalAccuracy:0 timestamp:[NSDate new]]]; - } -} - -- (void)startDecayForSign { - [self.timerSign invalidate]; - self.timerSign = nil; - self.timerSign = [NSTimer scheduledTimerWithTimeInterval:2 target:self - selector:@selector(shouldRemoveCurrentSign) - userInfo:nil - repeats:YES]; -} - -/* - http://jira.telenav.com:8080/browse/OSV-9 - */ -- (NSInteger)distanceBetweenPhotosWithLocation:(CLLocation *)start nextLocation:(CLLocation *)destination { - - if (start == nil || destination == nil) { - return 0; - } - - BOOL startInvalid = start.horizontalAccuracy < 0; - BOOL startLowQuality = start.horizontalAccuracy > 20; - - BOOL destinationInvalid = destination.horizontalAccuracy < 0; - BOOL destinationLowQuality = destination.horizontalAccuracy > 20; - - if ((startInvalid || startLowQuality) && (destinationInvalid || destinationLowQuality)) { - return 0; - } - - startInvalid = start.speed < 0; - destinationInvalid = destination.speed < 0; - - if (startInvalid && destinationInvalid) { - return 0; - } - - if (destinationInvalid) { - return [self distanceBasedOnSpeed:start.speed]; + [self makeStillCaptureWithLocation:[[CLLocation alloc] initWithCoordinate:self.lastPhotoLocation.coordinate + altitude:0 + horizontalAccuracy:1000 + verticalAccuracy:0 + timestamp:[NSDate new]]]; } - - return [self distanceBasedOnSpeed:destination.speed]; -} - -- (NSInteger)distanceBasedOnSpeed:(CLLocationSpeed)speed { - double KmPerHourSpeed = speed * 3.6; - - NSArray *allIntervals = self.speedIntevals.allKeys; - - for (int i = 0; i < allIntervals.count; i++) { - NSArray *interval = allIntervals[i]; - if ([interval[0] doubleValue] < KmPerHourSpeed && KmPerHourSpeed < [interval[1] doubleValue]) { - return [self.speedIntevals[interval] integerValue]; - } - } - - return 0; } #pragma mark - UIApplication Notifications - (void)willEnterForgroundNotification:(NSNotification *)notification { - if (self.isSnapping) { + if (self.isRecording) { self.backgroundRenderingID = UIBackgroundTaskInvalid; AVCaptureVideoOrientation orientation = [[self.previewLayer connection] videoOrientation]; - [self.videoRecorder createRecordingWithURL:[self fileNameForTrackID:self.currentSequence videoID:self.videoIndex] orientation:orientation]; + [self.videoRecorder createRecordingWithURL:[OSVUtils fileNameForTrackID:self.currentSequence videoID:self.videoIndex] + orientation:orientation]; self.isValidVideo = NO; } } @@ -608,16 +512,25 @@ - (void)willEnterBackgroundNotification:(NSNotification *)notificaiton { [[OSVLogger sharedInstance] logMessage:[NSString stringWithFormat:@"Failed to Write Video error:%@", error] withLevel:LogLevelDEBUG]; } - self.usedMemory += [self.videoRecorder currentVideoSize]; + self.memoryUsedUntilNow += [self.videoRecorder currentVideoSize]; [[UIApplication sharedApplication] endBackgroundTask:self.backgroundRenderingID]; }]; } } -#pragma mark - SensorManager +#pragma mark - SensorLibManager + +- (void)initSensorLib { + if ([OSVUserDefaults sharedInstance].useImageRecognition) { + self.sensorLib = [OSVSensorLibManager sharedInstance]; + } +} + +#pragma mark - OSVOBDController Notifications - (void)manager:(OSVSensorsManager *)manager didUpdateOBDData:(OSVOBDData *)data withError:(NSError *)error { self.hadOBD = YES; + self.hasOBD = YES; if (!error) { [self.badGPSTimer invalidate]; @@ -646,37 +559,98 @@ - (void)manager:(OSVSensorsManager *)manager didUpdateOBDData:(OSVOBDData *)data } } -#pragma mark - OSVOBDController Notifications - - (void)managerDidConnectToOBD:(OSVSensorsManager *)manager { dispatch_async(dispatch_get_main_queue(), ^{ - [self.delegate showOBD:NO]; + [self.delegate hideOBD:NO]; }); self.hadOBD = YES; } - (void)managerDidDisconnectFromOBD:(OSVSensorsManager *)manager { - if (self.isSnapping) { - [[OSVLocationManager sharedInstance].sensorsManager reconnectOBD]; + if (self.isRecording) { + [[OSVSensorsManager sharedInstance] reconnectOBD]; } self.currentOBDSpeed = -1; + self.hasOBD = NO; + dispatch_async(dispatch_get_main_queue(), ^{ - [self.delegate showOBD:YES]; + [self.delegate hideOBD:YES]; }); } - (void)managerDidFailToConnectODB:(OSVSensorsManager *)manager { self.currentOBDSpeed = -1; + self.hasOBD = NO; + dispatch_async(dispatch_get_main_queue(), ^{ - [self.delegate showOBD:YES]; + [self.delegate hideOBD:YES]; }); } -#pragma mark - Private +#pragma mark - Private + +- (void)computeDistanceWithLocation:(CLLocation *)location { + if (location.horizontalAccuracy < 0) { + return; + } + + if (!self.lastDistanceLocation || (self.lastDistanceLocation.coordinate.latitude == 0 && self.lastDistanceLocation.coordinate.longitude == 0)) { + self.lastDistanceLocation = location; + } + + CLLocationDistance distance = [self.lastDistanceLocation distanceFromLocation:location]; + if (distance > 10) { + self.distanceCoverd += distance; + self.lastDistanceLocation = location; + } +} + +- (void)shouldRemoveCurrentSign { + [self.timerSign invalidate]; + self.timerSign = nil; + [self.delegate shouldDisplayTraficSign:nil]; +} + +- (void)startDecayForSign { + [self.timerSign invalidate]; + self.timerSign = nil; + self.timerSign = [NSTimer scheduledTimerWithTimeInterval:2 target:self + selector:@selector(shouldRemoveCurrentSign) + userInfo:nil + repeats:YES]; +} + +- (NSInteger)usedMemory { + return self.memoryUsedUntilNow + [self.videoRecorder currentVideoSize]; +} + +- (BOOL)hasCoverage { + return self.cameraMapManager.matcher.hasCoverage || self.matcher.hasCoverage; +} + +#pragma mark - Helpers + +- (void)didLoadNewTracks { + if (!self.isRecording) { + OSVTrackMatcher *matcher = self.matcher; + if (!self.matcher) { + matcher = self.cameraMapManager.matcher; + } + + CLLocation *location = [[OSVLocationManager sharedInstance] currentLocation]; + if (matcher.hasCoverage && + (location.coordinate.latitude != 0.0 && location.coordinate.longitude != 0.0)) { + + OSVPolyline *poly = [matcher nearestPolylineToLocation:location]; + [self.scoreManager updateMultiplierOnSegment:poly withOBD:self.hasOBD]; + [self.delegate didReceiveUIUpdate]; + } + } +} - (void)addObservers { @@ -686,6 +660,56 @@ - (void)addObservers { [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managerDidConnectToOBD:) name:@"kOBDDidConnect" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managerDidDisconnectFromOBD:) name:@"kOBDDidDisconnect" object:nil]; [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(managerDidFailToConnectODB:) name:@"kOBDFailedToConnectInTime" object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didLoadNewTracks) name:@"kdidLoadNewBox" object:nil]; + +} + +/* + http://jira.telenav.com:8080/browse/OSV-9 + */ +- (NSInteger)distanceBetweenPhotosWithLocation:(CLLocation *)start nextLocation:(CLLocation *)destination { + + if (start == nil || destination == nil) { + return 0; + } + + BOOL startInvalid = start.horizontalAccuracy < 0; + BOOL startLowQuality = start.horizontalAccuracy > kMediumGPSQuality; + + BOOL destinationInvalid = destination.horizontalAccuracy < 0; + BOOL destinationLowQuality = destination.horizontalAccuracy > kMediumGPSQuality; + + if ((startInvalid || startLowQuality) && (destinationInvalid || destinationLowQuality)) { + return 0; + } + + startInvalid = start.speed < 0; + destinationInvalid = destination.speed < 0; + + if (startInvalid && destinationInvalid) { + return 0; + } + + if (destinationInvalid) { + return [self distanceBasedOnSpeed:start.speed]; + } + + return [self distanceBasedOnSpeed:destination.speed]; +} + +- (NSInteger)distanceBasedOnSpeed:(CLLocationSpeed)speed { + double KmPerHourSpeed = speed * 3.6; + + NSArray *allIntervals = self.speedIntevals.allKeys; + + for (int i = 0; i < allIntervals.count; i++) { + NSArray *interval = allIntervals[i]; + if ([interval[0] doubleValue] < KmPerHourSpeed && KmPerHourSpeed < [interval[1] doubleValue]) { + return [self.speedIntevals[interval] integerValue]; + } + } + + return 0; } @end diff --git a/OpenStreetView/ViewControllers/OSVLayersViewController.m b/OpenStreetView/ViewControllers/OSVLayersViewController.m index ad7a09b..32785af 100644 --- a/OpenStreetView/ViewControllers/OSVLayersViewController.m +++ b/OpenStreetView/ViewControllers/OSVLayersViewController.m @@ -75,14 +75,18 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } } +- (UIStatusBarStyle)preferredStatusBarStyle { + return UIStatusBarStyleLightContent; +} + #pragma mark - Orientation - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } #pragma mark - UITableViewDatasource @@ -98,6 +102,12 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N OSVTrackCell *trackCell = [tableView dequeueReusableCellWithIdentifier:@"layerCell"]; [[OSVSyncController sharedInstance].tracksController loadPreviewForTrack:track intoImageView:trackCell.previewImage withCompletion:^(UIImage *image, NSError *error) { dispatch_async(dispatch_get_main_queue(), ^{ + float x = image.size.height / image.size.width; + if (fabs(x - 4.0/3.0) > 0.1 && fabs(x - 3.0/4.0) > 0.1) { + trackCell.previewImage.contentMode = UIViewContentModeScaleAspectFill; + } else { + trackCell.previewImage.contentMode = UIViewContentModeScaleAspectFit; + } trackCell.previewImage.image = image; }); }]; @@ -122,6 +132,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N trackCell.dateLabel.attributedText = [NSAttributedString combineString:dString withSize:12.f color:[UIColor whiteColor] fontName:@"HelveticaNeue" withString:hString withSize:12.f color:[UIColor colorWithHex:0x6e707b] fontName:@"HelveticaNeue"]; + trackCell.locationLabel.text = @"-"; if ((!track.location || [track.location isEqualToString:@""])) { CLLocation *location = [[CLLocation alloc] initWithLatitude:track.coordinate.latitude longitude:track.coordinate.longitude] ; @@ -135,8 +146,10 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N CLPlacemark *placemark = placemarks[0]; NSArray *lines = placemark.addressDictionary[@"FormattedAddressLines"]; NSString *addressString = [lines componentsJoinedByString:@","]; - track.location = addressString; - trackCell.locationLabel.text = addressString; + if (!addressString || [addressString isEqualToString:@""]) { + track.location = addressString; + trackCell.locationLabel.text = addressString; + } } [woperation asyncTaskDone]; }]; diff --git a/OpenStreetView/ViewControllers/OSVLeaderboardViewController.h b/OpenStreetView/ViewControllers/OSVLeaderboardViewController.h new file mode 100644 index 0000000..cd60349 --- /dev/null +++ b/OpenStreetView/ViewControllers/OSVLeaderboardViewController.h @@ -0,0 +1,13 @@ +// +// OSVLeaderboardViewController.h +// OpenStreetView +// +// Created by Bogdan Sala on 16/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVLeaderboardViewController : UIViewController + +@end diff --git a/OpenStreetView/ViewControllers/OSVLeaderboardViewController.m b/OpenStreetView/ViewControllers/OSVLeaderboardViewController.m new file mode 100644 index 0000000..23881ba --- /dev/null +++ b/OpenStreetView/ViewControllers/OSVLeaderboardViewController.m @@ -0,0 +1,258 @@ +// +// OSVLeaderboardViewController.m +// OpenStreetView +// +// Created by Bogdan Sala on 16/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVLeaderboardViewController.h" +#import "OSVSyncController.h" +#import "OSVUser.h" + +#import "OSVRankHeaderCell.h" +#import "OSVRankCell.h" +#import "UIColor+OSVColor.h" +#import "OSVUtils.h" +#import "OSVUnderlineButton.h" + +#import "OSVSyncController.h" + +@interface OSVLeaderboardViewController () + +@property (strong, nonatomic) UIColor *previousBarTintColor; +@property (strong, nonatomic) UIImage *previousShadowImage; +@property (strong, nonatomic) UIImage *previousBackgroundImage; + +@property (nonatomic, strong) NSArray *datasource; +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property (nonatomic, strong) NSArray *tableViewColors; + +@property (weak, nonatomic) IBOutlet OSVUnderlineButton *usRegionButton; +@property (weak, nonatomic) IBOutlet OSVUnderlineButton *allWorldRegionButton; + +@property (weak, nonatomic) IBOutlet UIButton *leaderboardTitle; +@property (weak, nonatomic) IBOutlet UILabel *timePeriodTitle; + +@property (strong, nonatomic) NSArray *timePeriods; +@property (assign, nonatomic) NSInteger timePeriodIndex; +@property (weak, nonatomic) IBOutlet UILabel *allWorldNoLogin; + +@property (strong, nonatomic) id currentUser; +@end + +@implementation OSVLeaderboardViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + self.tableViewColors = @[[UIColor whiteColor], [UIColor colorWithHex:0xf8f8fa]]; + self.timePeriodIndex = 0; + self.timePeriods = @[NSLocalizedString(@"All Time", @""), + NSLocalizedString(@"This Month", @""), + NSLocalizedString(@"This Week", @""), + NSLocalizedString(@"Today", @"")]; + self.timePeriodTitle.text = self.timePeriods[self.timePeriodIndex]; + + + self.allWorldRegionButton.backgroundColor = [UIColor colorWithHex:0x1daa63]; + self.allWorldRegionButton.selected = YES; + self.currentUser = [OSVSyncController sharedInstance].tracksController.oscUser; + + self.usRegionButton.backgroundColor = [UIColor colorWithHex:0x1daa63]; + + if (![OSVSyncController sharedInstance].tracksController.userIsLoggedIn) { + self.allWorldRegionButton.selected = NO; + self.allWorldRegionButton.userInteractionEnabled = NO; + [self.allWorldRegionButton setTitle:@"" forState:UIControlStateNormal]; + + self.usRegionButton.selected = NO; + self.usRegionButton.userInteractionEnabled = NO; + [self.usRegionButton setTitle:@"" forState:UIControlStateNormal]; + + self.allWorldNoLogin.hidden = NO; + } + + [self reloadGameLeaderboard]; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:animated]; + [self setNeedsStatusBarAppearanceUpdate]; + self.previousBarTintColor = self.navigationController.navigationBar.barTintColor; + self.previousShadowImage = self.navigationController.navigationBar.shadowImage; + self.previousBackgroundImage = [self.navigationController.navigationBar backgroundImageForBarMetrics:UIBarMetricsDefault]; + + self.navigationController.navigationBar.barTintColor = [UIColor colorWithHex:0x1daa63]; + self.navigationController.navigationBar.translucent = NO; + self.navigationController.navigationBar.shadowImage = [UIImage new]; + [self.navigationController.navigationBar setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; + + [self.leaderboardTitle setTitle:NSLocalizedString(@"Leaderboard", @"") forState:UIControlStateNormal]; +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + self.navigationController.navigationBar.barTintColor = self.previousBarTintColor; + self.navigationController.navigationBar.shadowImage = self.previousShadowImage; + [self.navigationController.navigationBar setBackgroundImage:self.previousBackgroundImage forBarMetrics:UIBarMetricsDefault]; +} + +- (UIStatusBarStyle)preferredStatusBarStyle { + return UIStatusBarStyleLightContent; +} + +#pragma mark - UITableViewDatasource + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + return self.datasource.count; +} + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + OSVRankCell *rankCell = [tableView dequeueReusableCellWithIdentifier:@"rankCell"]; + rankCell.rank.text = [@(indexPath.row + 1) stringValue]; + rankCell.name.text = self.datasource[indexPath.row].name; + rankCell.points.text = [NSString stringWithFormat:@"%@", [OSVUtils pointsFormatedFromPoints:(NSInteger)self.datasource[indexPath.row].gameInfo.totalPoints]]; + + BOOL isLoggedin = [self.currentUser.name isEqualToString:self.datasource[indexPath.row].name]; + if (isLoggedin) { + rankCell.rank.textColor = [UIColor whiteColor]; + rankCell.name.textColor = [UIColor whiteColor]; + rankCell.points.textColor = [UIColor whiteColor]; + rankCell.backgroundColor = [UIColor colorWithHex:0x1daa63]; + } else { + rankCell.rank.textColor = [UIColor blackColor]; + rankCell.name.textColor = [UIColor blackColor]; + rankCell.points.textColor = [UIColor blackColor]; + rankCell.backgroundColor = self.tableViewColors[indexPath.row % self.tableViewColors.count]; + } + + return rankCell; +} + +#pragma mark - Actions + +- (IBAction)didTapBackButton:(id)sender { + [self.navigationController popViewControllerAnimated:YES]; +} + +- (IBAction)didTapAllWorld:(UIButton *)sender { + sender.selected = YES; + self.usRegionButton.selected = NO; + [self reloadGameLeaderboard]; +} + +- (IBAction)didTapUS:(UIButton *)sender { + sender.selected = YES; + self.allWorldRegionButton.selected = NO; + [self reloadGameLeaderboard]; +} + +- (IBAction)didTapLeftTime:(id)sender { + NSInteger prevValue = self.timePeriodIndex; + + self.timePeriodIndex = MAX(self.timePeriodIndex - 1, 0); + self.timePeriodTitle.text = self.timePeriods[self.timePeriodIndex]; + + if (prevValue != self.timePeriodIndex) { + [self reloadGameLeaderboard]; + } +} + +- (IBAction)didTapRightTime:(id)sender { + NSInteger prevValue = self.timePeriodIndex; + + self.timePeriodIndex = MIN(self.timePeriodIndex + 1, self.timePeriods.count - 1); + self.timePeriodTitle.text = self.timePeriods[self.timePeriodIndex]; + + if (prevValue != self.timePeriodIndex) { + [self reloadGameLeaderboard]; + } +} + +#pragma mark - Private + +- (void)reloadGameLeaderboard { + BOOL allWorldRegion = self.allWorldRegionButton.selected; + NSString *region = nil; + + if (!allWorldRegion && self.currentUser.gameInfo) { + region = self.currentUser.gameInfo.regionCode; + } + + NSDate *date = nil; + switch (self.timePeriodIndex) { + case 1: { + NSCalendar *cal = [NSCalendar currentCalendar]; + NSDate *now = [NSDate date]; + NSDate *startOfTheMonth; + NSTimeInterval interval; + [cal rangeOfUnit:NSCalendarUnitMonth + startDate:&startOfTheMonth + interval:&interval + forDate:now]; + date = startOfTheMonth; + } + break; + case 2: { + NSCalendar *cal = [NSCalendar currentCalendar]; + NSDate *now = [NSDate date]; + NSDate *startOfTheWeek; + NSTimeInterval interval; + [cal rangeOfUnit:NSCalendarUnitWeekOfMonth + startDate:&startOfTheWeek + interval:&interval + forDate:now]; + date = startOfTheWeek; + } + break; + case 3: + date = [NSDate new]; + break; + default: + + break; + } + + self.datasource = [NSArray array]; + [self.tableView reloadData]; + + [[OSVSyncController sharedInstance].tracksController gameLeaderBoardForRegion:region + formDate:date + withCompletion:^(NSArray *leaderBoard, NSError *error) { + self.datasource = leaderBoard; + NSIndexPath *indexPath = nil; + NSString *country = nil; + if (self.currentUser.name) { + int i = 0; + for (OSVUser *user in leaderBoard) { + if ([user.name isEqualToString:self.currentUser.name]) { + self.currentUser.gameInfo = user.gameInfo; + //the server is buggy we have to check this. + if (user.gameInfo.regionCode) { + NSString *identifier = [NSLocale localeIdentifierFromComponents:[NSDictionary dictionaryWithObject:user.gameInfo.regionCode forKey:NSLocaleCountryCode]]; + country = [[NSLocale currentLocale] displayNameForKey:NSLocaleIdentifier value:identifier]; + + indexPath = [NSIndexPath indexPathForRow:i inSection:0]; + } + } + i++; + } + } + + dispatch_async(dispatch_get_main_queue(), ^{ + if (country) { + [self.usRegionButton setTitle:country forState:UIControlStateNormal]; + } + + [self.tableView reloadData]; + if (indexPath) { + [self.tableView scrollToRowAtIndexPath:indexPath + atScrollPosition:UITableViewScrollPositionMiddle + animated:YES]; + } + }); + }]; +} + +@end diff --git a/OpenStreetView/ViewControllers/OSVMapViewController.h b/OpenStreetView/ViewControllers/OSVMapViewController.h index 894228e..92fd125 100644 --- a/OpenStreetView/ViewControllers/OSVMapViewController.h +++ b/OpenStreetView/ViewControllers/OSVMapViewController.h @@ -18,7 +18,8 @@ @interface OSVMapViewController : UIViewController @property (strong, nonatomic) id controller; -@property (strong, nonatomic) IBOutlet SKMapView *mapView; +@property (weak, nonatomic) IBOutlet UIView *mapContainer; +@property (strong, nonatomic) SKMapView *mapView; @property (weak, nonatomic) IBOutlet UIButton *bottomRightButton; diff --git a/OpenStreetView/ViewControllers/OSVMapViewController.m b/OpenStreetView/ViewControllers/OSVMapViewController.m index d46a7d9..8bf06fd 100644 --- a/OpenStreetView/ViewControllers/OSVMapViewController.m +++ b/OpenStreetView/ViewControllers/OSVMapViewController.m @@ -15,17 +15,25 @@ #import "OSVSequenceMapController.h" #import "OSVBasicMapController.h" #import "OSVVideoPlayerViewController.h" +#import "UIViewController+Additions.h" #import "OSVMainViewController.h" #import "OSVSyncController.h" #import "OSVSettingsViewController.h" #import "OSVLayersViewController.h" +#import "OSVRecordTransition.h" +#import "OSVDissmissRecordTransition.h" +#import "OSVPushTransition.h" +#import "OSVPopTransition.h" #import "OSVLogger.h" +#import "OSVTipView.h" +#import "OSC-Swift.h" + #define kMainViewController (OSVMainViewController *)[UIApplication sharedApplication].delegate.window.rootViewController -@interface OSVMapViewController () +@interface OSVMapViewController () @property (strong, nonatomic) OSVSyncController *syncController; @@ -42,6 +50,11 @@ - (void)awakeFromNib { - (void)viewDidLoad { [super viewDidLoad]; + if ([OSVUserDefaults sharedInstance].enableMap) { + self.mapView = [[SKMapView alloc] initWithFrame:self.mapContainer.bounds]; + } + [UIViewController addMapView:self.mapView toView:self.mapContainer]; + self.mapView.settings.showCurrentPosition = NO; self.mapView.mapScaleView.hidden = YES; @@ -53,11 +66,6 @@ - (void)viewDidLoad { self.sequenceMapController = [OSVSequenceMapController new]; self.sequenceMapController.viewController = self; - SKMapViewStyle *mapViewStyle = [SKMapViewStyle mapViewStyle]; - mapViewStyle.resourcesFolderName = @"GrayscaleStyle"; - mapViewStyle.styleFileName = @"grayscalestyle.json"; - [SKMapView setMapStyle:mapViewStyle]; - self.syncController.didChangeReachabliyStatus = ^(OSVReachabilityStatus status) { BOOL shouldUseCellular = ((status == OSVReachabilityStatusCellular) && [OSVUserDefaults sharedInstance].useCellularData); @@ -79,10 +87,12 @@ - (void)viewDidLoad { - (void)viewWillAppear:(BOOL)animated { [super viewWillAppear:animated]; - + self.navigationController.delegate = self; + self.mapView.frame = self.mapContainer.bounds; if ([CLLocationManager authorizationStatus] != kCLAuthorizationStatusNotDetermined) { - if ([OSVUserDefaults sharedInstance].realPositions) { - [[SKPositionerService sharedInstance] setPositionerMode:SKPositionerModeRealPositions]; + if ([OSVUserDefaults sharedInstance].realPositions && + [OSVUserDefaults sharedInstance].enableMap) { + [OSVLocationManager sharedInstance].positionerMode = SKPositionerModeRealPositions; } } else { SKCoordinateRegion region; @@ -91,8 +101,9 @@ - (void)viewWillAppear:(BOOL)animated { [self.mapView setVisibleRegion:region]; } - if (![OSVUserDefaults sharedInstance].realPositions) { - [[SKPositionerService sharedInstance] setPositionerMode:SKPositionerModePositionSimulation]; + if (![OSVUserDefaults sharedInstance].realPositions && + [OSVUserDefaults sharedInstance].enableMap) { + [OSVLocationManager sharedInstance].positionerMode = SKPositionerModePositionSimulation; } [OSVLocationManager sharedInstance].delegate = self; @@ -103,6 +114,28 @@ - (void)viewWillAppear:(BOOL)animated { [self.controller willChangeUIControllerFrom:self.controller animated:NO]; self.actIndicator.hidden = YES; + + if ([OSVUserDefaults sharedInstance].isFreshInstall) { + + [OSVUserDefaults sharedInstance].isFreshInstall = NO; + [[OSVUserDefaults sharedInstance] save]; + + PortraitViewController *vc = [PortraitViewController new]; + vc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve; + + OSVTipView *tipView = [[[NSBundle mainBundle] loadNibNamed:@"OSVTipView" owner:self options:nil] objectAtIndex:0]; + [tipView prepareIntro]; + [tipView configureViews]; + tipView.willDissmiss = ^() { + [vc dismissViewControllerAnimated:YES completion:^{}]; + return YES; + }; + + [self presentViewController:vc animated:NO completion:^{ + [vc.view addSubview:tipView]; + }]; + tipView.frame = self.navigationController.view.frame; + } } - (void)viewDidAppear:(BOOL)animated { @@ -115,6 +148,8 @@ - (void)viewDidAppear:(BOOL)animated { - (void)viewWillDisappear:(BOOL)animated { [super viewWillDisappear:animated]; + + [self.mapView clearAllOverlays]; } - (void)didReceiveMemoryWarning { @@ -122,12 +157,18 @@ - (void)didReceiveMemoryWarning { [self.controller didReceiveMemoryWarning]; } +- (UIStatusBarStyle)preferredStatusBarStyle { + return UIStatusBarStyleDefault; +} + +#pragma mark - Orientation + - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { @@ -136,10 +177,6 @@ - (UIInterfaceOrientation)preferredInterfaceOrientationForPresentation { #pragma mark - Actions -- (IBAction)didTapRightButton:(id)sender { - [self.sequenceMapController didTapRightButton]; -} - - (IBAction)didTapPositionMe:(id)sender { [self.controller didTapBottomRightButton]; } @@ -156,8 +193,9 @@ - (IBAction)didTapMenuItem:(id)sender { #pragma mark - CLLocationManagerDelegate - (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)newLocation { - if (![OSVUserDefaults sharedInstance].realPositions) { - [[SKPositionerService sharedInstance] reportGPSLocation:[newLocation firstObject]]; + if (![OSVUserDefaults sharedInstance].realPositions && + [OSVUserDefaults sharedInstance].enableMap) { + [[OSVLocationManager sharedInstance] reportGPSLocation:[newLocation firstObject]]; } else { if (!self.hasFirstLocation) { self.mapView.settings.showCurrentPosition = YES; @@ -190,11 +228,7 @@ - (void)mapView:(SKMapView *)mapView didTapAtCoordinate:(CLLocationCoordinate2D) - (IBAction)didTapCameraShow:(id)sender { [self.mapView clearAllOverlays]; - - UIStoryboard *storyBoard = self.storyboard; - UIViewController *targetViewController = [storyBoard instantiateViewControllerWithIdentifier:@"cameraViewController"]; - - [self.navigationController pushViewController:targetViewController animated:NO]; + [self performSegueWithIdentifier:@"showCamera" sender:self]; } #pragma mark - Overriden @@ -213,7 +247,57 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } else if ([segue.identifier isEqualToString:@"showLayers"]) { OSVLayersViewController *vc = segue.destinationViewController; vc.datasource = sender; + } else if ([segue.identifier isEqualToString:@"showCamera"] || + [segue.identifier isEqualToString:@"showMyProfile"] || + [segue.identifier isEqualToString:@"showLocalTracks"] || + [segue.identifier isEqualToString:@"showLeaderboard"] || + [segue.identifier isEqualToString:@"showLoginController"]) { + UIViewController *vc = segue.destinationViewController; + vc.transitioningDelegate = self; + } +} + +#pragma mark - UIViewControllerTransitioningDelegate + +- (id )animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source { + if ([presented isKindOfClass:NSClassFromString(@"OSVCamViewController")]) { + return [OSVRecordTransition new]; } + + return nil; } +- (id )animationControllerForDismissedController:(UIViewController *)dismissed { + if ([dismissed isKindOfClass:NSClassFromString(@"OSVCamViewController")]) { + [self.controller didTapBottomRightButton]; + return [OSVDissmissRecordTransition new]; + } + return nil; +} + +- (nullable id )navigationController:(UINavigationController *)navigationController + animationControllerForOperation:(UINavigationControllerOperation)operation + fromViewController:(UIViewController *)fromVC + toViewController:(UIViewController *)toVC { + if ([toVC isKindOfClass:NSClassFromString(@"OSVMyProfileViewController")]|| + [toVC isKindOfClass:NSClassFromString(@"OSVLocalTracksViewController")]|| + [toVC isKindOfClass:NSClassFromString(@"OSVSettingsViewController")]|| + [toVC isKindOfClass:NSClassFromString(@"OSVLeaderboardViewController")] || + [NSStringFromClass(toVC.class) containsString:@"LoginViewController"]) { + + return [[OSVPushTransition alloc] initWithoutAnimatingSource:YES]; + } else if ([fromVC isKindOfClass:NSClassFromString(@"OSVMyProfileViewController")]|| + [fromVC isKindOfClass:NSClassFromString(@"OSVLocalTracksViewController")]|| + [fromVC isKindOfClass:NSClassFromString(@"OSVSettingsViewController")]|| + [fromVC isKindOfClass:NSClassFromString(@"OSVLeaderboardViewController")] || + [NSStringFromClass(fromVC.class) containsString:@"LoginViewController"]) { + + return [[OSVPopTransition alloc] initWithoutAnimatingSource:YES]; + } + + return nil; +} + + + @end diff --git a/OpenStreetView/ViewControllers/OSVSettingsViewController.m b/OpenStreetView/ViewControllers/OSVSettingsViewController.m index 1c84870..a702c4f 100644 --- a/OpenStreetView/ViewControllers/OSVSettingsViewController.m +++ b/OpenStreetView/ViewControllers/OSVSettingsViewController.m @@ -32,6 +32,10 @@ @interface OSVSettingsViewController () +#import "OSVScoreDetailsView.h" +#import "OSVScoreHistory.h" +#import "OSVUserDefaults.h" + +#import "OSVUtils.h" + +#import "OSC-Swift.h" + @interface OSVVideoPlayerViewController () @property (weak, nonatomic) IBOutlet UIButton *playButton; -@property (weak, nonatomic) IBOutlet SKMapView *mapView; +@property (strong, nonatomic) SKMapView *mapView; @property (weak, nonatomic) IBOutlet UILabel *dateLabel; @property (weak, nonatomic) IBOutlet UILabel *frameIndexLabel; @property (weak, nonatomic) IBOutlet UIImageView *frameIndexImage; @property (weak, nonatomic) IBOutlet UISlider *basicSlider; @property (weak, nonatomic) IBOutlet UIButton *fullScreenButton; @property (weak, nonatomic) IBOutlet UIButton *deletePhotoButton; +@property (weak, nonatomic) IBOutlet UILabel *pointsLabel; +@property (weak, nonatomic) IBOutlet UIButton *pointsButton; @property (strong, nonatomic) id player; @property (assign, nonatomic) NSInteger frameIndex; @@ -45,10 +56,24 @@ @interface OSVVideoPlayerViewController () seq, NSError *error) { - self.player = [[OSVPhotoPlayer alloc] initWithView:self.videoPlayerPreview andSlider:self.basicSlider]; - self.player.delegate = self; - if (self.player.currentPlayableItem != self.selectedSequence.photos) { - [self.player prepareForPlayableItem:self.selectedSequence.photos startingFromIndex:self.startingFrameIndex]; - [self zoomOnSequence:self.selectedSequence]; - [self addSequenceOnMap:self.selectedSequence]; - } + dispatch_async(dispatch_get_main_queue(), ^{ + self.player = [[OSVPhotoPlayer alloc] initWithView:self.videoPlayerPreview andSlider:self.basicSlider]; + self.player.delegate = self; + if (self.player.currentPlayableItem != self.selectedSequence.photos) { + [self.player prepareForPlayableItem:self.selectedSequence.photos startingFromIndex:self.startingFrameIndex]; + [self zoomOnSequence:self.selectedSequence]; + [self addSequenceOnMap:self.selectedSequence]; + } + }); }]; } } else { @@ -103,18 +130,65 @@ - (void)viewWillAppear:(BOOL)animated { self.videoPlayerPreview.layer.borderColor = [[UIColor colorWithHex:0x6e707b] colorWithAlphaComponent:0.3].CGColor; self.videoPlayerPreview.layer.borderWidth = 1; self.videoPlayerPreview.layer.cornerRadius = 3; + + if ([OSVUserDefaults sharedInstance].useGamification && + ![self.selectedSequence isKindOfClass:[OSVServerSequencePart class]]) { + NSString *pointsString = [@(((OSVSequence *)self.selectedSequence).points) stringValue]; + if (((OSVSequence *)self.selectedSequence).points > 9999) { + pointsString = [NSString stringWithFormat:@"%ldK", ((OSVSequence *)self.selectedSequence).points/1000]; + } + NSAttributedString *points = [NSAttributedString combineString:pointsString + withSize:16.f + color:[UIColor whiteColor] + fontName:@"HelveticaNeue" + withString:@"\npts" + withSize:10.f + color:[UIColor whiteColor] + fontName:@"HelveticaNeue"]; + self.pointsLabel.attributedText = points; + self.pointsButton.hidden = NO; + self.pointsLabel.hidden = NO; + self.scoreDetails.hidden = NO; + self.circleAnimation.hidden = NO; + } else { + self.pointsLabel.text = @""; + self.pointsButton.hidden = YES; + self.pointsLabel.hidden = YES; + self.scoreDetails.hidden = YES; + self.circleAnimation.hidden = YES; + } + + self.scoreDetails.alpha = 0; + self.circleAnimation.layer.cornerRadius = self.circleAnimation.frame.size.width/2.0; + + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + [self enlageMultiplyerWithCompletion:^{ + [UIView animateWithDuration:0.2 animations:^{ + self.pointsButton.transform = CGAffineTransformIdentity; + self.pointsLabel.transform = CGAffineTransformIdentity; + self.circleAnimation.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + [self enlageMultiplyerWithCompletion:^{ + [self diminishMultiplyerWithCompletion:^{ + + }]; + }]; + }]; + }]; + }); } - (void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; if (self.frameIndex == 0) { - if ([self.selectedSequence isKindOfClass:[OSVServerSequence class]]) { + if ([self.selectedSequence isKindOfClass:[OSVServerSequence class]]|| + [self.selectedSequence isKindOfClass:[OSVServerSequencePart class]]) { if (self.player.currentPlayableItem != self.selectedSequence.photos) { [self.player prepareForPlayableItem:self.selectedSequence.photos startingFromIndex:self.startingFrameIndex]; } } else { - [self.player prepareForPlayableItem:[self fileNameForTrackID:self.selectedSequence.uid] startingFromIndex:self.startingFrameIndex]; + [self.player prepareForPlayableItem:[OSVUtils fileNameForTrackID:self.selectedSequence.uid] startingFromIndex:self.startingFrameIndex]; } [self.player play]; [self.player pause]; @@ -152,19 +226,19 @@ - (BOOL)prefersStatusBarHidden { } - (BOOL)shouldAutorotate { - return NO; + return YES; } - (UIInterfaceOrientationMask)supportedInterfaceOrientations { - return UIInterfaceOrientationMaskPortrait; + return UIInterfaceOrientationMaskAll; } - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator { [coordinator animateAlongsideTransition:^(id context) { self.player.playerLayer.frame = self.videoPlayerPreview.bounds; self.player.playerLayer.position = CGPointMake(CGRectGetMidX(self.videoPlayerPreview.bounds), CGRectGetMidY(self.videoPlayerPreview.bounds)); + self.player.imageView.frame = self.videoPlayerPreview.bounds; } completion:^(id context) { - }]; } @@ -179,7 +253,7 @@ - (IBAction)play:(id)sender { if (self.player.currentPlayableItem) { [self.player resume]; } else { - [self.player prepareForPlayableItem:[self fileNameForTrackID:self.selectedSequence.uid] startingFromIndex:self.startingFrameIndex]; + [self.player prepareForPlayableItem:[OSVUtils fileNameForTrackID:self.selectedSequence.uid] startingFromIndex:self.startingFrameIndex]; [self.player play]; } } @@ -222,11 +296,11 @@ - (IBAction)fullScreen:(id)sender { } - (IBAction)didTapDelete:(id)sender { - if (self.frameIndex > 0 && self.selectedSequence.photos.count >= self.frameIndex) { + if (self.selectedSequence.photos.count > 0 && self.frameIndex > 0 && self.selectedSequence.photos.count >= self.frameIndex) { [[OSVSyncController sharedInstance].tracksController deletePhoto:self.selectedSequence.photos[self.frameIndex - 1] withCompletionBlock:^(NSError *error) { [self.selectedSequence.photos removeObjectAtIndex:self.frameIndex-1]; dispatch_async(dispatch_get_main_queue(), ^{ - [self totalNumberOfFrames:self.selectedSequence.photos.count]; + [self.player prepareForPlayableItem:self.selectedSequence.photos startingFromIndex:self.frameIndex - 1]; }); }]; } @@ -247,12 +321,6 @@ - (void)zoomOnSequence:(id)seq { [self.mapView fitBounds:box withInsets:UIEdgeInsetsMake(20, 20, 20, 20)]; } -- (NSURL *)fileNameForTrackID:(NSInteger)trackUID { - NSString *folderPathString = [NSString stringWithFormat:@"%@%ld", [OSVSyncController sharedInstance].tracksController.basePathToPhotos, (long)trackUID]; - - return [[NSURL alloc] initWithString:folderPathString]; -} - - (void)addSequenceOnMap:(id)sequence { [self orderPhotosIntoSequence:sequence]; @@ -456,4 +524,119 @@ - (void)willDissmissViewController:(OSVFullScreenImageViewController *)vc { } } +- (IBAction)didTapTrackDetails:(id)sender { + if ([self.selectedSequence isKindOfClass:[OSVServerSequence class]]) { + OSVServerSequence *seq = self.selectedSequence; + self.scoreDetails.totalPointsLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Total Points: %ld", @""), seq.points]; + + int i = 0; + [seq.scoreHistory sortUsingComparator:^NSComparisonResult(OSVScoreHistory *obj1, OSVScoreHistory *obj2) { + if (obj1.multiplier < obj2.multiplier) { + return NSOrderedAscending; + } else { + return NSOrderedDescending; + } + }]; + + for (OSVScoreHistory *sch in seq.scoreHistory) { + self.scoreDetails.pointsLabels[i].text = [@(sch.points) stringValue]; + self.scoreDetails.pointsLabels[i].hidden = NO; + self.scoreDetails.multiplierLabels[i].text = [@(sch.multiplier) stringValue]; + self.scoreDetails.multiplierLabels[i].hidden = NO; + self.scoreDetails.distanceLabels[i].text = [NSString stringWithFormat:@"%ld", sch.photos]; + self.scoreDetails.distanceLabels[i].hidden = NO; + i++; + } + } + + if ([self.selectedSequence isKindOfClass:[OSVSequence class]]) { + + OSVSequence *seq = self.selectedSequence; + self.scoreDetails.totalPointsLabel.text = [NSString stringWithFormat:NSLocalizedString(@"Total Points: %ld", @""), seq.points]; + + int i = 0; + [seq.scoreHistory sortUsingComparator:^NSComparisonResult(OSVScoreHistory *obj1, OSVScoreHistory *obj2) { + if (obj1.multiplier < obj2.multiplier) { + return NSOrderedAscending; + } else { + return NSOrderedDescending; + } + }]; + + for (OSVScoreHistory *sch in seq.scoreHistory) { + + self.scoreDetails.pointsLabels[i].text = [@(sch.points) stringValue]; + self.scoreDetails.pointsLabels[i].hidden = NO; + self.scoreDetails.multiplierLabels[i].text = sch.multiplier ? [@(sch.multiplier) stringValue] : NSLocalizedString(@"no connection", @""); + self.scoreDetails.multiplierLabels[i].hidden = NO; + self.scoreDetails.distanceLabels[i].text = [NSString stringWithFormat:@"%ld", sch.photos]; + self.scoreDetails.distanceLabels[i].hidden = NO; + + i++; + } + self.scoreDetails.disclosureLabel.hidden = NO; + self.scoreDetails.disclosureLabel.text = NSLocalizedString(@"", @""); + } + + if (![self.selectedSequence isKindOfClass:[OSVServerSequencePart class]]) { + + self.circleAnimation.transform = CGAffineTransformIdentity; + + [UIView animateWithDuration:0.3 animations:^{ + self.circleAnimation.transform = CGAffineTransformMakeScale(20, 20); + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.1 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations:^{ + self.scoreDetails.alpha = 1; + } completion:^(BOOL finished) { + + }]; + }]; + } +} + +- (IBAction)didTapDissmissDetails:(id)sender { + [UIView animateWithDuration:0.1 animations:^{ + self.scoreDetails.alpha = 0; + } completion:^(BOOL finished) { + [UIView animateWithDuration:0.3 delay:0.1 options:UIViewAnimationOptionCurveEaseOut animations:^{ + self.circleAnimation.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + + }]; + }]; +} + +- (void)enlageMultiplyerWithCompletion:(void (^)(void))completion { + + self.pointsLabel.transform = CGAffineTransformIdentity; + self.pointsButton.transform = CGAffineTransformIdentity; + self.circleAnimation.transform = CGAffineTransformIdentity; + [UIView animateWithDuration:0.15 animations:^{ + self.pointsLabel.transform = CGAffineTransformMakeScale(1.25, 1.25); + self.pointsButton.transform = CGAffineTransformMakeScale(1.25, 1.25); + self.circleAnimation.transform = CGAffineTransformMakeScale(1.25, 1.25); + } completion:^(BOOL finished) { + if (finished) { + completion(); + } + }]; +} + +- (void)diminishMultiplyerWithCompletion:(void (^)(void))completion { + + [UIView animateWithDuration:0.7 + delay:0.0 + usingSpringWithDamping:0.10 + initialSpringVelocity:0.2 + options:UIViewAnimationOptionCurveLinear animations:^{ + self.pointsLabel.transform = CGAffineTransformIdentity; + self.pointsButton.transform = CGAffineTransformIdentity; + self.circleAnimation.transform = CGAffineTransformIdentity; + } completion:^(BOOL finished) { + if (finished) { + completion(); + } + }]; +} + @end diff --git a/OpenStreetView/Views/OSVRankCell.h b/OpenStreetView/Views/OSVRankCell.h new file mode 100644 index 0000000..c5790ee --- /dev/null +++ b/OpenStreetView/Views/OSVRankCell.h @@ -0,0 +1,17 @@ +// +// OSVRankCell.h +// OpenStreetView +// +// Created by Bogdan Sala on 17/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVRankCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *rank; +@property (weak, nonatomic) IBOutlet UILabel *name; +@property (weak, nonatomic) IBOutlet UILabel *points; + +@end diff --git a/OpenStreetView/Views/OSVRankCell.m b/OpenStreetView/Views/OSVRankCell.m new file mode 100644 index 0000000..e1af4e6 --- /dev/null +++ b/OpenStreetView/Views/OSVRankCell.m @@ -0,0 +1,24 @@ +// +// OSVRankCell.m +// OpenStreetView +// +// Created by Bogdan Sala on 17/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVRankCell.h" + +@implementation OSVRankCell + +- (void)awakeFromNib { + [super awakeFromNib]; + // Initialization code +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + + // Configure the view for the selected state +} + +@end diff --git a/OpenStreetView/Views/OSVRankHeaderCell.h b/OpenStreetView/Views/OSVRankHeaderCell.h new file mode 100644 index 0000000..3df8378 --- /dev/null +++ b/OpenStreetView/Views/OSVRankHeaderCell.h @@ -0,0 +1,17 @@ +// +// OSVRankHeaderCell.h +// OpenStreetView +// +// Created by Bogdan Sala on 17/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVRankHeaderCell : UITableViewCell + +@property (weak, nonatomic) IBOutlet UILabel *rank; +@property (weak, nonatomic) IBOutlet UILabel *name; +@property (weak, nonatomic) IBOutlet UILabel *points; + +@end diff --git a/OpenStreetView/Views/OSVRankHeaderCell.m b/OpenStreetView/Views/OSVRankHeaderCell.m new file mode 100644 index 0000000..802f223 --- /dev/null +++ b/OpenStreetView/Views/OSVRankHeaderCell.m @@ -0,0 +1,17 @@ +// +// OSVRankHeaderCell.m +// OpenStreetView +// +// Created by Bogdan Sala on 17/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVRankHeaderCell.h" + +@interface OSVRankHeaderCell () + +@end + +@implementation OSVRankHeaderCell + +@end diff --git a/OpenStreetView/Views/OSVSettingsButtonCell.h b/OpenStreetView/Views/OSVSettingsButtonCell.h deleted file mode 100644 index 9542259..0000000 --- a/OpenStreetView/Views/OSVSettingsButtonCell.h +++ /dev/null @@ -1,19 +0,0 @@ -// -// OSVSettingsButtonCell.h -// OpenStreetView -// -// Created by Bogdan Sala on 23/03/16. -// Copyright © 2016 Bogdan Sala. All rights reserved. -// - -#import - -@interface OSVSettingsButtonCell : UITableViewCell - -@property (weak, nonatomic) IBOutlet UILabel *titleLabel; -@property (weak, nonatomic) IBOutlet UILabel *subtitleLabel; -@property (weak, nonatomic) IBOutlet UIButton *button; - -@property (copy, nonatomic) void (^actionBlock)(UIButton *button); - -@end diff --git a/OpenStreetView/Views/OSVSettingsButtonCell.m b/OpenStreetView/Views/OSVSettingsButtonCell.m deleted file mode 100644 index 07a1e17..0000000 --- a/OpenStreetView/Views/OSVSettingsButtonCell.m +++ /dev/null @@ -1,23 +0,0 @@ -// -// OSVSettingsButtonCell.m -// OpenStreetView -// -// Created by Bogdan Sala on 23/03/16. -// Copyright © 2016 Bogdan Sala. All rights reserved. -// - -#import "OSVSettingsButtonCell.h" - -@interface OSVSettingsButtonCell () - -@property (nonatomic, assign) BOOL isConnected; - -@end - -@implementation OSVSettingsButtonCell - -- (IBAction)didTapButton:(id)sender { - self.actionBlock(sender); -} - -@end diff --git a/OpenStreetView/Views/OSVTipView.h b/OpenStreetView/Views/OSVTipView.h index 37fddce..f8078d1 100644 --- a/OpenStreetView/Views/OSVTipView.h +++ b/OpenStreetView/Views/OSVTipView.h @@ -10,6 +10,13 @@ @interface OSVTipView : UIView +@property (copy, nonatomic) void (^didDissmiss)(); +@property (copy, nonatomic) BOOL (^willDissmiss)(); + - (void)randomize; +- (void)configureViews; +- (void)prepareWalkthrough; +- (void)prepareIntro; + @end diff --git a/OpenStreetView/Views/OSVTipView.m b/OpenStreetView/Views/OSVTipView.m index a053b86..119f873 100644 --- a/OpenStreetView/Views/OSVTipView.m +++ b/OpenStreetView/Views/OSVTipView.m @@ -8,6 +8,7 @@ #import "OSVTipView.h" #import "OSVTipPageViewController.h" +#import "OSVIntroViewController.h" #import "UIColor+OSVColor.h" @interface OSVTipView () @@ -16,6 +17,7 @@ @interface OSVTipView () @property (strong, nonatomic) NSArray *specialTips; @property (strong, nonatomic) NSArray *tipTitles; @property (strong, nonatomic) NSArray *specialTipsTitle; +@property (strong, nonatomic) NSArray *imageNames; @property (strong, nonatomic) NSTimer *timer; @@ -24,14 +26,16 @@ @interface OSVTipView () @property (assign, nonatomic) BOOL manualyChanged; -@property (weak, nonatomic) IBOutlet UIScrollView *scrollView; +@property (weak, nonatomic) IBOutlet UIScrollView *scrollView; -@property (nonatomic, strong) NSMutableArray *pages; -@property (nonatomic, strong) NSArray *tipColors; +@property (nonatomic, strong) NSMutableArray *pages; +@property (nonatomic, strong) NSArray *tipColors; -@property (weak, nonatomic) IBOutlet UIButton *dissmissButton; +@property (weak, nonatomic) IBOutlet UIButton *dissmissButton; -@property (weak, nonatomic) IBOutlet UIPageControl *pageControl; +@property (weak, nonatomic) IBOutlet UIPageControl *pageControl; + +@property (nonatomic, assign) NSInteger controlerType; @end @@ -40,60 +44,27 @@ @implementation OSVTipView - (instancetype)initWithCoder:(NSCoder *)coder { self = [super initWithCoder:coder]; if (self) { - self.tips = @[NSLocalizedString(@"Check that the front hood of the car and the phone’s mount are not visible in the pictures.", @""), - NSLocalizedString(@"Try to keep your car’s windshield clean.", @""), - NSLocalizedString(@"You can tap on screen to focus. Long press locks it.", @""), - NSLocalizedString(@"", @"")]; - self.tipTitles = @[NSLocalizedString(@"Phone mount", @""), - NSLocalizedString(@"Windshield", @""), - NSLocalizedString(@"Camera Focus", @""), - NSLocalizedString(@"", @"")]; - - self.tipColors = @[[UIColor colorWithHex:0x019ED3], - [UIColor colorWithHex:0xBD10E0], - [UIColor colorWithHex:0x1DAA63], - [UIColor colorWithHex:0x1DAA63], - [UIColor colorWithHex:0x1DAA63], - [UIColor colorWithHex:0x1DAA63], - [UIColor colorWithHex:0x1DAA63]]; - - self.specialTips = @[NSLocalizedString(@"Record in landscape mode to capture better images. Turn your phone if possible.", @""), - NSLocalizedString(@"Check that the front hood of the car and the phone’s mount are not visible in the pictures.", @""), - NSLocalizedString(@"Try to keep your car’s windshield clean.", @""), - NSLocalizedString(@"You can tap on screen to focus. Long press locks it.", @""), - NSLocalizedString(@"", @"")]; - - self.specialTipsTitle = @[NSLocalizedString(@"Landscape", @""), - NSLocalizedString(@"Phone mount", @""), - NSLocalizedString(@"Windshield", @""), - NSLocalizedString(@"Camera Focus", @""), - NSLocalizedString(@"", @"")]; + [self prepareWalkthrough]; } return self; } -- (void)awakeFromNib { - [super awakeFromNib]; - self.pages = [NSMutableArray array]; +- (id)viewControllerAtIndex:(NSUInteger)index { - for (int i = 0; i < self.specialTips.count; i++) { - OSVTipPageViewController *initialViewController = [self viewControllerAtIndex:i]; - [self.pages addObject:initialViewController]; - [self.scrollView addSubview:initialViewController.view]; + if (!self.controlerType) { + OSVTipPageViewController *childViewController = [[OSVTipPageViewController alloc] initWithNibName:@"OSVTipPageViewController" bundle:nil]; + childViewController.index = index; + childViewController.view.backgroundColor = self.tipColors[index]; + + return childViewController; + } else { + OSVIntroViewController *childViewController = [[OSVIntroViewController alloc] initWithNibName:@"OSVIntroViewController" bundle:nil]; + childViewController.index = index; + childViewController.view.backgroundColor = self.tipColors[index]; + + return childViewController; } - - self.scrollView.contentSize = CGSizeMake(self.frame.size.width * self.tips.count, self.frame.size.height); - self.pageControl.numberOfPages = self.tips.count; - self.scrollView.delegate = self; -} - -- (OSVTipPageViewController *)viewControllerAtIndex:(NSUInteger)index { - OSVTipPageViewController *childViewController = [[OSVTipPageViewController alloc] initWithNibName:@"OSVTipPageViewController" bundle:nil]; - childViewController.index = index; - childViewController.view.backgroundColor = self.tipColors[index]; - - return childViewController; } - (void)layoutSubviews { @@ -117,6 +88,10 @@ - (void)layoutSubviews { vc.tipDescriptionLabel.text = self.tips[i]; vc.tipTitleLabel.text = self.tipTitles[i]; } + + if ([vc isKindOfClass:[OSVIntroViewController class]]) { + ((OSVIntroViewController *)vc).image.image = self.imageNames[i]; + } } } @@ -153,13 +128,111 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView { } - (IBAction)shouldDissmiss:(id)sender { - [UIView animateWithDuration:0.6 animations:^{ - self.alpha = 0; - } completion:^(BOOL finished) { - [self removeFromSuperview]; - self.scrollView.contentOffset = CGPointMake(0, 0); - self.alpha = 1; - }]; + BOOL isDissmissed = NO; + if (self.willDissmiss) { + isDissmissed = self.willDissmiss(); + } + + if (!isDissmissed) { + [UIView animateWithDuration:0.6 animations:^{ + self.alpha = 0; + } completion:^(BOOL finished) { + [self removeFromSuperview]; + + self.scrollView.contentOffset = CGPointMake(0, 0); + self.alpha = 1; + if (self.didDissmiss) { + self.didDissmiss(); + } + }]; + } else { + if (self.didDissmiss) { + self.didDissmiss(); + } + } +} + +- (void)prepareWalkthrough { + self.controlerType = 0; + + self.tips = @[NSLocalizedString(@"You will get more points when the streets you're driving have less coverage. Get 10X for a new street in OpenStreetCam!", @""), + NSLocalizedString(@"Check that the front hood of the car and the phone’s mount are not visible in the pictures.", @""), + NSLocalizedString(@"Try to keep your car’s windshield clean.", @""), + NSLocalizedString(@"You can tap on screen to focus. Long press locks it.", @""), + NSLocalizedString(@"", @"")]; + self.tipTitles = @[NSLocalizedString(@"Points", @""), + NSLocalizedString(@"Phone mount", @""), + NSLocalizedString(@"Windshield", @""), + NSLocalizedString(@"Camera Focus", @""), + NSLocalizedString(@"", @"")]; + + self.tipColors = @[[UIColor colorWithHex:0x019ED3], + [UIColor colorWithHex:0xe7a200], + [UIColor colorWithHex:0xBD10E0], + [UIColor colorWithHex:0x1DAA63], + [UIColor colorWithHex:0x1DAA63], + [UIColor colorWithHex:0x1DAA63], + [UIColor colorWithHex:0x1DAA63], + [UIColor colorWithHex:0x1DAA63]]; + + self.specialTips = @[NSLocalizedString(@"You will get more points when the streets you're driving have less coverage. Get 10X for a new street in OpenStreetCam!", @""), + NSLocalizedString(@"Record in landscape mode to capture better images. Turn your phone if possible.", @""), + NSLocalizedString(@"Check that the front hood of the car and the phone’s mount are not visible in the pictures.", @""), + NSLocalizedString(@"Try to keep your car’s windshield clean.", @""), + NSLocalizedString(@"You can tap on screen to focus. Long press locks it.", @""), + NSLocalizedString(@"", @"")]; + + self.specialTipsTitle = @[NSLocalizedString(@"Points", @""), + NSLocalizedString(@"Landscape", @""), + NSLocalizedString(@"Phone mount", @""), + NSLocalizedString(@"Windshield", @""), + NSLocalizedString(@"Camera Focus", @""), + NSLocalizedString(@"", @"")]; + self.dissmissButton.hidden = NO; +} + +- (void)prepareIntro { + self.controlerType = 1; + + self.tips = @[NSLocalizedString(@"You’re now joining a great community of people that contribute to a free and open platform for street imagery.\n\nBy detecting street features from your photos we can build the best map in the world, together!", @""), + NSLocalizedString(@"Use your phone to record the streets you drive, bike or walk, the app will take photos automatically and upload when Wi-Fi is available.", @""), + NSLocalizedString(@"Contribute your recordings, gain points and increase your ranking in the OpenStreetCam leaderboard.\n\nTip: Find streets that are not yet covered for many bonus points!", @""), + NSLocalizedString(@"", @"")]; + self.tipTitles = @[NSLocalizedString(@"Welcome to OpenStreetCam!", @""), + NSLocalizedString(@"How do I contribute?", @""), + NSLocalizedString(@"Make it count", @""), + NSLocalizedString(@"", @"")]; + + self.tipColors = @[[UIColor colorWithHex:0x019ED3], + [UIColor colorWithHex:0x0fab60], + [UIColor colorWithHex:0xe7a200], + [UIColor colorWithHex:0xe7a200], + [UIColor colorWithHex:0xe7a200], + [UIColor colorWithHex:0xe7a200], + [UIColor colorWithHex:0xe7a200]]; + + self.specialTips = self.tips; + self.specialTipsTitle = self.tipTitles; + + self.imageNames = @[[UIImage imageNamed:@"windyRoadLineTall"], + [UIImage imageNamed:@"windyRoadLineTall-1"], + [UIImage imageNamed:@"windyRoadLineTall-2"], + [UIImage new]]; + self.dissmissButton.hidden = YES; +} + +- (void)configureViews { + self.pages = [NSMutableArray array]; + + for (int i = 0; i < self.specialTips.count; i++) { + UIViewController *initialViewController = [self viewControllerAtIndex:i]; + [self.pages addObject:initialViewController]; + [self.scrollView addSubview:initialViewController.view]; + } + + self.scrollView.contentSize = CGSizeMake(self.frame.size.width * self.tips.count, self.frame.size.height); + self.pageControl.numberOfPages = self.tips.count; + self.scrollView.delegate = self; } @end diff --git a/OpenStreetView/Views/OSVUnderlineButton.h b/OpenStreetView/Views/OSVUnderlineButton.h new file mode 100644 index 0000000..eeb3694 --- /dev/null +++ b/OpenStreetView/Views/OSVUnderlineButton.h @@ -0,0 +1,13 @@ +// +// OSVUnderlineButton.h +// OpenStreetView +// +// Created by Bogdan Sala on 17/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import + +@interface OSVUnderlineButton : UIButton + +@end diff --git a/OpenStreetView/Views/OSVUnderlineButton.m b/OpenStreetView/Views/OSVUnderlineButton.m new file mode 100644 index 0000000..05e29a1 --- /dev/null +++ b/OpenStreetView/Views/OSVUnderlineButton.m @@ -0,0 +1,47 @@ +// +// OSVUnderlineButton.m +// OpenStreetView +// +// Created by Bogdan Sala on 17/11/2016. +// Copyright © 2016 Bogdan Sala. All rights reserved. +// + +#import "OSVUnderlineButton.h" + +@interface OSVUnderlineButton () + +@property (nonatomic, strong) UIView *underline; + +@end + +@implementation OSVUnderlineButton + +- (instancetype)init { + self = [super init]; + if (self) { + + } + return self; +} + +- (void)awakeFromNib { + [super awakeFromNib]; + + self.underline = [UIView new]; + self.underline.backgroundColor = [UIColor whiteColor]; + self.underline.hidden = !self.selected; + + [self addSubview:self.underline]; +} + +- (void)layoutSubviews { + [super layoutSubviews]; + self.underline.frame = CGRectMake(0, self.frame.size.height - 2, self.frame.size.width, 2); +} + +- (void)setSelected:(BOOL)selected { + [super setSelected:selected]; + self.underline.hidden = !selected; +} + +@end diff --git a/OpenStreetView/exif_iOS.proto b/OpenStreetView/exif_iOS.proto new file mode 100644 index 0000000..1fdf3f7 --- /dev/null +++ b/OpenStreetView/exif_iOS.proto @@ -0,0 +1,28 @@ +syntax = "proto2"; + +message OSCImageInfo +{ + optional uint32 frameIndex = 1; + optional float aperture = 2; + optional float brightness = 3; + optional float exposureTime = 4; + optional float isoSpeed = 5; + optional uint32 sceneType = 6; + optional uint32 sensingMethod = 7; + optional uint32 shutterSpeedValue = 8; + optional uint32 whiteBalance = 9; + optional uint32 meteringMode = 10; +} + +message OSCTrackInfo { + repeated OSCImageInfo images = 1; + optional string lensModel = 2; + optional string lensMake = 3; + optional float fNumber = 4; + optional uint32 focalLenIn35mmFilm = 5; + optional float focalLenght = 6; + optional uint32 pixelXDimension = 7; + optional uint32 pixelYDimension = 8; + repeated float lensSpecification = 9; + +} diff --git a/OpenStreetView/oSVLogoV1.png b/OpenStreetView/oSVLogoV1.png index 5f415815d32a8b4e916f782dd3f32ef79d6c30b0..f97f4453f2ad702913d651230ed26f718e57b8d8 100755 GIT binary patch literal 21409 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 MaRspw5yPPW2f|2-jQ{`u literal 12502 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 L6vZn<4FmrV5GtT- diff --git a/OpenStreetView/oSVLogoV1@3x.png b/OpenStreetView/oSVLogoV1@3x.png index 4a10ab074a60f667b07207fe13d748c2baada01b..88f20734f0cbb87b3cbfbf5e9ce3d03adbbbbf42 100755 GIT binary patch literal 36662 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 ki>7}5ufbBzn|n-*rKFg^UPCw)nsV!Z literal 19804 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 diff --git a/OpenStreetViewUITests/OpenStreetViewUITests.m b/OpenStreetViewUITests/OpenStreetViewUITests.m index 51d5c8b..4e4b12e 100644 --- a/OpenStreetViewUITests/OpenStreetViewUITests.m +++ b/OpenStreetViewUITests/OpenStreetViewUITests.m @@ -33,6 +33,7 @@ - (void)tearDown { } - (void)testExample { + // Use recording to get started writing UI tests. // Use XCTAssert and related functions to verify your tests produce the correct results. } diff --git a/Podfile b/Podfile index 0583af4..d2f41c8 100644 --- a/Podfile +++ b/Podfile @@ -3,20 +3,28 @@ platform :ios, '8.0' target 'OpenStreetView' do use_frameworks! + pod 'Google/SignIn' + pod 'FBSDKCoreKit' + pod 'FBSDKLoginKit' pod 'SDWebImage', '~>3.8' - pod 'ScoutMaps-iOS-SDK' pod 'Realm' + pod 'ScoutMaps-iOS-SDK' pod 'Fabric' pod 'Crashlytics' + end target 'OpenStreetViewRelease' do use_frameworks! + pod 'Google/SignIn' + pod 'FBSDKCoreKit' + pod 'FBSDKLoginKit' pod 'SDWebImage', '~>3.8' - pod 'ScoutMaps-iOS-SDK' pod 'Realm' + pod 'ScoutMaps-iOS-SDK' pod 'Fabric' - pod 'Crashlytics' + pod 'Crashlytics' + end diff --git a/Podfile.lock b/Podfile.lock new file mode 100644 index 0000000..993f9de --- /dev/null +++ b/Podfile.lock @@ -0,0 +1,87 @@ +PODS: + - Bolts (1.8.4): + - Bolts/AppLinks (= 1.8.4) + - Bolts/Tasks (= 1.8.4) + - Bolts/AppLinks (1.8.4): + - Bolts/Tasks + - Bolts/Tasks (1.8.4) + - Crashlytics (3.8.4): + - Fabric (~> 1.6.3) + - Fabric (1.6.11) + - FBSDKCoreKit (4.20.0): + - Bolts (~> 1.7) + - FBSDKLoginKit (4.20.0): + - FBSDKCoreKit + - FirebaseAnalytics (3.7.0): + - FirebaseCore (~> 3.5) + - FirebaseInstanceID (~> 1.0) + - GoogleToolboxForMac/NSData+zlib (~> 2.1) + - FirebaseCore (3.5.1): + - GoogleToolboxForMac/NSData+zlib (~> 2.1) + - FirebaseInstanceID (1.0.9) + - Google/Core (3.0.3): + - FirebaseAnalytics (~> 3.2) + - Google/SignIn (3.0.3): + - Google/Core + - GoogleSignIn (~> 4.0) + - GoogleSignIn (4.0.2): + - GoogleToolboxForMac/NSDictionary+URLArguments (~> 2.1) + - GoogleToolboxForMac/NSString+URLArguments (~> 2.1) + - GTMOAuth2 (~> 1.0) + - GTMSessionFetcher/Core (~> 1.1) + - GoogleToolboxForMac/DebugUtils (2.1.1): + - GoogleToolboxForMac/Defines (= 2.1.1) + - GoogleToolboxForMac/Defines (2.1.1) + - GoogleToolboxForMac/NSData+zlib (2.1.1): + - GoogleToolboxForMac/Defines (= 2.1.1) + - GoogleToolboxForMac/NSDictionary+URLArguments (2.1.1): + - GoogleToolboxForMac/DebugUtils (= 2.1.1) + - GoogleToolboxForMac/Defines (= 2.1.1) + - GoogleToolboxForMac/NSString+URLArguments (= 2.1.1) + - GoogleToolboxForMac/NSString+URLArguments (2.1.1) + - GTMOAuth2 (1.1.4): + - GTMSessionFetcher (~> 1.1) + - GTMSessionFetcher (1.1.8): + - GTMSessionFetcher/Full (= 1.1.8) + - GTMSessionFetcher/Core (1.1.8) + - GTMSessionFetcher/Full (1.1.8): + - GTMSessionFetcher/Core (= 1.1.8) + - Realm (2.4.3): + - Realm/Headers (= 2.4.3) + - Realm/Headers (2.4.3) + - ScoutMaps-iOS-SDK (3.0.2) + - SDWebImage (3.8.2): + - SDWebImage/Core (= 3.8.2) + - SDWebImage/Core (3.8.2) + +DEPENDENCIES: + - Crashlytics + - Fabric + - FBSDKCoreKit + - FBSDKLoginKit + - Google/SignIn + - Realm + - ScoutMaps-iOS-SDK + - SDWebImage (~> 3.8) + +SPEC CHECKSUMS: + Bolts: 8a7995239dbe724f9cba2248b766d48b7ebdd322 + Crashlytics: 79e236942ca1e7fc641df1feb9a275360a78ab6a + Fabric: 5911403591946b8228ab1c51d98f1d7137e863c6 + FBSDKCoreKit: 2d16979b28fe28c2b95af0d275ad5f9703c6c8de + FBSDKLoginKit: a9d9391506c687e2304a590bf9312837fce7f375 + FirebaseAnalytics: 0d1b7d81d5021155be37702a94ba1ec16d45365d + FirebaseCore: 225d40532489835a034b8f4e2c9c87fbf4f615a2 + FirebaseInstanceID: 2d0518b1378fe9d685ef40cbdd63d2fdc1125339 + Google: 813c467362eabc11385f5a5cc9ad0cb651a58f4e + GoogleSignIn: d7ad83f13480e1f30453471d00d19b5293ac46af + GoogleToolboxForMac: 8e329f1b599f2512c6b10676d45736bcc2cbbeb0 + GTMOAuth2: 7fc9c10f5c745f4d9850419ea88889fe3baa6b7d + GTMSessionFetcher: 6f8d8b28b7e345549ac471071608170b31cb4977 + Realm: e08d60b0048ccccd3949c8c28a92c4db5712d7e9 + ScoutMaps-iOS-SDK: 2b50decc60d3ff54c50f4dc2dd5b87513130930e + SDWebImage: 098e97e6176540799c27e804c96653ee0833d13c + +PODFILE CHECKSUM: 067e6ed93b573cbd216e6fa65943739e61f34e93 + +COCOAPODS: 1.2.0 diff --git a/photoShutter2.caf b/photoShutter2.caf deleted file mode 100644 index 2a05264b25fd4e584c33b41cd644cb102d27b0c2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 91366 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 axjmje*7wxj=H&{WMR_>*dno(Yzy2E`7#33i

!OU_#6YQHBUF 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