本文主要学习到:
- App Group 数据共享知识
- Widget 获取 Location 权限
为了达到如上图的位置信息,需要做到两点:
- 在主 App 上使用 Location;
- 在 Widget 小组件上使用 Location。
关于第一点,可以直接在 APP 的 Info.plist 增加:
1 | <key>NSLocationWhenInUseUsageDescription</key> |
在 Widget target 的 Info.plist 增加:
1 | <key>NSWidgetWantsLocation</key> |
Location
创建热门城市列表,这里需要实现函数:
1 | func provideLocationOptionsCollection(for intent: WeatherIntent, with completion: @escaping (INObjectCollection<CLPlacemark>?, Error?) -> Void) |
这里的 [CLPlacemark] 数组,需要用到 CLPlacemark 初始化函数,而且也只有在 Intents Framework 中才有。
init(location:name:postalAddress:)
App extensions built with the Intents framework can use this method to create a placemark from existing location and address data. For example, an app that offers a ride service might create a new placemark when resolving a user’s pickup or drop-off location. The returned placemark contains only the data that you provide.
按照之前的扩展,需要我们增加位置选择,罗列主要热门城市:
1 | import Intents |
看看运行效果:
我的定位
获取地理位置,查看 Accessing Location Information in Widgets
就如文章说的,因为我是多个 Widgets 在同一个 APP 中,所以采用后面一种方案:
Isolate Location Usage With Multiple Widget Extensions
If your app provides multiple widgets and only some of the widgets use location, separate your widgets into multiple extensions. Add the NSWidgetWantsLocation to the extension that contains widgets that use location. This allows the system to only prompt the user for the widgets that use location information, and makes it more contextually relevant for users.
How to manage location data access for iPhone and iPad widgets
A widget like Weather may requesting access to your location. “Widgets may use your location for up to 15 minutes after being viewed to stay up to date,” reads the permission prompt.
需要对 Location 做详细 Test:
Test Your Widget in Real-World Scenarios
Due to the timeline-based updates of widgets, and the variability of a widget’s in-use status, it’s important to test widgets that use location in real-world scenarios. For example, create test scenarios that:
Extend the app’s location authorization when adding the widget.
Don’t extend the app’s location authorization when adding the widget.
Change the app’s authorization in Settings > Privacy > Location Services after the widget is added.
Change the widget’s approval of location authorization in Settings > Privacy > Location Services after the widget is added.
Add the widget to Home screen pages that are both frequently and infrequently viewed.
Because widgets receive a limited number of refreshes every day, test your widget over multiple days.
1 | /* |
这一步是整个 Widget 的重点。
数据共享
在主 APP target 增加 App Group 能力:
增加容器:
这样就可以在 Widget target 增加 App Group 能力和选择容器。
扩展 FileManager 类:
1 | import Foundation |
同时,增加读写方法:
1 | static func saveLocation(data: [String: String], isMy: Bool) { |
有了以上的整理,接下来就是在 Location 获取后,存入文件,在需要的时候,直接读取,如在我们的获选区域里加入「我的位置」:
1 | func provideLocationOptionsCollection(for intent: WeatherIntent, with completion: @escaping (INObjectCollection<CLPlacemark>?, Error?) -> Void) { |
总结
到此,基本完成「天气」小组件的开发工作。