Coding01

Coding 点滴

0%

学习 iOS Widgets 开发之股票小组件(一)

我们发现 iOS 自带的「股市」小组件有时候更新数据有问题,主要是因为使用雅虎的股票接口,在国内网络等因素,老出现拿不到数据。

所以今天我们根据这一情况,自己尝试使用国内一些主流股票接口,重新模仿写一个相似的股市小组件。

数据接口

由于国内一些类似百度智能云阿里云等都提供股票接口服务,所以我在选择其中几家性价比实惠的,自己封装成一个统一接口。

我们自定义的接口比较简单:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
public function getKLineData(Request $request)
{
$symbol = $request->input('symbol', 'sz000700');
$datalen = $request->input('datalen', 10);

$client = new Client(['base_uri' => '****']);
try {
$response = $client->request('GET', 'get', [
'query' => [
'symbol' => $symbol,
'***' => $datalen
]
]);

return $this->change2array($response->getBody()->getContents());
} catch (RequestException $e) {
return [];
} catch (GuzzleException $e) {
return [];
}
}

/**
* 将数据转变成统一的数据数组
* @param String $data
* @return array
*/
private function change2array(String $data) : array
{
$json_array = json_decode($data, true);
$keyed = collect($json_array)->map(function ($item) {
return [
"day" => $item['***'],
"price" => $item['***']
];
});

return $keyed->all();
}

获取数据

有了接口,我们可以直接获取数据,再转换为我们显示的数据数组,这里我推荐使用 Swift 插件:KakaJSON,可以直接将网络请求回来的 Data 类型数据转变为我们的 [Model] 数组。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import Foundation
import KakaJSON

struct KLine: Convertible {
var day: String = ""
var price: Double = 0.0

public static var klines: [KLine] {
return [KLine(day: "2020-11-20 14:15:00", price: 1.00)]
}
}

struct KLineLoader {
static func fetch(symbol: String, completion: @escaping (Result<[KLine], Error>) -> Void) {
let ExchangeURL = URL(string: "我们的数据API?symbols=\(symbol)")!
let task = URLSession.shared.dataTask(with: ExchangeURL) { (data, response, error) in
guard error == nil else {
completion(.failure(error!))
return
}
// 看这个
let kLines = data?.kj.modelArray(KLine.self)
completion(.success(kLines!))
}
task.resume()
}
}

Widget View

有了初步数据,我们先显示看看效果,代码参考。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import SwiftUI
import SwiftDate

struct SharesView: View {
let data: [KLine]

var redColor = Color(UIColor(displayP3Red: 1, green: 15/255, blue: 83/255, alpha: 1))

@Environment(\.widgetFamily) var family

var body: some View {
HStack(spacing: 20) {
// 1. Dislpay data of currency
VStack(alignment: .leading) {
Text(String(format: "%.3f", data.last!.price))
.bold()
.font(.system(size: 50))
.foregroundColor(Color.black)
.shadow(color: .gray, radius: 15, x: 7, y: 7)
.minimumScaleFactor(0.5)
}

// 2. Make responsive widget, by setting up sepearate view for systemMedium family widget
if family == .systemMedium {
VStack(alignment: .center) {
Text("更新时间")
.bold()
.font(.system(size: 12))
.foregroundColor(redColor)
.shadow(color: .gray, radius: 15, x: 7, y: 7)
.minimumScaleFactor(0.5)
Text(data.last!.day)
.bold()
.font(.system(size: 22))
.foregroundColor(Color.black)
.shadow(color: .gray, radius: 15, x: 7, y: 7)
.minimumScaleFactor(0.5)
}
}
}.padding(.all, 10)
}
}

显示如下:

总结

从数据获取部分,我们基本完成了,接下来就是动态输入我们关注的股票代码,还有就是显示是多条股票动态信息的,而且还需要有一个股票的走势图。有待下一步开发。

Welcome to my other publishing channels