├── PKLocationManager.xcodeproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── project.pbxproj ├── PKLocationManager ├── LocationManager.h ├── LocationMonitor.swift ├── Info.plist └── LocationManager.swift ├── Demo ├── AppDelegate.swift ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── Info.plist ├── DemoViewController.swift └── Base.lproj │ └── Main.storyboard ├── .gitignore ├── PKLocationManager.podspec ├── LICENSE └── README.md /PKLocationManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /PKLocationManager/LocationManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // PKLocationManager.h 3 | // PKLocationManager 4 | // 5 | // Created by Philip Kluz on 6/20/14. 6 | // Copyright (c) 2014 NSExceptional. All rights reserved. 7 | // 8 | 9 | @import UIKit; 10 | 11 | //! Project version number for PKLocationManager. 12 | FOUNDATION_EXPORT double PKLocationManagerVersionNumber; 13 | 14 | //! Project version string for PKLocationManager. 15 | FOUNDATION_EXPORT const unsigned char PKLocationManagerVersionString[]; 16 | -------------------------------------------------------------------------------- /Demo/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Demo 4 | // 5 | // Created by Philip Kluz on 6/20/14. 6 | // Copyright (c) 2014 NSExceptional. 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: NSDictionary?) -> Bool { 17 | return true 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Mac OS X Finder and whatnot 2 | .DS_Store 3 | *.swp 4 | *~.nib 5 | 6 | # XCode (and ancestors) per-user config (very noisy, and not relevant) 7 | *.mode1 8 | *.mode1v3 9 | *.mode2v3 10 | *.perspective 11 | *.perspectivev3 12 | *.pbxuser 13 | *.xcworkspace 14 | *.xccheckout 15 | 16 | # XCode 4 17 | xcuserdata 18 | 19 | # build products 20 | build/ 21 | 22 | # Other source repository archive directories (protects when importing) 23 | .hg 24 | .svn 25 | CVS 26 | 27 | # temporary script folders/files 28 | ThirdParty/boost/* 29 | 30 | # Eclipse Workspace 31 | .metadata 32 | 33 | # Maya temporary 34 | .mayaSwatches/ 35 | -------------------------------------------------------------------------------- /PKLocationManager/LocationMonitor.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKLocationMonitor.swift 3 | // PKLocationManager 4 | // 5 | // Created by Philip Kluz on 6/20/14. 6 | // Copyright (c) 2014 NSExceptional. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreLocation 11 | 12 | final internal class LocationMonitor { 13 | internal var monitoringObject: AnyObject 14 | internal var queue: dispatch_queue_t 15 | internal var handler: ((CLLocation) -> ())? 16 | internal var desiredAccuracy: CLLocationAccuracy 17 | 18 | internal init(monitoringObject object: AnyObject, queue: dispatch_queue_t = dispatch_get_main_queue(), desiredAccuracy: CLLocationAccuracy = kCLLocationAccuracyHundredMeters, handler: ((CLLocation) -> ())?) { 19 | self.monitoringObject = object 20 | self.queue = queue 21 | self.desiredAccuracy = desiredAccuracy 22 | self.handler = handler 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /PKLocationManager.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'PKLocationManager' 3 | s.module_name = 'PKLocationManager' 4 | s.version = '1.0.2' 5 | s.summary = 'A Swift based, centralized location manager, simplifying the CLLocationManager API by adding closures and automatically adjusting accuracy, based on the subscribers common needs.' 6 | s.homepage = 'https://github.com/pkluz/PKLocationManager' 7 | s.license = 'MIT' 8 | s.author = { 'Philip Kluz' => 'Philip.Kluz@gmail.com' } 9 | s.platform = :ios, '8.0' 10 | s.ios.deployment_target = '8.0' 11 | s.requires_arc = true 12 | s.source = { :git => 'https://github.com/pkluz/PKLocationManager.git', :tag => '1.0.2' } 13 | s.source_files = 'PKLocationManager/**/*.{h,swift}' 14 | end 15 | -------------------------------------------------------------------------------- /PKLocationManager/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.NSExceptional.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "40x40", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "60x60", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "ipad", 20 | "size" : "29x29", 21 | "scale" : "1x" 22 | }, 23 | { 24 | "idiom" : "ipad", 25 | "size" : "29x29", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "ipad", 30 | "size" : "40x40", 31 | "scale" : "1x" 32 | }, 33 | { 34 | "idiom" : "ipad", 35 | "size" : "40x40", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "76x76", 41 | "scale" : "1x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "76x76", 46 | "scale" : "2x" 47 | } 48 | ], 49 | "info" : { 50 | "version" : 1, 51 | "author" : "xcode" 52 | } 53 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Philip Kluz (Philip.Kluz@zuui.org) 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. -------------------------------------------------------------------------------- /Demo/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "orientation" : "portrait", 20 | "idiom" : "ipad", 21 | "extent" : "full-screen", 22 | "minimum-system-version" : "7.0", 23 | "scale" : "1x" 24 | }, 25 | { 26 | "orientation" : "landscape", 27 | "idiom" : "ipad", 28 | "extent" : "full-screen", 29 | "minimum-system-version" : "7.0", 30 | "scale" : "1x" 31 | }, 32 | { 33 | "orientation" : "portrait", 34 | "idiom" : "ipad", 35 | "extent" : "full-screen", 36 | "minimum-system-version" : "7.0", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "orientation" : "landscape", 41 | "idiom" : "ipad", 42 | "extent" : "full-screen", 43 | "minimum-system-version" : "7.0", 44 | "scale" : "2x" 45 | } 46 | ], 47 | "info" : { 48 | "version" : 1, 49 | "author" : "xcode" 50 | } 51 | } -------------------------------------------------------------------------------- /Demo/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | com.NSExceptional.${PRODUCT_NAME:rfc1034identifier} 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | ${PRODUCT_NAME} 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | NSLocationAlwaysUsageDescription 32 | The PKLocationManager Demo App requires your authorization to always monitor your location because it is awesome. 33 | NSLocationWhenInUseUsageDescription 34 | The PKLocationManager Demo App requires your authorization to monitor your location because it is awesome. 35 | 36 | 37 | -------------------------------------------------------------------------------- /Demo/DemoViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // DemoViewController.swift 3 | // Demo 4 | // 5 | // Created by Philip Kluz on 6/20/14. 6 | // Copyright (c) 2014 NSExceptional. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import PKLocationManager 11 | import CoreLocation 12 | 13 | class DemoViewController: UIViewController { 14 | 15 | @IBOutlet var locationMonitoringActiveLabel: UILabel! 16 | @IBOutlet var locationLabel: UILabel! 17 | var secondMonitor = NSObject() 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | locationLabel.adjustsFontSizeToFitWidth = true 22 | 23 | LocationManager.sharedManager.requiresLocationMonitoringWhenInUse = true 24 | } 25 | 26 | @IBAction func registerForLocationUpdates(sender: AnyObject) { 27 | var (success, error) = LocationManager.sharedManager.register(locationMonitor: self, desiredAccuracy: kCLLocationAccuracyBest, queue: dispatch_get_main_queue()) { 28 | [weak self] location in 29 | self!.locationLabel.text = location.description 30 | } 31 | 32 | LocationManager.sharedManager.register(locationMonitor: secondMonitor, desiredAccuracy: kCLLocationAccuracyBest, queue: dispatch_get_main_queue()) { 33 | location in 34 | println("Second Monitor received location: \(location)") 35 | } 36 | 37 | if success { 38 | locationMonitoringActiveLabel.text = "YES" 39 | } else { 40 | let alert = UIAlertController(title: "Registration Failed", message: error!.localizedDescription, preferredStyle: UIAlertControllerStyle.Alert) 41 | alert.addAction(UIAlertAction(title: "Dismiss", style: UIAlertActionStyle.Default, handler: nil)) 42 | self.presentViewController(alert, animated: true, completion: nil) 43 | } 44 | } 45 | 46 | @IBAction func deregisterFromLocationUpdates(sender: AnyObject) { 47 | LocationManager.sharedManager.deregister(self) 48 | LocationManager.sharedManager.deregister(secondMonitor) 49 | locationMonitoringActiveLabel.text = "NO" 50 | locationLabel.text = "--" 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | PKLocationManager 2 | ==== 3 | A **Swift** based, centralized location manager, simplifying the CLLocationManager API by adding closures and automatically adjusting accuracy, based on the subscribers common needs. 4 | 5 | ## Features 6 | - **Centralized** location manager abstraction. 7 | - **Closure based** interface. 8 | - **Automatic start and stop** of location retrieval, based on subscriber count. 9 | - **Automatic accuracy adjustment**, based on subscriber needs in order to **save battery**. 10 | - Builds as an **iOS 8 framework** 11 | 12 | ## How To 13 | After adding the framework to your project, you need to import the module 14 | ``` 15 | import PKLocationManager 16 | ``` 17 | 18 | More detailed documentation incoming. See `LocationManager.swift` for comments, and the Demo project for example usage. 19 | 20 | ## Disclaimer 21 | 22 | While basically the basic feature set is complete and stable, make sure you understand that the API **is likely to change as Swift matures** and some of the annoying compiler quirks are resolved. 23 | 24 | ## License 25 | 26 | The MIT License (MIT) 27 | 28 | Copyright (c) 2014 Philip Kluz (Philip.Kluz@zuui.org) 29 | 30 | Permission is hereby granted, free of charge, to any person obtaining a copy 31 | of this software and associated documentation files (the "Software"), to deal 32 | in the Software without restriction, including without limitation the rights 33 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 34 | copies of the Software, and to permit persons to whom the Software is 35 | furnished to do so, subject to the following conditions: 36 | 37 | The above copyright notice and this permission notice shall be included in all 38 | copies or substantial portions of the Software. 39 | 40 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 43 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 44 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 45 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 46 | SOFTWARE. 47 | -------------------------------------------------------------------------------- /PKLocationManager/LocationManager.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PKLocationManager.swift 3 | // PKLocationManager 4 | // 5 | // Created by Philip Kluz on 6/20/14. 6 | // Copyright (c) 2014 NSExceptional. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import CoreLocation 11 | 12 | @objc public class LocationManager: NSObject, CLLocationManagerDelegate { 13 | 14 | /// Shared PKLocationManager instance. 15 | public class var sharedManager: LocationManager { 16 | return Constants.sharedManager 17 | } 18 | 19 | required public override init() { 20 | super.init() 21 | 22 | sharedLocationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers 23 | sharedLocationManager.delegate = self 24 | } 25 | 26 | /// Adds an object to a list of objects interested in aquiring location updates. Note that the updates might be deferred. 27 | public func register(locationMonitor monitoringObject:AnyObject!, desiredAccuracy: CLLocationAccuracy, queue: dispatch_queue_t, handler:(location: CLLocation) -> ()) -> (success: Bool, error: NSError?) { 28 | if !isLocationMonitoringAvailable { 29 | return (false, NSError(domain: "com.NSExceptional.PKLocationManager", code: 0, userInfo: [NSLocalizedDescriptionKey : "Location monitoring unavailable." ])) 30 | } 31 | 32 | var presentMonitor = self.locationMonitorFor(monitoringObject) 33 | 34 | if (presentMonitor != nil) { 35 | return (false, NSError(domain: "com.NSExceptional.PKLocationManager", code: 1, userInfo: [NSLocalizedDescriptionKey : "Object is already registered as a location monitor." ])) 36 | } 37 | 38 | var monitor = LocationMonitor(monitoringObject: monitoringObject, queue: queue, desiredAccuracy: desiredAccuracy, handler: handler) 39 | 40 | monitors.append(monitor) 41 | sharedLocationManager.desiredAccuracy = accuracy 42 | 43 | if monitors.count > 0 { 44 | sharedLocationManager.startUpdatingLocation() 45 | } 46 | 47 | return (true, nil) 48 | } 49 | 50 | 51 | /// Adds an object to a list of objects interested in aquiring location updates. Note that the updates might be deferred. 52 | public func register(locationMonitor monitoringObject:AnyObject!, desiredAccuracy: CLLocationAccuracy, handler:(location: CLLocation) -> ()) -> (success: Bool, error: NSError?) { 53 | return register(locationMonitor: monitoringObject, desiredAccuracy: desiredAccuracy, queue: dispatch_get_main_queue(), handler: handler) 54 | } 55 | 56 | /// OBJETIVE-C COMPATIBILITY METHOD - Adds an object to a list of objects interested in aquiring location updates. Note that the updates might be deferred. 57 | public func register(locationMonitor monitoringObject:AnyObject!, desiredAccuracy: CLLocationAccuracy, queue: dispatch_queue_t, errorPtr: NSErrorPointer, handler:(location: CLLocation) -> ()) -> Bool { 58 | let (success, error) = register(locationMonitor: monitoringObject, desiredAccuracy: desiredAccuracy, queue: queue, handler: handler); 59 | 60 | if (errorPtr != nil) { 61 | errorPtr.memory = error 62 | return false 63 | } 64 | 65 | return true 66 | } 67 | 68 | /// OBJETIVE-C COMPATIBILITY METHOD - Adds an object to a list of objects interested in aquiring location updates. Note that the updates might be deferred. 69 | public func register(locationMonitor monitoringObject:AnyObject!, desiredAccuracy: CLLocationAccuracy, errorPtr: NSErrorPointer, handler:(location: CLLocation) -> ()) -> Bool { 70 | return register(locationMonitor: monitoringObject, desiredAccuracy: desiredAccuracy, queue: dispatch_get_main_queue(), errorPtr: errorPtr, handler: handler) 71 | } 72 | 73 | /// Removes an object from the list of objects registered for location updates. 74 | public func deregister(locationMonitor:AnyObject!) { 75 | monitors = monitors.filter { element in 76 | return element.monitoringObject !== locationMonitor; 77 | } 78 | 79 | sharedLocationManager.desiredAccuracy = accuracy 80 | 81 | if monitors.count == 0 { 82 | sharedLocationManager.stopUpdatingLocation() 83 | } 84 | } 85 | 86 | /// Determines whether location monitoring is currently active. 87 | public var isLocationMonitoringActive: Bool { 88 | return monitors.count > 0 89 | } 90 | 91 | /// Determines whether location monitoring is available. 92 | public var isLocationMonitoringAvailable: Bool { 93 | return CLLocationManager.locationServicesEnabled() 94 | } 95 | 96 | private var _requiresLocationMonitoringWhenInUse: Bool = false 97 | 98 | /// If set to 'true' the user will be prompted by the system and asked to grant location access permissions while the application is in use (foreground). Please note that you will need to provide a value for the 'NSLocationWhenInUseUsageDescription' key in your application's 'Info.plist' file. 99 | public var requiresLocationMonitoringWhenInUse: Bool { 100 | get { 101 | return _requiresLocationMonitoringWhenInUse 102 | } 103 | set { 104 | if newValue { 105 | sharedLocationManager.requestWhenInUseAuthorization() 106 | } 107 | } 108 | } 109 | 110 | private var _requiresLocationMonitoringAlways: Bool = false 111 | /// If set to 'true' the user will be prompted by the system and asked to grant location access permissions, which will also work if the application were to be in the background. Please note that you will need to provide a value for the 'NSLocationAlwaysUsageDescription' key in you application's 'Info.plist' file. 112 | public var requiresLocationMonitoringAlways: Bool { 113 | get { 114 | return _requiresLocationMonitoringAlways 115 | } 116 | set { 117 | if newValue { 118 | sharedLocationManager.requestAlwaysAuthorization() 119 | } 120 | } 121 | } 122 | 123 | /// Returns 'true' if the user denied location access permissions, 'false' otherwise. 124 | public var isLocationMonitoringPermissionDenied: Bool { 125 | return CLLocationManager.authorizationStatus() == CLAuthorizationStatus.Denied 126 | } 127 | 128 | /// Returns 'true' if the user granted location access permissions while the application is in use (foreground), 'false' otherwise. 129 | public var isLocationMonitoringPermittedWhenInUse: Bool { 130 | return CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedWhenInUse 131 | } 132 | 133 | /// Returns 'true' if the user granted location access permissions, independent of the application's state (foreground + background), 'false' otherwise. 134 | public var isLocationMonitoringAlwaysPermitted: Bool { 135 | return CLLocationManager.authorizationStatus() == CLAuthorizationStatus.AuthorizedAlways 136 | } 137 | 138 | /// Computes the accuracy for the location manager, which is equal to the most precise accuracy requested by one of the monitoring objects. 139 | public var accuracy: CLLocationAccuracy { 140 | return monitors.reduce(kCLLocationAccuracyThreeKilometers) { current, next in 141 | return next.desiredAccuracy <= current ? next.desiredAccuracy : current 142 | } 143 | } 144 | 145 | /// Returns the monitor wrapper object for a given existing monitoring object. 146 | private func locationMonitorFor(monitoringObject: AnyObject!) -> LocationMonitor? { 147 | for monitor in monitors { 148 | if monitor.monitoringObject === monitoringObject { 149 | return monitor 150 | } 151 | } 152 | 153 | return nil 154 | } 155 | 156 | // #MARK: CLLocationManagerDelegate 157 | 158 | public func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) { 159 | for location in locations as Array { 160 | for monitor in monitors { 161 | monitor.handler?(location) 162 | } 163 | } 164 | } 165 | 166 | public func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 167 | var permissionGiven = status == CLAuthorizationStatus.AuthorizedAlways || status == CLAuthorizationStatus.AuthorizedWhenInUse 168 | if permissionGiven && monitors.count > 0 { 169 | sharedLocationManager.startUpdatingLocation() 170 | } 171 | } 172 | 173 | // #MARK: Private 174 | 175 | private struct Constants { 176 | static let sharedManager = LocationManager() 177 | } 178 | 179 | private let sharedLocationManager = CLLocationManager() 180 | private var monitors = [LocationMonitor]() 181 | } 182 | -------------------------------------------------------------------------------- /Demo/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 34 | 49 | 55 | 61 | 67 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /PKLocationManager.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | F90DA3FB1953B6170086AEFD /* PKLocationManager.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F9D585321953956800B04CB4 /* PKLocationManager.framework */; }; 11 | F90DA3FC1953B6170086AEFD /* PKLocationManager.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = F9D585321953956800B04CB4 /* PKLocationManager.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; }; 12 | F9D585381953956800B04CB4 /* LocationManager.h in Headers */ = {isa = PBXBuildFile; fileRef = F9D585371953956800B04CB4 /* LocationManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; 13 | F9D5854F195395BD00B04CB4 /* LocationManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9D5854E195395BD00B04CB4 /* LocationManager.swift */; }; 14 | F9D58551195395D600B04CB4 /* LocationMonitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9D58550195395D600B04CB4 /* LocationMonitor.swift */; }; 15 | F9D5855B1953B43300B04CB4 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9D5855A1953B43300B04CB4 /* AppDelegate.swift */; }; 16 | F9D5855D1953B43300B04CB4 /* DemoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = F9D5855C1953B43300B04CB4 /* DemoViewController.swift */; }; 17 | F9D585601953B43300B04CB4 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = F9D5855E1953B43300B04CB4 /* Main.storyboard */; }; 18 | F9D585621953B43300B04CB4 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = F9D585611953B43300B04CB4 /* Images.xcassets */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXContainerItemProxy section */ 22 | F90DA3FD1953B6170086AEFD /* PBXContainerItemProxy */ = { 23 | isa = PBXContainerItemProxy; 24 | containerPortal = F9D585291953956800B04CB4 /* Project object */; 25 | proxyType = 1; 26 | remoteGlobalIDString = F9D585311953956800B04CB4; 27 | remoteInfo = PKLocationManager; 28 | }; 29 | /* End PBXContainerItemProxy section */ 30 | 31 | /* Begin PBXCopyFilesBuildPhase section */ 32 | F90DA3FF1953B6170086AEFD /* Embed Frameworks */ = { 33 | isa = PBXCopyFilesBuildPhase; 34 | buildActionMask = 2147483647; 35 | dstPath = ""; 36 | dstSubfolderSpec = 10; 37 | files = ( 38 | F90DA3FC1953B6170086AEFD /* PKLocationManager.framework in Embed Frameworks */, 39 | ); 40 | name = "Embed Frameworks"; 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXCopyFilesBuildPhase section */ 44 | 45 | /* Begin PBXFileReference section */ 46 | F9D585321953956800B04CB4 /* PKLocationManager.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = PKLocationManager.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | F9D585361953956800B04CB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | F9D585371953956800B04CB4 /* LocationManager.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = LocationManager.h; sourceTree = ""; }; 49 | F9D5854E195395BD00B04CB4 /* LocationManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationManager.swift; sourceTree = ""; }; 50 | F9D58550195395D600B04CB4 /* LocationMonitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationMonitor.swift; sourceTree = ""; }; 51 | F9D585561953B43300B04CB4 /* PKLocationManagerDemo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = PKLocationManagerDemo.app; sourceTree = BUILT_PRODUCTS_DIR; }; 52 | F9D585591953B43300B04CB4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 53 | F9D5855A1953B43300B04CB4 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 54 | F9D5855C1953B43300B04CB4 /* DemoViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DemoViewController.swift; sourceTree = ""; }; 55 | F9D5855F1953B43300B04CB4 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 56 | F9D585611953B43300B04CB4 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; 57 | /* End PBXFileReference section */ 58 | 59 | /* Begin PBXFrameworksBuildPhase section */ 60 | F9D5852E1953956800B04CB4 /* Frameworks */ = { 61 | isa = PBXFrameworksBuildPhase; 62 | buildActionMask = 2147483647; 63 | files = ( 64 | ); 65 | runOnlyForDeploymentPostprocessing = 0; 66 | }; 67 | F9D585531953B43300B04CB4 /* Frameworks */ = { 68 | isa = PBXFrameworksBuildPhase; 69 | buildActionMask = 2147483647; 70 | files = ( 71 | F90DA3FB1953B6170086AEFD /* PKLocationManager.framework in Frameworks */, 72 | ); 73 | runOnlyForDeploymentPostprocessing = 0; 74 | }; 75 | /* End PBXFrameworksBuildPhase section */ 76 | 77 | /* Begin PBXGroup section */ 78 | F9D585281953956800B04CB4 = { 79 | isa = PBXGroup; 80 | children = ( 81 | F9D585571953B43300B04CB4 /* Demo */, 82 | F9D585341953956800B04CB4 /* PKLocationManager */, 83 | F9D585331953956800B04CB4 /* Products */, 84 | ); 85 | sourceTree = ""; 86 | }; 87 | F9D585331953956800B04CB4 /* Products */ = { 88 | isa = PBXGroup; 89 | children = ( 90 | F9D585321953956800B04CB4 /* PKLocationManager.framework */, 91 | F9D585561953B43300B04CB4 /* PKLocationManagerDemo.app */, 92 | ); 93 | name = Products; 94 | sourceTree = ""; 95 | }; 96 | F9D585341953956800B04CB4 /* PKLocationManager */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | F9D585371953956800B04CB4 /* LocationManager.h */, 100 | F9D5854E195395BD00B04CB4 /* LocationManager.swift */, 101 | F9D58550195395D600B04CB4 /* LocationMonitor.swift */, 102 | F9D585351953956800B04CB4 /* Supporting Files */, 103 | ); 104 | path = PKLocationManager; 105 | sourceTree = ""; 106 | }; 107 | F9D585351953956800B04CB4 /* Supporting Files */ = { 108 | isa = PBXGroup; 109 | children = ( 110 | F9D585361953956800B04CB4 /* Info.plist */, 111 | ); 112 | name = "Supporting Files"; 113 | sourceTree = ""; 114 | }; 115 | F9D585571953B43300B04CB4 /* Demo */ = { 116 | isa = PBXGroup; 117 | children = ( 118 | F9D5855A1953B43300B04CB4 /* AppDelegate.swift */, 119 | F9D5855C1953B43300B04CB4 /* DemoViewController.swift */, 120 | F9D5855E1953B43300B04CB4 /* Main.storyboard */, 121 | F9D585611953B43300B04CB4 /* Images.xcassets */, 122 | F9D585581953B43300B04CB4 /* Supporting Files */, 123 | ); 124 | path = Demo; 125 | sourceTree = ""; 126 | }; 127 | F9D585581953B43300B04CB4 /* Supporting Files */ = { 128 | isa = PBXGroup; 129 | children = ( 130 | F9D585591953B43300B04CB4 /* Info.plist */, 131 | ); 132 | name = "Supporting Files"; 133 | sourceTree = ""; 134 | }; 135 | /* End PBXGroup section */ 136 | 137 | /* Begin PBXHeadersBuildPhase section */ 138 | F9D5852F1953956800B04CB4 /* Headers */ = { 139 | isa = PBXHeadersBuildPhase; 140 | buildActionMask = 2147483647; 141 | files = ( 142 | F9D585381953956800B04CB4 /* LocationManager.h in Headers */, 143 | ); 144 | runOnlyForDeploymentPostprocessing = 0; 145 | }; 146 | /* End PBXHeadersBuildPhase section */ 147 | 148 | /* Begin PBXNativeTarget section */ 149 | F9D585311953956800B04CB4 /* PKLocationManager */ = { 150 | isa = PBXNativeTarget; 151 | buildConfigurationList = F9D585481953956800B04CB4 /* Build configuration list for PBXNativeTarget "PKLocationManager" */; 152 | buildPhases = ( 153 | F9D5852D1953956800B04CB4 /* Sources */, 154 | F9D5852E1953956800B04CB4 /* Frameworks */, 155 | F9D5852F1953956800B04CB4 /* Headers */, 156 | F9D585301953956800B04CB4 /* Resources */, 157 | ); 158 | buildRules = ( 159 | ); 160 | dependencies = ( 161 | ); 162 | name = PKLocationManager; 163 | productName = PKLocationManager; 164 | productReference = F9D585321953956800B04CB4 /* PKLocationManager.framework */; 165 | productType = "com.apple.product-type.framework"; 166 | }; 167 | F9D585551953B43300B04CB4 /* PKLocationManagerDemo */ = { 168 | isa = PBXNativeTarget; 169 | buildConfigurationList = F9D5856F1953B43300B04CB4 /* Build configuration list for PBXNativeTarget "PKLocationManagerDemo" */; 170 | buildPhases = ( 171 | F9D585521953B43300B04CB4 /* Sources */, 172 | F9D585531953B43300B04CB4 /* Frameworks */, 173 | F9D585541953B43300B04CB4 /* Resources */, 174 | F90DA3FF1953B6170086AEFD /* Embed Frameworks */, 175 | ); 176 | buildRules = ( 177 | ); 178 | dependencies = ( 179 | F90DA3FE1953B6170086AEFD /* PBXTargetDependency */, 180 | ); 181 | name = PKLocationManagerDemo; 182 | productName = Demo; 183 | productReference = F9D585561953B43300B04CB4 /* PKLocationManagerDemo.app */; 184 | productType = "com.apple.product-type.application"; 185 | }; 186 | /* End PBXNativeTarget section */ 187 | 188 | /* Begin PBXProject section */ 189 | F9D585291953956800B04CB4 /* Project object */ = { 190 | isa = PBXProject; 191 | attributes = { 192 | LastUpgradeCheck = 0600; 193 | ORGANIZATIONNAME = NSExceptional; 194 | TargetAttributes = { 195 | F9D585311953956800B04CB4 = { 196 | CreatedOnToolsVersion = 6.0; 197 | }; 198 | F9D585551953B43300B04CB4 = { 199 | CreatedOnToolsVersion = 6.0; 200 | }; 201 | }; 202 | }; 203 | buildConfigurationList = F9D5852C1953956800B04CB4 /* Build configuration list for PBXProject "PKLocationManager" */; 204 | compatibilityVersion = "Xcode 3.2"; 205 | developmentRegion = English; 206 | hasScannedForEncodings = 0; 207 | knownRegions = ( 208 | en, 209 | Base, 210 | ); 211 | mainGroup = F9D585281953956800B04CB4; 212 | productRefGroup = F9D585331953956800B04CB4 /* Products */; 213 | projectDirPath = ""; 214 | projectRoot = ""; 215 | targets = ( 216 | F9D585551953B43300B04CB4 /* PKLocationManagerDemo */, 217 | F9D585311953956800B04CB4 /* PKLocationManager */, 218 | ); 219 | }; 220 | /* End PBXProject section */ 221 | 222 | /* Begin PBXResourcesBuildPhase section */ 223 | F9D585301953956800B04CB4 /* Resources */ = { 224 | isa = PBXResourcesBuildPhase; 225 | buildActionMask = 2147483647; 226 | files = ( 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | }; 230 | F9D585541953B43300B04CB4 /* Resources */ = { 231 | isa = PBXResourcesBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | F9D585601953B43300B04CB4 /* Main.storyboard in Resources */, 235 | F9D585621953B43300B04CB4 /* Images.xcassets in Resources */, 236 | ); 237 | runOnlyForDeploymentPostprocessing = 0; 238 | }; 239 | /* End PBXResourcesBuildPhase section */ 240 | 241 | /* Begin PBXSourcesBuildPhase section */ 242 | F9D5852D1953956800B04CB4 /* Sources */ = { 243 | isa = PBXSourcesBuildPhase; 244 | buildActionMask = 2147483647; 245 | files = ( 246 | F9D58551195395D600B04CB4 /* LocationMonitor.swift in Sources */, 247 | F9D5854F195395BD00B04CB4 /* LocationManager.swift in Sources */, 248 | ); 249 | runOnlyForDeploymentPostprocessing = 0; 250 | }; 251 | F9D585521953B43300B04CB4 /* Sources */ = { 252 | isa = PBXSourcesBuildPhase; 253 | buildActionMask = 2147483647; 254 | files = ( 255 | F9D5855D1953B43300B04CB4 /* DemoViewController.swift in Sources */, 256 | F9D5855B1953B43300B04CB4 /* AppDelegate.swift in Sources */, 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | }; 260 | /* End PBXSourcesBuildPhase section */ 261 | 262 | /* Begin PBXTargetDependency section */ 263 | F90DA3FE1953B6170086AEFD /* PBXTargetDependency */ = { 264 | isa = PBXTargetDependency; 265 | target = F9D585311953956800B04CB4 /* PKLocationManager */; 266 | targetProxy = F90DA3FD1953B6170086AEFD /* PBXContainerItemProxy */; 267 | }; 268 | /* End PBXTargetDependency section */ 269 | 270 | /* Begin PBXVariantGroup section */ 271 | F9D5855E1953B43300B04CB4 /* Main.storyboard */ = { 272 | isa = PBXVariantGroup; 273 | children = ( 274 | F9D5855F1953B43300B04CB4 /* Base */, 275 | ); 276 | name = Main.storyboard; 277 | sourceTree = ""; 278 | }; 279 | /* End PBXVariantGroup section */ 280 | 281 | /* Begin XCBuildConfiguration section */ 282 | F9D585461953956800B04CB4 /* Debug */ = { 283 | isa = XCBuildConfiguration; 284 | buildSettings = { 285 | ALWAYS_SEARCH_USER_PATHS = NO; 286 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 287 | CLANG_CXX_LIBRARY = "libc++"; 288 | CLANG_ENABLE_MODULES = YES; 289 | CLANG_ENABLE_OBJC_ARC = YES; 290 | CLANG_WARN_BOOL_CONVERSION = YES; 291 | CLANG_WARN_CONSTANT_CONVERSION = YES; 292 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 293 | CLANG_WARN_EMPTY_BODY = YES; 294 | CLANG_WARN_ENUM_CONVERSION = YES; 295 | CLANG_WARN_INT_CONVERSION = YES; 296 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 297 | CLANG_WARN_UNREACHABLE_CODE = YES; 298 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 299 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 300 | COPY_PHASE_STRIP = NO; 301 | CURRENT_PROJECT_VERSION = 1; 302 | ENABLE_STRICT_OBJC_MSGSEND = YES; 303 | GCC_C_LANGUAGE_STANDARD = gnu99; 304 | GCC_DYNAMIC_NO_PIC = NO; 305 | GCC_OPTIMIZATION_LEVEL = 0; 306 | GCC_PREPROCESSOR_DEFINITIONS = ( 307 | "DEBUG=1", 308 | "$(inherited)", 309 | ); 310 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 311 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 312 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 313 | GCC_WARN_UNDECLARED_SELECTOR = YES; 314 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 315 | GCC_WARN_UNUSED_FUNCTION = YES; 316 | GCC_WARN_UNUSED_VARIABLE = YES; 317 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 318 | METAL_ENABLE_DEBUG_INFO = YES; 319 | ONLY_ACTIVE_ARCH = YES; 320 | SDKROOT = iphoneos; 321 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 322 | TARGETED_DEVICE_FAMILY = "1,2"; 323 | VERSIONING_SYSTEM = "apple-generic"; 324 | VERSION_INFO_PREFIX = ""; 325 | }; 326 | name = Debug; 327 | }; 328 | F9D585471953956800B04CB4 /* Release */ = { 329 | isa = XCBuildConfiguration; 330 | buildSettings = { 331 | ALWAYS_SEARCH_USER_PATHS = NO; 332 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 333 | CLANG_CXX_LIBRARY = "libc++"; 334 | CLANG_ENABLE_MODULES = YES; 335 | CLANG_ENABLE_OBJC_ARC = YES; 336 | CLANG_WARN_BOOL_CONVERSION = YES; 337 | CLANG_WARN_CONSTANT_CONVERSION = YES; 338 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 339 | CLANG_WARN_EMPTY_BODY = YES; 340 | CLANG_WARN_ENUM_CONVERSION = YES; 341 | CLANG_WARN_INT_CONVERSION = YES; 342 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 343 | CLANG_WARN_UNREACHABLE_CODE = YES; 344 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 345 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 346 | COPY_PHASE_STRIP = YES; 347 | CURRENT_PROJECT_VERSION = 1; 348 | ENABLE_NS_ASSERTIONS = NO; 349 | ENABLE_STRICT_OBJC_MSGSEND = YES; 350 | GCC_C_LANGUAGE_STANDARD = gnu99; 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 358 | METAL_ENABLE_DEBUG_INFO = NO; 359 | SDKROOT = iphoneos; 360 | TARGETED_DEVICE_FAMILY = "1,2"; 361 | VALIDATE_PRODUCT = YES; 362 | VERSIONING_SYSTEM = "apple-generic"; 363 | VERSION_INFO_PREFIX = ""; 364 | }; 365 | name = Release; 366 | }; 367 | F9D585491953956800B04CB4 /* Debug */ = { 368 | isa = XCBuildConfiguration; 369 | buildSettings = { 370 | CLANG_ENABLE_MODULES = YES; 371 | DEFINES_MODULE = YES; 372 | DYLIB_COMPATIBILITY_VERSION = 1; 373 | DYLIB_CURRENT_VERSION = 1; 374 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 375 | INFOPLIST_FILE = PKLocationManager/Info.plist; 376 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 377 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 378 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 379 | PRODUCT_NAME = "$(TARGET_NAME)"; 380 | SKIP_INSTALL = YES; 381 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 382 | }; 383 | name = Debug; 384 | }; 385 | F9D5854A1953956800B04CB4 /* Release */ = { 386 | isa = XCBuildConfiguration; 387 | buildSettings = { 388 | CLANG_ENABLE_MODULES = YES; 389 | DEFINES_MODULE = YES; 390 | DYLIB_COMPATIBILITY_VERSION = 1; 391 | DYLIB_CURRENT_VERSION = 1; 392 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 393 | INFOPLIST_FILE = PKLocationManager/Info.plist; 394 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 395 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 396 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | SKIP_INSTALL = YES; 399 | }; 400 | name = Release; 401 | }; 402 | F9D585701953B43300B04CB4 /* Debug */ = { 403 | isa = XCBuildConfiguration; 404 | buildSettings = { 405 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 406 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 407 | GCC_PREPROCESSOR_DEFINITIONS = ( 408 | "DEBUG=1", 409 | "$(inherited)", 410 | ); 411 | INFOPLIST_FILE = Demo/Info.plist; 412 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 413 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 414 | METAL_ENABLE_DEBUG_INFO = YES; 415 | PRODUCT_NAME = "$(TARGET_NAME)"; 416 | }; 417 | name = Debug; 418 | }; 419 | F9D585711953B43300B04CB4 /* Release */ = { 420 | isa = XCBuildConfiguration; 421 | buildSettings = { 422 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 423 | ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; 424 | INFOPLIST_FILE = Demo/Info.plist; 425 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 426 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 427 | METAL_ENABLE_DEBUG_INFO = NO; 428 | PRODUCT_NAME = "$(TARGET_NAME)"; 429 | }; 430 | name = Release; 431 | }; 432 | /* End XCBuildConfiguration section */ 433 | 434 | /* Begin XCConfigurationList section */ 435 | F9D5852C1953956800B04CB4 /* Build configuration list for PBXProject "PKLocationManager" */ = { 436 | isa = XCConfigurationList; 437 | buildConfigurations = ( 438 | F9D585461953956800B04CB4 /* Debug */, 439 | F9D585471953956800B04CB4 /* Release */, 440 | ); 441 | defaultConfigurationIsVisible = 0; 442 | defaultConfigurationName = Release; 443 | }; 444 | F9D585481953956800B04CB4 /* Build configuration list for PBXNativeTarget "PKLocationManager" */ = { 445 | isa = XCConfigurationList; 446 | buildConfigurations = ( 447 | F9D585491953956800B04CB4 /* Debug */, 448 | F9D5854A1953956800B04CB4 /* Release */, 449 | ); 450 | defaultConfigurationIsVisible = 0; 451 | defaultConfigurationName = Release; 452 | }; 453 | F9D5856F1953B43300B04CB4 /* Build configuration list for PBXNativeTarget "PKLocationManagerDemo" */ = { 454 | isa = XCConfigurationList; 455 | buildConfigurations = ( 456 | F9D585701953B43300B04CB4 /* Debug */, 457 | F9D585711953B43300B04CB4 /* Release */, 458 | ); 459 | defaultConfigurationIsVisible = 0; 460 | defaultConfigurationName = Release; 461 | }; 462 | /* End XCConfigurationList section */ 463 | }; 464 | rootObject = F9D585291953956800B04CB4 /* Project object */; 465 | } 466 | --------------------------------------------------------------------------------