iOS 14 widget开发实践

自定义多个widget

参考:https://www.jianshu.com/p/48d7fa52ce84

@main
struct WeatherInterWidget: WidgetBundle {
    @WidgetBundleBuilder
    var body: some Widget {
        ClassicStyle()
    }
}

ClassicStyle需要在widget的Target中

配置点说明

1. PreviewProvider

用于在模拟器上直接预览,默认只预览smll类型,添加systemMedium和systemLarge可以预览另两种

2. Widget

configurationDisplayName:添加时的标题
description:添加时的描述信息
supportedFamilies:支持的尺寸

3. View,与主应用交互
  • widgetURL
  • Link

在主项目的SceneDelegatez代理方法中接收回调

- (void)scene:(UIScene *)scene openURLContexts:(NSSet<UIOpenURLContext *> *)URLContexts {
    /// 根据不同的URL回调做出响应
    NSLog(@"%@",URLContexts);
}
4. IntentTimelineProvider

placeholder: 提供占位的方法,作为一种没有特定属性的通用可视化视图
getSnapshot:提供表示当前时间和状态的视图,可以理解为虚假或者供用户临时选择组件的展示信息。可用展示在Add Widget页面数据
getTimeline:提供视图更新数组,或者说跟上面方法形成对比的真实信息数,通过时间线来显示

功能知识点

1. 网络请求
let url = URL(string: "https://api.seniverse.com/v3/weather/now.json?key=xxxxxx&location=beijing&language=zh-Hans&unit=c")!
let request = URLRequest(url: url, cachePolicy: .reloadIgnoringLocalCacheData, timeoutInterval: 60.0)

let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
    guard error == nil else {
        completion(.failure(error!))
        return
    }
    let nowEntry = getNowDataInfo(fromData: data!,time: str);
    completion(.success(nowEntry))
}
task.resume()
let url = URL(string: "https://api.seniverse.com/v3/weather/daily.json?key=xxxxxx&location=beijing&language=zh-Hans&unit=c&start=0&days=5")!
let task = URLSession.shared.dataTask(with: url) { (data, response, error) in
    guard error == nil else {
        completion(.failure(error!))
        return
    }
    let testData = getThreeDayDataInfo(fromData: data!,time: str, nowEntry:nowEntry);
    completion(.success(testData))
}
task.resume()
2. 解析JSON字符串

使用JSONSerialization.jsonObject解析JSON数据

  • 把Foundation.Data解析为JSON格式
    let json = try! JSONSerialization.jsonObject(with: data, options: []) as! [String: Any]
  • 解析数组
    let content = json["results"] as! [Any]
  • 解析字典
    let results:[String:AnyObject]? = content[0] as? [String:AnyObject]
3. 主app和widget之间数据通信

分别在主app和widget的Signing & Capabilties中添加App Groups,保持groupid相同

存储:
let sharedDefaults = UserDefaults(suiteName: "group.com.apuray.weatherwidget.Weather.WidgetWeather")
sharedDefaults?.setValue("三亚", forKey: "city")
读取:
var currentCity = sharedDefaults?.string(forKey: "city")
4. 在主app中控制widget刷新

刷新所有的widget
WidgetCenter.shared.reloadAllTimelines()
根据widget名称对指定的widget进行刷新
WidgetCenter.shared.reloadTimelines(ofKind: "WidgetFirst")

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容