Skip to content

Commit f833886

Browse files
committed
save web
1 parent a342635 commit f833886

File tree

7 files changed

+155
-32
lines changed

7 files changed

+155
-32
lines changed

SwiftPamphletApp/Core/FundationFunction.swift

+29-1
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,35 @@ func validHTTPUrlStrFromUrlStr(urlStr: String) -> String {
116116
return httpsPrefix + urlStr
117117
}
118118

119-
// MARK: - 文件
119+
// MARK: - 文件 - 沙盒
120+
// 获取沙盒Document目录路径
121+
func getDocumentsDirectory() -> URL {
122+
let paths = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
123+
return paths[0]
124+
}
125+
126+
// 保存数据到沙盒中
127+
func saveDataToSandbox(data: Data, fileName: String) {
128+
let fileURL = getDocumentsDirectory().appendingPathComponent(fileName)
129+
do {
130+
try data.write(to: fileURL)
131+
print("文件保存成功:\(fileURL.path)")
132+
} catch {
133+
print("保存文件时出错:\(error)")
134+
}
135+
}
136+
// 删除沙盒中的文件
137+
func deleteFileFromSandbox(fileName: String) {
138+
let fileURL = getDocumentsDirectory().appendingPathComponent(fileName)
139+
do {
140+
try FileManager.default.removeItem(at: fileURL)
141+
print("文件删除成功:\(fileURL.path)")
142+
} catch {
143+
print("删除文件时出错:\(error)")
144+
}
145+
}
146+
147+
// MARK: - 文件 - 系统和 Bundle
120148
// just for test
121149
func writeToDownload(fileName: String, content: String) {
122150
try! content.write(toFile: "/Users/mingdai/Downloads/\(fileName)", atomically: true, encoding: String.Encoding.utf8)

SwiftPamphletApp/InfoOrganizer/Category/CategoryListView.swift

+18-17
Original file line numberDiff line numberDiff line change
@@ -24,24 +24,25 @@ struct CategoryListView: View {
2424
}
2525
GroupBox("图表显示") {
2626
Chart(cates) { cate in
27-
// BarMark(
28-
// x: .value("数量", cate.infos?.count ?? 0),
29-
// y: .value("名字", cate.name)
30-
// )
31-
// .annotation(position: .overlay, alignment: .trailing, spacing: 3) {
32-
// Text("\(cate.infos?.count ?? 0)")
33-
// .font(.footnote)
34-
// .foregroundColor(light: .white, dark: .white)
35-
// }
36-
SectorMark(angle: .value("数量", cate.infos?.count ?? 0), innerRadius: .ratio(0.5),
37-
angularInset: 1.5)
38-
.foregroundStyle(by: .value("名字", cate.name))
39-
.annotation(position: .overlay, alignment: .trailing, spacing: 3) {
40-
Text("\(cate.infos?.count ?? 0)")
41-
.font(.footnote)
42-
.foregroundColor(light: .white, dark: .white)
43-
}
27+
BarMark(
28+
x: .value("数量", cate.infos?.count ?? 0),
29+
y: .value("名字", cate.name)
30+
)
31+
.annotation(position: .overlay, alignment: .trailing, spacing: 3) {
32+
Text("\(cate.infos?.count ?? 0)")
33+
.font(.footnote)
34+
.foregroundColor(light: .white, dark: .white)
35+
}
36+
// SectorMark(angle: .value("数量", cate.infos?.count ?? 0), innerRadius: .ratio(0.5),
37+
// angularInset: 1.5)
38+
// .foregroundStyle(by: .value("名字", cate.name))
39+
// .annotation(position: .overlay, alignment: .trailing, spacing: 3) {
40+
// Text(cate.name)
41+
// .font(.footnote)
42+
// .foregroundColor(light: .white, dark: .white)
43+
// }
4444
}
45+
.chartLegend(.hidden)
4546
.chartXAxis(.hidden)
4647
// .chartYAxis(.hidden)
4748
// .aspectRatio(1, contentMode: .fit)

SwiftPamphletApp/InfoOrganizer/Info/EditInfoView.swift

+35-11
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ struct EditInfoView: View {
2323
@State var urlContent = ""
2424
@State var selectedTab = 1
2525

26+
// webarchive
27+
@State var savingDataTrigger = false
28+
2629
var body: some View {
2730
VStack {
2831
Form {
@@ -63,19 +66,36 @@ struct EditInfoView: View {
6366
Image(systemName: "safari")
6467
}
6568
// TODO: 图片可选,下载到照片
69+
// Button {
70+
//
71+
// Task {
72+
// let re = await fetchTitleFromUrl(urlString:info.url, isFetchContent: true)
73+
//
74+
// DispatchQueue.main.async {
75+
// if re.content.isEmpty == false {
76+
// info.des = re.content
77+
// }
78+
// }
79+
// } // end Task
80+
// } label: {
81+
// Image(systemName: "square.and.arrow.down")
82+
// }
83+
// 本地存
6684
Button {
67-
Task {
68-
let re = await fetchTitleFromUrl(urlString:info.url, isFetchContent: true)
69-
70-
DispatchQueue.main.async {
71-
if re.content.isEmpty == false {
72-
info.des = re.content
73-
}
74-
}
75-
} // end Task
85+
if info.webArchive == nil {
86+
savingDataTrigger = true
87+
} else {
88+
info.webArchive = nil
89+
}
7690
} label: {
77-
Image(systemName: "square.and.arrow.down")
91+
if info.webArchive == nil {
92+
Image(systemName: "square.and.arrow.down")
93+
} else {
94+
Image(systemName: "square.and.arrow.down.fill")
95+
}
7896
}
97+
98+
7999
} // end if
80100

81101
}
@@ -118,7 +138,11 @@ struct EditInfoView: View {
118138
.tabItem { Label("预览", systemImage: "circle") }
119139
.tag(2)
120140
if let url = URL(string: info.url) {
121-
WebUIView(urlStr: url.absoluteString)
141+
WebUIViewWithSave(
142+
urlStr: url.absoluteString,
143+
savingDataTrigger: $savingDataTrigger,
144+
savingData: $info.webArchive
145+
)
122146
.tabItem { Label("网页", systemImage: "circle") }
123147
.tag(3)
124148
}

SwiftPamphletApp/InfoOrganizer/Info/InfoListView.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ struct InfoListView: View {
8585
}
8686

8787
func addInfo() {
88-
let info = IOInfo(name: "简单记录 - \(nowDateString())", url: "", des: "\n", star: false, createDate: Date.now, updateDate: Date.now)
88+
let info = IOInfo(name: "简单记录 - \(nowDateString())", url: "", des: "\n", star: false, webArchive: nil , createDate: Date.now, updateDate: Date.now)
8989
for cate in cates {
9090
if cate.name == filterCate {
9191
info.category = cate

SwiftPamphletApp/InfoOrganizer/Info/InfoRowView.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ struct InfoRowView: View {
1919
var body: some View {
2020
VStack(alignment:.leading) {
2121
HStack {
22-
2322
if info.category != nil {
2423
Text(info.category?.name ?? "")
2524
}
@@ -31,13 +30,16 @@ struct InfoRowView: View {
3130
if info.star == true {
3231
Image(systemName: "star.fill")
3332
}
33+
if info.webArchive != nil {
34+
Image(systemName: "square.and.arrow.down.fill")
35+
}
3436
Spacer()
3537
}
3638
.font(.footnote)
3739
.foregroundColor(light: .secondary, dark: .secondary)
3840

3941
Text(info.name)
40-
HStack {
42+
HStack(alignment: .center) {
4143
Text(howLongAgo(date: info.updateDate))
4244
.font(.footnote)
4345
Spacer()

SwiftPamphletApp/InfoOrganizer/Model/InfoDataModel.swift

+3
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ final class IOInfo {
1515
var des: String = ""
1616
var category: IOCategory? = nil// 关系字段,链接 IOCategory
1717
var star: Bool = false
18+
@Attribute(.externalStorage) var webArchive: Data? = nil
1819

1920
var createDate: Date = Date.now
2021
var updateDate: Date = Date.now
@@ -24,6 +25,7 @@ final class IOInfo {
2425
des: String,
2526
category: IOCategory? = nil,
2627
star: Bool,
28+
webArchive: Data? = nil,
2729
createDate: Date,
2830
updateDate: Date
2931
) {
@@ -32,6 +34,7 @@ final class IOInfo {
3234
self.des = des
3335
self.category = category
3436
self.star = star
37+
self.webArchive = webArchive
3538
self.createDate = createDate
3639
self.updateDate = updateDate
3740
}

SwiftPamphletApp/ViewComponet/ViewComponet.swift

+65
Original file line numberDiff line numberDiff line change
@@ -155,6 +155,7 @@ struct WebUIView: NSViewRepresentable {
155155
nsView.load(r)
156156
}
157157
}
158+
158159
}
159160

160161
class Coordinator: NSObject, WKNavigationDelegate {
@@ -189,6 +190,70 @@ struct WebUIView: NSViewRepresentable {
189190
}
190191
}
191192

193+
struct WebUIViewWithSave: NSViewRepresentable {
194+
var urlStr: String = ""
195+
var html: String = ""
196+
var baseURLStr: String = ""
197+
198+
@Binding var savingDataTrigger: Bool
199+
@Binding var savingData: Data?
200+
201+
func makeCoordinator() -> Coordinator {
202+
Coordinator()
203+
}
204+
205+
func makeNSView(context: Context) -> some WKWebView {
206+
let webView = WKWebView()
207+
webView.navigationDelegate = context.coordinator
208+
return webView
209+
}
210+
211+
func updateNSView(_ nsView: NSViewType, context: Context) {
212+
if savingData != nil {
213+
if let data = savingData {
214+
nsView.load(data, mimeType: "application/x-webarchive", characterEncodingName: "utf-8", baseURL: getDocumentsDirectory())
215+
}
216+
} else if urlStr.isEmpty {
217+
let host = URL(string: baseURLStr)?.host ?? ""
218+
nsView.loadHTMLString(html, baseURL: URL(string: "https://\(host)"))
219+
} else {
220+
if let url = URL(string: urlStr) {
221+
let r = URLRequest(url: url)
222+
nsView.load(r)
223+
}
224+
}
225+
226+
if savingDataTrigger == true {
227+
nsView.createWebArchiveData { result in
228+
do {
229+
let data = try result.get()
230+
savingData = data
231+
} catch {
232+
print("创建 webarchivedata 数据失败,\(error)")
233+
}
234+
}
235+
savingDataTrigger = false
236+
}
237+
}
238+
239+
class Coordinator: NSObject, WKNavigationDelegate {
240+
241+
func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) {
242+
if navigationAction.navigationType == .linkActivated {
243+
if let url = navigationAction.request.url {
244+
let components = URLComponents(url: url, resolvingAgainstBaseURL: false)
245+
if components?.scheme == "http" || components?.scheme == "https" {
246+
NSWorkspace.shared.open(url)
247+
decisionHandler(.cancel)
248+
return
249+
}
250+
}
251+
}
252+
decisionHandler(.allow)
253+
}
254+
} // end Coordinator
255+
}
256+
192257
// MARK: - Time
193258
struct GitHubApiTimeView: View {
194259
var timeStr: String

0 commit comments

Comments
 (0)