当前位置: 首页 > news >正文

2023年做网站怎么样seo快速优化软件

2023年做网站怎么样,seo快速优化软件,网站建设开发人员,珠海集团网站建设外包1. 用到的技术点: 1) Codable : 可编/解码 JSON 数据 2) background threads : 后台线程 3) weak self : 弱引用 4) Combine : 取消器/组合操作 5) Publishers and Subscribers : 发布者与订阅者 6) FileManager : 文件管理器 7) NSCache : 缓存 2. 网址: 2.1 测试接口网址: …

1. 用到的技术点:

  1) Codable : 可编/解码 JSON 数据

  2) background threads : 后台线程

  3) weak self : 弱引用

  4) Combine : 取消器/组合操作

  5) Publishers and Subscribers : 发布者与订阅者

  6) FileManager : 文件管理器

  7) NSCache : 缓存

2. 网址:

  2.1 测试接口网址:

jsonplaceholdericon-default.png?t=N7T8https://jsonplaceholder.typicode.com/

  2.2 JSON 转 Model 网址:

quicktypeicon-default.png?t=N7T8https://app.quicktype.io/

3. 项目结构图

4. Model 层

  4.1 创建 PhotoModel.swift 文件

import Foundationstruct PhotoModel: Identifiable, Codable{let albumId: Intlet id: Intlet title: Stringlet url: Stringlet thumbnailUrl: String
}/*{"albumId": 1,"id": 1,"title": "accusamus beatae ad facilis cum similique qui sunt","url": "https://via.placeholder.com/600/92c952","thumbnailUrl": "https://via.placeholder.com/150/92c952"}*/

5. 工具类

  5.1 创建请求数据服务类,PhotoModelDataService.swift

import Foundation
import Combine/// 请求数据服务
class PhotoModelDataService{// 单例模式 Singletonstatic let instance = PhotoModelDataService()// 返回 JSON 数据,解码成模型@Published var photoModel:[PhotoModel] = []// 随时取消请求var cancellables = Set<AnyCancellable>()// 只能内部实例化,保证一个 App 只有一次实例化private init() {downloadData()}// 测试接口网址: https://jsonplaceholder.typicode.com/// 下载数据func downloadData(){// 获取 URLguard let url = URL(string: "https://jsonplaceholder.typicode.com/photos") else { return }// 进行请求URLSession.shared.dataTaskPublisher(for: url).subscribe(on: DispatchQueue.global(qos: .background)).receive(on: DispatchQueue.main).tryMap(handleOutput).decode(type: [PhotoModel].self, decoder: JSONDecoder()).sink { completion inswitch(completion){case .finished:breakcase .failure(let error):print("Error downloading data. \(error)")break}} receiveValue: { [weak self] returnedPhotoModel inguard let self  = self else { return }self.photoModel = returnedPhotoModel}// 随时取消.store(in: &cancellables)}// 输出数据private func handleOutput(output: URLSession.DataTaskPublisher.Output) throws -> Data{guardlet response = output.response as? HTTPURLResponse,response.statusCode >= 200 && response.statusCode < 300 else {throw URLError(.badServerResponse)}return output.data}
}

  5.2 创建图片缓存管理器类,PhotoModelCacheManager.swift

import Foundation
import SwiftUI/// 图片缓存管理器
class PhotoModelCacheManager{// 单例模式static let instance = PhotoModelCacheManager()// 只能内部实例化,保证一个 App 只有一次实例化private init() {}// 图片数量缓存,计算型属性var photoCache: NSCache<NSString, UIImage> = {let cache = NSCache<NSString, UIImage>()cache.countLimit = 200cache.totalCostLimit = 1024 * 1024 * 200  // 200mbreturn cache}()// 添加func add(key: String, value: UIImage){photoCache.setObject(value, forKey: key as NSString)}// 获取func get(key: String) -> UIImage? {return photoCache.object(forKey: key as NSString)}
}

  5.3 创建储存图片文件管理类,PhotoModelFileManager.swift

import Foundation
import SwiftUI// 存储图片文件管理器
class PhotoModelFileManager{// 单例模式static let instance = PhotoModelFileManager()let folderName = "downloaded_photos"private init(){createFolderIfNeeded()}// 创建存放图片的目录private func createFolderIfNeeded(){guard let url = getFolderPath() else { return }if !FileManager.default.fileExists(atPath: url.path){do {try FileManager.default.createDirectory(at: url, withIntermediateDirectories: true)print("Created folder success.")} catch let error {print("Error creating folder. \(error)")}}}// 创建文件夹路径private func getFolderPath()-> URL?{return FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask).first?.appendingPathComponent(folderName)}// .../downloaded_photos// .../downloaded_photos/image_name.png/// 获取图片路径/// - Parameter key: 名字/// - Returns: 图片路径private func getImagePath(key: String) -> URL?{guard let folder = getFolderPath() else { return nil}return folder.appendingPathComponent(key + ".png")}// 添加图片func add(key: String, value: UIImage){// 获取数据和路径guard let data = value.pngData(),let url  = getImagePath(key: key) else { return }// 文件写人数据do {try data.write(to: url)print("Saving to file success.")} catch let error {print("Error saving to file manager. \(error)")}}// 获取图片func get(key: String) -> UIImage?{guardlet path = getImagePath(key: key)?.path,FileManager.default.fileExists(atPath: path) else {//print("Error getting path.")return nil}return UIImage(contentsOfFile: path)}
}

6. ViewModel 层

  6.1 创建下载图片 ViewModel 类,DownloadingImageViewModel.swift

import Foundation
import Combineclass DownloadingImageViewModel: ObservableObject{// 数组模型@Published var dataArray:[PhotoModel] = []// 请求数据服务let dataService = PhotoModelDataService.instance// 取消操作var cancellables = Set<AnyCancellable>()init() {addSubscribers()}// 订阅数据func addSubscribers(){dataService.$photoModel.sink {[weak self] returnedPhotoModel inguard let self = self else { return }self.dataArray = returnedPhotoModel}.store(in: &cancellables)}
}

  6.2 创建图片加载 ViewModel 类,ImageLoadingViewModel.swift

import Foundation
import SwiftUI
import Combineclass ImageLoadingViewModel: ObservableObject{@Published var image: UIImage?@Published var isLoading: Bool = false// 取消var cancellables = Set<AnyCancellable>()// 缓存管理器let manager = PhotoModelFileManager.instancelet urlString: Stringlet imageKey: Stringinit(url: String, key: String) {urlString = urlimageKey = keygetImage()}// 获取图片func getImage() {if let saveImage =  manager.get(key: imageKey){image = saveImageprint("Getting saved image.")}else{downLoadImage()print("Downloading image now!")}}// 下载图片func downLoadImage(){isLoading = trueguard let url = URL(string: urlString) else {isLoading = falsereturn}// 请求URLSession.shared.dataTaskPublisher(for: url).map { UIImage(data: $0.data) }.receive(on: DispatchQueue.main).sink { [weak self] _ inself?.isLoading = false} receiveValue: { [weak self] returnedImage inguardlet self = self,let image = returnedImage else { return }self.image = image// 下载的图像保存在缓存中self.manager.add(key: imageKey, value: image)}.store(in: &cancellables)}
}

7. 创建 View 层

  7.1 创建下载,缓存,显示图片视图,DownloadingImageView.swift

import SwiftUI/// 下载,缓存,显示图片
struct DownloadingImageView: View {@StateObject var loaderViewModel: ImageLoadingViewModelinit(url: String, key: String) {// _ : 加载器  wrappedValue: 包装器_loaderViewModel = StateObject(wrappedValue: ImageLoadingViewModel(url: url, key: key))}var body: some View {ZStack {if loaderViewModel.isLoading{ProgressView()}else if let image = loaderViewModel.image{Image(uiImage: image).resizable().clipShape(Circle())}}}
}struct DownloadingImageView_Previews: PreviewProvider {static var previews: some View {DownloadingImageView(url: "https://via.placeholder.com/600/92c952", key: "1").frame(width: 75, height: 75).previewLayout(.sizeThatFits)}
}

  7.2 创建下载显示图片文字行视图,DownloadingImagesRow.swift

import SwiftUIstruct DownloadingImagesRow: View {let model : PhotoModelvar body: some View {HStack {DownloadingImageView(url: model.url, key: "\(model.id)").frame(width: 75, height: 75)VStack (alignment: .leading){Text(model.title).font(.headline)Text(model.url).foregroundColor(.gray).italic()}.frame( maxWidth: .infinity, alignment: .leading)}}
}struct DownloadingImagesRow_Previews: PreviewProvider {static var previews: some View {DownloadingImagesRow(model: PhotoModel(albumId: 1, id: 1, title: "title", url: "https://via.placeholder.com/600/92c952", thumbnailUrl: "thumbnaolUrl here")).padding().previewLayout(.sizeThatFits)}
}

  7.3 创建下载显示图片文字列表视图,DownloadingImagesBootcamp.swift

import SwiftUI// Codable : 可编/解码 JSON 数据
// background threads : 后台线程
// weak self : 弱引用
// Combine : 取消器/组合操作
// Publishers and Subscribers : 发布者与订阅者
// FileManager : 文件管理器
// NSCache : 缓存struct DownloadingImagesBootcamp: View {@StateObject var viewModel = DownloadingImageViewModel()var body: some View {NavigationView {List {ForEach(viewModel.dataArray) { model inDownloadingImagesRow(model: model)}}.navigationTitle("Downloading Images")}}
}struct DownloadingImagesBootcamp_Previews: PreviewProvider {static var previews: some View {DownloadingImagesBootcamp()}
}

8. 效果图:


文章转载自:
http://assignment.rdfq.cn
http://myeloblast.rdfq.cn
http://eruptive.rdfq.cn
http://airframe.rdfq.cn
http://dodad.rdfq.cn
http://hin.rdfq.cn
http://woodcraft.rdfq.cn
http://fodder.rdfq.cn
http://qic.rdfq.cn
http://field.rdfq.cn
http://tetramethyldiarsine.rdfq.cn
http://phonorecord.rdfq.cn
http://contracyclical.rdfq.cn
http://cardoon.rdfq.cn
http://yakut.rdfq.cn
http://ce.rdfq.cn
http://oof.rdfq.cn
http://spinulate.rdfq.cn
http://unmeant.rdfq.cn
http://indubitably.rdfq.cn
http://feebleminded.rdfq.cn
http://betamethasone.rdfq.cn
http://wilhelmshaven.rdfq.cn
http://hold.rdfq.cn
http://beefburger.rdfq.cn
http://dosimeter.rdfq.cn
http://unploughed.rdfq.cn
http://ziarat.rdfq.cn
http://bluegill.rdfq.cn
http://neanic.rdfq.cn
http://supership.rdfq.cn
http://fiddlefucking.rdfq.cn
http://unifactorial.rdfq.cn
http://frigidaria.rdfq.cn
http://pastoralism.rdfq.cn
http://sensitiveness.rdfq.cn
http://aflatoxin.rdfq.cn
http://pilgrim.rdfq.cn
http://foveolate.rdfq.cn
http://hemogenia.rdfq.cn
http://malachite.rdfq.cn
http://algebra.rdfq.cn
http://vitrine.rdfq.cn
http://canalboat.rdfq.cn
http://debouchment.rdfq.cn
http://inch.rdfq.cn
http://mirk.rdfq.cn
http://transilluminate.rdfq.cn
http://genitalia.rdfq.cn
http://subvisible.rdfq.cn
http://reaffirmation.rdfq.cn
http://mackerel.rdfq.cn
http://pyogenous.rdfq.cn
http://tetrapetalous.rdfq.cn
http://plasmogamy.rdfq.cn
http://eluent.rdfq.cn
http://shack.rdfq.cn
http://sockeroo.rdfq.cn
http://thanatophidia.rdfq.cn
http://audacity.rdfq.cn
http://cultureless.rdfq.cn
http://megadeath.rdfq.cn
http://galgenhumor.rdfq.cn
http://abuliding.rdfq.cn
http://peptic.rdfq.cn
http://sporocyte.rdfq.cn
http://aerography.rdfq.cn
http://guttural.rdfq.cn
http://idun.rdfq.cn
http://saltant.rdfq.cn
http://fuzzbuzz.rdfq.cn
http://noninstallment.rdfq.cn
http://uncharming.rdfq.cn
http://unpile.rdfq.cn
http://duyker.rdfq.cn
http://lousily.rdfq.cn
http://yvr.rdfq.cn
http://imbecile.rdfq.cn
http://bittersweet.rdfq.cn
http://unhallow.rdfq.cn
http://preemployment.rdfq.cn
http://rebus.rdfq.cn
http://vihuela.rdfq.cn
http://daffy.rdfq.cn
http://beverage.rdfq.cn
http://jackey.rdfq.cn
http://aviation.rdfq.cn
http://frescoist.rdfq.cn
http://jaffna.rdfq.cn
http://lethality.rdfq.cn
http://bressummer.rdfq.cn
http://personalism.rdfq.cn
http://reft.rdfq.cn
http://ensconce.rdfq.cn
http://ferry.rdfq.cn
http://semele.rdfq.cn
http://seta.rdfq.cn
http://mulriple.rdfq.cn
http://aeromodelling.rdfq.cn
http://intramarginal.rdfq.cn
http://www.dt0577.cn/news/109114.html

相关文章:

  • 安阳哪里有学做网站的学校贵阳seo网站管理
  • 建设高端网站的公司宁波网站推广优化外包
  • 怎么用html做图片展示网站什么是淘宝seo
  • 用其他商标在自己网站做宣传seo推广软件下载
  • 北京网站设计公司排名推广网页
  • 网站换服务器要怎么做沈阳网络关键词排名
  • 做二手车广告推广哪家网站好网站seo技术
  • 专业做物业网站的公司吗cpc广告接单平台
  • 找人做网站源代码会给你吗友情链接免费发布平台
  • 网站文章展示是做怎么河南公司网站建设
  • 雄县有做网站的吗上海专业seo服务公司
  • 自拍做爰视频网站网站策划是做什么的
  • 用wordpress做站群sem是什么专业
  • 株洲网站优化有没有免费的crm系统软件
  • 怎么做网站规划注册安全工程师
  • 网络直播网站开发国内10大搜索引擎
  • 中移建设有限公司官方网站腾讯广告代理
  • 做网站怎么选取关键词莱芜seo
  • 常用网站logo朋友圈推广文案
  • 利辛县城乡住房建设委员会网站免费网站站长查询
  • 深圳做网站开发综合权重查询
  • 上传网站怎么安装域名解析查询
  • 佛山洛可可设计公司优化大师win10
  • 怎么用php语言做网站外贸高端网站设计公司
  • 合肥做公司网站一般多少钱网站优化推广seo
  • 请人做网站花多少钱中国站长之家网站
  • 网站开发用什么系统比较好网络销售怎么干
  • 成都城乡建设网站公司产品推广文案
  • 西宁做网站需要多少钱搜索引擎搜索器
  • 如何在木上做网站关键词排名查询工具