An easy way to get the device's current location and geographical region monitoring on iOS(swift).
LocationKit provide asynchronous block-based way to get the current location and region monitoring. It can manages multiple simultaneous location and region requests. Each request can specify its own setting like detect type(Once, UpdatingLocation, or SignificantLocationChanges), accuracy level, detect frequency, and distance filter.
- Asynchronous block-based.
- Get location. (Once, UpdatingLocation, or SignificantLocationChanges)
- Geographic region monitoring.(enter/exit from regions)
- Monitor more than 20 regions.
- Manages multiple simultaneous location service.
- iOS 8.0+
- Xcode 8.0+ Swift 3
Check out Get Started tab on cocoapods.org.
To use LocationKit in your project add the following 'Podfile' to your project
pod 'JLocationKit', '~> 1.0.3'
Then run:
pod install
Go ahead and import JLocationKit
Copy the LocationKit Directory to your project. Go ahead and import LocationKit to your file.
Please check out the Example project included.
Before using LocationKit, you must configure your project to use location services. Apparently in iOS 8 SDK, requestAlwaysAuthorization (for background location) or requestWhenInUseAuthorization (location only when foreground) call on CLLocationManager is needed before starting location updates. Open Info.plist
, and add the following lines~
<key>NSLocationWhenInUseUsageDescription</key>
<string>LocationKit</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>LocationKit</string>
The string value which you add will be shown when your app try to use location services at the first time.
First, create a new LocationManager instance and set the requests permission to use location services.
Here's an example:
let location: LocationManager = LocationManager()
location.requestAccess = .requestAlwaysAuthorization //default is .requestAlwaysAuthorization
Get the device's current location(.Once style), then stop service automatically.
Here's an example:
location.getLocation(detectStyle: .Once, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, error: { (error) in
//optional
}
)
Get the device's current location(.UpdatingLocation style). You must stop service manually.
Here's an example:
location.getLocation(detectStyle: .UpdatingLocation, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, error: { (error) in
//optional
}
)
You can set distanceFilter, locationAccuracy, and detectFrequency properties.
- distanceFilter: Receive a new update when a new distance interval is travelled (default is 0 meter)
distanceFilter: double value //meter
- locationAccuracy: The accuracy of the location data (default is .Best)
locationAccuracy: .Best //kCLLocationAccuracyBest
locationAccuracy: .BestForNavigation //kCLLocationAccuracyBestForNavigation
locationAccuracy: .HundredMeters //kCLLocationAccuracyHundredMeters
locationAccuracy: .Kilometer //kCLLocationAccuracyKilometer
locationAccuracy: .NearestTenMeters //kCLLocationAccuracyNearestTenMeters
locationAccuracy: .ThreeKilometers //kCLLocationAccuracyThreeKilometers
- detectFrequency: The frequency of the location update (default is 5 seconds)
detectFrequency: Int value //seconds
You can get current location ever 5 seconds if you move more than 10 meter
Here's an example:
location.getLocation(detectStyle: .UpdatingLocation, distanceFilter: 10, locationAccuracy: .Best, detectFrequency: 5, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, error: { (error) in
//optional
}
)
If you use the .SignificantLocationChanges detectStyle to get location, this request will response new event only when it detects changes to the device’s associated cell towers, resulting in less frequent updates and significantly lower power usage, even when your app is terminated.(need requestAlwaysAuthorization requestAccess)
Here's an example:
location.getLocation(detectStyle: .SignificantLocationChanges, distanceFilter: 0, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, error: { (error) in
//optional
}
)
You don't need to set the locationAccuracy and detectFrequency properties.
public class JLocationResponse {
public var currentLocation: CLLocation! //current location
public var previousLocation: CLLocation! //the last time location
public var distanceInterval: Double! //the interval distance from previous location to current location.
}
You can easily to be notified when the user crosses a region based boundary. LocationKit provide three region monitoring way.
First, you need to create region list which you want to monitior.
Here's an example:
//create region list
var locationList: [JLocation] = []
let item:JLocation = JLocation(latitude: 22.22222, longitude: 22.22222, radius: 500(meter), identifier: "test")
locationList.append(item)
It is a standard region monitoring way by didDetermineState function(.MonitoringRegion style). In this way, you can monitor region even when your app is terminated(need requestAlwaysAuthorization requestAccess). But, please note that there's a limit of 20 regions that can be monitored at the same time.
Here's an example:
location.regionNotify(notifyStyle: .MonitoringRegion, locations: locationList, completion: { (region) in
print(region.regionState.description())
}, error: { (error) in
}
)
You don't need to set the locationAccuracy, distanceFilter and detectFrequency properties.
In this way, you can monitor more than 20 regions(.UpdatingLocation style). But, please note that can't monitor regions when your app is terminated.
Here's an example:
location.regionNotify(notifyStyle: .UpdatingLocation, distanceFilter: 0, locations: locationList, detectFrequency: 5, completion: { (region) in
print(region.regionState.description())
}, error: { (error) in
}
)
You can set the locationAccuracy, distanceFilter and detectFrequency properties.
In this way, you can monitor more than 20 regions even when your app is terminated(need requestAlwaysAuthorization requestAccess). But this request will response new event only when it detects changes to the device’s associated cell towers.
Here's an example:
location.regionNotify(notifyStyle: .SignificantLocationChanges, locations: locationList, completion: { (region) in
print(region.regionState.description())
}, error: { (error) in
}
)
You don't need to set the locationAccuracy, distanceFilter and detectFrequency properties.
public class JRegion:CLCircularRegion {
public var regionRadius: Double! //the radius of region
public var regionIdentifier: String! //the region identifier
public var regionState: RegionState! // region state(inside/outside)
public var previousIntervalSec: Int! = 0 //the time(seconds) from previous location to current location
public var previousDate: Date! //the previous location date when you enter
public var firstNotify: Bool = false //at first when you enter region, it will be true
}
You can set the requests permission by LocationManager instance.
Here's an example:
let location: LocationManager = LocationManager()
location.requestAccess = .requestAlwaysAuthorization //default is .requestAlwaysAuthorization
.requestWhenInUseAuthorization //when in use
.requestAlwaysAuthorization //always
You can use .stopAll
to stop all location service.
Here's an example:
location.stopAll()
Or, you can create an identification service
location.getLocation(detectStyle: .UpdatingLocation, distanceFilter: 0, detectFrequency: 15, identification: "test", completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}
)
Now, you can stop this service by identification name.
location.stop(identification: "test")
You can get the change event by authorizationChange block
Here's an example:
location.getLocation(detectStyle: .UpdatingLocation, distanceFilter: 0, locationAccuracy: .NearestTenMeters, detectFrequency: 10, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, authorizationChange: { (status) in
//optional (CLAuthorizationStatus)
}
)
When you create LocationManager instance, the default number of managed location service is ten. You can easily get multiple simultaneous location service response.
Here's an example:
let location: LocationManager = LocationManager()
location.requestAccess = .requestAlwaysAuthorization
location.getLocation(detectStyle: .UpdatingLocation, distanceFilter: 0, locationAccuracy: .NearestTenMeters, detectFrequency: 10, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, authorizationChange: { (status) in
//optional (CLAuthorizationStatus)
}
)
location.getLocation(detectStyle: .SignificantLocationChanges, distanceFilter: 0, locationAccuracy: .NearestTenMeters, detectFrequency: 10, completion: { (loc) in
print(loc.currentLocation.coordinate.latitude.description)
print(loc.currentLocation.coordinate.longitude.description)
}, authorizationChange: { (status) in
//optional (CLAuthorizationStatus)
}
)
location.regionNotify(notifyStyle: .MonitoringRegion, distanceFilter: 0, locations: locationList, completion: { (region) in
print(region.regionState.description())
}, error: { (error) in
}
)
If you want LocationKit to manage more than ten simultaneous location service, you can set the detect instance number.
Here's an example:
let location: LocationManager = LocationManager(detectInstanceNumber: 20)
LocationKit is available under the MIT License.
Copyright © 2016 Joe.