{"id":1240,"url":"https://github.com/intuit/LocationManager","last_synced_at":"2025-07-30T20:32:49.943Z","repository":{"id":15457775,"uuid":"18190835","full_name":"intuit/LocationManager","owner":"intuit","description":"Easily get the device's current location on iOS.","archived":false,"fork":false,"pushed_at":"2021-09-12T04:11:08.000Z","size":304,"stargazers_count":2563,"open_issues_count":12,"forks_count":389,"subscribers_count":85,"default_branch":"master","last_synced_at":"2025-07-28T16:06:06.339Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Objective-C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/intuit.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2014-03-27T20:45:12.000Z","updated_at":"2025-07-16T10:29:06.000Z","dependencies_parsed_at":"2022-08-20T20:50:34.523Z","dependency_job_id":null,"html_url":"https://github.com/intuit/LocationManager","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/intuit/LocationManager","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intuit%2FLocationManager","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intuit%2FLocationManager/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intuit%2FLocationManager/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intuit%2FLocationManager/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/intuit","download_url":"https://codeload.github.com/intuit/LocationManager/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/intuit%2FLocationManager/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":267911430,"owners_count":24164460,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-07-30T02:00:09.044Z","response_time":70,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-01-05T20:15:41.998Z","updated_at":"2025-07-30T20:32:49.607Z","avatar_url":"https://github.com/intuit.png","language":"Objective-C","funding_links":[],"categories":["Hardware","HarmonyOS","Objective-C","Layout","Foundation"],"sub_categories":["Location","Windows Manager","Other free courses"],"readme":"# [![INTULocationManager](https://github.com/intuit/LocationManager/blob/master/Images/INTULocationManager.png?raw=true)](#)  \n[![Build Status](http://img.shields.io/travis/intuit/LocationManager.svg?style=flat)](https://travis-ci.org/intuit/LocationManager) [![Test Coverage](http://img.shields.io/coveralls/intuit/LocationManager.svg?style=flat)](https://coveralls.io/r/intuit/LocationManager) [![Version](http://img.shields.io/cocoapods/v/INTULocationManager.svg?style=flat)](http://cocoapods.org/pods/INTULocationManager) [![Platform](http://img.shields.io/cocoapods/p/INTULocationManager.svg?style=flat)](http://cocoapods.org/pods/INTULocationManager) [![License](http://img.shields.io/cocoapods/l/INTULocationManager.svg?style=flat)](LICENSE)\n\nINTULocationManager makes it easy to get the device's current location and is currently heading on iOS. It is an Objective-C library that also works great in Swift.\n\nINTULocationManager provides a block-based asynchronous API to request the current location, either once or continuously. It internally manages multiple simultaneous locations and heading requests, and each one-time location request can specify its own desired accuracy level and timeout duration. INTULocationManager automatically starts location services when the first request comes in and stops the location services when all requests have been completed, while dynamically managing the power consumed by location services to reduce the impact on battery life.\n\n## What's wrong with CLLocationManager?\nCLLocationManager requires you to manually detect and handle things like permissions, stale/inaccurate locations, errors, and more. CLLocationManager uses a more traditional delegate pattern instead of the modern block-based callback pattern. And while it works fine to track changes in the user's location over time (such as, for turn-by-turn navigation), it is extremely cumbersome to correctly request a single location update (such as to determine the user's current city to get a weather forecast, or to autofill an address from the current location).\n\nINTULocationManager makes it easy to request both the device's current location, either once or continuously, as well as the device's continuous heading. The API is extremely simple for both one-time location requests and recurring subscriptions to location updates. For one-time location requests, you can specify how accurate of a location you need, and how long you're willing to wait to get it. Significant location change monitoring is also supported. INTULocationManager is power efficient and conserves the device's battery by automatically determining and using the most efficient Core Location accuracy settings, and by automatically powering down location services (e.g. GPS or compass) when they are no longer needed.\n\n## Installation\n*INTULocationManager requires iOS 9.0 or later.*\n\n### Using [CocoaPods](http://cocoapods.org)\n\n1.\tAdd the pod `INTULocationManager` to your [Podfile](http://guides.cocoapods.org/using/the-podfile.html).\n\n  ```ruby\n  pod 'INTULocationManager'\n  ```\n\n1.\tRun `pod install` from Terminal, then open your app's `.xcworkspace` file to launch Xcode.\n1.\tImport the `INTULocationManager.h` header.\n  * With `use_frameworks!` in your Podfile\n    * Swift: `import INTULocationManager`\n    * Objective-C: `#import \u003cINTULocationManager/INTULocationManager.h\u003e` (or with Modules enabled: `@import INTULocationManager;`)\n  * Without `use_frameworks!` in your Podfile\n    * Swift: Add `#import \"INTULocationManager.h\"` to your bridging header.\n    * Objective-C: `#import \"INTULocationManager.h\"`\n\n### Using [Carthage](https://github.com/Carthage/Carthage)\n\n1. Add the `intuit/LocationManager` project to your [Cartfile](https://github.com/Carthage/Carthage/blob/master/Documentation/Artifacts.md#cartfile).\n\n  ```ogdl\n  github \"intuit/LocationManager\"\n  ```\n\n1. Run `carthage update`, then follow the [additional steps required](https://github.com/Carthage/Carthage#adding-frameworks-to-an-application) to add the iOS and/or Mac frameworks into your project.\n1. Import the INTULocationManager framework/module.\n  * Swift: `import INTULocationManager`\n  * Objective-C: `#import \u003cINTULocationManager/INTULocationManager.h\u003e` (or with Modules enabled: `@import INTULocationManager;`)\n\n### Manually from GitHub\n\n1. Download all the files in [INTULocationManager subdirectory](LocationManager/INTULocationManager).\n1. Add the source files to your Xcode project (drag and drop is easiest).\n1. Import the `INTULocationManager.h` header.\n  * Swift: Add `#import \"INTULocationManager.h\"` to your bridging header.\n  * Objective-C: `#import \"INTULocationManager.h\"`\n\n## Usage\n\n### Requesting Permission to Access Location Services\nINTULocationManager automatically handles obtaining permission to access location services when you issue a location request and the user has not already granted your app the permission to access that location services.\n\n#### iOS 9 and above\nStarting with iOS 8, you **must** provide a description for how your app uses location services by setting a string for the key [`NSLocationWhenInUseUsageDescription`](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW26) or [`NSLocationAlwaysUsageDescription`](https://developer.apple.com/library/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html#//apple_ref/doc/uid/TP40009251-SW18) in your app's `Info.plist` file. INTULocationManager determines which level of permissions to request based on which description key is present. You should only request the minimum permission level that your app requires, therefore it is recommended that you use the \"When In Use\" level unless you require more access. If you provide values for both description keys, the more permissive \"Always\" level is requested.\n\n#### iOS 11\nStarting with iOS 11, you **must** provide a description for how your app uses location services by setting a string for the key `NSLocationAlwaysAndWhenInUseUsageDescription` in your app's `Info.plist` file.\n\n#### iOS 12\nStarting with iOS 12, you will have access to set the `desiredActivityType` as `CLActivityTypeAirborne`.\n\n### Getting the Current Location (once)\nTo get the device's current location, use the method `requestLocationWithDesiredAccuracy:timeout:block:`.\n\nThe `desiredAccuracy` parameter specifies how **accurate and recent** of a location you need. The possible values are:\n```objective-c\nINTULocationAccuracyCity          // 5000 meters or better, received within the last 10 minutes  -- lowest accuracy\nINTULocationAccuracyNeighborhood  // 1000 meters or better, received within the last 5 minutes\nINTULocationAccuracyBlock         // 100 meters or better, received within the last 1 minute\nINTULocationAccuracyHouse         // 15 meters or better, received within the last 15 seconds\nINTULocationAccuracyRoom          // 5 meters or better, received within the last 5 seconds      -- highest accuracy\n```\n\nThe `desiredActivityType` parameter indicated the **type of activity** that is being tracked. The possible values are:\n```objective-c\nCLActivityTypeFitness               // Track fitness activities such as walking, running, cycling, and so on\nCLActivityTypeAutomotiveNavigation  // Track location changes to the automobile\nCLActivityTypeAirborne              // Track airborne activities - iOS 12 and above\nCLActivityTypeOtherNavigation       // Track vehicular navigation that are not automobile related\nCLActivityTypeOther                 // Track unknown activities. This is the default value\n```\n\nThe `timeout` parameter specifies that how long you are willing to wait for a location with the accuracy you requested. The timeout guarantees that your block will execute within this period of time, either with a location of at least the accuracy you requested (`INTULocationStatusSuccess`), or with whichever location could be determined before the timeout interval was up (`INTULocationStatusTimedOut`). Pass `0.0` for no timeout *(not recommended)*.\n\nBy default, the timeout countdown begins as soon as the `requestLocationWithDesiredAccuracy:timeout:block:` method is called. However, there is another variant of this method that includes a `delayUntilAuthorized:` parameter, which allows you to pass `YES` to delay the start of the timeout countdown until the user has responded to the system location services permissions prompt (if the user hasn't allowed or denied the app access yet).\n\nHere's an example:\n```objective-c\nINTULocationManager *locMgr = [INTULocationManager sharedInstance];\n[locMgr requestLocationWithDesiredAccuracy:INTULocationAccuracyCity\n                                   timeout:10.0\n                      delayUntilAuthorized:YES\t// This parameter is optional, defaults to NO if omitted\n                                     block:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {\n                                         if (status == INTULocationStatusSuccess) {\n                                             // Request succeeded, meaning achievedAccuracy is at least the requested accuracy, and\n                                             // currentLocation contains the device's current location.\n                                         }\n                                         else if (status == INTULocationStatusTimedOut) {\n                                             // Wasn't able to locate the user with the requested accuracy within the timeout interval.\n                                             // However, currentLocation contains the best location available (if any) as of right now,\n                                             // and achievedAccuracy has info on the accuracy/recency of the location in currentLocation.\n                                         }\n                                         else {\n                                             // An error occurred, more info is available by looking at the specific status returned.\n                                         }\n                                     }];\n```\n```swift\nlet locationManager = INTULocationManager.sharedInstance()\nlocationManager.requestLocation(withDesiredAccuracy: .city,\n                                            timeout: 10.0,\n                               delayUntilAuthorized: true) { (currentLocation, achievedAccuracy, status) in\n                                   if (status == INTULocationStatus.success) {\n                                       // Request succeeded, meaning achievedAccuracy is at least the requested accuracy, and\n                                       // currentLocation contains the device's current location\n                                   }\n                                   else if (status == INTULocationStatus.timedOut) {\n                                       // Wasn't able to locate the user with the requested accuracy within the timeout interval.\n                                       // However, currentLocation contains the best location available (if any) as of right now,\n                                       // and achievedAccuracy has info on the accuracy/recency of the location in currentLocation.\n                                   }\n                                   else {\n                                       // An error occurred, more info is available by looking at the specific status returned.\n                                   }\n           }\n\n\n```\n\n### Subscribing to Continuous Location Updates\nTo subscribe to continuous location updates, use the method `subscribeToLocationUpdatesWithBlock:`. This method instructs location services to use the highest accuracy available (which also requires the most power). The block will execute indefinitely (even across errors, until canceled), once for every new updated location regardless of its accuracy.\n\nIf you do not need the highest possible accuracy level, you should instead use `subscribeToLocationUpdatesWithDesiredAccuracy:block:`. This method takes the desired accuracy level and uses it to control how much power is used by location services, with lower accuracy levels like Neighborhood and City requiring less power. Note that INTULocationManager will automatically manage the system location services accuracy level, including when there are multiple active location requests/subscriptions with different desired accuracies.\n\nIf an error occurs, the block will execute with a status other than `INTULocationStatusSuccess`, and the subscription will be kept alive.\n\nHere's an example:\n```objective-c\nINTULocationManager *locMgr = [INTULocationManager sharedInstance];\n[locMgr subscribeToLocationUpdatesWithDesiredAccuracy:INTULocationAccuracyHouse\n                                                block:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {\n                                                    if (status == INTULocationStatusSuccess) {\n                                                        // A new updated location is available in currentLocation, and achievedAccuracy indicates how accurate this particular location is.\n                                                    }\n                                                    else {\n                                                        // An error occurred, more info is available by looking at the specific status returned. The subscription has been kept alive.\n                                                    }\n                                                }];\n```\n\n### Subscribing to Significant Location Changes\nTo subscribe the significant location changes, use the method `subscribeToSignificantLocationChangesWithBlock:`. This instructs the location services to begin monitoring for significant location changes, which is very power efficient. The block will execute indefinitely (until canceled), once for every new updated location regardless of its accuracy. Note that if there are other simultaneously active location requests or subscriptions, the block will execute for every location update (not just for significant location changes). If you intend to take action only when the location has changed significantly, you should implement custom filtering based on the distance \u0026 time received from the last location.\n\nIf an error occurs, the block will execute with a status other than `INTULocationStatusSuccess`, and the subscription will be kept alive.\n\nHere's an example:\n```objective-c\nINTULocationManager *locMgr = [INTULocationManager sharedInstance];\n[locMgr subscribeToSignificantLocationChangesWithBlock:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {\n    if (status == INTULocationStatusSuccess) {\n\t\t// A new updated location is available in currentLocation, and achievedAccuracy indicates how accurate this particular location is.\n    }\n    else {\n        // An error occurred, more info is available by looking at the specific status returned. The subscription has been kept alive.\n    }\n}];\n```\n\nIf your app has acquired the \"Always\" location services authorization and your app is terminated with at least one active significant location change subscription, your app may be launched in the background when the system detects a significant location change. Note that when the app terminates, all of your active location requests \u0026 subscriptions with INTULocationManager are canceled. Therefore, when the app launches due to a significant location change, you should immediately use INTULocationManager to set up a new subscription for significant location changes in order to receive the location information.\n\nHere is an example of how to handle being launched in the background due to a significant location change:\n```objective-c\n- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions\n{\n    // If you start monitoring significant location changes and your app is subsequently terminated, the system automatically relaunches the app into the background if a new event arrives.\n    // Upon relaunch, you must still subscribe to significant location changes to continue receiving location events. \n    if ([launchOptions objectForKey:UIApplicationLaunchOptionsLocationKey]) {\n        INTULocationManager *locMgr = [INTULocationManager sharedInstance];\n        [locMgr subscribeToSignificantLocationChangesWithBlock:^(CLLocation *currentLocation, INTULocationAccuracy achievedAccuracy, INTULocationStatus status) {\n            // This block will be executed with the details of the significant location change that triggered the background app launch,\n            // and will continue to execute for any future significant location change events as well (unless canceled).\n        }];\n    }\n    return YES;\n}\n```\n\n### Managing Active Requests or Subscriptions\nWhen issuing a location request, you can optionally store the request ID, which allows you to force complete or cancel the request at any time:\n```objective-c\nINTULocationManager *locMgr = [INTULocationManager sharedInstance];\nINTULocationRequestID requestID = [locMgr requestLocationWithDesiredAccuracy:INTULocationAccuracyHouse\n                                                                     timeout:5.0\n                                                                       block:locationRequestBlock];\n\n// Force the request to complete early, like a manual timeout (will execute the block)\n[[INTULocationManager sharedInstance] forceCompleteLocationRequest:requestID];\n\n// Cancel the request (won't execute the block)\n[[INTULocationManager sharedInstance] cancelLocationRequest:requestID];\n```\n\nNote that subscriptions never timeout; calling `forceCompleteLocationRequest:` on a subscription will simply cancel it.\n\n### Subscribing to Continuous Heading Updates\nTo subscribe to continuous heading updates, use the method `subscribeToHeadingUpdatesWithBlock:`. This method does not set any default heading filter value, but you can do so using the `headingFilter` property on the manager instance. It also does not filter based on accuracy of the result, but rather leaves it up to you to check the returned `CLHeading` object's `headingAccuracy` property to determine whether or not it is acceptable. \n\nThe block will execute indefinitely (until canceled), once for every new updated heading regardless of its accuracy. Note that if heading requests are removed or canceled, the manager will automatically stop updating the device heading in order to preserve battery life.\n\nIf an error occurs, the block will execute with a status other than `INTUHeadingStatusSuccess`, and the subscription will only be automatically canceled if the device doesn't have heading support (i.e. for status `INTUHeadingStatusUnavailable`).\n\nHere's an example:\n```objective-c\nINTULocationManager *locMgr = [INTULocationManager sharedInstance];\n[locMgr subscribeToHeadingUpdatesWithBlock:^(CLHeading *heading, INTUHeadingStatus status) {\n    if (status == INTUHeadingStatusSuccess) {\n        // An updated heading is available\n        NSLog(@\"'Heading updates' subscription block called with Current Heading:\\n%@\", heading);\n    } else {\n        // An error occurred, more info is available by looking at the specific status returned. The subscription will be canceled only if the device doesn't have heading support.\n    }\n}];\n```\n\n## Example Project\nOpen the [project](LocationManager) included in the repository (requires Xcode 6 and iOS 8.0 or later). It contains a `LocationManagerExample` scheme that will run a simple demo app. Please note that it can run in the iOS Simulator, but you need to go to the iOS Simulator's **Debug \u003e Location** menu once running the app to simulate a location (the default is **None**).\n\n## Issues \u0026 Contributions\nPlease [open an issue here on GitHub](https://github.com/intuit/LocationManager/issues/new) if you have a problem, suggestion, or other comment.\n\nPull requests are welcome and encouraged! There are no official guidelines, but please try to be consistent with the existing code style.\n\n## License\nINTULocationManager is provided under the MIT license.\n\n# INTU on GitHub\nCheck out more [iOS and OS X open source projects from Intuit](https://github.com/search?utf8=✓\u0026q=user%3Aintuit+language%3Aobjective-c\u0026type=Repositories\u0026ref=searchresults)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintuit%2FLocationManager","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fintuit%2FLocationManager","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fintuit%2FLocationManager/lists"}