├── .ruby-version ├── .ruby-gemset ├── Gemfile ├── 360iDev AR Navigation ├── Assets.xcassets │ ├── Contents.json │ ├── AppIcon.appiconset │ │ ├── Icon.png │ │ ├── icon_20pt.png │ │ ├── icon_29pt.png │ │ ├── icon_40pt.png │ │ ├── icon_76pt.png │ │ ├── icon_20pt@2x.png │ │ ├── icon_20pt@3x.png │ │ ├── icon_29pt@2x.png │ │ ├── icon_29pt@3x.png │ │ ├── icon_40pt@2x.png │ │ ├── icon_40pt@3x.png │ │ ├── icon_60pt@2x.png │ │ ├── icon_60pt@3x.png │ │ ├── icon_76pt@2x.png │ │ ├── icon_83.5@2x.png │ │ ├── icon_20pt@2x-1.png │ │ ├── icon_29pt@2x-1.png │ │ ├── icon_40pt@2x-1.png │ │ └── Contents.json │ ├── 360_logo.imageset │ │ ├── 360_logo.png │ │ ├── 360_logo@2x.png │ │ ├── 360_logo@3x.png │ │ └── Contents.json │ ├── henrys_bubble.imageset │ │ ├── henrys_bubble.png │ │ ├── henrys_bubble@2x.png │ │ ├── henrys_bubble@3x.png │ │ └── Contents.json │ ├── hyatt_bubble.imageset │ │ ├── hyatt_bubble.png │ │ ├── hyatt_bubble@2x.png │ │ ├── hyatt_bubble@3x.png │ │ └── Contents.json │ ├── beer_garden_bubble.imageset │ │ ├── beer_garden_bubble.png │ │ ├── beer_garden_bubble@2x.png │ │ ├── beer_garden_bubble@3x.png │ │ └── Contents.json │ └── civic_center_bubble.imageset │ │ ├── civic_center_bubble.png │ │ ├── civic_center_bubble@2x.png │ │ ├── civic_center_bubble@3x.png │ │ └── Contents.json ├── Extensions │ ├── MKMapView+Zoom.swift │ ├── UIColor+Hex.swift │ ├── UIViewController+Alert.swift │ └── String+HTML.swift ├── AppDelegate.swift ├── Base.lproj │ └── LaunchScreen.storyboard ├── Models │ ├── Schedule.swift │ ├── Schedule+Additions.swift │ └── Action.swift ├── Info.plist ├── Main │ └── MainViewController.swift ├── Services │ ├── RemoteScheduleService.swift │ └── ScheduleService.swift ├── AR │ └── ShowPinsViewController.swift └── Schedule │ ├── Schedule.storyboard │ └── ScheduleTableViewController.swift ├── Pods ├── Target Support Files │ ├── ARCL │ │ ├── ARCL.modulemap │ │ ├── ARCL-dummy.m │ │ ├── ARCL-prefix.pch │ │ ├── ARCL-umbrella.h │ │ ├── ARCL.xcconfig │ │ └── ARCL-Info.plist │ ├── Kingfisher │ │ ├── Kingfisher.modulemap │ │ ├── Kingfisher-dummy.m │ │ ├── Kingfisher-prefix.pch │ │ ├── Kingfisher-umbrella.h │ │ ├── Kingfisher.xcconfig │ │ └── Kingfisher-Info.plist │ ├── Cartography │ │ ├── Cartography.modulemap │ │ ├── Cartography-dummy.m │ │ ├── Cartography-prefix.pch │ │ ├── Cartography-umbrella.h │ │ ├── Cartography.xcconfig │ │ └── Cartography-Info.plist │ └── Pods-360iDev AR Navigation │ │ ├── Pods-360iDev AR Navigation.modulemap │ │ ├── Pods-360iDev AR Navigation-dummy.m │ │ ├── Pods-360iDev AR Navigation-frameworks-Debug-output-files.xcfilelist │ │ ├── Pods-360iDev AR Navigation-frameworks-Release-output-files.xcfilelist │ │ ├── Pods-360iDev AR Navigation-frameworks-Debug-input-files.xcfilelist │ │ ├── Pods-360iDev AR Navigation-frameworks-Release-input-files.xcfilelist │ │ ├── Pods-360iDev AR Navigation-umbrella.h │ │ ├── Pods-360iDev AR Navigation-Info.plist │ │ ├── Pods-360iDev AR Navigation.debug.xcconfig │ │ ├── Pods-360iDev AR Navigation.release.xcconfig │ │ └── Pods-360iDev AR Navigation-acknowledgements.markdown ├── ARCL │ ├── Sources │ │ └── ARKit-CoreLocation │ │ │ ├── ARKit_CoreLocation.swift │ │ │ ├── Extensions │ │ │ ├── FloatingPoint+Radians.swift │ │ │ ├── SCNVector3+Extensions.swift │ │ │ ├── CGPoint+Extensions.swift │ │ │ ├── BaseTypes+Extensions.swift │ │ │ ├── SCNNode+Extensions.swift │ │ │ └── CLLocation+Extensions.swift │ │ │ ├── Location Manager │ │ │ ├── SceneLocationEstimate.swift │ │ │ ├── SceneLocationEstimate+Extensions.swift │ │ │ └── LocationManager.swift │ │ │ ├── SceneLocationViewEstimateDelegate.swift │ │ │ └── Nodes │ │ │ ├── PolylineNode.swift │ │ │ ├── ScalingScheme.swift │ │ │ └── LocationAnnotationNode.swift │ └── LICENSE ├── Cartography │ ├── Cartography │ │ ├── AutoresizingMaskLayoutProxy.swift │ │ ├── LayoutItem.swift │ │ ├── Extensions.swift │ │ ├── Expression.swift │ │ ├── Point.swift │ │ ├── Constraint.swift │ │ ├── Edge.swift │ │ ├── LayoutSupportProxy.swift │ │ ├── Dimension.swift │ │ ├── View.swift │ │ ├── LayoutGuideProxy.swift │ │ ├── LayoutSupport.swift │ │ ├── LayoutGuide.swift │ │ ├── ConstraintGroup.swift │ │ ├── Size.swift │ │ ├── Coefficients.swift │ │ ├── Context.swift │ │ ├── Priority.swift │ │ ├── ViewProxy.swift │ │ └── Compound.swift │ └── LICENSE ├── Manifest.lock ├── Local Podspecs │ └── ARCL.podspec.json └── Kingfisher │ ├── LICENSE │ └── Sources │ ├── Utility │ ├── Box.swift │ ├── Runtime.swift │ ├── String+MD5.swift │ ├── Delegate.swift │ ├── CallbackQueue.swift │ └── SizeExtensions.swift │ ├── Kingfisher.h │ ├── General │ ├── ImageSource │ │ ├── Resource.swift │ │ └── Source.swift │ └── Kingfisher.swift │ ├── Image │ └── Placeholder.swift │ ├── Networking │ ├── ImageDataProcessor.swift │ ├── RequestModifier.swift │ ├── RedirectHandler.swift │ ├── AuthenticationChallengeResponsable.swift │ ├── SessionDataTask.swift │ └── ImageModifier.swift │ └── Cache │ └── Storage.swift ├── Podfile ├── 360iDev AR Navigation.xcodeproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── xcuserdata │ └── einternicola.xcuserdatad │ └── xcschemes │ └── xcschememanagement.plist ├── 360iDev AR Navigation.xcworkspace ├── xcshareddata │ └── IDEWorkspaceChecks.plist └── contents.xcworkspacedata ├── CHANGELOG.md ├── Notes.md ├── Podfile.lock ├── 360iDevARNavigationTests ├── Info.plist ├── ARNavigationTests.swift └── RemoteScheduleServiceTest.swift ├── README.md └── .gitignore /.ruby-version: -------------------------------------------------------------------------------- 1 | ruby-2.5.0 2 | -------------------------------------------------------------------------------- /.ruby-gemset: -------------------------------------------------------------------------------- 1 | 360iDev-AR-Navigation 2 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | gem "cocoapods" 3 | gem "fastlane" 4 | gem "synx" 5 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /Pods/Target Support Files/ARCL/ARCL.modulemap: -------------------------------------------------------------------------------- 1 | framework module ARCL { 2 | umbrella header "ARCL-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ARCL/ARCL-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_ARCL : NSObject 3 | @end 4 | @implementation PodsDummy_ARCL 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/ARKit_CoreLocation.swift: -------------------------------------------------------------------------------- 1 | struct ARKit_CoreLocation { 2 | // swiftlint:disable:previous type_name 3 | var text = "Hello, World!" 4 | } 5 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/Icon.png -------------------------------------------------------------------------------- /Pods/Target Support Files/Kingfisher/Kingfisher.modulemap: -------------------------------------------------------------------------------- 1 | framework module Kingfisher { 2 | umbrella header "Kingfisher-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/360_logo.imageset/360_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/360_logo.imageset/360_logo.png -------------------------------------------------------------------------------- /Pods/Target Support Files/Cartography/Cartography.modulemap: -------------------------------------------------------------------------------- 1 | framework module Cartography { 2 | umbrella header "Cartography-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_76pt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_76pt.png -------------------------------------------------------------------------------- /Pods/Target Support Files/Cartography/Cartography-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Cartography : NSObject 3 | @end 4 | @implementation PodsDummy_Cartography 5 | @end 6 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Kingfisher/Kingfisher-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Kingfisher : NSObject 3 | @end 4 | @implementation PodsDummy_Kingfisher 5 | @end 6 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/360_logo.imageset/360_logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/360_logo.imageset/360_logo@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/360_logo.imageset/360_logo@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/360_logo.imageset/360_logo@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_60pt@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_60pt@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_76pt@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_83.5@2x.png -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | 2 | platform :ios, '11.0' 3 | 4 | target '360iDev AR Navigation' do 5 | use_frameworks! 6 | pod 'ARCL', '1.2.1' 7 | pod 'Cartography' 8 | pod 'Kingfisher' 9 | 10 | 11 | end 12 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_20pt@2x-1.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_29pt@2x-1.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/icon_40pt@2x-1.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/henrys_bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/henrys_bubble.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/hyatt_bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/hyatt_bubble.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/hyatt_bubble@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/hyatt_bubble@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/hyatt_bubble@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/hyatt_bubble@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/henrys_bubble@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/henrys_bubble@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/henrys_bubble@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/henrys_bubble@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/beer_garden_bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/beer_garden_bubble.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/civic_center_bubble.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/civic_center_bubble.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/beer_garden_bubble@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/beer_garden_bubble@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/beer_garden_bubble@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/beer_garden_bubble@3x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/civic_center_bubble@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/civic_center_bubble@2x.png -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/civic_center_bubble@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/intere/360iDevARNavigation/HEAD/360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/civic_center_bubble@3x.png -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_360iDev_AR_Navigation { 2 | umbrella header "Pods-360iDev AR Navigation-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_360iDev_AR_Navigation : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_360iDev_AR_Navigation 5 | @end 6 | -------------------------------------------------------------------------------- /360iDev AR Navigation.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ARCL/ARCL-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Cartography/Cartography-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Kingfisher/Kingfisher-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-frameworks-Debug-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ARCL.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cartography.framework 3 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-frameworks-Release-output-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/ARCL.framework 2 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Cartography.framework 3 | ${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Kingfisher.framework -------------------------------------------------------------------------------- /360iDev AR Navigation.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /360iDev AR Navigation.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /360iDev AR Navigation.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-frameworks-Debug-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/ARCL/ARCL.framework 3 | ${BUILT_PRODUCTS_DIR}/Cartography/Cartography.framework 4 | ${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-frameworks-Release-input-files.xcfilelist: -------------------------------------------------------------------------------- 1 | ${PODS_ROOT}/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-frameworks.sh 2 | ${BUILT_PRODUCTS_DIR}/ARCL/ARCL.framework 3 | ${BUILT_PRODUCTS_DIR}/Cartography/Cartography.framework 4 | ${BUILT_PRODUCTS_DIR}/Kingfisher/Kingfisher.framework -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | * 1.0.1 4 | * [Adds the schedule](https://github.com/intere/360iDevARNavigation/pull/1) 5 | * Adds error messages for unsupported devices 6 | * Adds error messages to show users when things fail (instead of just `print` or `assertionFailure`) 7 | 8 | * 1.0.0 9 | * Shows pins for each of the locations 10 | * Shows AR navigation to each of the locations 11 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ARCL/ARCL-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double ARCLVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char ARCLVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/AutoresizingMaskLayoutProxy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AutoresizingMaskLayoutProxy.swift 3 | // Cartography-iOS 4 | // 5 | // Created by Vitor Travain on 24/10/17. 6 | // Copyright © 2017 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol AutoresizingMaskLayoutProxy: LayoutProxy { 12 | var translatesAutoresizingMaskIntoConstraints: Bool { get set } 13 | } 14 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Cartography/Cartography-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double CartographyVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char CartographyVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Extensions/FloatingPoint+Radians.swift: -------------------------------------------------------------------------------- 1 | // 2 | // FloatingPoint+Radians.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 03/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public extension FloatingPoint { 12 | var degreesToRadians: Self { return self * .pi / 180 } 13 | var radiansToDegrees: Self { return self * 180 / .pi } 14 | } 15 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Kingfisher/Kingfisher-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "Kingfisher.h" 14 | 15 | FOUNDATION_EXPORT double KingfisherVersionNumber; 16 | FOUNDATION_EXPORT const unsigned char KingfisherVersionString[]; 17 | 18 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_360iDev_AR_NavigationVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_360iDev_AR_NavigationVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /360iDev AR Navigation.xcodeproj/xcuserdata/einternicola.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | 360iDev AR Navigation.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 4 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/LayoutItem.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LayoutItem.swift 3 | // Cartography-iOS 4 | // 5 | // Created by Vitor Travain on 10/10/17. 6 | // Copyright © 2017 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | public protocol LayoutItem: class { 10 | associatedtype ProxyType: LayoutProxy 11 | 12 | func asProxy(context: Context) -> ProxyType 13 | } 14 | 15 | extension LayoutItem { 16 | public func asProxy() -> ProxyType { 17 | return asProxy(context: Context()) 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Extensions.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 22/01/15. 6 | // Copyright (c) 2015 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | internal extension Dictionary { 16 | init(_ pairs: [Element]) { 17 | self.init() 18 | 19 | for (key, value) in pairs { 20 | self[key] = value 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/360_logo.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "360_logo.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "360_logo@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "360_logo@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Pods/Target Support Files/Cartography/Cartography.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Cartography 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Cartography 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/hyatt_bubble.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "hyatt_bubble.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "hyatt_bubble@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "hyatt_bubble@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Expression.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Expression.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 17/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public struct Expression { 12 | let value: T 13 | var coefficients: [Coefficients] 14 | 15 | init(_ value: T, _ coefficients: [Coefficients]) { 16 | assert(coefficients.count > 0) 17 | 18 | self.value = value 19 | self.coefficients = coefficients 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/henrys_bubble.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "henrys_bubble.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "henrys_bubble@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "henrys_bubble@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/beer_garden_bubble.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "beer_garden_bubble.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "beer_garden_bubble@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "beer_garden_bubble@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Notes.md: -------------------------------------------------------------------------------- 1 | # Developer Notes 2 | 3 | #### Schedule JSON 4 | ```bash 5 | curl 'https://360idev.com/wp-admin/admin-ajax.php' \ 6 | -H 'sec-fetch-mode: cors' \ 7 | -H 'origin: https://360idev.com' \ 8 | -H 'content-type: application/x-www-form-urlencoded; charset=UTF-8' \ 9 | -H 'accept: application/json, text/javascript, */*; q=0.01' \ 10 | -H 'referer: https://360idev.com/schedule/' \ 11 | -H 'authority: 360idev.com' \ 12 | -H 'sec-fetch-site: same-origin' --data 'action=get_schedule&data-timestamp=&data-location=&data-track=' --compressed > /tmp/schedule.json 13 | ``` 14 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/civic_center_bubble.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "civic_center_bubble.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "civic_center_bubble@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "civic_center_bubble@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ARCL (1.2.1) 3 | - Cartography (4.0.0) 4 | - Kingfisher (5.6.0) 5 | 6 | DEPENDENCIES: 7 | - ARCL (= 1.2.1) 8 | - Cartography 9 | - Kingfisher 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - ARCL 14 | - Cartography 15 | - Kingfisher 16 | 17 | SPEC CHECKSUMS: 18 | ARCL: d1a534afb4d5b8ff5c51c5cfe23bb998df36c606 19 | Cartography: c5626d29056b20f1e95c017326ee4df57cc39ad8 20 | Kingfisher: 1a50df6880a60bae26f3e21a0df3d17b892f5e0b 21 | 22 | PODFILE CHECKSUM: c86e57ec44e3c2e75360980f12b017115e1890d9 23 | 24 | COCOAPODS: 1.7.5 25 | -------------------------------------------------------------------------------- /Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ARCL (1.2.1) 3 | - Cartography (4.0.0) 4 | - Kingfisher (5.6.0) 5 | 6 | DEPENDENCIES: 7 | - ARCL (= 1.2.1) 8 | - Cartography 9 | - Kingfisher 10 | 11 | SPEC REPOS: 12 | https://github.com/cocoapods/specs.git: 13 | - ARCL 14 | - Cartography 15 | - Kingfisher 16 | 17 | SPEC CHECKSUMS: 18 | ARCL: d1a534afb4d5b8ff5c51c5cfe23bb998df36c606 19 | Cartography: c5626d29056b20f1e95c017326ee4df57cc39ad8 20 | Kingfisher: 1a50df6880a60bae26f3e21a0df3d17b892f5e0b 21 | 22 | PODFILE CHECKSUM: c86e57ec44e3c2e75360980f12b017115e1890d9 23 | 24 | COCOAPODS: 1.7.5 25 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Kingfisher/Kingfisher.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "Accelerate" -framework "CFNetwork" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/Kingfisher 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Location Manager/SceneLocationEstimate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneLocationEstimate.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 03/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreLocation 11 | import SceneKit 12 | 13 | public class SceneLocationEstimate { 14 | public let location: CLLocation 15 | public let position: SCNVector3 16 | 17 | init(location: CLLocation, position: SCNVector3) { 18 | self.location = location 19 | self.position = position 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Extensions/SCNVector3+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SCNVecto3+Extensions.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 23/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import SceneKit 10 | 11 | public extension SCNVector3 { 12 | ///Calculates distance between vectors 13 | ///Doesn't include the y axis, matches functionality of CLLocation 'distance' function. 14 | func distance(to anotherVector: SCNVector3) -> Float { 15 | return sqrt(pow(anotherVector.x - x, 2) + pow(anotherVector.z - z, 2)) 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Point.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Point.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 18/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | public struct Point: Compound, RelativeCompoundEquality, RelativeCompoundInequality { 16 | public let context: Context 17 | public let properties: [Property] 18 | 19 | internal init(_ context: Context, _ properties: [Property]) { 20 | self.context = context 21 | self.properties = properties 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ARCL/ARCL.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/ARCL 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "CoreLocation" -framework "Foundation" -framework "MapKit" -framework "SceneKit" -framework "UIKit" -weak_framework "ARKit" 4 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 5 | PODS_BUILD_DIR = ${BUILD_DIR} 6 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 7 | PODS_ROOT = ${SRCROOT} 8 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/ARCL 9 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 10 | SKIP_INSTALL = YES 11 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Extensions/MKMapView+Zoom.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MKMapView+Zoom.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import MapKit 10 | 11 | extension MKMapView { 12 | 13 | /// Zooms to the provided route for you. 14 | /// 15 | /// - Parameters: 16 | /// - route: The route to zoom into. 17 | /// - animated: Whether or not to animate (defaults to true). 18 | func zoom(to route: MKRoute, animated: Bool = true) { 19 | let mapRect = route.polyline.boundingMapRect 20 | setVisibleMapRect(mapRect, animated: animated) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Constraint.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Constraint.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 06/10/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | internal class Constraint { 16 | let layoutConstraint: NSLayoutConstraint 17 | 18 | func install() { 19 | layoutConstraint.isActive = true 20 | } 21 | 22 | func uninstall() { 23 | layoutConstraint.isActive = false 24 | } 25 | 26 | init(_ layoutConstraint: NSLayoutConstraint) { 27 | self.layoutConstraint = layoutConstraint 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Edge.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Edge.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 17/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | public struct Edge : Property, RelativeEquality, RelativeInequality, Addition, Multiplication { 16 | public let attribute: LayoutAttribute 17 | public let context: Context 18 | public let item: AnyObject 19 | 20 | internal init(_ context: Context, _ item: AnyObject, _ attribute: LayoutAttribute) { 21 | self.attribute = attribute 22 | self.context = context 23 | self.item = item 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/LayoutSupportProxy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LayoutSupportProxy.swift 3 | // Cartography-iOS 4 | // 5 | // Created by Vitor Travain on 11/10/17. 6 | // Copyright © 2017 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | 12 | public final class LayoutSupportProxy: SupportsHeightLayoutProxy, SupportsTopLayoutProxy, SupportsBottomLayoutProxy { 13 | public let context: Context 14 | 15 | private let layoutGuide: UILayoutSupport 16 | public var item: AnyObject { 17 | return layoutGuide 18 | } 19 | 20 | public init(context: Context, item: LayoutSupport) { 21 | self.context = context 22 | self.layoutGuide = item.layoutGuide 23 | } 24 | } 25 | #endif 26 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Extensions/CGPoint+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CGPoint+Extensions.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 03/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import SceneKit 11 | 12 | extension CGPoint { 13 | static func pointWithVector(vector: SCNVector3) -> CGPoint { 14 | return CGPoint(x: CGFloat(vector.x), y: CGFloat(0 - vector.z)) 15 | } 16 | 17 | func radiusContainsPoint(radius: CGFloat, point: CGPoint) -> Bool { 18 | let x = pow(point.x - self.x, 2) 19 | let y = pow(point.y - self.y, 2) 20 | let radiusSquared = pow(radius, 2) 21 | 22 | return x + y <= radiusSquared 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Dimension.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Dimension.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 17/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | public struct Dimension : Property, NumericalEquality, RelativeEquality, NumericalInequality, RelativeInequality, Addition, Multiplication { 16 | public let attribute: LayoutAttribute 17 | public let context: Context 18 | public let item: AnyObject 19 | 20 | internal init(_ context: Context, _ item: AnyObject, _ attribute: LayoutAttribute) { 21 | self.attribute = attribute 22 | self.context = context 23 | self.item = item 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/View.swift: -------------------------------------------------------------------------------- 1 | // 2 | // View.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 26/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | #if os(iOS) || os(tvOS) 12 | import UIKit 13 | public typealias View = UIView 14 | 15 | extension UIView: LayoutItem { 16 | public func asProxy(context: Context) -> ViewProxy { 17 | return ViewProxy(context: context, view: self) 18 | } 19 | } 20 | #else 21 | import AppKit 22 | public typealias View = NSView 23 | 24 | extension NSView: LayoutItem { 25 | public func asProxy(context: Context) -> ViewProxy { 26 | return ViewProxy(context: context, view: self) 27 | } 28 | } 29 | #endif 30 | -------------------------------------------------------------------------------- /360iDevARNavigationTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Extensions/BaseTypes+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // BaseTypes+Extensions.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Ilya Seliverstov on 08/08/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public extension Double { 12 | 13 | var metersToLatitude: Double { 14 | return self / (6_378_137.0) 15 | } 16 | 17 | var metersToLongitude: Double { 18 | return self / (6_356_752.3) 19 | } 20 | } 21 | 22 | public extension Float { 23 | var short: String { return String(format: "%.2f", self) } 24 | } 25 | 26 | public extension Int { 27 | var short: String { return String(format: "%02d", self) } 28 | var short3: String { return String(format: "%03d", self / 1_000_000) } 29 | } 30 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Extensions/UIColor+Hex.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIColor+Hex.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/15/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIColor { 12 | 13 | convenience init(red: Int, green: Int, blue: Int, a: CGFloat = 1.0) { 14 | self.init( 15 | red: CGFloat(red) / 255.0, 16 | green: CGFloat(green) / 255.0, 17 | blue: CGFloat(blue) / 255.0, 18 | alpha: a 19 | ) 20 | } 21 | 22 | convenience init(rgb: Int, a: CGFloat = 1.0) { 23 | self.init( 24 | red: (rgb >> 16) & 0xFF, 25 | green: (rgb >> 8) & 0xFF, 26 | blue: rgb & 0xFF, 27 | a: a 28 | ) 29 | } 30 | 31 | } 32 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/LayoutGuideProxy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LayoutGuideProxy.swift 3 | // Cartography 4 | // 5 | // Created by Vitor Travain on 11/10/17. 6 | // Copyright © 2017 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | @available(iOS, introduced: 9.0) 10 | @available(tvOS, introduced: 9.0) 11 | @available(OSX, introduced: 10.11) 12 | public final class LayoutGuideProxy: SupportsPositioningLayoutProxy { 13 | public let context: Context 14 | 15 | private let layoutGuide: LayoutGuide 16 | public var item: AnyObject { 17 | return layoutGuide 18 | } 19 | 20 | public init(context: Context, item: LayoutGuide) { 21 | self.context = context 22 | self.layoutGuide = item 23 | } 24 | 25 | public var owningView: ViewProxy? { 26 | return layoutGuide.owningView?.asProxy(context: context) 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Extensions/UIViewController+Alert.swift: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Alert.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | extension UIViewController { 12 | 13 | typealias AlertOKCallback = (UIAlertAction) -> Void 14 | 15 | /// Shows an alert with a title of "Error" and an "OK" button that dismisses 16 | /// the alert. 17 | /// 18 | /// - Parameter message: The message to show in the alert. 19 | func showErrorAlert(message: String, completion handler: AlertOKCallback? = nil) { 20 | let alertVC = UIAlertController(title: "Error", message: message, preferredStyle: .alert) 21 | alertVC.addAction(UIAlertAction(title: "OK", style: .default, handler: handler)) 22 | 23 | present(alertVC, animated: true) 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /Pods/Local Podspecs/ARCL.podspec.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ARCL", 3 | "version": "1.2.1", 4 | "summary": "ARKit + CoreLocation combines the high accuracy of AR with the scale of GPS data.", 5 | "homepage": "https://github.com/ProjectDent/arkit-corelocation", 6 | "authors": { 7 | "Andrew Hart": "Andrew@ProjectDent.com" 8 | }, 9 | "license": { 10 | "type": "MIT", 11 | "file": "LICENSE" 12 | }, 13 | "source": { 14 | "git": "https://ProjectDent@github.com/ProjectDent/ARKit-CoreLocation.git", 15 | "tag": "1.2.1", 16 | "submodules": false 17 | }, 18 | "platforms": { 19 | "ios": "9.0" 20 | }, 21 | "swift_versions": "5.0", 22 | "requires_arc": true, 23 | "source_files": "Sources/**/*.{swift}", 24 | "frameworks": [ 25 | "Foundation", 26 | "UIKit", 27 | "CoreLocation", 28 | "MapKit", 29 | "SceneKit" 30 | ], 31 | "weak_frameworks": "ARKit", 32 | "swift_version": "5.0" 33 | } 34 | -------------------------------------------------------------------------------- /Pods/Target Support Files/ARCL/ARCL-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.2.1 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Kingfisher/Kingfisher-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 5.6.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Cartography/Cartography-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 4.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | ${PRODUCT_BUNDLE_IDENTIFIER} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /360iDevARNavigationTests/ARNavigationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ARNavigationTests.swift 3 | // 360iDevARNavigationTests 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | @testable import _60iDev_AR_Navigation 10 | import XCTest 11 | 12 | class ARNavigationTests: XCTestCase { 13 | 14 | func testFindJSONFile() { 15 | guard let schedulePath = Bundle.main.path(forResource: "schedule", ofType: "json") else { 16 | return XCTFail("No path for schedule.json") 17 | } 18 | let url = URL(fileURLWithPath: schedulePath) 19 | do { 20 | let data = try Data(contentsOf: url) 21 | let schedule = try JSONDecoder().decode(Schedule.self, from: data) 22 | XCTAssertNotEqual(0, schedule.sessions.count) 23 | print("There are \(schedule.sessions.count) sessions") 24 | 25 | } catch { 26 | XCTFail("Failed with error: \(error.localizedDescription)") 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /360iDevARNavigationTests/RemoteScheduleServiceTest.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RemoteScheduleServiceTest.swift 3 | // 360iDevARNavigationTests 4 | // 5 | // Created by Eric Internicola on 8/20/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | @testable import _60iDev_AR_Navigation 10 | import XCTest 11 | 12 | class RemoteScheduleServiceTest: XCTestCase { 13 | 14 | func testFetchSchedule() { 15 | let exp = expectation(description: "Load Schedule from 360iDev Site") 16 | 17 | RemoteScheduleService.shared.loadSchedule { (schedule, error) in 18 | defer { 19 | exp.fulfill() 20 | } 21 | if let error = error { 22 | return XCTFail("Failed with error: \(error.localizedDescription)") 23 | } 24 | guard let schedule = schedule else { 25 | return XCTFail("No schedule") 26 | } 27 | 28 | XCTAssertNotEqual(0, schedule.sessions.count) 29 | } 30 | 31 | waitForExpectations(timeout: 30, handler: nil) 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/LayoutSupport.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LayoutSupport.swift 3 | // Cartography 4 | // 5 | // Created by Timothy Chilvers on 30/03/2016. 6 | // Copyright © 2016 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | #if os(iOS) || os(tvOS) 12 | import UIKit 13 | 14 | public final class LayoutSupport: LayoutItem { 15 | let layoutGuide : UILayoutSupport 16 | 17 | init(layoutGuide: UILayoutSupport) { 18 | self.layoutGuide = layoutGuide 19 | } 20 | 21 | public func asProxy(context: Context) -> LayoutSupportProxy { 22 | return LayoutSupportProxy(context: context, item: self) 23 | } 24 | } 25 | 26 | public extension UIViewController { 27 | var car_topLayoutGuide : LayoutSupport { 28 | get { 29 | return LayoutSupport(layoutGuide: self.topLayoutGuide) 30 | } 31 | } 32 | 33 | var car_bottomLayoutGuide : LayoutSupport { 34 | get { 35 | return LayoutSupport(layoutGuide: self.bottomLayoutGuide) 36 | } 37 | } 38 | } 39 | 40 | #endif 41 | -------------------------------------------------------------------------------- /Pods/ARCL/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Project Dent (https://ProjectDent.com) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /Pods/Kingfisher/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2018 Wei Wang 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/LayoutGuide.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LayoutGuide.swift 3 | // Cartography 4 | // 5 | // Created by Vitor Travain on 11/10/17. 6 | // Copyright © 2017 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | 12 | @available(iOS, introduced: 9.0) 13 | @available(tvOS, introduced: 9.0) 14 | public typealias LayoutGuide = UILayoutGuide 15 | 16 | @available(iOS, introduced: 9.0) 17 | @available(tvOS, introduced: 9.0) 18 | extension UILayoutGuide: LayoutItem { 19 | 20 | @available(iOS, introduced: 9.0) 21 | @available(tvOS, introduced: 9.0) 22 | public func asProxy(context: Context) -> LayoutGuideProxy { 23 | return LayoutGuideProxy(context: context, item: self) 24 | } 25 | } 26 | #elseif os(OSX) 27 | import AppKit 28 | 29 | @available(OSX, introduced: 10.11) 30 | public typealias LayoutGuide = NSLayoutGuide 31 | 32 | @available(OSX, introduced: 10.11) 33 | extension NSLayoutGuide: LayoutItem { 34 | 35 | @available(OSX, introduced: 10.11) 36 | public func asProxy(context: Context) -> LayoutGuideProxy { 37 | return LayoutGuideProxy(context: context, item: self) 38 | } 39 | } 40 | #endif 41 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/ConstraintGroup.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ConstraintGroup.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 22/01/15. 6 | // Copyright (c) 2015 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public class ConstraintGroup { 12 | private var constraints: [Constraint] = [] 13 | 14 | @available(OSX, introduced: 10.10) 15 | @available(iOS, introduced: 8.0) 16 | public var active: Bool { 17 | get { 18 | return constraints 19 | .map { $0.layoutConstraint.isActive } 20 | .reduce(true) { $0 && $1 } 21 | } 22 | set { 23 | for constraint in constraints { 24 | constraint.layoutConstraint.isActive = newValue 25 | } 26 | } 27 | } 28 | 29 | public init() { 30 | 31 | } 32 | 33 | internal func replaceConstraints(_ constraints: [Constraint]) { 34 | for constraint in self.constraints { 35 | constraint.uninstall() 36 | } 37 | 38 | self.constraints = constraints 39 | 40 | for constraint in self.constraints { 41 | constraint.install() 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Location Manager/SceneLocationEstimate+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneLocationEstimate+Extensions.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 16/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import CoreLocation 10 | import SceneKit 11 | 12 | extension SceneLocationEstimate { 13 | ///Compares the location's position to another position, to determine the translation between them 14 | public func locationTranslation(to position: SCNVector3) -> LocationTranslation { 15 | return LocationTranslation( 16 | latitudeTranslation: Double(self.position.z - position.z), 17 | longitudeTranslation: Double(position.x - self.position.x), 18 | altitudeTranslation: Double(position.y - self.position.y)) 19 | } 20 | 21 | ///Translates the location by comparing with a given position 22 | public func translatedLocation(to position: SCNVector3) -> CLLocation { 23 | let translation = self.locationTranslation(to: position) 24 | let translatedLocation = self.location.translatedLocation(with: translation) 25 | 26 | return translatedLocation 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation.debug.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ARCL" "${PODS_CONFIGURATION_BUILD_DIR}/Cartography" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ARCL/ARCL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cartography/Cartography.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "ARCL" -framework "Accelerate" -framework "CFNetwork" -framework "Cartography" -framework "CoreLocation" -framework "Foundation" -framework "Kingfisher" -framework "MapKit" -framework "SceneKit" -framework "UIKit" -weak_framework "ARKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation.release.xcconfig: -------------------------------------------------------------------------------- 1 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES 2 | FRAMEWORK_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ARCL" "${PODS_CONFIGURATION_BUILD_DIR}/Cartography" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher" 3 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 4 | HEADER_SEARCH_PATHS = $(inherited) "${PODS_CONFIGURATION_BUILD_DIR}/ARCL/ARCL.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Cartography/Cartography.framework/Headers" "${PODS_CONFIGURATION_BUILD_DIR}/Kingfisher/Kingfisher.framework/Headers" 5 | LD_RUNPATH_SEARCH_PATHS = $(inherited) '@executable_path/Frameworks' '@loader_path/Frameworks' 6 | OTHER_LDFLAGS = $(inherited) -framework "ARCL" -framework "Accelerate" -framework "CFNetwork" -framework "Cartography" -framework "CoreLocation" -framework "Foundation" -framework "Kingfisher" -framework "MapKit" -framework "SceneKit" -framework "UIKit" -weak_framework "ARKit" 7 | OTHER_SWIFT_FLAGS = $(inherited) -D COCOAPODS 8 | PODS_BUILD_DIR = ${BUILD_DIR} 9 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 10 | PODS_PODFILE_DIR_PATH = ${SRCROOT}/. 11 | PODS_ROOT = ${SRCROOT}/Pods 12 | -------------------------------------------------------------------------------- /360iDev AR Navigation/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/11/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool { 17 | 18 | return true 19 | } 20 | 21 | func applicationDidBecomeActive(_ application: UIApplication) { 22 | DispatchQueue.global(qos: .utility).async { 23 | ScheduleService.shared.reloadBundle() 24 | } 25 | RemoteScheduleService.shared.cacheSchedule { (schedule, error) in 26 | if let error = error { 27 | return assertionFailure(error.localizedDescription) 28 | } 29 | guard schedule != nil else { 30 | return assertionFailure() 31 | } 32 | ScheduleService.shared.reloadBundle() 33 | assert(ScheduleService.shared.source == .documents) 34 | } 35 | } 36 | 37 | } 38 | 39 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | [](https://apps.apple.com/app/id1476472126) 4 | 5 | # 360iDev AR Navigation 6 | 7 | An ARKit-CoreLocation based experience for 360iDev 2019. 8 | AR Features include: 9 | - Directions to the Hyatt (conference) and the various food venues that the conference will go to. 10 | - AR Pins to show you the direction of each of the conference locations (Hyatt, food venues). 11 | - The conference schedule is available in the app and the app checks for updates to the schedule. 12 | 13 | v1.1.0 Adds remote updates to the schedule and PTR for the schedule VC. 14 | 15 | v1.0.1 Adds the Schedule 16 | 17 | ## Use Cases 18 | 19 | ### Navigation 20 | 21 | 22 | ### AR Pins 23 | Think: What direction is Henry's Tavern? 24 | 25 | 26 | 27 | ### Schedule 28 | 29 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Size.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Size.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 18/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | public struct Size : Compound, RelativeCompoundEquality, RelativeCompoundInequality { 16 | public let context: Context 17 | public let properties: [Property] 18 | 19 | internal init(_ context: Context, _ properties: [Property]) { 20 | self.context = context 21 | self.properties = properties 22 | } 23 | } 24 | 25 | // MARK: Multiplication 26 | 27 | public func * (m: CGFloat, rhs: Expression) -> Expression { 28 | return Expression(rhs.value, rhs.coefficients.map { $0 * m }) 29 | } 30 | 31 | public func * (lhs: Expression, rhs: CGFloat) -> Expression { 32 | return rhs * lhs 33 | } 34 | 35 | public func * (m: CGFloat, rhs: Size) -> Expression { 36 | return Expression(rhs, [ Coefficients(m, 0), Coefficients(m, 0) ]) 37 | } 38 | 39 | public func * (lhs: Size, rhs: CGFloat) -> Expression { 40 | return rhs * lhs 41 | } 42 | 43 | // MARK: Division 44 | 45 | public func / (lhs: Expression, rhs: CGFloat) -> Expression { 46 | return lhs * (1 / rhs) 47 | } 48 | 49 | public func / (lhs: Size, rhs: CGFloat) -> Expression { 50 | return lhs * (1 / rhs) 51 | } 52 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Utility/Box.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Box.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2018/3/17. 6 | // Copyright (c) 2019 Wei Wang 7 | // 8 | // Permission is hereby granted, free of charge, to any person obtaining a copy 9 | // of this software and associated documentation files (the "Software"), to deal 10 | // in the Software without restriction, including without limitation the rights 11 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 | // copies of the Software, and to permit persons to whom the Software is 13 | // furnished to do so, subject to the following conditions: 14 | // 15 | // The above copyright notice and this permission notice shall be included in 16 | // all copies or substantial portions of the Software. 17 | // 18 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 24 | // THE SOFTWARE. 25 | 26 | import Foundation 27 | 28 | class Box { 29 | var value: T 30 | 31 | init(_ value: T) { 32 | self.value = value 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Coefficients.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Coefficients.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 17/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | #if os(iOS) 11 | import UIKit 12 | #endif 13 | 14 | public struct Coefficients { 15 | var multiplier: CGFloat = 1 16 | var constant: CGFloat = 0 17 | 18 | init() { } 19 | 20 | init(_ multiplier: CGFloat, _ constant: CGFloat) { 21 | self.constant = constant 22 | self.multiplier = multiplier 23 | } 24 | } 25 | 26 | // MARK: Addition 27 | 28 | public func + (c: CGFloat, rhs: Coefficients) -> Coefficients { 29 | return Coefficients(rhs.multiplier, rhs.constant + c) 30 | } 31 | 32 | public func + (lhs: Coefficients, rhs: CGFloat) -> Coefficients { 33 | return rhs + lhs 34 | } 35 | 36 | // MARK: Subtraction 37 | 38 | public func - (c: CGFloat, rhs: Coefficients) -> Coefficients { 39 | return Coefficients(rhs.multiplier, rhs.constant - c) 40 | } 41 | 42 | public func - (lhs: Coefficients, rhs: CGFloat) -> Coefficients { 43 | return rhs - lhs 44 | } 45 | 46 | // MARK: Multiplication 47 | 48 | public func * (m: CGFloat, rhs: Coefficients) -> Coefficients { 49 | return Coefficients(rhs.multiplier * m, rhs.constant * m) 50 | } 51 | 52 | public func * (lhs: Coefficients, rhs: CGFloat) -> Coefficients { 53 | return rhs * lhs 54 | } 55 | 56 | // MARK: Division 57 | 58 | public func / (m: CGFloat, rhs: Coefficients) -> Coefficients { 59 | return Coefficients(rhs.multiplier / m, rhs.constant / m) 60 | } 61 | 62 | public func / (lhs: Coefficients, rhs: CGFloat) -> Coefficients { 63 | return rhs / lhs 64 | } 65 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Utility/Runtime.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Runtime.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2018/10/12. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | func getAssociatedObject(_ object: Any, _ key: UnsafeRawPointer) -> T? { 30 | return objc_getAssociatedObject(object, key) as? T 31 | } 32 | 33 | func setRetainedAssociatedObject(_ object: Any, _ key: UnsafeRawPointer, _ value: T) { 34 | objc_setAssociatedObject(object, key, value, .OBJC_ASSOCIATION_RETAIN_NONATOMIC) 35 | } 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | .DS_Store 6 | 7 | ## Build generated 8 | build/ 9 | DerivedData/ 10 | fastlane/README.md 11 | 12 | ## Various settings 13 | *.pbxuser 14 | !default.pbxuser 15 | *.mode1v3 16 | !default.mode1v3 17 | *.mode2v3 18 | !default.mode2v3 19 | *.perspectivev3 20 | !default.perspectivev3 21 | xcuserdata/ 22 | 23 | ## Other 24 | *.moved-aside 25 | *.xcuserstate 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | ## Playgrounds 34 | timeline.xctimeline 35 | playground.xcworkspace 36 | 37 | # Swift Package Manager 38 | # 39 | # Add this line if you want to avoid checking in source code from Swift Package Manager dependencies. 40 | # Packages/ 41 | .build/ 42 | 43 | # CocoaPods 44 | # 45 | # We recommend against adding the Pods directory to your .gitignore. However 46 | # you should judge for yourself, the pros and cons are mentioned at: 47 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 48 | # 49 | # Pods/ 50 | 51 | # Carthage 52 | # 53 | # Add this line if you want to avoid checking in source code from Carthage dependencies. 54 | # Carthage/Checkouts 55 | 56 | Carthage/Build 57 | 58 | # fastlane 59 | # 60 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the 61 | # screenshots whenever they are needed. 62 | # For more information about the recommended setup visit: 63 | # https://github.com/fastlane/fastlane/blob/master/fastlane/docs/Gitignore.md 64 | 65 | fastlane/report.xml 66 | fastlane/Preview.html 67 | fastlane/screenshots 68 | fastlane/test_output 69 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Kingfisher.h: -------------------------------------------------------------------------------- 1 | // 2 | // Kingfisher.h 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 15/4/6. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | #import 28 | 29 | //! Project version number for Kingfisher. 30 | FOUNDATION_EXPORT double KingfisherVersionNumber; 31 | 32 | //! Project version string for Kingfisher. 33 | FOUNDATION_EXPORT const unsigned char KingfisherVersionString[]; 34 | 35 | // In this header, you should import all the public headers of your framework using statements like #import 36 | 37 | 38 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Models/Schedule.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Schedule.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | // This file was generated from JSON Schema using quicktype, do not modify it directly. 10 | // To parse the JSON, add this file to your project and do: 11 | // 12 | // let schedule = try? JSONDecoder().decode(Schedule.self, from: jsonData) 13 | 14 | import Foundation 15 | 16 | // MARK: - Schedule 17 | struct Schedule: Codable { 18 | let sessions: [Session] 19 | let strings: Strings 20 | } 21 | 22 | // MARK: - Session 23 | struct Session: Codable { 24 | let postTitle: String 25 | let url: String 26 | let time, endTime: String 27 | let date: DateEnum 28 | let location, color: String 29 | let speakers: [Speaker] 30 | 31 | enum CodingKeys: String, CodingKey { 32 | case postTitle = "post_title" 33 | case url, time 34 | case endTime = "end_time" 35 | case date, location, color, speakers 36 | } 37 | 38 | } 39 | 40 | enum DateEnum: String, Codable { 41 | case august252019 = "August 25, 2019" 42 | case august262019 = "August 26, 2019" 43 | case august272019 = "August 27, 2019" 44 | case august282019 = "August 28, 2019" 45 | } 46 | 47 | // MARK: - Speaker 48 | struct Speaker: Codable { 49 | let postTitle, featured: String 50 | let url: String 51 | let postImage: String 52 | 53 | enum CodingKeys: String, CodingKey { 54 | case postTitle = "post_title" 55 | case featured, url 56 | case postImage = "post_image" 57 | } 58 | } 59 | 60 | // MARK: - Strings 61 | struct Strings: Codable { 62 | let moreInfo: String 63 | 64 | enum CodingKeys: String, CodingKey { 65 | case moreInfo = "more_info" 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Models/Schedule+Additions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Schedule+Additions.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/21/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | extension Session { 12 | 13 | static let dateFormatter: DateFormatter = { 14 | var formatter = DateFormatter() 15 | //August 25, 2019 16 | // 5:00 pm, 1:30 pm, etc 17 | formatter.dateFormat = "MMMM dd, yyyy, h:mm a" 18 | 19 | return formatter 20 | }() 21 | 22 | func compareDates(to currentTime: Date) -> Bool { 23 | let dateFormatter = Session.dateFormatter 24 | let day = date.rawValue 25 | 26 | guard let start = dateFormatter.date(from: day + ", " + time.uppercased()), 27 | let end = dateFormatter.date(from: day + ", " + endTime.uppercased()) else { 28 | return false 29 | } 30 | 31 | let result = currentTime.compare(start) 32 | let endResult = currentTime.compare(end) 33 | 34 | if (result == .orderedDescending || result == .orderedSame) && 35 | (endResult == .orderedAscending || endResult == .orderedSame) { 36 | return true 37 | } 38 | 39 | return false 40 | } 41 | 42 | } 43 | 44 | extension DateEnum { 45 | 46 | static var allSorted: [DateEnum] { 47 | return [.august252019, .august262019, .august272019, .august282019] 48 | } 49 | } 50 | 51 | extension Speaker { 52 | 53 | var imageUrlString: String? { 54 | let parts = postImage.split(separator: "\"") 55 | 56 | for idx in 0.. 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | 360iDev 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | $(PRODUCT_NAME) 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.1.0 21 | CFBundleVersion 22 | 2 23 | LSRequiresIPhoneOS 24 | 25 | NSCameraUsageDescription 26 | Access to your camera is needed to provide you with an AR experience. 27 | NSLocationWhenInUseUsageDescription 28 | Access to your location is required to place AR objects at specific real-world locations. 29 | UILaunchStoryboardName 30 | LaunchScreen 31 | UIMainStoryboardFile 32 | Main 33 | UIRequiredDeviceCapabilities 34 | 35 | armv7 36 | 37 | UISupportedInterfaceOrientations 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationLandscapeLeft 41 | UIInterfaceOrientationLandscapeRight 42 | 43 | UISupportedInterfaceOrientations~ipad 44 | 45 | UIInterfaceOrientationPortrait 46 | UIInterfaceOrientationPortraitUpsideDown 47 | UIInterfaceOrientationLandscapeLeft 48 | UIInterfaceOrientationLandscapeRight 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Context.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Context.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 06/10/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | 12 | public typealias LayoutRelation = NSLayoutConstraint.Relation 13 | #else 14 | import AppKit 15 | 16 | public typealias LayoutRelation = NSLayoutConstraint.Relation 17 | #endif 18 | 19 | public class Context { 20 | internal var constraints: [Constraint] = [] 21 | 22 | internal func addConstraint(_ from: Property, to: Property? = nil, coefficients: Coefficients = Coefficients(), relation: LayoutRelation = .equal) -> NSLayoutConstraint { 23 | if let fromItem = from.item as? View { 24 | fromItem.translatesAutoresizingMaskIntoConstraints = false 25 | } 26 | 27 | let layoutConstraint = NSLayoutConstraint(item: from.item, 28 | attribute: from.attribute, 29 | relatedBy: relation, 30 | toItem: to?.item, 31 | attribute: to?.attribute ?? .notAnAttribute, 32 | multiplier: CGFloat(coefficients.multiplier), 33 | constant: CGFloat(coefficients.constant)) 34 | 35 | constraints.append(Constraint(layoutConstraint)) 36 | 37 | return layoutConstraint 38 | } 39 | 40 | internal func addConstraint(_ from: Compound, coefficients: [Coefficients]? = nil, to: Compound? = nil, relation: LayoutRelation = .equal) -> [NSLayoutConstraint] { 41 | var results: [NSLayoutConstraint] = [] 42 | 43 | for i in 0.. 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | import CommonCrypto 29 | 30 | extension String: KingfisherCompatibleValue { } 31 | extension KingfisherWrapper where Base == String { 32 | var md5: String { 33 | guard let data = base.data(using: .utf8) else { 34 | return base 35 | } 36 | var digest = [UInt8](repeating: 0, count: Int(CC_MD5_DIGEST_LENGTH)) 37 | #if swift(>=5.0) 38 | _ = data.withUnsafeBytes { (bytes: UnsafeRawBufferPointer) in 39 | return CC_MD5(bytes.baseAddress, CC_LONG(data.count), &digest) 40 | } 41 | #else 42 | _ = data.withUnsafeBytes { bytes in 43 | return CC_MD5(bytes, CC_LONG(data.count), &digest) 44 | } 45 | #endif 46 | 47 | return digest.reduce(into: "") { $0 += String(format: "%02x", $1) } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Utility/Delegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Delegate.swift 3 | // Kingfisher 4 | // 5 | // Created by onevcat on 2018/10/10. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// A delegate helper type to "shadow" weak `self`, to prevent creating an unexpected retain cycle. 30 | class Delegate { 31 | init() {} 32 | 33 | private var block: ((Input) -> Output?)? 34 | 35 | func delegate(on target: T, block: ((T, Input) -> Output)?) { 36 | // The `target` is weak inside block, so you do not need to worry about it in the caller side. 37 | self.block = { [weak target] input in 38 | guard let target = target else { return nil } 39 | return block?(target, input) 40 | } 41 | } 42 | 43 | func call(_ input: Input) -> Output? { 44 | return block?(input) 45 | } 46 | } 47 | 48 | extension Delegate where Input == Void { 49 | // To make syntax better for `Void` input. 50 | func call() -> Output? { 51 | return call(()) 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Priority.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Priority.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 18/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | 12 | public typealias LayoutPriority = UILayoutPriority 13 | #else 14 | import AppKit 15 | 16 | public typealias LayoutPriority = NSLayoutConstraint.Priority 17 | #endif 18 | 19 | precedencegroup CarthographyPriorityPrecedence { 20 | lowerThan: ComparisonPrecedence 21 | higherThan: AssignmentPrecedence 22 | } 23 | 24 | infix operator ~: CarthographyPriorityPrecedence 25 | 26 | /// Sets the priority for a constraint. 27 | /// 28 | /// - parameter lhs: The constraint to update. 29 | /// - parameter rhs: The new priority. 30 | /// 31 | /// - returns: The same constraint with its priority updated. 32 | /// 33 | @discardableResult public func ~ (lhs: NSLayoutConstraint, rhs: LayoutPriority) -> NSLayoutConstraint { 34 | lhs.priority = rhs 35 | 36 | return lhs 37 | } 38 | 39 | /// Sets the priority for a constraint. 40 | /// 41 | /// - parameter lhs: The constraint to update. 42 | /// - parameter rhs: The new priority. 43 | /// 44 | /// - returns: The same constraint with its priority updated. 45 | /// 46 | @discardableResult public func ~ (lhs: NSLayoutConstraint, rhs: Float) -> NSLayoutConstraint { 47 | lhs.priority = LayoutPriority(rawValue: rhs) 48 | 49 | return lhs 50 | } 51 | 52 | /// Sets the priority for multiple constraints. 53 | /// 54 | /// - parameter lhs: An array of `NSLayoutConstraint` instances. 55 | /// - parameter rhs: The new priority. 56 | /// 57 | /// - returns: The same constraints with their priorities updated. 58 | /// 59 | @discardableResult public func ~ (lhs: [NSLayoutConstraint], rhs: LayoutPriority) -> [NSLayoutConstraint] { 60 | return lhs.map { 61 | $0 ~ rhs 62 | } 63 | } 64 | 65 | /// Sets the priority for multiple constraints. 66 | /// 67 | /// - parameter lhs: An array of `NSLayoutConstraint` instances. 68 | /// - parameter rhs: The new priority. 69 | /// 70 | /// - returns: The same constraints with their priorities updated. 71 | /// 72 | @discardableResult public func ~ (lhs: [NSLayoutConstraint], rhs: Float) -> [NSLayoutConstraint] { 73 | return lhs.map { 74 | $0 ~ rhs 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/ViewProxy.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewProxy.swift 3 | // Cartography-iOS 4 | // 5 | // Created by Vitor Travain on 10/10/17. 6 | // Copyright © 2017 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | public final class ViewProxy: SupportsPositioningLayoutProxy, SupportsBaselineLayoutProxy, AutoresizingMaskLayoutProxy { 10 | public var context: Context 11 | 12 | private let view: View 13 | public var item: AnyObject { 14 | return self.view 15 | } 16 | 17 | public var translatesAutoresizingMaskIntoConstraints: Bool { 18 | get { 19 | return view.translatesAutoresizingMaskIntoConstraints 20 | } 21 | set(value) { 22 | view.translatesAutoresizingMaskIntoConstraints = value 23 | } 24 | } 25 | 26 | public init(context: Context, view: View) { 27 | self.context = context 28 | self.view = view 29 | } 30 | 31 | public var superview: ViewProxy? { 32 | return view.superview?.asProxy(context: context) 33 | } 34 | 35 | #if os(iOS) || os(tvOS) 36 | @available(iOS, introduced: 11.0) 37 | @available(tvOS, introduced: 11.0) 38 | public var safeAreaLayoutGuide: LayoutGuideProxy { 39 | return view.safeAreaLayoutGuide.asProxy(context: context) 40 | } 41 | 42 | @available(iOS, introduced: 9.0) 43 | @available(tvOS, introduced: 9.0) 44 | public var layoutMarginsGuide: LayoutGuideProxy { 45 | return view.layoutMarginsGuide.asProxy(context: context) 46 | } 47 | 48 | @available(iOS, introduced: 9.0) 49 | @available(tvOS, introduced: 9.0) 50 | public var readableContentGuide: LayoutGuideProxy { 51 | return view.readableContentGuide.asProxy(context: context) 52 | } 53 | #endif 54 | } 55 | 56 | @available(iOS, introduced: 9.0) 57 | @available(tvOS, introduced: 9.0) 58 | @available(iOS, deprecated: 11.0, message: "The safe area is available on iOS 11+ via 'safeAreaLayoutGuide'!") 59 | @available(tvOS, deprecated: 11.0, message: "The safe area is available on tvOS 11+ via 'safeAreaLayoutGuide'!") 60 | extension ViewProxy { 61 | #if os(iOS) || os(tvOS) 62 | var safeArea: LayoutGuideProxy { 63 | if #available(iOS 11, *), #available(tvOS 11, *) { 64 | return safeAreaLayoutGuide 65 | } else { 66 | return layoutMarginsGuide 67 | } 68 | } 69 | #endif 70 | } 71 | -------------------------------------------------------------------------------- /Pods/Cartography/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014 Robert Böhnke 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is furnished 8 | to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 | THE SOFTWARE. 20 | 21 | This license does not apply to the contents of the images folder. 22 | 23 | --- 24 | 25 | This project uses portions of code from FLKAutoLayout, 26 | copyright (c) 2013 Florian Kugler 27 | 28 | Permission is hereby granted, free of charge, to any person obtaining a copy 29 | of this software and associated documentation files (the "Software"), to deal 30 | in the Software without restriction, including without limitation the rights 31 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 32 | copies of the Software, and to permit persons to whom the Software is furnished 33 | to do so, subject to the following conditions: 34 | 35 | The above copyright notice and this permission notice shall be included in all 36 | copies or substantial portions of the Software. 37 | 38 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 39 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 40 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 41 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 42 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 43 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 44 | THE SOFTWARE. 45 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Extensions/SCNNode+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SCNNode+Extensions.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 09/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import SceneKit 10 | 11 | extension SCNNode { 12 | /// Overlapping nodes require unique renderingOrder values to avoid flicker 13 | /// This method will select random values if you don't care which node is in front of the other, 14 | /// or you can specify a particular z-order value 15 | func removeFlicker (withRenderingOrder renderingOrder: Int = Int.random(in: 1.. SCNNode { 22 | let quiverThickness = (quiverLength / 50.0) * quiverThickness 23 | let chamferRadius = quiverThickness / 2.0 24 | 25 | let xQuiverBox = SCNBox(width: quiverLength, 26 | height: quiverThickness, 27 | length: quiverThickness, 28 | chamferRadius: chamferRadius) 29 | xQuiverBox.firstMaterial?.diffuse.contents = UIColor.red 30 | let xQuiverNode = SCNNode(geometry: xQuiverBox) 31 | xQuiverNode.position = SCNVector3Make(Float(quiverLength / 2.0), 0.0, 0.0) 32 | 33 | let yQuiverBox = SCNBox(width: quiverThickness, 34 | height: quiverLength, 35 | length: quiverThickness, 36 | chamferRadius: chamferRadius) 37 | yQuiverBox.firstMaterial?.diffuse.contents = UIColor.green 38 | let yQuiverNode = SCNNode(geometry: yQuiverBox) 39 | yQuiverNode.position = SCNVector3Make(0.0, Float(quiverLength / 2.0), 0.0) 40 | 41 | let zQuiverBox = SCNBox(width: quiverThickness, 42 | height: quiverThickness, 43 | length: quiverLength, 44 | chamferRadius: chamferRadius) 45 | zQuiverBox.firstMaterial?.diffuse.contents = UIColor.blue 46 | let zQuiverNode = SCNNode(geometry: zQuiverBox) 47 | zQuiverNode.position = SCNVector3Make(0.0, 0.0, Float(quiverLength / 2.0)) 48 | 49 | let quiverNode = SCNNode() 50 | quiverNode.addChildNode(xQuiverNode) 51 | quiverNode.addChildNode(yQuiverNode) 52 | quiverNode.addChildNode(zQuiverNode) 53 | quiverNode.name = "Axes" 54 | return quiverNode 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "icon_20pt@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "icon_20pt@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "icon_29pt@2x.png", 19 | "scale" : "2x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "icon_29pt@3x.png", 25 | "scale" : "3x" 26 | }, 27 | { 28 | "size" : "40x40", 29 | "idiom" : "iphone", 30 | "filename" : "icon_40pt@2x.png", 31 | "scale" : "2x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "icon_40pt@3x.png", 37 | "scale" : "3x" 38 | }, 39 | { 40 | "size" : "60x60", 41 | "idiom" : "iphone", 42 | "filename" : "icon_60pt@2x.png", 43 | "scale" : "2x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "icon_60pt@3x.png", 49 | "scale" : "3x" 50 | }, 51 | { 52 | "size" : "20x20", 53 | "idiom" : "ipad", 54 | "filename" : "icon_20pt.png", 55 | "scale" : "1x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "icon_20pt@2x-1.png", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "size" : "29x29", 65 | "idiom" : "ipad", 66 | "filename" : "icon_29pt.png", 67 | "scale" : "1x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "icon_29pt@2x-1.png", 73 | "scale" : "2x" 74 | }, 75 | { 76 | "size" : "40x40", 77 | "idiom" : "ipad", 78 | "filename" : "icon_40pt.png", 79 | "scale" : "1x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "icon_40pt@2x-1.png", 85 | "scale" : "2x" 86 | }, 87 | { 88 | "size" : "76x76", 89 | "idiom" : "ipad", 90 | "filename" : "icon_76pt.png", 91 | "scale" : "1x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "icon_76pt@2x.png", 97 | "scale" : "2x" 98 | }, 99 | { 100 | "size" : "83.5x83.5", 101 | "idiom" : "ipad", 102 | "filename" : "icon_83.5@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "1024x1024", 107 | "idiom" : "ios-marketing", 108 | "filename" : "Icon.png", 109 | "scale" : "1x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } -------------------------------------------------------------------------------- /360iDev AR Navigation/Main/MainViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/11/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import CoreLocation 10 | import UIKit 11 | 12 | 13 | class MainViewController: UIViewController, UITableViewDelegate, UITableViewDataSource { 14 | 15 | @IBOutlet weak var tableView: UITableView! 16 | 17 | override func viewDidLoad() { 18 | super.viewDidLoad() 19 | tableView.dataSource = self 20 | tableView.delegate = self 21 | tableView.rowHeight = UITableView.automaticDimension 22 | tableView.estimatedRowHeight = 100 23 | tableView.tableFooterView = UIView() 24 | } 25 | 26 | func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 27 | if indexPath.section == 0 { 28 | guard let url = URL(string: "https://360idev.com/") else { 29 | return 30 | } 31 | UIApplication.shared.open(url, options: [:], completionHandler: nil) 32 | } else { 33 | guard indexPath.row < Action.all.count else { 34 | return 35 | } 36 | switch indexPath.row { 37 | case 0: 38 | let scheduleVC = ScheduleTableViewController.loadFromStoryboard() 39 | navigationController?.pushViewController(scheduleVC, animated: true) 40 | case 1: 41 | let vc = ShowPinsViewController() 42 | navigationController?.pushViewController(vc, animated: true) 43 | default: 44 | let vc = NavigateToViewController() 45 | vc.action = Action.all[indexPath.row] 46 | navigationController?.pushViewController(vc, animated: true) 47 | } 48 | } 49 | } 50 | 51 | func numberOfSections(in tableView: UITableView) -> Int { 52 | return 2 53 | } 54 | 55 | func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 56 | if section == 0 { 57 | return 1 58 | } 59 | 60 | return Action.all.count 61 | } 62 | 63 | func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 64 | if indexPath.section == 0 { 65 | return tableView.dequeueReusableCell(withIdentifier: "LogoCell", for: indexPath) 66 | } 67 | 68 | let cell = tableView.dequeueReusableCell(withIdentifier: "ActionCell", for: indexPath) 69 | guard indexPath.row < Action.all.count else { 70 | return cell 71 | } 72 | 73 | cell.textLabel?.text = Action.all[indexPath.row].rawValue 74 | return cell 75 | } 76 | 77 | } 78 | 79 | extension CLLocation { 80 | 81 | convenience init(latitude: CLLocationDegrees, longitude: CLLocationDegrees, altitude: CLLocationDistance) { 82 | self.init(coordinate: CLLocationCoordinate2D(latitude: latitude, longitude: longitude), altitude: altitude) 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/SceneLocationViewEstimateDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SceneLocationViewDelegate.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Ilya Seliverstov on 09/08/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import ARKit 11 | import CoreLocation 12 | import MapKit 13 | 14 | // Delegate for touch events on LocationNode 15 | public protocol LNTouchDelegate: class { 16 | func locationNodeTouched(node: AnnotationNode) 17 | } 18 | 19 | @available(iOS 11.0, *) 20 | public protocol SceneLocationViewEstimateDelegate: class { 21 | func didAddSceneLocationEstimate(sceneLocationView: SceneLocationView, position: SCNVector3, location: CLLocation) 22 | func didRemoveSceneLocationEstimate(sceneLocationView: SceneLocationView, position: SCNVector3, location: CLLocation) 23 | } 24 | 25 | @available(iOS 11.0, *) 26 | public extension SceneLocationViewEstimateDelegate { 27 | func didAddSceneLocationEstimate(sceneLocationView: SceneLocationView, position: SCNVector3, location: CLLocation) { 28 | // 29 | } 30 | func didRemoveSceneLocationEstimate(sceneLocationView: SceneLocationView, position: SCNVector3, location: CLLocation) { 31 | // 32 | } 33 | } 34 | 35 | @available(iOS 11.0, *) 36 | public protocol SceneLocationViewDelegate: class { 37 | ///After a node's location is initially set based on current location, 38 | ///it is later confirmed once the user moves far enough away from it. 39 | ///This update uses location data collected since the node was placed to give a more accurate location. 40 | func didConfirmLocationOfNode(sceneLocationView: SceneLocationView, node: LocationNode) 41 | 42 | func didSetupSceneNode(sceneLocationView: SceneLocationView, sceneNode: SCNNode) 43 | 44 | func didUpdateLocationAndScaleOfLocationNode(sceneLocationView: SceneLocationView, locationNode: LocationNode) 45 | } 46 | 47 | /// Subset of delegate methods from ARSCNViewDelegate to be notified on tracking status changes 48 | @available(iOS 11.0, *) 49 | public protocol SceneTrackingDelegate: class { 50 | 51 | func sessionWasInterrupted(_ session: ARSession) 52 | 53 | func sessionInterruptionEnded(_ session: ARSession) 54 | 55 | func session(_ session: ARSession, didFailWithError error: Error) 56 | 57 | func session(_ session: ARSession, cameraDidChangeTrackingState camera: ARCamera) 58 | 59 | } 60 | 61 | @available(iOS 11.0, *) 62 | public extension SceneLocationViewDelegate { 63 | func didAddSceneLocationEstimate(sceneLocationView: SceneLocationView, position: SCNVector3, location: CLLocation) { 64 | // 65 | } 66 | func didRemoveSceneLocationEstimate(sceneLocationView: SceneLocationView, position: SCNVector3, location: CLLocation) { 67 | // 68 | } 69 | 70 | func didConfirmLocationOfNode(sceneLocationView: SceneLocationView, node: LocationNode) { 71 | // 72 | } 73 | func didSetupSceneNode(sceneLocationView: SceneLocationView, sceneNode: SCNNode) { 74 | // 75 | } 76 | 77 | func didUpdateLocationAndScaleOfLocationNode(sceneLocationView: SceneLocationView, locationNode: LocationNode) { 78 | // 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/General/ImageSource/Resource.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Resource.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 15/4/6. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Represents an image resource at a certain url and a given cache key. 30 | /// Kingfisher will use a `Resource` to download a resource from network and cache it with the cache key when 31 | /// using `Source.network` as its image setting source. 32 | public protocol Resource { 33 | 34 | /// The key used in cache. 35 | var cacheKey: String { get } 36 | 37 | /// The target image URL. 38 | var downloadURL: URL { get } 39 | } 40 | 41 | /// ImageResource is a simple combination of `downloadURL` and `cacheKey`. 42 | /// When passed to image view set methods, Kingfisher will try to download the target 43 | /// image from the `downloadURL`, and then store it with the `cacheKey` as the key in cache. 44 | public struct ImageResource: Resource { 45 | 46 | // MARK: - Initializers 47 | 48 | /// Creates an image resource. 49 | /// 50 | /// - Parameters: 51 | /// - downloadURL: The target image URL from where the image can be downloaded. 52 | /// - cacheKey: The cache key. If `nil`, Kingfisher will use the `absoluteString` of `downloadURL` as the key. 53 | /// Default is `nil`. 54 | public init(downloadURL: URL, cacheKey: String? = nil) { 55 | self.downloadURL = downloadURL 56 | self.cacheKey = cacheKey ?? downloadURL.absoluteString 57 | } 58 | 59 | // MARK: Protocol Conforming 60 | 61 | /// The key used in cache. 62 | public let cacheKey: String 63 | 64 | /// The target image URL. 65 | public let downloadURL: URL 66 | } 67 | 68 | /// URL conforms to `Resource` in Kingfisher. 69 | /// The `absoluteString` of this URL is used as `cacheKey`. And the URL itself will be used as `downloadURL`. 70 | /// If you need customize the url and/or cache key, use `ImageResource` instead. 71 | extension URL: Resource { 72 | public var cacheKey: String { return absoluteString } 73 | public var downloadURL: URL { return self } 74 | } 75 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/General/Kingfisher.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Kingfisher.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 16/9/14. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | import ImageIO 29 | 30 | #if os(macOS) 31 | import AppKit 32 | public typealias Image = NSImage 33 | public typealias View = NSView 34 | public typealias Color = NSColor 35 | public typealias ImageView = NSImageView 36 | public typealias Button = NSButton 37 | #else 38 | import UIKit 39 | public typealias Image = UIImage 40 | public typealias Color = UIColor 41 | #if !os(watchOS) 42 | public typealias ImageView = UIImageView 43 | public typealias View = UIView 44 | public typealias Button = UIButton 45 | #else 46 | import WatchKit 47 | #endif 48 | #endif 49 | 50 | /// Wrapper for Kingfisher compatible types. This type provides an extension point for 51 | /// connivence methods in Kingfisher. 52 | public struct KingfisherWrapper { 53 | public let base: Base 54 | public init(_ base: Base) { 55 | self.base = base 56 | } 57 | } 58 | 59 | /// Represents an object type that is compatible with Kingfisher. You can use `kf` property to get a 60 | /// value in the namespace of Kingfisher. 61 | public protocol KingfisherCompatible: AnyObject { } 62 | 63 | /// Represents a value type that is compatible with Kingfisher. You can use `kf` property to get a 64 | /// value in the namespace of Kingfisher. 65 | public protocol KingfisherCompatibleValue {} 66 | 67 | extension KingfisherCompatible { 68 | /// Gets a namespace holder for Kingfisher compatible types. 69 | public var kf: KingfisherWrapper { 70 | get { return KingfisherWrapper(self) } 71 | set { } 72 | } 73 | } 74 | 75 | extension KingfisherCompatibleValue { 76 | /// Gets a namespace holder for Kingfisher compatible types. 77 | public var kf: KingfisherWrapper { 78 | get { return KingfisherWrapper(self) } 79 | set { } 80 | } 81 | } 82 | 83 | extension Image: KingfisherCompatible { } 84 | #if !os(watchOS) 85 | extension ImageView: KingfisherCompatible { } 86 | extension Button: KingfisherCompatible { } 87 | #else 88 | extension WKInterfaceImage: KingfisherCompatible { } 89 | #endif 90 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Image/Placeholder.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Placeholder.swift 3 | // Kingfisher 4 | // 5 | // Created by Tieme van Veen on 28/08/2017. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | #if os(macOS) 28 | import AppKit 29 | #else 30 | import UIKit 31 | #endif 32 | 33 | /// Represents a placeholder type which could be set while loading as well as 34 | /// loading finished without getting an image. 35 | public protocol Placeholder { 36 | 37 | /// How the placeholder should be added to a given image view. 38 | func add(to imageView: ImageView) 39 | 40 | /// How the placeholder should be removed from a given image view. 41 | func remove(from imageView: ImageView) 42 | } 43 | 44 | /// Default implementation of an image placeholder. The image will be set or 45 | /// reset directly for `image` property of the image view. 46 | extension Image: Placeholder { 47 | /// How the placeholder should be added to a given image view. 48 | public func add(to imageView: ImageView) { imageView.image = self } 49 | 50 | /// How the placeholder should be removed from a given image view. 51 | public func remove(from imageView: ImageView) { imageView.image = nil } 52 | } 53 | 54 | /// Default implementation of an arbitrary view as placeholder. The view will be 55 | /// added as a subview when adding and be removed from its super view when removing. 56 | /// 57 | /// To use your customize View type as placeholder, simply let it conforming to 58 | /// `Placeholder` by `extension MyView: Placeholder {}`. 59 | extension Placeholder where Self: View { 60 | 61 | /// How the placeholder should be added to a given image view. 62 | public func add(to imageView: ImageView) { 63 | imageView.addSubview(self) 64 | translatesAutoresizingMaskIntoConstraints = false 65 | 66 | centerXAnchor.constraint(equalTo: imageView.centerXAnchor).isActive = true 67 | centerYAnchor.constraint(equalTo: imageView.centerYAnchor).isActive = true 68 | heightAnchor.constraint(equalTo: imageView.heightAnchor).isActive = true 69 | widthAnchor.constraint(equalTo: imageView.widthAnchor).isActive = true 70 | } 71 | 72 | /// How the placeholder should be removed from a given image view. 73 | public func remove(from imageView: ImageView) { 74 | removeFromSuperview() 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Nodes/PolylineNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PolylineNode.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Ilya Seliverstov on 11/08/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import SceneKit 11 | import MapKit 12 | 13 | /// A block that will build an SCNBox with the provided distance. 14 | /// Note: the distance should be aassigned to the length 15 | public typealias BoxBuilder = (_ distance: CGFloat) -> SCNBox 16 | 17 | /// A Node that is used to show directions in AR-CL. 18 | public class PolylineNode: LocationNode { 19 | public private(set) var locationNodes = [LocationNode]() 20 | 21 | public let polyline: MKPolyline 22 | public let altitude: CLLocationDistance 23 | public let boxBuilder: BoxBuilder 24 | 25 | /// Creates a `PolylineNode` from the provided polyline, altitude (which is assumed to be uniform 26 | /// for all of the points) and an optional SCNBox to use as a prototype for the location boxes. 27 | /// 28 | /// - Parameters: 29 | /// - polyline: The polyline that we'll be creating location nodes for. 30 | /// - altitude: The uniform altitude to use to show the location nodes. 31 | /// - boxBuilder: A block that will customize how a box is built. 32 | public init(polyline: MKPolyline, altitude: CLLocationDistance, boxBuilder: BoxBuilder? = nil) { 33 | self.polyline = polyline 34 | self.altitude = altitude 35 | self.boxBuilder = boxBuilder ?? Constants.defaultBuilder 36 | 37 | super.init(location: nil) 38 | 39 | contructNodes() 40 | } 41 | 42 | required public init?(coder aDecoder: NSCoder) { 43 | fatalError("init(coder:) has not been implemented") 44 | } 45 | 46 | } 47 | 48 | // MARK: - Implementation 49 | 50 | private extension PolylineNode { 51 | 52 | struct Constants { 53 | static let defaultBuilder: BoxBuilder = { (distance) -> SCNBox in 54 | let box = SCNBox(width: 1, height: 0.2, length: distance, chamferRadius: 0) 55 | box.firstMaterial?.diffuse.contents = UIColor(red: 47.0/255.0, green: 125.0/255.0, blue: 255.0/255.0, alpha: 1.0) 56 | return box 57 | } 58 | } 59 | 60 | /// This is what actually builds the SCNNodes and appends them to the 61 | /// locationNodes collection so they can be added to the scene and shown 62 | /// to the user. If the prototype box is nil, then the default box will be used 63 | func contructNodes() { 64 | let points = polyline.points() 65 | 66 | for i in 0 ..< polyline.pointCount - 1 { 67 | let currentLocation = CLLocation(coordinate: points[i].coordinate, altitude: altitude) 68 | let nextLocation = CLLocation(coordinate: points[i + 1].coordinate, altitude: altitude) 69 | 70 | let distance = currentLocation.distance(from: nextLocation) 71 | 72 | let box = boxBuilder(CGFloat(distance)) 73 | let boxNode = SCNNode(geometry: box) 74 | boxNode.removeFlicker() 75 | 76 | let bearing = -currentLocation.bearing(between: nextLocation) 77 | 78 | boxNode.pivot = SCNMatrix4MakeTranslation(0, 0, 0.5 * Float(distance)) 79 | boxNode.eulerAngles.y = Float(bearing).degreesToRadians 80 | 81 | let locationNode = LocationNode(location: currentLocation) 82 | locationNode.addChildNode(boxNode) 83 | 84 | locationNodes.append(locationNode) 85 | } 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Networking/ImageDataProcessor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageDataProcessor.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2018/10/11. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | private let sharedProcessingQueue: CallbackQueue = 30 | .dispatch(DispatchQueue(label: "com.onevcat.Kingfisher.ImageDownloader.Process")) 31 | 32 | // Handles image processing work on an own process queue. 33 | class ImageDataProcessor { 34 | let data: Data 35 | let callbacks: [SessionDataTask.TaskCallback] 36 | let queue: CallbackQueue 37 | 38 | // Note: We have an optimization choice there, to reduce queue dispatch by checking callback 39 | // queue settings in each option... 40 | let onImageProcessed = Delegate<(Result, SessionDataTask.TaskCallback), Void>() 41 | 42 | init(data: Data, callbacks: [SessionDataTask.TaskCallback], processingQueue: CallbackQueue?) { 43 | self.data = data 44 | self.callbacks = callbacks 45 | self.queue = processingQueue ?? sharedProcessingQueue 46 | } 47 | 48 | func process() { 49 | queue.execute(doProcess) 50 | } 51 | 52 | private func doProcess() { 53 | var processedImages = [String: Image]() 54 | for callback in callbacks { 55 | let processor = callback.options.processor 56 | var image = processedImages[processor.identifier] 57 | if image == nil { 58 | image = processor.process(item: .data(data), options: callback.options) 59 | processedImages[processor.identifier] = image 60 | } 61 | 62 | let result: Result 63 | if let image = image { 64 | var finalImage = image 65 | if let imageModifier = callback.options.imageModifier { 66 | finalImage = imageModifier.modify(image) 67 | } 68 | if callback.options.backgroundDecode { 69 | finalImage = finalImage.kf.decoded 70 | } 71 | result = .success(finalImage) 72 | } else { 73 | let error = KingfisherError.processorError( 74 | reason: .processingFailed(processor: processor, item: .data(data))) 75 | result = .failure(error) 76 | } 77 | onImageProcessed.call((result, callback)) 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Utility/CallbackQueue.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CallbackQueue.swift 3 | // Kingfisher 4 | // 5 | // Created by onevcat on 2018/10/15. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Represents callback queue behaviors when an calling of closure be dispatched. 30 | /// 31 | /// - asyncMain: Dispatch the calling to `DispatchQueue.main` with an `async` behavior. 32 | /// - currentMainOrAsync: Dispatch the calling to `DispatchQueue.main` with an `async` behavior if current queue is not 33 | /// `.main`. Otherwise, call the closure immediately in current main queue. 34 | /// - untouch: Do not change the calling queue for closure. 35 | /// - dispatch: Dispatches to a specified `DispatchQueue`. 36 | public enum CallbackQueue { 37 | /// Dispatch the calling to `DispatchQueue.main` with an `async` behavior. 38 | case mainAsync 39 | /// Dispatch the calling to `DispatchQueue.main` with an `async` behavior if current queue is not 40 | /// `.main`. Otherwise, call the closure immediately in current main queue. 41 | case mainCurrentOrAsync 42 | /// Do not change the calling queue for closure. 43 | case untouch 44 | /// Dispatches to a specified `DispatchQueue`. 45 | case dispatch(DispatchQueue) 46 | 47 | public func execute(_ block: @escaping () -> Void) { 48 | switch self { 49 | case .mainAsync: 50 | DispatchQueue.main.async { block() } 51 | case .mainCurrentOrAsync: 52 | DispatchQueue.main.safeAsync { block() } 53 | case .untouch: 54 | block() 55 | case .dispatch(let queue): 56 | queue.async { block() } 57 | } 58 | } 59 | 60 | var queue: DispatchQueue { 61 | switch self { 62 | case .mainAsync: return .main 63 | case .mainCurrentOrAsync: return .main 64 | case .untouch: return OperationQueue.current?.underlyingQueue ?? .main 65 | case .dispatch(let queue): return queue 66 | } 67 | } 68 | } 69 | 70 | extension DispatchQueue { 71 | // This method will dispatch the `block` to self. 72 | // If `self` is the main queue, and current thread is main thread, the block 73 | // will be invoked immediately instead of being dispatched. 74 | func safeAsync(_ block: @escaping ()->()) { 75 | if self === DispatchQueue.main && Thread.isMainThread { 76 | block() 77 | } else { 78 | async { block() } 79 | } 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Services/RemoteScheduleService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RemoteScheduleService.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/20/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | typealias ScheduleCallback = (Schedule?, Error?) -> Void 12 | 13 | class RemoteScheduleService { 14 | static let shared = RemoteScheduleService() 15 | 16 | /// Loads the schedule from the remote and then caches it to disk 17 | func cacheSchedule(completion: ScheduleCallback?) { 18 | guard let documentsDirectory = documentsDirectory else { 19 | return print("ERROR: documents directory couldn't be found") 20 | } 21 | loadSchedule { (schedule, error) in 22 | if let error = error { 23 | completion?(schedule, error) 24 | return print("ERROR: \(error.localizedDescription)") 25 | } 26 | guard let schedule = schedule, schedule.sessions.count > 0 else { 27 | completion?(nil, error) 28 | return print("ERROR: no schedule or no sessions in schedule") 29 | } 30 | let docsURL = URL(fileURLWithPath: documentsDirectory) 31 | let scheduleFile = URL(fileURLWithPath: "schedule.json", relativeTo: docsURL) 32 | do { 33 | let data = try JSONEncoder().encode(schedule) 34 | try data.write(to: scheduleFile, options: .atomicWrite) 35 | completion?(schedule, error) 36 | } catch { 37 | completion?(nil, error) 38 | } 39 | } 40 | } 41 | 42 | } 43 | 44 | // MARK: - Implementation 45 | 46 | extension RemoteScheduleService { 47 | 48 | /// Gets you the path of the User Documents directory. 49 | var documentsDirectory: String? { 50 | let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 51 | return paths.first 52 | } 53 | 54 | /// Loads the schedule and calls back to your block. 55 | /// 56 | /// - Parameter completion: The block to handle the result 57 | func loadSchedule(completion: @escaping ScheduleCallback) { 58 | guard let url = URL(string: "https://360idev.com/wp-admin/admin-ajax.php") else { 59 | return completion(nil, nil) 60 | } 61 | var request = URLRequest(url: url, cachePolicy: .reloadIgnoringCacheData, timeoutInterval: 10) 62 | request.addValue("application/x-www-form-urlencoded; charset=UTF-8", forHTTPHeaderField: "Content-Type") 63 | request.addValue("application/json, text/javascript, */*; q=0.01", forHTTPHeaderField: "Accept") 64 | 65 | let postData = "action=get_schedule".data(using: .utf8) 66 | request.httpBody = postData 67 | request.httpMethod = "POST" 68 | 69 | let defaultSession = URLSession(configuration: .default) 70 | 71 | defaultSession.dataTask(with: request) { (data, response, error) in 72 | if let error = error { 73 | return completion(nil, error) 74 | } 75 | guard let response = response as? HTTPURLResponse, response.statusCode == 200 else { 76 | return completion(nil, nil) 77 | } 78 | guard let data = data else { 79 | return completion(nil, nil) 80 | } 81 | do { 82 | let schedule = try JSONDecoder().decode(Schedule.self, from: data) 83 | completion(schedule, nil) 84 | } catch { 85 | completion(nil, error) 86 | } 87 | 88 | }.resume() 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Extensions/String+HTML.swift: -------------------------------------------------------------------------------- 1 | // 2 | // String+HTML.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/15/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // The following source is from: https://stackoverflow.com/questions/25607247/how-do-i-decode-html-entities-in-swift 12 | 13 | // Mapping from XML/HTML character entity reference to character 14 | // From http://en.wikipedia.org/wiki/List_of_XML_and_HTML_character_entity_references 15 | private let characterEntities : [ Substring : Character ] = [ 16 | // XML predefined entities: 17 | """ : "\"", 18 | "&" : "&", 19 | "'" : "'", 20 | "<" : "<", 21 | ">" : ">", 22 | 23 | // HTML character entity references: 24 | " " : "\u{00a0}", 25 | // ... 26 | "♦" : "♦", 27 | ] 28 | 29 | extension String { 30 | 31 | /// Returns a new string made by replacing in the `String` 32 | /// all HTML character entity references with the corresponding 33 | /// character. 34 | var stringByDecodingHTMLEntities: String { 35 | 36 | // ===== Utility functions ===== 37 | 38 | // Convert the number in the string to the corresponding 39 | // Unicode character, e.g. 40 | // decodeNumeric("64", 10) --> "@" 41 | // decodeNumeric("20ac", 16) --> "€" 42 | func decodeNumeric(_ string : Substring, base : Int) -> Character? { 43 | guard let code = UInt32(string, radix: base), 44 | let uniScalar = UnicodeScalar(code) else { return nil } 45 | return Character(uniScalar) 46 | } 47 | 48 | // Decode the HTML character entity to the corresponding 49 | // Unicode character, return `nil` for invalid input. 50 | // decode("@") --> "@" 51 | // decode("€") --> "€" 52 | // decode("<") --> "<" 53 | // decode("&foo;") --> nil 54 | func decode(_ entity : Substring) -> Character? { 55 | 56 | if entity.hasPrefix("&#x") || entity.hasPrefix("&#X") { 57 | return decodeNumeric(entity.dropFirst(3).dropLast(), base: 16) 58 | } else if entity.hasPrefix("&#") { 59 | return decodeNumeric(entity.dropFirst(2).dropLast(), base: 10) 60 | } else { 61 | return characterEntities[entity] 62 | } 63 | } 64 | 65 | // ===== Method starts here ===== 66 | 67 | var result = "" 68 | var position = startIndex 69 | 70 | // Find the next '&' and copy the characters preceding it to `result`: 71 | while let ampRange = self[position...].range(of: "&") { 72 | result.append(contentsOf: self[position ..< ampRange.lowerBound]) 73 | position = ampRange.lowerBound 74 | 75 | // Find the next ';' and copy everything from '&' to ';' into `entity` 76 | guard let semiRange = self[position...].range(of: ";") else { 77 | // No matching ';'. 78 | break 79 | } 80 | let entity = self[position ..< semiRange.upperBound] 81 | position = semiRange.upperBound 82 | 83 | if let decoded = decode(entity) { 84 | // Replace by decoded character: 85 | result.append(decoded) 86 | } else { 87 | // Invalid entity, copy verbatim: 88 | result.append(contentsOf: entity) 89 | } 90 | } 91 | // Copy remaining characters to `result`: 92 | result.append(contentsOf: self[position...]) 93 | return result 94 | } 95 | } 96 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Nodes/ScalingScheme.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScalingScheme.swift 3 | // ARCL 4 | // 5 | // Created by Eric Internicola on 5/17/19. 6 | // 7 | 8 | import Foundation 9 | 10 | /// A set of schemes that can be used to scale a LocationNode. 11 | /// 12 | /// - normal: The default way of scaling 13 | /// - tiered: A way of scaling everything beyond a specific distance (threshold) at 14 | /// a specific scale. 15 | /// - doubleTiered: A way of scaling everything beyond 2 specific distances at two 16 | /// specific scales. 17 | /// - linear: linearly scales an object based on its distance. 18 | /// - linearBuffer: linearly scales an object based on its distance as long as it is 19 | /// further than the buffer distance, otherwise it just returns 100% scale. 20 | public enum ScalingScheme { 21 | 22 | case normal 23 | case tiered(threshold: Double, scale: Float) 24 | case doubleTiered(firstThreshold: Double, firstScale: Float, secondThreshold: Double, secondScale: Float) 25 | case linear(threshold: Double) 26 | case linearBuffer(threshold: Double, buffer: Double) 27 | 28 | public func getScheme() -> ( (_ distance: Double, _ adjustedDistance: Double) -> Float) { 29 | switch self { 30 | case .tiered(let threshold, let scale): 31 | return { (distance, adjustedDistance) in 32 | if adjustedDistance > threshold { 33 | return scale 34 | } else { 35 | return 1.0 36 | } 37 | } 38 | case .doubleTiered(let firstThreshold, let firstScale, let secondThreshold, let secondScale): 39 | return { (distance, adjustedDistance) in 40 | if adjustedDistance > secondThreshold { 41 | return secondScale 42 | } else if adjustedDistance > firstThreshold { 43 | return firstScale 44 | } else { 45 | return 1.0 46 | } 47 | } 48 | case .linear(let threshold): 49 | return { (distance, adjustedDistance) in 50 | 51 | let maxSize = 1.0 52 | let absThreshold = abs(threshold) 53 | let absAdjDist = abs(adjustedDistance) 54 | 55 | let scaleToReturn = Float( max (maxSize - (absAdjDist / absThreshold), 0.0)) 56 | // print("threshold: \(absThreshold) adjDist: \(absAdjDist) scaleToReturn: \(scaleToReturn)") 57 | return scaleToReturn 58 | } 59 | 60 | case .linearBuffer(let threshold, let buffer): 61 | return { (distance, adjustedDistance) in 62 | let maxSize = 1.0 63 | let absThreshold = abs(threshold) 64 | let absAdjDist = abs(adjustedDistance) 65 | 66 | if absAdjDist < buffer { 67 | // print("threshold: \(absThreshold) adjDist: \(absAdjDist)") 68 | return Float(maxSize) 69 | } else { 70 | let scaleToReturn = Float( max( maxSize - (absAdjDist / absThreshold), 0.0 )) 71 | // print("threshold: \(absThreshold) adjDist: \(absAdjDist) scaleToReturn: \(scaleToReturn)") 72 | return scaleToReturn 73 | } 74 | } 75 | case .normal: 76 | return { (distance, adjustedDistance) in 77 | 78 | // Scale it to be an appropriate size so that it can be seen 79 | var scale = Float(adjustedDistance) * 0.181 80 | if distance > 3000 { 81 | scale *= 0.75 82 | } 83 | return scale 84 | } 85 | } 86 | 87 | } 88 | 89 | } 90 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Networking/RequestModifier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RequestModifier.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2016/09/05. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Represents and wraps a method for modifying request before an image download request starts. 30 | public protocol ImageDownloadRequestModifier { 31 | 32 | /// A method will be called just before the `request` being sent. 33 | /// This is the last chance you can modify the image download request. You can modify the request for some 34 | /// customizing purpose, such as adding auth token to the header, do basic HTTP auth or something like url mapping. 35 | /// 36 | /// Usually, you pass an `ImageDownloadRequestModifier` as the associated value of 37 | /// `KingfisherOptionsInfoItem.requestModifier` and use it as the `options` parameter in related methods. 38 | /// 39 | /// If you do nothing with the input `request` and return it as is, a downloading process will start with it. 40 | /// 41 | /// - Parameter request: The input request contains necessary information like `url`. This request is generated 42 | /// according to your resource url as a GET request. 43 | /// - Returns: A modified version of request, which you wish to use for downloading an image. If `nil` returned, 44 | /// a `KingfisherError.requestError` with `.emptyRequest` as its reason will occur. 45 | /// 46 | func modified(for request: URLRequest) -> URLRequest? 47 | } 48 | 49 | /// A wrapper for creating an `ImageDownloadRequestModifier` easier. 50 | /// This type conforms to `ImageDownloadRequestModifier` and wraps an image modify block. 51 | public struct AnyModifier: ImageDownloadRequestModifier { 52 | 53 | let block: (URLRequest) -> URLRequest? 54 | 55 | /// For `ImageDownloadRequestModifier` conformation. 56 | public func modified(for request: URLRequest) -> URLRequest? { 57 | return block(request) 58 | } 59 | 60 | /// Creates a value of `ImageDownloadRequestModifier` which runs `modify` block. 61 | /// 62 | /// - Parameter modify: The request modifying block runs when a request modifying task comes. 63 | /// The return `URLRequest?` value of this block will be used as the image download request. 64 | /// If `nil` returned, a `KingfisherError.requestError` with `.emptyRequest` as its 65 | /// reason will occur. 66 | public init(modify: @escaping (URLRequest) -> URLRequest?) { 67 | block = modify 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /360iDev AR Navigation/AR/ShowPinsViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ShowPinsViewController.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/11/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import ARCL 10 | import ARKit 11 | import Cartography 12 | import CoreLocation 13 | import UIKit 14 | 15 | class ShowPinsViewController: UIViewController { 16 | 17 | let sceneLocationView = SceneLocationView() 18 | let activityView = UIActivityIndicatorView(style: .whiteLarge) 19 | 20 | var currentLocation: CLLocation? { 21 | return sceneLocationView.sceneLocationManager.currentLocation 22 | } 23 | 24 | override func viewDidLoad() { 25 | super.viewDidLoad() 26 | title = Action.showPins.title 27 | 28 | guard ARConfiguration.isSupported else { 29 | return showErrorAlert(message: "Your device does not support ARKit") { [weak self] _ in 30 | self?.dismiss(animated: true, completion: nil) 31 | } 32 | } 33 | 34 | view.addSubview(sceneLocationView) 35 | view.addSubview(activityView) 36 | 37 | constrain(view, sceneLocationView, activityView) { view, sceneLocationView, activityView in 38 | sceneLocationView.left == view.left 39 | sceneLocationView.top == view.top 40 | sceneLocationView.right == view.right 41 | sceneLocationView.bottom == view.bottom 42 | 43 | activityView.centerX == view.centerX 44 | activityView.centerY == view.centerY 45 | } 46 | 47 | showActivityControl() 48 | addPins() 49 | } 50 | 51 | override func viewWillAppear(_ animated: Bool) { 52 | super.viewWillAppear(animated) 53 | sceneLocationView.run() 54 | } 55 | 56 | override func viewWillDisappear(_ animated: Bool) { 57 | super.viewWillDisappear(animated) 58 | sceneLocationView.pause() 59 | } 60 | 61 | /// Adds the pins to the ARCL Scene 62 | func addPins() { 63 | guard let currentLocation = currentLocation, 64 | currentLocation.horizontalAccuracy < 15 else { 65 | return DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { [weak self] in 66 | self?.addPins() 67 | } 68 | } 69 | 70 | hideActivityControl() 71 | 72 | Action.all.forEach { action in 73 | guard action.isLocation else { 74 | return 75 | } 76 | guard let location = action.location(with: currentLocation.altitude + 10) else { 77 | return DispatchQueue.main.async { [weak self] in 78 | self?.showErrorAlert(message: "No location associated with \(action.title), please contact support.") 79 | } 80 | } 81 | guard let image = action.image else { 82 | return DispatchQueue.main.async { [weak self] in 83 | self?.showErrorAlert(message: "No image associated with \(action.title), please contact support.") 84 | } 85 | } 86 | 87 | let node = LocationAnnotationNode(location: location, image: image) 88 | 89 | sceneLocationView.addLocationNodeWithConfirmedLocation(locationNode: node) 90 | } 91 | } 92 | } 93 | 94 | // MARK: - Implementation 95 | 96 | extension ShowPinsViewController { 97 | 98 | func showActivityControl() { 99 | activityView.isHidden = false 100 | activityView.startAnimating() 101 | } 102 | 103 | func hideActivityControl() { 104 | activityView.isHidden = false 105 | activityView.stopAnimating() 106 | } 107 | 108 | } 109 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Networking/RedirectHandler.swift: -------------------------------------------------------------------------------- 1 | // 2 | // RedirectHandler.swift 3 | // Kingfisher 4 | // 5 | // Created by Roman Maidanovych on 2018/12/10. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Represents and wraps a method for modifying request during an image download request redirection. 30 | public protocol ImageDownloadRedirectHandler { 31 | 32 | /// The `ImageDownloadRedirectHandler` contained will be used to change the request before redirection. 33 | /// This is the posibility you can modify the image download request during redirection. You can modify the 34 | /// request for some customizing purpose, such as adding auth token to the header, do basic HTTP auth or 35 | /// something like url mapping. 36 | /// 37 | /// Usually, you pass an `ImageDownloadRedirectHandler` as the associated value of 38 | /// `KingfisherOptionsInfoItem.redirectHandler` and use it as the `options` parameter in related methods. 39 | /// 40 | /// If you do nothing with the input `request` and return it as is, a downloading process will redirect with it. 41 | /// 42 | /// - Parameters: 43 | /// - task: The current `SessionDataTask` which triggers this redirect. 44 | /// - response: The response received during redirection. 45 | /// - newRequest: The request for redirection which can be modified. 46 | /// - completionHandler: A closure for being called with modified request. 47 | func handleHTTPRedirection( 48 | for task: SessionDataTask, 49 | response: HTTPURLResponse, 50 | newRequest: URLRequest, 51 | completionHandler: @escaping (URLRequest?) -> Void) 52 | } 53 | 54 | /// A wrapper for creating an `ImageDownloadRedirectHandler` easier. 55 | /// This type conforms to `ImageDownloadRedirectHandler` and wraps an redirect request modify block. 56 | public struct AnyRedirectHandler: ImageDownloadRedirectHandler { 57 | 58 | let block: (SessionDataTask, HTTPURLResponse, URLRequest, (URLRequest?) -> Void) -> Void 59 | 60 | public func handleHTTPRedirection( 61 | for task: SessionDataTask, 62 | response: HTTPURLResponse, 63 | newRequest: URLRequest, 64 | completionHandler: @escaping (URLRequest?) -> Void) 65 | { 66 | block(task, response, newRequest, completionHandler) 67 | } 68 | 69 | /// Creates a value of `ImageDownloadRedirectHandler` which runs `modify` block. 70 | /// 71 | /// - Parameter modify: The request modifying block runs when a request modifying task comes. 72 | /// 73 | public init(handle: @escaping (SessionDataTask, HTTPURLResponse, URLRequest, (URLRequest?) -> Void) -> Void) { 74 | block = handle 75 | } 76 | } 77 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Models/Action.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Action.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import CoreLocation 10 | import UIKit 11 | 12 | /// These are the actions for each (non-title) cell: 13 | enum Action: String { 14 | case schedule = "Schedule" 15 | case showPins = "Show Location Pins" 16 | case navigateToConference = "Navigate to Hyatt" 17 | case navigateToHenrys = "Navigate to Henry's Tavern" 18 | case navigateToFoodTrucks = "Navigate to Food Trucks" 19 | case navigateToRhinoBeerGarden = "Navigate to RiNo Beer Garden" 20 | 21 | static let all: [Action] = [ 22 | .schedule, 23 | .showPins, 24 | .navigateToConference, 25 | .navigateToHenrys, 26 | .navigateToFoodTrucks, 27 | .navigateToRhinoBeerGarden 28 | ] 29 | 30 | /// Is this Action a location? 31 | var isLocation: Bool { 32 | switch self { 33 | case .showPins, .schedule: 34 | return false 35 | default: 36 | return true 37 | } 38 | } 39 | 40 | /// Get the title for this action's view controller 41 | var title: String { 42 | switch self { 43 | case .schedule: 44 | return "Schedule" 45 | case .showPins: 46 | return "Pins" 47 | case .navigateToConference: 48 | return "Hyatt" 49 | case .navigateToHenrys: 50 | return "Henry's" 51 | case .navigateToFoodTrucks: 52 | return "Food Trucks" 53 | case .navigateToRhinoBeerGarden: 54 | return "Beer Garden" 55 | } 56 | } 57 | 58 | /// Get the location of this action with the provided elevation. 59 | /// 60 | /// - Parameter elevation: The elevation to set on the pin. 61 | /// - Returns: A CLLocation with the appropriate location and altitude. 62 | func location(with elevation: CLLocationDistance) -> CLLocation? { 63 | switch self { 64 | case .navigateToConference: 65 | return CLLocation(latitude: 39.7456001, longitude: -105.023832, altitude: elevation) 66 | case .navigateToHenrys: 67 | return CLLocation(latitude: 39.7440861, longitude: -104.9915639, altitude: elevation) 68 | case .navigateToFoodTrucks: 69 | return CLLocation(latitude: 39.7337442, longitude: -104.9972431, altitude: elevation) 70 | case .navigateToRhinoBeerGarden: 71 | return CLLocation(latitude: 39.7701405, longitude: -104.9735078, altitude: elevation) 72 | default: 73 | return nil 74 | } 75 | } 76 | 77 | /// Get the address for this pin (for navigation). 78 | var address: String? { 79 | switch self { 80 | case .navigateToConference: 81 | return "1750 Welton St, Denver, CO 80202" 82 | case .navigateToHenrys: 83 | return "500 16th St, Denver, CO 80202" 84 | case .navigateToFoodTrucks: 85 | return "Civic Center, Denver, CO" 86 | case .navigateToRhinoBeerGarden: 87 | return "3800 Walnut St, Denver, CO 80205" 88 | default: 89 | return nil 90 | } 91 | } 92 | 93 | /// Get the image for this pin. 94 | var image: UIImage? { 95 | switch self { 96 | case .navigateToConference: 97 | return UIImage(named: "hyatt_bubble") 98 | case .navigateToHenrys: 99 | return UIImage(named: "henrys_bubble") 100 | case .navigateToFoodTrucks: 101 | return UIImage(named: "civic_center_bubble") 102 | case .navigateToRhinoBeerGarden: 103 | return UIImage(named: "beer_garden_bubble") 104 | default: 105 | return nil 106 | } 107 | } 108 | } 109 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/General/ImageSource/Source.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Source.swift 3 | // Kingfisher 4 | // 5 | // Created by onevcat on 2018/11/17. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Represents an image setting source for Kingfisher methods. 30 | /// 31 | /// A `Source` value indicates the way how the target image can be retrieved and cached. 32 | /// 33 | /// - network: The target image should be got from network remotely. The associated `Resource` 34 | /// value defines detail information like image URL and cache key. 35 | /// - provider: The target image should be provided in a data format. Normally, it can be an image 36 | /// from local storage or in any other encoding format (like Base64). 37 | public enum Source { 38 | 39 | /// Represents the source task identifier when setting an image to a view with extension methods. 40 | public enum Identifier { 41 | 42 | /// The underlying value type of source identifier. 43 | public typealias Value = UInt 44 | static var current: Value = 0 45 | static func next() -> Value { 46 | current += 1 47 | return current 48 | } 49 | } 50 | 51 | // MARK: Member Cases 52 | 53 | /// The target image should be got from network remotely. The associated `Resource` 54 | /// value defines detail information like image URL and cache key. 55 | case network(Resource) 56 | 57 | /// The target image should be provided in a data format. Normally, it can be an image 58 | /// from local storage or in any other encoding format (like Base64). 59 | case provider(ImageDataProvider) 60 | 61 | // MARK: Getting Properties 62 | 63 | /// The cache key defined for this source value. 64 | public var cacheKey: String { 65 | switch self { 66 | case .network(let resource): return resource.cacheKey 67 | case .provider(let provider): return provider.cacheKey 68 | } 69 | } 70 | 71 | /// The URL defined for this source value. 72 | /// 73 | /// For a `.network` source, it is the `downloadURL` of associated `Resource` instance. 74 | /// For a `.provider` value, it is always `nil`. 75 | public var url: URL? { 76 | switch self { 77 | case .network(let resource): return resource.downloadURL 78 | // `ImageDataProvider` does not provide a URL. All it cares is how to get the data back. 79 | case .provider(_): return nil 80 | } 81 | } 82 | } 83 | 84 | extension Source { 85 | var asResource: Resource? { 86 | guard case .network(let resource) = self else { 87 | return nil 88 | } 89 | return resource 90 | } 91 | 92 | var asProvider: ImageDataProvider? { 93 | guard case .provider(let provider) = self else { 94 | return nil 95 | } 96 | return provider 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Schedule/Schedule.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Location Manager/LocationManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocationManager.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 02/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreLocation 11 | 12 | protocol LocationManagerDelegate: class { 13 | func locationManagerDidUpdateLocation(_ locationManager: LocationManager, 14 | location: CLLocation) 15 | func locationManagerDidUpdateHeading(_ locationManager: LocationManager, 16 | heading: CLLocationDirection, 17 | accuracy: CLLocationDirection) 18 | } 19 | 20 | extension LocationManagerDelegate { 21 | func locationManagerDidUpdateLocation(_ locationManager: LocationManager, 22 | location: CLLocation) { } 23 | 24 | func locationManagerDidUpdateHeading(_ locationManager: LocationManager, 25 | heading: CLLocationDirection, 26 | accuracy: CLLocationDirection) { } 27 | } 28 | 29 | /// Handles retrieving the location and heading from CoreLocation 30 | /// Does not contain anything related to ARKit or advanced location 31 | public class LocationManager: NSObject { 32 | weak var delegate: LocationManagerDelegate? 33 | 34 | private var locationManager: CLLocationManager? 35 | 36 | var currentLocation: CLLocation? 37 | 38 | private(set) public var heading: CLLocationDirection? 39 | private(set) public var headingAccuracy: CLLocationDirection? 40 | 41 | override init() { 42 | super.init() 43 | 44 | self.locationManager = CLLocationManager() 45 | self.locationManager!.desiredAccuracy = kCLLocationAccuracyBestForNavigation 46 | self.locationManager!.distanceFilter = kCLDistanceFilterNone 47 | self.locationManager!.headingFilter = kCLHeadingFilterNone 48 | self.locationManager!.pausesLocationUpdatesAutomatically = false 49 | self.locationManager!.delegate = self 50 | self.locationManager!.startUpdatingHeading() 51 | self.locationManager!.startUpdatingLocation() 52 | 53 | self.locationManager!.requestWhenInUseAuthorization() 54 | 55 | self.currentLocation = self.locationManager!.location 56 | } 57 | 58 | func requestAuthorization() { 59 | if CLLocationManager.authorizationStatus() == .authorizedAlways || 60 | CLLocationManager.authorizationStatus() == .authorizedWhenInUse { 61 | return 62 | } 63 | 64 | if CLLocationManager.authorizationStatus() == .denied || 65 | CLLocationManager.authorizationStatus() == .restricted { 66 | return 67 | } 68 | 69 | locationManager?.requestWhenInUseAuthorization() 70 | } 71 | } 72 | 73 | // MARK: - CLLocationManagerDelegate 74 | 75 | extension LocationManager: CLLocationManagerDelegate { 76 | 77 | public func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { 78 | 79 | } 80 | 81 | public func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 82 | locations.forEach { 83 | delegate?.locationManagerDidUpdateLocation(self, location: $0) 84 | } 85 | 86 | self.currentLocation = manager.location 87 | } 88 | 89 | public func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) { 90 | heading = newHeading.headingAccuracy >= 0 ? newHeading.trueHeading : newHeading.magneticHeading 91 | headingAccuracy = newHeading.headingAccuracy 92 | 93 | delegate?.locationManagerDidUpdateHeading(self, heading: heading!, accuracy: newHeading.headingAccuracy) 94 | } 95 | 96 | public func locationManagerShouldDisplayHeadingCalibration(_ manager: CLLocationManager) -> Bool { 97 | return true 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /Pods/Cartography/Cartography/Compound.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Compound.swift 3 | // Cartography 4 | // 5 | // Created by Robert Böhnke on 18/06/14. 6 | // Copyright (c) 2014 Robert Böhnke. All rights reserved. 7 | // 8 | 9 | #if os(iOS) || os(tvOS) 10 | import UIKit 11 | #else 12 | import AppKit 13 | #endif 14 | 15 | public protocol Compound { 16 | var context: Context { get } 17 | var properties: [Property] { get } 18 | } 19 | 20 | /// Compound properties conforming to this protocol can use the `==` operator 21 | /// with other compound properties of the same type. 22 | public protocol RelativeCompoundEquality : Compound { } 23 | 24 | /// Declares a property equal to a the result of an expression. 25 | /// 26 | /// - parameter lhs: The affected property. The associated item will have 27 | /// `translatesAutoresizingMaskIntoConstraints` set to `false`. 28 | /// - parameter rhs: The expression. 29 | /// 30 | /// - returns: An `NSLayoutConstraint`. 31 | /// 32 | @discardableResult public func == (lhs: P, rhs: Expression

) -> [NSLayoutConstraint] { 33 | return lhs.context.addConstraint(lhs, coefficients: rhs.coefficients, to: rhs.value) 34 | } 35 | 36 | /// Declares a property equal to another compound property. 37 | /// 38 | /// - parameter lhs: The affected property. The associated item will have 39 | /// `translatesAutoresizingMaskIntoConstraints` set to `false`. 40 | /// - parameter rhs: The other property. 41 | /// 42 | @discardableResult public func == (lhs: P, rhs: P) -> [NSLayoutConstraint] { 43 | return lhs.context.addConstraint(lhs, to: rhs) 44 | } 45 | 46 | /// Compound properties conforming to this protocol can use the `<=` and `>=` 47 | /// operators with other compound properties of the same type. 48 | public protocol RelativeCompoundInequality : Compound { } 49 | 50 | /// Declares a property less than or equal to another compound property. 51 | /// 52 | /// - parameter lhs: The affected property. The associated item will have 53 | /// `translatesAutoresizingMaskIntoConstraints` set to `false`. 54 | /// - parameter rhs: The other property. 55 | /// 56 | /// - returns: An `NSLayoutConstraint`. 57 | /// 58 | @discardableResult public func <= (lhs: P, rhs: P) -> [NSLayoutConstraint] { 59 | return lhs.context.addConstraint(lhs, to: rhs, relation: .lessThanOrEqual) 60 | } 61 | 62 | /// Declares a property greater than or equal to another compound property. 63 | /// 64 | /// - parameter lhs: The affected property. The associated item will have 65 | /// `translatesAutoresizingMaskIntoConstraints` set to `false`. 66 | /// - parameter rhs: The other property. 67 | /// 68 | /// - returns: An `NSLayoutConstraint`. 69 | /// 70 | @discardableResult public func >= (lhs: P, rhs: P) -> [NSLayoutConstraint] { 71 | return lhs.context.addConstraint(lhs, to: rhs, relation: .greaterThanOrEqual) 72 | } 73 | 74 | /// Declares a property less than or equal to the result of an expression. 75 | /// 76 | /// - parameter lhs: The affected property. The associated item will have 77 | /// `translatesAutoresizingMaskIntoConstraints` set to `false`. 78 | /// - parameter rhs: The other property. 79 | /// 80 | /// - returns: An `NSLayoutConstraint`. 81 | /// 82 | @discardableResult public func <= (lhs: P, rhs: Expression

) -> [NSLayoutConstraint] { 83 | return lhs.context.addConstraint(lhs, coefficients: rhs.coefficients, to: rhs.value, relation: .lessThanOrEqual) 84 | } 85 | 86 | /// Declares a property greater than or equal to the result of an expression. 87 | /// 88 | /// - parameter lhs: The affected property. The associated item will have 89 | /// `translatesAutoresizingMaskIntoConstraints` set to `false`. 90 | /// - parameter rhs: The other property. 91 | /// 92 | /// - returns: An `NSLayoutConstraint`. 93 | /// 94 | @discardableResult public func >= (lhs: P, rhs: Expression

) -> [NSLayoutConstraint] { 95 | return lhs.context.addConstraint(lhs, coefficients: rhs.coefficients, to: rhs.value, relation: .greaterThanOrEqual) 96 | } 97 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Networking/AuthenticationChallengeResponsable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AuthenticationChallengeResponsable.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2018/10/11. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Protocol indicates that an authentication challenge could be handled. 30 | public protocol AuthenticationChallengeResponsable: AnyObject { 31 | 32 | /// Called when a session level authentication challenge is received. 33 | /// This method provide a chance to handle and response to the authentication 34 | /// challenge before downloading could start. 35 | /// 36 | /// - Parameters: 37 | /// - downloader: The downloader which receives this challenge. 38 | /// - challenge: An object that contains the request for authentication. 39 | /// - completionHandler: A handler that your delegate method must call. 40 | /// 41 | /// - Note: This method is a forward from `URLSessionDelegate.urlSession(:didReceiveChallenge:completionHandler:)`. 42 | /// Please refer to the document of it in `URLSessionDelegate`. 43 | func downloader( 44 | _ downloader: ImageDownloader, 45 | didReceive challenge: URLAuthenticationChallenge, 46 | completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) 47 | 48 | /// Called when a task level authentication challenge is received. 49 | /// This method provide a chance to handle and response to the authentication 50 | /// challenge before downloading could start. 51 | /// 52 | /// - Parameters: 53 | /// - downloader: The downloader which receives this challenge. 54 | /// - task: The task whose request requires authentication. 55 | /// - challenge: An object that contains the request for authentication. 56 | /// - completionHandler: A handler that your delegate method must call. 57 | func downloader( 58 | _ downloader: ImageDownloader, 59 | task: URLSessionTask, 60 | didReceive challenge: URLAuthenticationChallenge, 61 | completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) 62 | } 63 | 64 | extension AuthenticationChallengeResponsable { 65 | 66 | public func downloader( 67 | _ downloader: ImageDownloader, 68 | didReceive challenge: URLAuthenticationChallenge, 69 | completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) 70 | { 71 | if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust { 72 | if let trustedHosts = downloader.trustedHosts, trustedHosts.contains(challenge.protectionSpace.host) { 73 | let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!) 74 | completionHandler(.useCredential, credential) 75 | return 76 | } 77 | } 78 | 79 | completionHandler(.performDefaultHandling, nil) 80 | } 81 | 82 | public func downloader( 83 | _ downloader: ImageDownloader, 84 | task: URLSessionTask, 85 | didReceive challenge: URLAuthenticationChallenge, 86 | completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) 87 | { 88 | completionHandler(.performDefaultHandling, nil) 89 | } 90 | 91 | } 92 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Nodes/LocationAnnotationNode.swift: -------------------------------------------------------------------------------- 1 | // 2 | // LocationNode.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 02/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | import Foundation 9 | import SceneKit 10 | import CoreLocation 11 | 12 | open class LocationAnnotationNode: LocationNode { 13 | /// Subnodes and adjustments should be applied to this subnode 14 | /// Required to allow scaling at the same time as having a 2D 'billboard' appearance 15 | public let annotationNode: AnnotationNode 16 | 17 | public init(location: CLLocation?, image: UIImage) { 18 | let plane = SCNPlane(width: image.size.width / 100, height: image.size.height / 100) 19 | plane.firstMaterial!.diffuse.contents = image 20 | plane.firstMaterial!.lightingModel = .constant 21 | 22 | annotationNode = AnnotationNode(view: nil, image: image) 23 | annotationNode.geometry = plane 24 | annotationNode.removeFlicker() 25 | 26 | super.init(location: location) 27 | 28 | let billboardConstraint = SCNBillboardConstraint() 29 | billboardConstraint.freeAxes = SCNBillboardAxis.Y 30 | constraints = [billboardConstraint] 31 | 32 | addChildNode(annotationNode) 33 | } 34 | 35 | @available(iOS 10.0, *) 36 | /// Use this constructor to add a UIView as an annotation. Keep in mind that it is not live, instead 37 | /// it's a "snapshot" of that UIView. UIView is more configurable then a UIImage, allowing you to add 38 | /// background image, labels, etc. 39 | /// 40 | /// - Parameters: 41 | /// - location: The location of the node in the world. 42 | /// - view: The view to display at the specified location. 43 | public convenience init(location: CLLocation?, view: UIView) { 44 | self.init(location: location, image: view.image) 45 | } 46 | 47 | required public init?(coder aDecoder: NSCoder) { 48 | fatalError("init(coder:) has not been implemented") 49 | } 50 | 51 | override func updatePositionAndScale(setup: Bool = false, scenePosition: SCNVector3?, 52 | locationNodeLocation nodeLocation: CLLocation, 53 | locationManager: SceneLocationManager, 54 | onCompletion: (() -> Void)) { 55 | guard let position = scenePosition, let location = locationManager.currentLocation else { return } 56 | 57 | SCNTransaction.begin() 58 | SCNTransaction.animationDuration = setup ? 0.0 : 0.1 59 | 60 | let distance = self.location(locationManager.bestLocationEstimate).distance(from: location) 61 | 62 | let adjustedDistance = self.adjustedDistance(setup: setup, position: position, 63 | locationNodeLocation: nodeLocation, locationManager: locationManager) 64 | 65 | // The scale of a node with a billboard constraint applied is ignored 66 | // The annotation subnode itself, as a subnode, has the scale applied to it 67 | let appliedScale = self.scale 68 | self.scale = SCNVector3(x: 1, y: 1, z: 1) 69 | 70 | var scale: Float 71 | 72 | if scaleRelativeToDistance { 73 | scale = appliedScale.y 74 | annotationNode.scale = appliedScale 75 | annotationNode.childNodes.forEach { child in 76 | child.scale = appliedScale 77 | } 78 | } else { 79 | let scaleFunc = scalingScheme.getScheme() 80 | scale = scaleFunc(distance, adjustedDistance) 81 | 82 | annotationNode.scale = SCNVector3(x: scale, y: scale, z: scale) 83 | annotationNode.childNodes.forEach { node in 84 | node.scale = SCNVector3(x: scale, y: scale, z: scale) 85 | } 86 | } 87 | 88 | self.pivot = SCNMatrix4MakeTranslation(0, -1.1 * scale, 0) 89 | 90 | SCNTransaction.commit() 91 | 92 | onCompletion() 93 | } 94 | } 95 | 96 | // MARK: - Image from View 97 | 98 | public extension UIView { 99 | 100 | @available(iOS 10.0, *) 101 | /// Gets you an image from the view. 102 | var image: UIImage { 103 | let renderer = UIGraphicsImageRenderer(bounds: bounds) 104 | return renderer.image { rendererContext in 105 | layer.render(in: rendererContext.cgContext) 106 | } 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Cache/Storage.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Storage.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2018/10/15. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Constants for some time intervals 30 | struct TimeConstants { 31 | static let secondsInOneMinute = 60 32 | static let minutesInOneHour = 60 33 | static let hoursInOneDay = 24 34 | static let secondsInOneDay = secondsInOneMinute * minutesInOneHour * hoursInOneDay 35 | } 36 | 37 | /// Represents the expiration strategy used in storage. 38 | /// 39 | /// - never: The item never expires. 40 | /// - seconds: The item expires after a time duration of given seconds from now. 41 | /// - days: The item expires after a time duration of given days from now. 42 | /// - date: The item expires after a given date. 43 | public enum StorageExpiration { 44 | /// The item never expires. 45 | case never 46 | /// The item expires after a time duration of given seconds from now. 47 | case seconds(TimeInterval) 48 | /// The item expires after a time duration of given days from now. 49 | case days(Int) 50 | /// The item expires after a given date. 51 | case date(Date) 52 | /// Indicates the item is already expired. Use this to skip cache. 53 | case expired 54 | 55 | func estimatedExpirationSince(_ date: Date) -> Date { 56 | switch self { 57 | case .never: return .distantFuture 58 | case .seconds(let seconds): return date.addingTimeInterval(seconds) 59 | case .days(let days): return date.addingTimeInterval(TimeInterval(TimeConstants.secondsInOneDay * days)) 60 | case .date(let ref): return ref 61 | case .expired: return .distantPast 62 | } 63 | } 64 | 65 | var estimatedExpirationSinceNow: Date { 66 | return estimatedExpirationSince(Date()) 67 | } 68 | 69 | var isExpired: Bool { 70 | return timeInterval <= 0 71 | } 72 | 73 | var timeInterval: TimeInterval { 74 | switch self { 75 | case .never: return .infinity 76 | case .seconds(let seconds): return seconds 77 | case .days(let days): return TimeInterval(TimeConstants.secondsInOneDay * days) 78 | case .date(let ref): return ref.timeIntervalSinceNow 79 | case .expired: return -(.infinity) 80 | } 81 | } 82 | } 83 | 84 | /// Represents the expiration extending strategy used in storage to after access. 85 | /// 86 | /// - none: The item expires after the original time, without extending after access. 87 | /// - cacheTime: The item expiration extends by the original cache time after each access. 88 | /// - expirationTime: The item expiration extends by the provided time after each access. 89 | public enum ExpirationExtending { 90 | /// The item expires after the original time, without extending after access. 91 | case none 92 | /// The item expiration extends by the original cache time after each access. 93 | case cacheTime 94 | /// The item expiration extends by the provided time after each access. 95 | case expirationTime(_ expiration: StorageExpiration) 96 | } 97 | 98 | /// Represents types which cost in memory can be calculated. 99 | public protocol CacheCostCalculable { 100 | var cacheCost: Int { get } 101 | } 102 | 103 | /// Represents types which can be converted to and from data. 104 | public protocol DataTransformable { 105 | func toData() throws -> Data 106 | static func fromData(_ data: Data) throws -> Self 107 | static var empty: Self { get } 108 | } 109 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Networking/SessionDataTask.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SessionDataTask.swift 3 | // Kingfisher 4 | // 5 | // Created by Wei Wang on 2018/11/1. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// Represents a session data task in `ImageDownloader`. It consists of an underlying `URLSessionDataTask` and 30 | /// an array of `TaskCallback`. Multiple `TaskCallback`s could be added for a single downloading data task. 31 | public class SessionDataTask { 32 | 33 | /// Represents the type of token which used for cancelling a task. 34 | public typealias CancelToken = Int 35 | 36 | struct TaskCallback { 37 | let onCompleted: Delegate, Void>? 38 | let options: KingfisherParsedOptionsInfo 39 | } 40 | 41 | /// Downloaded raw data of current task. 42 | public private(set) var mutableData: Data 43 | 44 | /// The underlying download task. It is only for debugging purpose when you encountered an error. You should not 45 | /// modify the content of this task or start it yourself. 46 | public let task: URLSessionDataTask 47 | private var callbacksStore = [CancelToken: TaskCallback]() 48 | 49 | var callbacks: [SessionDataTask.TaskCallback] { 50 | lock.lock() 51 | defer { lock.unlock() } 52 | return Array(callbacksStore.values) 53 | } 54 | 55 | private var currentToken = 0 56 | private let lock = NSLock() 57 | 58 | let onTaskDone = Delegate<(Result<(Data, URLResponse?), KingfisherError>, [TaskCallback]), Void>() 59 | let onCallbackCancelled = Delegate<(CancelToken, TaskCallback), Void>() 60 | 61 | var started = false 62 | var containsCallbacks: Bool { 63 | // We should be able to use `task.state != .running` to check it. 64 | // However, in some rare cases, cancelling the task does not change 65 | // task state to `.cancelling` immediately, but still in `.running`. 66 | // So we need to check callbacks count to for sure that it is safe to remove the 67 | // task in delegate. 68 | return !callbacks.isEmpty 69 | } 70 | 71 | init(task: URLSessionDataTask) { 72 | self.task = task 73 | mutableData = Data() 74 | } 75 | 76 | func addCallback(_ callback: TaskCallback) -> CancelToken { 77 | lock.lock() 78 | defer { lock.unlock() } 79 | callbacksStore[currentToken] = callback 80 | defer { currentToken += 1 } 81 | return currentToken 82 | } 83 | 84 | func removeCallback(_ token: CancelToken) -> TaskCallback? { 85 | lock.lock() 86 | defer { lock.unlock() } 87 | if let callback = callbacksStore[token] { 88 | callbacksStore[token] = nil 89 | return callback 90 | } 91 | return nil 92 | } 93 | 94 | func resume() { 95 | guard !started else { return } 96 | started = true 97 | task.resume() 98 | } 99 | 100 | func cancel(token: CancelToken) { 101 | guard let callback = removeCallback(token) else { 102 | return 103 | } 104 | if callbacksStore.count == 0 { 105 | task.cancel() 106 | } 107 | onCallbackCancelled.call((token, callback)) 108 | } 109 | 110 | func forceCancel() { 111 | for token in callbacksStore.keys { 112 | cancel(token: token) 113 | } 114 | } 115 | 116 | func didReceiveData(_ data: Data) { 117 | mutableData.append(data) 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Schedule/ScheduleTableViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScheduleTableViewController.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import Cartography 10 | import UIKit 11 | 12 | class ScheduleTableViewController: UITableViewController { 13 | 14 | let dateFormatter: DateFormatter = { 15 | var formatter = DateFormatter() 16 | //August 25, 2019 17 | formatter.dateFormat = "MMMM dd, yyyy" 18 | 19 | return formatter 20 | }() 21 | 22 | class func loadFromStoryboard() -> ScheduleTableViewController { 23 | return UIStoryboard(name: "Schedule", bundle: nil).instantiateViewController(withIdentifier: "ScheduleTableViewController") as! ScheduleTableViewController 24 | } 25 | 26 | override func viewDidLoad() { 27 | super.viewDidLoad() 28 | title = "Schedule" 29 | 30 | tableView.rowHeight = UITableView.automaticDimension 31 | tableView.estimatedRowHeight = 100 32 | 33 | scrollToNow() 34 | } 35 | 36 | override func numberOfSections(in tableView: UITableView) -> Int { 37 | return DateEnum.allSorted.count 38 | } 39 | 40 | override func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? { 41 | let view = HeaderView() 42 | view.date = DateEnum.allSorted[section] 43 | view.buildView() 44 | 45 | return view 46 | } 47 | 48 | override func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 49 | return 60 50 | } 51 | 52 | override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 53 | let schedule = ScheduleService.shared.schedule[DateEnum.allSorted[section]] 54 | return schedule?.count ?? 0 55 | } 56 | 57 | override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 58 | let cell = tableView.dequeueReusableCell(withIdentifier: "Session", for: indexPath) 59 | 60 | guard let sessionCell = cell as? SessionCell, 61 | let schedule = ScheduleService.shared.schedule[DateEnum.allSorted[indexPath.section]], 62 | indexPath.row < schedule.count else { 63 | return cell 64 | } 65 | sessionCell.session = schedule[indexPath.row] 66 | 67 | 68 | return sessionCell 69 | } 70 | 71 | @IBAction 72 | func didRefresh(_ source: UIRefreshControl) { 73 | RemoteScheduleService.shared.cacheSchedule { (schedule, error) in 74 | defer { 75 | DispatchQueue.main.async { 76 | source.endRefreshing() 77 | } 78 | } 79 | if let error = error { 80 | return DispatchQueue.main.async { 81 | self.showErrorAlert(message: "Failed to update schedule: \(error.localizedDescription)") 82 | } 83 | } 84 | if schedule == nil { 85 | return DispatchQueue.main.async { 86 | self.showErrorAlert(message: "Failed to update the schedule, please try again") 87 | } 88 | } 89 | ScheduleService.shared.reloadBundle() 90 | DispatchQueue.main.async { 91 | self.tableView.reloadData() 92 | } 93 | } 94 | } 95 | 96 | func scrollToNow() { 97 | let now = Date() 98 | 99 | let dateString = dateFormatter.string(from: now) 100 | 101 | guard let currentDay = DateEnum(rawValue: dateString), 102 | let dateIndex = DateEnum.allSorted.firstIndex(of: currentDay), 103 | let sessions = ScheduleService.shared.schedule[DateEnum.allSorted[dateIndex]] else { 104 | return 105 | } 106 | 107 | let itemIndex = sessions.indices.filter { 108 | sessions[$0].compareDates(to: now) 109 | }.first 110 | 111 | tableView.scrollToRow(at: IndexPath(item: itemIndex ?? 0, section: dateIndex), at: .middle, animated: true) 112 | } 113 | 114 | } 115 | 116 | class HeaderView: UIView { 117 | private let label = UILabel() 118 | var date: DateEnum? { 119 | didSet { 120 | label.text = date?.rawValue 121 | } 122 | } 123 | 124 | func buildView() { 125 | addSubview(label) 126 | label.textColor = .black 127 | backgroundColor = .lightGray 128 | 129 | constrain(self, label) { view, label in 130 | label.top == view.top + 8 131 | label.left == view.left + 8 132 | label.right == view.right - 8 133 | label.bottom == view.bottom + 8 134 | } 135 | 136 | label.font = UIFont.boldSystemFont(ofSize: 20) 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /360iDev AR Navigation/Services/ScheduleService.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ScheduleService.swift 3 | // 360iDev AR Navigation 4 | // 5 | // Created by Eric Internicola on 8/14/19. 6 | // Copyright © 2019 Eric Internicola. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | class ScheduleService { 12 | static let shared = ScheduleService() 13 | 14 | enum Source { 15 | case bundle 16 | case documents 17 | } 18 | 19 | /// A map of DateEnum to (sorted) array of Sessions. 20 | var schedule = [DateEnum: [Session]]() 21 | 22 | /// Where the schedule was loaded from. 23 | var source = Source.bundle 24 | 25 | /// First, tries to load the schedule from the documents folder. 26 | /// If that doesn't work, then it loads it from the bundle. 27 | func reloadBundle() { 28 | if loadScheduleFromDocuments() { 29 | source = .documents 30 | } else { 31 | loadScheduleFromBundle() 32 | source = .bundle 33 | } 34 | } 35 | } 36 | 37 | // MARK: - Implementation 38 | 39 | private extension ScheduleService { 40 | 41 | /// Gets you the path of the User Documents directory. 42 | var documentsDirectory: String? { 43 | let paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true) 44 | return paths.first 45 | } 46 | 47 | /// Reads the schedule from the main bundle 48 | func loadScheduleFromBundle() { 49 | guard let schedulePath = Bundle.main.path(forResource: "schedule", ofType: "json") else { 50 | return 51 | } 52 | let url = URL(fileURLWithPath: schedulePath) 53 | do { 54 | self.schedule = try schedule(from: url) 55 | } catch { 56 | assertionFailure(error.localizedDescription) 57 | } 58 | } 59 | 60 | /// Loads the schedule from the documents folder (if it exists). Returns 61 | /// a boolean to tell you whether or not it succeeded. 62 | /// 63 | /// - Returns: True if it succeeded, false if not. 64 | func loadScheduleFromDocuments() -> Bool { 65 | guard let documents = documentsDirectory else { 66 | return false 67 | } 68 | let docsPath = URL(fileURLWithPath: documents) 69 | let fileUrl = URL(fileURLWithPath: "schedule.json", relativeTo: docsPath) 70 | guard FileManager.default.fileExists(atPath: fileUrl.path) else { 71 | return false 72 | } 73 | do { 74 | self.schedule = try schedule(from: fileUrl) 75 | return true 76 | } catch { 77 | assertionFailure(error.localizedDescription) 78 | } 79 | return false 80 | } 81 | 82 | /// Reads the data from the provided file url, decodes it into JSON 83 | /// and then builds the schedule from that JSON. 84 | /// 85 | /// - Parameter file: The File URL to read. 86 | /// - Returns: The (organized and sorted) schedule. 87 | /// - Throws: If there's an error reading the file or decoding the JSON. 88 | func schedule(from fileUrl: URL) throws -> [DateEnum: [Session]] { 89 | let data = try Data(contentsOf: fileUrl) 90 | let schedule = try JSONDecoder().decode(Schedule.self, from: data) 91 | return buildSchedule(from: schedule) 92 | } 93 | 94 | /// Builds the schedule data structure from the raw schedule object. 95 | /// This function basically organizes the sessions by day and time. 96 | /// 97 | /// - Parameter schedule: The schedule to be organized. 98 | func buildSchedule(from schedule: Schedule) -> [DateEnum: [Session]] { 99 | var workingSet = [DateEnum: [Session]]() 100 | DateEnum.allSorted.forEach { workingSet[$0] = [Session]() } 101 | 102 | schedule.sessions.forEach { session in 103 | workingSet[session.date]?.append(session) 104 | } 105 | 106 | DateEnum.allSorted.forEach { date in 107 | workingSet[date] = workingSet[date]?.sorted { (first, second) -> Bool in 108 | guard let t1 = first.computeTimestamp(), let t2 = second.computeTimestamp() else { 109 | return false 110 | } 111 | return t1 < t2 112 | } 113 | } 114 | 115 | return workingSet 116 | } 117 | 118 | } 119 | 120 | extension Session { 121 | struct Constants { 122 | static let formatter: DateFormatter = { 123 | let df = DateFormatter() 124 | df.dateFormat = "MMMM d, yyyy h:mm a" 125 | df.amSymbol = "am" 126 | df.pmSymbol = "pm" 127 | df.timeZone = TimeZone(abbreviation: "MDT") 128 | 129 | return df 130 | }() 131 | } 132 | 133 | func computeTimestamp() -> Date? { 134 | let dateString = "\(date.rawValue) \(time)" 135 | return Constants.formatter.date(from: dateString) 136 | } 137 | } 138 | -------------------------------------------------------------------------------- /Pods/ARCL/Sources/ARKit-CoreLocation/Extensions/CLLocation+Extensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CLLocation+Extensions.swift 3 | // ARKit+CoreLocation 4 | // 5 | // Created by Andrew Hart on 02/07/2017. 6 | // Copyright © 2017 Project Dent. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreLocation 11 | 12 | ///Translation in meters between 2 locations 13 | public struct LocationTranslation { 14 | public var latitudeTranslation: Double 15 | public var longitudeTranslation: Double 16 | public var altitudeTranslation: Double 17 | } 18 | 19 | public extension CLLocation { 20 | convenience init(coordinate: CLLocationCoordinate2D, altitude: CLLocationDistance) { 21 | self.init(coordinate: coordinate, altitude: altitude, horizontalAccuracy: 0, verticalAccuracy: 0, timestamp: Date()) 22 | } 23 | 24 | /// Translates distance in meters between two locations. 25 | /// Returns the result as the distance in latitude and distance in longitude. 26 | func translation(toLocation location: CLLocation) -> LocationTranslation { 27 | let inbetweenLocation = CLLocation(latitude: self.coordinate.latitude, longitude: location.coordinate.longitude) 28 | 29 | let distanceLatitude = location.distance(from: inbetweenLocation) 30 | 31 | let latitudeTranslation = location.coordinate.latitude > inbetweenLocation.coordinate.latitude ? distanceLatitude 32 | : -distanceLatitude 33 | 34 | let distanceLongitude = distance(from: inbetweenLocation) 35 | 36 | let longitudeTranslation = coordinate.longitude > inbetweenLocation.coordinate.longitude ? -distanceLongitude 37 | : distanceLongitude 38 | 39 | let altitudeTranslation = location.altitude - self.altitude 40 | 41 | return LocationTranslation( latitudeTranslation: latitudeTranslation, 42 | longitudeTranslation: longitudeTranslation, 43 | altitudeTranslation: altitudeTranslation) 44 | } 45 | 46 | func translatedLocation(with translation: LocationTranslation) -> CLLocation { 47 | let latitudeCoordinate = self.coordinate.coordinateWithBearing(bearing: 0, 48 | distanceMeters: translation.latitudeTranslation) 49 | 50 | let longitudeCoordinate = self.coordinate.coordinateWithBearing(bearing: 90, 51 | distanceMeters: translation.longitudeTranslation) 52 | 53 | let coordinate = CLLocationCoordinate2D( latitude: latitudeCoordinate.latitude, longitude: longitudeCoordinate.longitude) 54 | 55 | let altitude = self.altitude + translation.altitudeTranslation 56 | 57 | return CLLocation(coordinate: coordinate, 58 | altitude: altitude, 59 | horizontalAccuracy: self.horizontalAccuracy, 60 | verticalAccuracy: self.verticalAccuracy, 61 | timestamp: self.timestamp) 62 | } 63 | 64 | func bearing(between point: CLLocation) -> Double { 65 | let lat1 = self.coordinate.latitude.degreesToRadians 66 | let lon1 = self.coordinate.longitude.degreesToRadians 67 | 68 | let lat2 = point.coordinate.latitude.degreesToRadians 69 | let lon2 = point.coordinate.longitude.degreesToRadians 70 | 71 | let dLon = lon2 - lon1 72 | 73 | let y = sin(dLon) * cos(lat2) 74 | let x = cos(lat1) * sin(lat2) - sin(lat1) * cos(lat2) * cos(dLon) 75 | return atan2(y, x).radiansToDegrees 76 | } 77 | } 78 | 79 | public extension CLLocation { 80 | var debugLog: String { 81 | return "location: \(self.coordinate), accuracy: \(self.horizontalAccuracy), date: \(self.timestamp)" 82 | } 83 | } 84 | 85 | public extension CLLocationCoordinate2D { 86 | 87 | func coordinateWithBearing(bearing: Double, distanceMeters: Double) -> CLLocationCoordinate2D { 88 | //The numbers for earth radius may be _off_ here 89 | //but this gives a reasonably accurate result.. 90 | //Any correction here is welcome. 91 | let distRadiansLat = distanceMeters.metersToLatitude // earth radius in meters latitude 92 | let distRadiansLong = distanceMeters.metersToLongitude // earth radius in meters longitude 93 | 94 | let lat1 = self.latitude * Double.pi / 180 95 | let lon1 = self.longitude * Double.pi / 180 96 | 97 | let lat2 = asin(sin(lat1) * cos(distRadiansLat) + cos(lat1) * sin(distRadiansLat) * cos(bearing)) 98 | let lon2 = lon1 + atan2(sin(bearing) * sin(distRadiansLong) * cos(lat1), cos(distRadiansLong) - sin(lat1) * sin(lat2)) 99 | 100 | return CLLocationCoordinate2D(latitude: lat2 * 180 / Double.pi, longitude: lon2 * 180 / Double.pi) 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Networking/ImageModifier.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ImageModifier.swift 3 | // Kingfisher 4 | // 5 | // Created by Ethan Gill on 2017/11/28. 6 | // 7 | // Copyright (c) 2019 Ethan Gill 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import Foundation 28 | 29 | /// An `ImageModifier` can be used to change properties on an image in between 30 | /// cache serialization and use of the image. The modified returned image will be 31 | /// only used for current rendering purpose, the serialization data will not contain 32 | /// the changes applied by the `ImageModifier`. 33 | public protocol ImageModifier { 34 | /// Modify an input `Image`. 35 | /// 36 | /// - parameter image: Image which will be modified by `self` 37 | /// 38 | /// - returns: The modified image. 39 | /// 40 | /// - Note: The return value will be unmodified if modifying is not possible on 41 | /// the current platform. 42 | /// - Note: Most modifiers support UIImage or NSImage, but not CGImage. 43 | func modify(_ image: Image) -> Image 44 | } 45 | 46 | /// A wrapper for creating an `ImageModifier` easier. 47 | /// This type conforms to `ImageModifier` and wraps an image modify block. 48 | /// If the `block` throws an error, the original image will be used. 49 | public struct AnyImageModifier: ImageModifier { 50 | 51 | /// A block which modifies images, or returns the original image 52 | /// if modification cannot be performed with an error. 53 | let block: (Image) throws -> Image 54 | 55 | /// Creates an `AnyImageModifier` with a given `modify` block. 56 | public init(modify: @escaping (Image) throws -> Image) { 57 | block = modify 58 | } 59 | 60 | /// Modify an input `Image`. See `ImageModifier` protocol for more. 61 | public func modify(_ image: Image) -> Image { 62 | return (try? block(image)) ?? image 63 | } 64 | } 65 | 66 | #if os(iOS) || os(tvOS) || os(watchOS) 67 | import UIKit 68 | 69 | /// Modifier for setting the rendering mode of images. 70 | public struct RenderingModeImageModifier: ImageModifier { 71 | 72 | /// The rendering mode to apply to the image. 73 | public let renderingMode: UIImage.RenderingMode 74 | 75 | /// Creates a `RenderingModeImageModifier`. 76 | /// 77 | /// - Parameter renderingMode: The rendering mode to apply to the image. Default is `.automatic`. 78 | public init(renderingMode: UIImage.RenderingMode = .automatic) { 79 | self.renderingMode = renderingMode 80 | } 81 | 82 | /// Modify an input `Image`. See `ImageModifier` protocol for more. 83 | public func modify(_ image: Image) -> Image { 84 | return image.withRenderingMode(renderingMode) 85 | } 86 | } 87 | 88 | /// Modifier for setting the `flipsForRightToLeftLayoutDirection` property of images. 89 | public struct FlipsForRightToLeftLayoutDirectionImageModifier: ImageModifier { 90 | 91 | /// Creates a `FlipsForRightToLeftLayoutDirectionImageModifier`. 92 | public init() {} 93 | 94 | /// Modify an input `Image`. See `ImageModifier` protocol for more. 95 | public func modify(_ image: Image) -> Image { 96 | return image.imageFlippedForRightToLeftLayoutDirection() 97 | } 98 | } 99 | 100 | /// Modifier for setting the `alignmentRectInsets` property of images. 101 | public struct AlignmentRectInsetsImageModifier: ImageModifier { 102 | 103 | /// The alignment insets to apply to the image 104 | public let alignmentInsets: UIEdgeInsets 105 | 106 | /// Creates an `AlignmentRectInsetsImageModifier`. 107 | public init(alignmentInsets: UIEdgeInsets) { 108 | self.alignmentInsets = alignmentInsets 109 | } 110 | 111 | /// Modify an input `Image`. See `ImageModifier` protocol for more. 112 | public func modify(_ image: Image) -> Image { 113 | return image.withAlignmentRectInsets(alignmentInsets) 114 | } 115 | } 116 | #endif 117 | -------------------------------------------------------------------------------- /Pods/Target Support Files/Pods-360iDev AR Navigation/Pods-360iDev AR Navigation-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## ARCL 5 | 6 | MIT License 7 | 8 | Copyright (c) 2017 Project Dent (https://ProjectDent.com) 9 | 10 | Permission is hereby granted, free of charge, to any person obtaining a copy 11 | of this software and associated documentation files (the "Software"), to deal 12 | in the Software without restriction, including without limitation the rights 13 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 14 | copies of the Software, and to permit persons to whom the Software is 15 | furnished to do so, subject to the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included in all 18 | copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 21 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 22 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 23 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 24 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 25 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 26 | SOFTWARE. 27 | 28 | ## Cartography 29 | 30 | Copyright (c) 2014 Robert Böhnke 31 | 32 | Permission is hereby granted, free of charge, to any person obtaining a copy 33 | of this software and associated documentation files (the "Software"), to deal 34 | in the Software without restriction, including without limitation the rights 35 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 36 | copies of the Software, and to permit persons to whom the Software is furnished 37 | to do so, subject to the following conditions: 38 | 39 | The above copyright notice and this permission notice shall be included in all 40 | copies or substantial portions of the Software. 41 | 42 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 43 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 44 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 45 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 46 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 47 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 48 | THE SOFTWARE. 49 | 50 | This license does not apply to the contents of the images folder. 51 | 52 | --- 53 | 54 | This project uses portions of code from FLKAutoLayout, 55 | copyright (c) 2013 Florian Kugler 56 | 57 | Permission is hereby granted, free of charge, to any person obtaining a copy 58 | of this software and associated documentation files (the "Software"), to deal 59 | in the Software without restriction, including without limitation the rights 60 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 61 | copies of the Software, and to permit persons to whom the Software is furnished 62 | to do so, subject to the following conditions: 63 | 64 | The above copyright notice and this permission notice shall be included in all 65 | copies or substantial portions of the Software. 66 | 67 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 68 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 69 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 70 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 71 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 72 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 73 | THE SOFTWARE. 74 | 75 | 76 | ## Kingfisher 77 | 78 | The MIT License (MIT) 79 | 80 | Copyright (c) 2018 Wei Wang 81 | 82 | Permission is hereby granted, free of charge, to any person obtaining a copy 83 | of this software and associated documentation files (the "Software"), to deal 84 | in the Software without restriction, including without limitation the rights 85 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 86 | copies of the Software, and to permit persons to whom the Software is 87 | furnished to do so, subject to the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be included in all 90 | copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 93 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 94 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 95 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 96 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 97 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 98 | SOFTWARE. 99 | 100 | 101 | Generated by CocoaPods - https://cocoapods.org 102 | -------------------------------------------------------------------------------- /Pods/Kingfisher/Sources/Utility/SizeExtensions.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SizeExtensions.swift 3 | // Kingfisher 4 | // 5 | // Created by onevcat on 2018/09/28. 6 | // 7 | // Copyright (c) 2019 Wei Wang 8 | // 9 | // Permission is hereby granted, free of charge, to any person obtaining a copy 10 | // of this software and associated documentation files (the "Software"), to deal 11 | // in the Software without restriction, including without limitation the rights 12 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 13 | // copies of the Software, and to permit persons to whom the Software is 14 | // furnished to do so, subject to the following conditions: 15 | // 16 | // The above copyright notice and this permission notice shall be included in 17 | // all copies or substantial portions of the Software. 18 | // 19 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 20 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 21 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 22 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 23 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 24 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 25 | // THE SOFTWARE. 26 | 27 | import CoreGraphics 28 | 29 | extension CGSize: KingfisherCompatibleValue {} 30 | extension KingfisherWrapper where Base == CGSize { 31 | 32 | /// Returns a size by resizing the `base` size to a target size under a given content mode. 33 | /// 34 | /// - Parameters: 35 | /// - size: The target size to resize to. 36 | /// - contentMode: Content mode of the target size should be when resizing. 37 | /// - Returns: The resized size under the given `ContentMode`. 38 | public func resize(to size: CGSize, for contentMode: ContentMode) -> CGSize { 39 | switch contentMode { 40 | case .aspectFit: 41 | return constrained(size) 42 | case .aspectFill: 43 | return filling(size) 44 | case .none: 45 | return size 46 | } 47 | } 48 | 49 | /// Returns a size by resizing the `base` size by making it aspect fitting the given `size`. 50 | /// 51 | /// - Parameter size: The size in which the `base` should fit in. 52 | /// - Returns: The size fitted in by the input `size`, while keeps `base` aspect. 53 | public func constrained(_ size: CGSize) -> CGSize { 54 | let aspectWidth = round(aspectRatio * size.height) 55 | let aspectHeight = round(size.width / aspectRatio) 56 | 57 | return aspectWidth > size.width ? 58 | CGSize(width: size.width, height: aspectHeight) : 59 | CGSize(width: aspectWidth, height: size.height) 60 | } 61 | 62 | /// Returns a size by resizing the `base` size by making it aspect filling the given `size`. 63 | /// 64 | /// - Parameter size: The size in which the `base` should fill. 65 | /// - Returns: The size be filled by the input `size`, while keeps `base` aspect. 66 | public func filling(_ size: CGSize) -> CGSize { 67 | let aspectWidth = round(aspectRatio * size.height) 68 | let aspectHeight = round(size.width / aspectRatio) 69 | 70 | return aspectWidth < size.width ? 71 | CGSize(width: size.width, height: aspectHeight) : 72 | CGSize(width: aspectWidth, height: size.height) 73 | } 74 | 75 | /// Returns a `CGRect` for which the `base` size is constrained to an input `size` at a given `anchor` point. 76 | /// 77 | /// - Parameters: 78 | /// - size: The size in which the `base` should be constrained to. 79 | /// - anchor: An anchor point in which the size constraint should happen. 80 | /// - Returns: The result `CGRect` for the constraint operation. 81 | public func constrainedRect(for size: CGSize, anchor: CGPoint) -> CGRect { 82 | 83 | let unifiedAnchor = CGPoint(x: anchor.x.clamped(to: 0.0...1.0), 84 | y: anchor.y.clamped(to: 0.0...1.0)) 85 | 86 | let x = unifiedAnchor.x * base.width - unifiedAnchor.x * size.width 87 | let y = unifiedAnchor.y * base.height - unifiedAnchor.y * size.height 88 | let r = CGRect(x: x, y: y, width: size.width, height: size.height) 89 | 90 | let ori = CGRect(origin: .zero, size: base) 91 | return ori.intersection(r) 92 | } 93 | 94 | private var aspectRatio: CGFloat { 95 | return base.height == 0.0 ? 1.0 : base.width / base.height 96 | } 97 | } 98 | 99 | extension CGRect { 100 | func scaled(_ scale: CGFloat) -> CGRect { 101 | return CGRect(x: origin.x * scale, y: origin.y * scale, 102 | width: size.width * scale, height: size.height * scale) 103 | } 104 | } 105 | 106 | extension Comparable { 107 | func clamped(to limits: ClosedRange) -> Self { 108 | return min(max(self, limits.lowerBound), limits.upperBound) 109 | } 110 | } 111 | --------------------------------------------------------------------------------