ios swift 多语言
Apple provides many good services to clients. One of the most useful and famous function is her location detection technology. With the help of GPS and cell tower signal, iOS can manipulate the user’s current location. Many apps has utilised this feature to make good apps, e.g. Google Map, Apple Map and Pokemon Go!
一个 pple为客户提供了许多良好的服务。 她的位置检测技术是最有用和最著名的功能之一。 借助GPS和手机信号塔信号,iOS可以操纵用户的当前位置。 许多应用程序已经利用此功能制作出了不错的应用程序,例如Google Map,Apple Map和Pokemon Go!。
CoreLocation
is the framework that is responsible for handling all the location requests and callbacks to and from the system. It provides many high level APIs for configuring location request and notifying app for any location information updates, including coordinates and heading direction.
CoreLocation
是负责处理往返系统的所有位置请求和回调的框架。 它提供了许多高级API,用于配置位置请求并通知应用任何位置信息更新,包括坐标和航向。
CoreLocation
is a large framework and I hope this article can help you understand more about it and make a fantastic app with it. Let’s start!
CoreLocation
是一个大型框架,我希望本文能够帮助您了解更多有关它的信息,并使用它来制作出色的应用程序。 开始吧!
项目设置— info.plist和功能 (Project Set up — info.plist and Capabilities)
1.添加关于位置隐私的显示消息 (1. Add a display message for location privacy)
These messages are displayed at the authentication dialog when request requestWhenInUseAuthorization() and requestAlwaysAuthorization()
当请求requestWhenInUseAuthorization()和requestAlwaysAuthorization ()
时,这些消息将显示在身份验证对话框中
NSLocationWhenInUseUsageDescription
must be added if foreground location is requested.如果请求前台位置,则必须添加
NSLocationWhenInUseUsageDescription
。Both
NSLocationAlwaysAndWhenInUseUsageDescription
andNSLocationWhenInUseUsageDescription
must be added if app wants to retrieve location information at background state.如果应用要在后台状态检索位置信息,则必须同时添加
NSLocationAlwaysAndWhenInUseUsageDescription
和NSLocationWhenInUseUsageDescription
。
Don’t mix up the keys with
Privacy — Location Always Usage Description
andPrivacy — Location Usage Description
. The former one has been deprecated since iOS 11 and the later one is only used in MacOS app不要将密钥与“
Privacy — Location Always Usage Description
和“Privacy — Location Usage Description
混在一起。 自iOS 11起不推荐使用前一个,而仅在MacOS应用中使用后一个
2.项目能力 (2. Project Capabilities)
“Location updates” option must be checked in the “Background Modes” tab if your app want to retrieve location information at background state!
如果您的应用要在后台状态下检索位置信息,则必须在“背景模式”标签中选中“位置更新”选项!
7个步骤—请求一次性位置信息 (7 Steps — Request for one-time location information)
步骤1:导入CoreLocation依赖项 (Step 1: Importing CoreLocation dependency)
CoreLocation
is the framework that contains CLLocationManager
which is the helper class for retrieving location information and handling all events triggered by location changes, e.g. geofence (when user enters or exits a specific CLCircularRegion
) and monitoring significant location changes.
CoreLocation
是包含CLLocationManager
的框架, CLLocationManager
是用于获取位置信息CLCircularRegion
位置更改触发的所有事件(例如地理围栏(当用户进入或退出特定的CLCircularRegion
)并监视重要的位置更改)的帮助程序类 。
步骤2:声明CLLocationManager变量 (Step 2: Declare CLLocationManager variable)
In order to hold a strong reference to CLLocationManager
, it is necessary to declare a variable at the ViewController
level. This can ensure we are dealing with the same CLLocationManager
throughout the whole ViewController
lifecycle.
为了保持对CLLocationManager
的强烈引用,有必要在ViewController
级别声明一个变量。 这样可以确保我们在整个ViewController
生命周期中都使用相同的CLLocationManager
。
步骤3:初始化和配置CLLocationManager (Step 3: Initialise and configure CLLocationManager)
Lots of properties can be optionally configured to a CLLocationManager
but only the delegate
property (CLLocationManagerDelegate
) is a must for handling all the callbacks from CLLocationManager
. Other properties includes desired accuracy, activity type, distance filter and heading filter, etc. They all will be discussed in details in the later sessions.
可以选择将许多属性配置为CLLocationManager
但是只有delegate
属性( CLLocationManagerDelegate
)才是处理CLLocationManager
所有回调所必需的。 其他属性包括所需的准确性 , 活动类型 , 距离过滤器和航向过滤器等。所有这些都将在以后的课程中进行详细讨论。
步骤4:请求位置授权 (Step 4: Request location authorization)
There are two types of location authorization can be requested, one is “when in use” and the another one is “always”.
可以请求两种类型的位置授权,一种是“在使用时”,另一种是“始终”。
“when in use” is requested only when app retrieves location information in foreground or at background with background location usage indicator enabled.
仅当应用在启用了后台位置使用指示器的情况下在前台或后台检索位置信息时,才请求“使用时” 。
“always” is requested when location information can be retrieved in background even the background location usage indicator is disabled.
当即使在后台位置使用指示已禁用的情况下也可以在后台检索位置信息时,请求“始终” 。
To obtain “Always” authorization, your app must first request “When In Use” permission followed by requesting “Always” authorization.
要获得“始终”授权,您的应用必须首先请求“使用中”权限,然后再请求“始终”授权。
Reference: Apple documentation
参考: Apple文档
步骤5:实现CLLocationManagerDelegate (Step 5: Implementing CLLocationManagerDelegate)
CLLocationManagerDelegate
is critical for handling all the events fired from CLLocationManager
. The most important callbacks are locationManager(_:didChangeAuthorization:)
, locationManager:didUpdateLocations:
and locationManager:didFailWithError:
. They will be discussed later in another sessions.
CLLocationManagerDelegate
对于处理从CLLocationManager
触发的所有事件至关重要。 最重要的回调是locationManager(_:didChangeAuthorization:)
, locationManager:didUpdateLocations:
和locationManager:didFailWithError:
它们将在以后的其他会议中讨论。
步骤6:在授予“使用中”或“始终”授权时请求位置 (Step 6: Requesting location when either “When In Use” or “Always” authorization is granted)
By calling requestLocation() after confirming with correct permission at the locationManager(_:didChangeAuthorization:)
, CLLocationManager
can then start getting location information by GPS or cell tower network.
通过在locationManager(_:didChangeAuthorization:)
以正确的权限确认后调用requestLocation() , CLLocationManager
随后可以开始通过GPS或手机信号塔网络获取位置信息。
步骤7:处理位置信息 (Step 7: Handle the location information)
Right after CLLocationManager
retrieves the location information, the locationManager:didUpdateLocations:
is fired with the information embedded in locations
parameter.
在CLLocationManager
检索到位置信息之后, locationManager:didUpdateLocations:
使用locations
参数中嵌入的信息触发locationManager:didUpdateLocations:
CLLocation
is a class containing lots of useful information about a location. The useful ones are the CLLocationCoordinate2D
with both latitude and longitude, timestamp
about the time of location retrieval and horizontalAccuracy
about the how much app can trust about the location.
C LLocation
是一个类,其中包含有关位置的许多有用信息。 有用的是具有纬度和经度的CLLocationCoordinate2D
,有关位置检索时间的timestamp
,以及有关应用程序可以信任多少位置的horizontalAccuracy
。
Here is an example of the CLLocation
object:
这是CLLocation
对象的示例:
{
coordinate: {
latitude: 22.42550181697769,
longitude: 114.23000319878552
},
altitude: 23.69447899864746,
horizontalAccuracy: 65.0,
verticalAccuracy: 10.0,
floor: {
level: 1
},
speed: 32.0,
speedAccuracy: 1.0,
timestamp: 2020-08-02 15:14:33,
courseAccuracy: 0.4,
course: 33.2,
}
进一步讨论 (Further discussions)
For now on, we will discuss on the configurations of CLLocationManager
and the corresponding callbacks at the CLLocationManagerDelegate
. If you just want to get a single location information at foreground, you are done and can skip the following parts. I will cover the following configurations and features:
现在,我们将在的配置讨论CLLocationManager
在和相应的回调CLLocationManagerDelegate
。 如果您只想在前台获取单个位置信息,则可以完成操作,并可以跳过以下部分。 我将介绍以下配置和功能:
- Authorization status 授权状态
- Desired accuracy (latitude & longitude) 所需精度(纬度和经度)
- Distance filter (tolerance in meter) 距离过滤器(以米为单位的公差)
- Heading (Direction from the magnetic North and true North) 航向(从磁北到真北的方向)
- Activity type 活动类型
- Geofencing (Enter / Exit a region) 地理围栏(输入/退出区域)
- Course & speed 路线与速度
- Continuously monitoring location updates 持续监控位置更新
- Monitoring Significant Location Changes 监视重要的位置更改
- Monitoring heading updates 监控标题更新
授权状态 (Authorization status)
User can grant location authorization to apps at two levels — System level and App level. System level authorization is a global setting which can either disable or enable for all apps in the device. App level one is only specified to that specific app and contains 5 different authorization status (although there are only 4 status shown at the above image):
用户可以在两个级别( 系统级别和应用程序级别)向应用程序授予位置授权。 系统级别授权是全局设置,可以禁用或启用设备中的所有应用程序。 仅针对该特定应用指定了应用一级,并且其中包含5种不同的授权状态(尽管上图中仅显示了4种状态):
-
Setting option:
设置选项:
NeverSystem setting: “Location Services” is disabled at the system level or
从不系统设置:在系统级别或以下位置禁用“位置服务”
NeverSystem setting: “Location Services” is disabled at the system level or Airplane mode is turned on and prohibit device to retrieve any location data.
从不系统设置:在系统级别禁用“位置服务”或打开飞行模式,并禁止设备检索任何位置数据。
CLAuthorizationStatus.notDetermined
CLAuthorizationStatus.notDetermined
Setting option:
设置选项:
Ask Next Time
下次询问
CLAuthorizationStatus.authorizedWhenInUse
CLAuthorizationStatus.authorizedWhenInUse
Setting option:
设置选项:
While Using the App
使用应用程序时
CLAuthorizationStatus.authorizedAlways
CLAuthorizationStatus.authorizedAlways
Setting option:
设置选项:
Always
总是
CLAuthorizationStatus.restricted
CLAuthorizationStatus.restricted
Restricted by
受限制
parental control
家长控制
When app requests location authorization but the system level location service is disabled, the above dialog is popped out and redirects user to Settings
page to manually toggle back the location service. This pop up dialog is the default iOS behaviour and developer does not need to implement any codes for this.
当应用程序请求位置授权但系统级位置服务被禁用时,将弹出以上对话框,并将用户重定向到Settings
页面以手动切换回位置服务。 此弹出对话框是默认的iOS行为,开发人员无需为此执行任何代码。
Furthermore, it is possible to use CLLocationManager.locationServicesEnabled()
to check if the system location service is enabled and then display certain messages at app side.
此外,可以使用CLLocationManager.locationServicesEnabled()
来检查是否启用了系统位置服务,然后在应用程序端显示某些消息。
所需精度 (Desired Accuracy)
Different accuracies cause different levels of battery usage. For more accurate location, system has to use GPS signal coming from satellite and the accuracy can be as good as tens of meters. However, the downside is high battery usage. By using lower accuracy level means (~city block) — cell tower signal, the power consumption is greatly reduces.
不同的精度会导致不同级别的电池使用情况。 为了更精确地定位,系统必须使用来自卫星的GPS信号,并且精度可以达到数十米。 但是,缺点是电池使用率高。 通过使用较低精度等级的手段(〜城市街区)- 蜂窝塔信号 ,功耗大大降低。
There are totally 7 CLLocationAccuracy
constants. The default value is kCLLocationAccuracyBest
.
总共有7个CLLocationAccuracy
常数。 默认值为kCLLocationAccuracyBest
。
kCLLocationAccuracyBestForNavigation
— Accuracy is the highest among all available options; It requires relative more power on maintaining high accuracy. It is recommended officially to use this option only when phone is plugged!kCLLocationAccuracyBestForNavigation
—精度是所有可用选项中最高的; 在保持高精度方面需要相对更多的能力 。 正式建议仅在插入电话后才使用此选项!
2. kCLLocationAccuracyBest
(Default) — High accuracy but not as accurate as the kCLLocationAccuracyBestForNavigation
2. kCLLocationAccuracyBest
(默认)—高精度,但不如kCLLocationAccuracyBestForNavigation
准确
3. kCLLocationAccuracyNearestTenMeters
— 10m
3. kCLLocationAccuracyNearestTenMeters
— 10m
4. kCLLocationAccuracyHundredMeters
— 100m
4. kCLLocationAccuracyHundredMeters
— 100m
5. kCLLocationAccuracyKilometer
— 1km
5. kCLLocationAccuracyKilometer
公里— 1公里
6. kCLLocationAccuracyThreeKilometers
— 3km
6. kCLLocationAccuracyThreeKilometers
公里— 3公里
Reference: CLLocationAccuracy Official Documentation
距离过滤器 (DistanceFilter)
It is the minimum distance (unit in meter) that a user has to travel “horizontally” in order for CLLocationManager
to trigger a location update. The definition of “horizontally” is along the latitude (North-to-South direction) and longitude (West-to-East direction) instead of the altitude (low-to-high direction).
它是用户必须“水平”行驶以使CLLocationManager
触发位置更新的最小距离 (以米为单位)。 “水平”的定义是沿着纬度(北-南方向)和经度(西-东方向)而不是海拔(低-高方向)。
The default value is kCLDistanceFilterNone
which means every change in horizontal direction can trigger the locationManager:didUpdateLocations:
callback.
默认值为kCLDistanceFilterNone
,这意味着水平方向的每次更改都可以触发locationManager:didUpdateLocations:
回调。
By setting this to a small value can eliminate those location updates caused by random signal instability.
通过将其设置为较小的值,可以消除由随机信号不稳定性引起的那些位置更新。
Reference: DistanceFilter
参考: DistanceFilter
标题 (Heading)
“Heading” represents the degree between the orientation of user’s device and either magnetic North or true North. Here is an example:
“航向”表示用户设备的方向与磁北或真北之间的程度。 这是一个例子:
didUpdateHeading
didUpdateHeading
{
magneticHeading: 123.333,
trueHeading: ...,
headingAccuracy: ...,
x: ...,
y: ...,
z: ...,
timestamp: ...
}
Magnetic North is the North that the South pole of a magnet is pointing towards. However, true North is the tip of the Earth’s rotational axis at magnetic North direction. It is recommended to watch a Youtube video — The Compass: True North vs Magnetic North to learn more about them.
磁北是磁铁南极指向的北。 但是,真正的北方是地球旋转轴在磁性北方方向上的尖端。 建议观看Youtube视频-指南针:真北与磁北,以了解更多有关它们的信息。
To conclude in one sentence, we usually use the value of magneticHeading
that trueHeading
in map navigation.
总而言之,在地图导航中,我们通常使用magneticHeading
的值trueHeading
。
活动类型 (ActivityType)
It is a variable for CLLocationManager
to determine the strategy for pausing location update at the background state in order to conserve power consumption when location is unlikely to change. There are 5 different types of activityType
:
CLLocationManager
可以使用此变量来确定在后台状态下暂停位置更新的策略,以便在位置不太可能更改时节省功耗。 有5种不同的activityType
类型:
automotiveNavigation
: Used for vehicular navigationautomotiveNavigation
:用于车辆导航otherNavigation
: Used for other transportation other than car, e.g. boat and trainotherNavigation
:用于汽车以外的其他交通工具,例如船和火车fitness
: Used for pedestrian navigationfitness
:用于行人导航* Indoor position is disabled
*室内位置被禁用
airborne
: Used for airplane navigationairborne
:用于飞机导航other
: Default valueother
:默认值
After pausing the location service according to activityType
, it is developer’s responsibility to restart the service instead of iOS! UNLocationNotificationTrigger
根据activityType
暂停定位服务后,开发者有责任重新启动服务而不是iOS! UNLocationNotificationTrigger
地理围栏(区域监视) (Geofencing (Region monitoring))
App can be notified when iOS detects user has “just” entered and exited that region which is defined by the CLCircularRegion
with latitude, longitude and radius.
当iOS检测到用户“正好”进入和退出了由CLCircularRegion
定义的纬度,经度和半径的区域时,可以通知App。
The code above is self-explanatory. When use enters and exits the specific CLCircularRegion
, locationManager:didEnterRegion:
and locationManager:didExitRegion:
will be called respectively.
上面的代码是不言自明的。 当use进入和退出特定的CLCircularRegion
,将分别调用locationManager:didEnterRegion:
和locationManager:didExitRegion:
In iOS architecture, the resources for monitoring
CLLocationRegion
are shared among all apps in the device. Therefore, iOS has limited the maximum amounts ofCLLocationRegion
to “20” in order to balance the benefits of all apps.在iOS体系结构中,用于监视
CLLocationRegion
的资源在设备中的所有应用之间共享。 因此,iOS已将CLLocationRegion
的最大数量限制为“ 20” ,以平衡所有应用程序的收益。Reference: Apple Developer Documentation — Monitoring the User’s Proximity to Geographic Regions
路线与速度 (Course & Speed)
The direction that the device user is moving towards. It is a Double
representing the degree counting from the magnetic North. The accuracy can be referenced to the courseAccuracy
field but it is only available since iOS 13.4.
设备用户的前进方向。 它是一个Double
代表从磁北数开始的度数。 精度可以参考courseAccuracy
字段,但仅自iOS 13.4起可用。
Until CLLocationManager
detects two or more location information, it can calculates the speed and store it in the speed
field with speedAccuracy
.
在CLLocationManager
检测到两个或多个位置信息之前,它可以计算速度并将其存储在具有speedAccuracy
的speed
字段中。
Reference: CLLocationDirection | Apple Developer Documentation
持续监控位置更新 (Continuously monitoring location updates)
Beyond requesting a single location, app can continuously monitor the location updates by calling startUpdatingLocation()
. It used the distanceFilter
to set the distance tolerance for each location update. In other words, app will be notify only when user has moved for a specific distance from last detected location.
除了请求一个位置之外,应用程序还可以通过调用startUpdatingLocation( )
来连续监视位置更新。 它使用distanceFilter
设置每个位置更新的距离公差。 换句话说,只有当用户从最近检测到的位置移动了特定距离时,app才会收到通知。
The new locations are all sent to the locationManager:didUpdateLocations: .
监视重要的位置更改 (Monitoring Significant Location Changes)
startMonitoringSignificantLocationChanges()
provides a similar service as startUpdatingLocation()
. They both provide a continuous location update service even app is sent into the background.
startMonitoringSignificantLocationChanges()
提供与startUpdatingLocation( )
类似的服务。 他们都提供连续的位置更新服务,即使应用程序被发送到后台。
However, the distance tolerance in startMonitoringSignificantLocationChanges()
is determined by the system. App can only receive notification when user has travelled for 500m or more. Two consecutive notifications must be at least 5 mins apart.
但是, startMonitoringSignificantLocationChanges()
的距离公差由系统确定。 仅当用户行驶500m或以上时,App才能收到通知。 两个连续的通知必须相隔至少5分钟。
监视标题更新 (Monitoring heading updates)
Just like coordinate (latitude and longitude) information, iOS provides a way to get notify when user’s heading direction has changed. The usage is similar to startUpdatingLocation()
function.
就像坐标(纬度和经度)信息一样,iOS提供了一种在用户的航向改变时获得通知的方法。 用法类似于startUpdatingLocation( )
函数。
摘要 (Summary)
CoreLocation
framework provides us a user-friendly tools to detect user’s location information and provides notification when location information gets changed.
CoreLocation
框架为我们提供了一个用户友好的工具,可以检测用户的位置信息,并在位置信息发生更改时提供通知。
Before start coding, NSLocationAlwaysAndWhenInUseUsageDescription
and NSLocationWhenInUseUsageDescription
should be added to the project info.plist
to provide message for requesting authorization.
开始编码之前, NSLocationAlwaysAndWhenInUseUsageDescription
和NSLocationWhenInUseUsageDescription
添加到项目info.plist
以提供用于请求授权的消息。
CLLocationManager
can be configured with desiredAccuracy
, activityType
, distanceFilter
and headingFilter
. It can also notify app when there is a significant change in user location (500m+) but consecutive notification must be 5 mins apart.
可以将CLLocationManager
配置为desiredAccuracy
, activityType
, distanceFilter
和headingFilter
。 当用户位置发生重大变化(500m +)时,它也可以通知应用程序,但连续的通知必须相隔5分钟。
You are welcome to follow me at Twitter@myrick_chow for more information and articles. Thank you for reading this article. Have a nice day! 😄
欢迎您通过Twitter @ myrick_chow关注我,以获取更多信息和文章。 感谢您阅读本文。 祝你今天愉快! 😄
翻译自: https://itnext.io/swift-ios-cllocationmanager-all-in-one-b786ffd37e4a
ios swift 多语言