Commit c6f00afb authored by CZ1004's avatar CZ1004

11

parent 8a505392
{
"images" : [
{
"filename" : "ic_delete_email.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "ic_delete_email@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "ic_delete_email@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}
...@@ -133,9 +133,28 @@ extension ContactViewController{ ...@@ -133,9 +133,28 @@ extension ContactViewController{
print("获取联系人信息时发生错误: \(error)") print("获取联系人信息时发生错误: \(error)")
} }
} }
// 获取备份数据
let vm = BackupViewModel()
vm.retrieveContactsFromBackup { model, error in
if let error = error {
Print("请求备份数据失败,\(error.localizedDescription)")
return
}
DispatchQueue.main.async {
self.dataSourceModel.backups = model!
self.updateModuleData()
self.moduleView.tableView.reloadData()
}
}
// fixme:获取重复数据
} }
func requestContactsPermission(completion: @escaping (Bool) -> Void) { func requestContactsPermission(completion: @escaping (Bool) -> Void) {
let store = CNContactStore() let store = CNContactStore()
switch CNContactStore.authorizationStatus(for: .contacts) { switch CNContactStore.authorizationStatus(for: .contacts) {
......
...@@ -37,6 +37,10 @@ class ContactBackUpNormalView : UIView { ...@@ -37,6 +37,10 @@ class ContactBackUpNormalView : UIView {
tableView.dataSource = self tableView.dataSource = self
tableView.register(ContactBackupCell.self, forCellReuseIdentifier: ContactBackupCell.identifier) tableView.register(ContactBackupCell.self, forCellReuseIdentifier: ContactBackupCell.identifier)
tableView.separatorStyle = .none tableView.separatorStyle = .none
tableView.showsVerticalScrollIndicator = false
if #available(iOS 15.0, *) {
tableView.sectionHeaderTopPadding = 0
}
return tableView return tableView
}() }()
...@@ -80,6 +84,10 @@ class ContactBackUpNormalView : UIView { ...@@ -80,6 +84,10 @@ class ContactBackUpNormalView : UIView {
extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return 1
}
func numberOfSections(in tableView: UITableView) -> Int {
return dataSourceModel.count return dataSourceModel.count
} }
...@@ -87,9 +95,18 @@ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{ ...@@ -87,9 +95,18 @@ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{
return 74 return 74
} }
func tableView(_ tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
let view = UIView()
view.backgroundColor = .clear
return view
}
func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
return 12
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: ContactBackupCell.identifier, for: indexPath) as! ContactBackupCell let cell = tableView.dequeueReusableCell(withIdentifier: ContactBackupCell.identifier, for: indexPath) as! ContactBackupCell
let backupInfo = dataSourceModel[indexPath.row] let backupInfo = dataSourceModel[indexPath.section]
let dateFormatter = DateFormatter() let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "dd MMM yyyy" dateFormatter.dateFormat = "dd MMM yyyy"
let dateString = dateFormatter.string(from: backupInfo.backupTime) let dateString = dateFormatter.string(from: backupInfo.backupTime)
...@@ -99,13 +116,49 @@ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{ ...@@ -99,13 +116,49 @@ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{
return cell return cell
} }
func deleteBackupDataFromMemory(){
let vm = BackupViewModel()
vm.saveModel(model: self.dataSourceModel) { finished, error in
if let error = error {
Print("删除失败,\(error.localizedDescription)")
}
DispatchQueue.main.async {
// 弹框提示成功
let buAlertVc = ContactBackUpDeleteCompletedAlertView(frame: (self.responderViewController()?.view.bounds)!)
self.responderViewController()?.view.addSubview(buAlertVc)
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
buAlertVc.removeFromSuperview()
}
}
}
}
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
let vc = ContactBackupDetailViewController()
vc.dataSourceModel = self.dataSourceModel[indexPath.section].contacts
vc.subTitleLabel.text = "\(self.dataSourceModel[indexPath.section].contacts.count) Contacts"
vc.sortContacts()
vc.setupCustomIndexView()
self.responderViewController()?.navigationController?.pushViewController(vc, animated: true)
}
@objc(tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:) func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? { @objc(tableView:trailingSwipeActionsConfigurationForRowAtIndexPath:) func tableView(_ tableView: UITableView, trailingSwipeActionsConfigurationForRowAt indexPath: IndexPath) -> UISwipeActionsConfiguration? {
let deleteAction = UIContextualAction(style: .destructive, title: nil) { [weak self] (action, view, completionHandler) in let deleteAction = UIContextualAction(style: .destructive, title: nil) { [weak self] (action, view, completionHandler) in
self?.dataSourceModel.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic) let alertVc = ContactDeleteAlertView()
alertVc.frame = (self?.responderViewController()?.view.bounds)!
self?.responderViewController()?.view.addSubview(alertVc)
alertVc.sureCallBack = {
self?.dataSourceModel.remove(at: indexPath.section)
// 删除整个部分而不是特定行
self?.tableView.deleteSections(IndexSet(integer: indexPath.section), with: .automatic)
// 删除存储的数据
self?.deleteBackupDataFromMemory()
}
completionHandler(true) completionHandler(true)
} }
deleteAction.backgroundColor = .red deleteAction.backgroundColor = UIColor(red: 0.92, green: 0.27, blue: 0.27, alpha: 1)
deleteAction.image = UIImage(named: "ic_delete_email") deleteAction.image = UIImage(named: "ic_delete_email")
let configuration = UISwipeActionsConfiguration(actions: [deleteAction]) let configuration = UISwipeActionsConfiguration(actions: [deleteAction])
return configuration return configuration
...@@ -123,7 +176,6 @@ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{ ...@@ -123,7 +176,6 @@ extension ContactBackUpNormalView : UITableViewDelegate,UITableViewDataSource{
// 再次请求数据 重新刷新页面 // 再次请求数据 重新刷新页面
self.updateData() self.updateData()
} }
} }
} }
......
...@@ -106,4 +106,21 @@ class BackupViewModel { ...@@ -106,4 +106,21 @@ class BackupViewModel {
} }
} }
func saveModel(model:[BackupInfoModel],completion: @escaping (Bool, Error?) -> Void){
guard let documentsDirectory = FileManager.default.urls(for:.documentDirectory, in:.userDomainMask).first else {
completion(false, NSError(domain: "ContactBackupError", code: 1, userInfo: [NSLocalizedDescriptionKey: "无法获取沙盒目录"]))
return
}
let backupFileURL = documentsDirectory.appendingPathComponent("partial_contacts_backup.json")
do {
let encoder = JSONEncoder()
encoder.dateEncodingStrategy = .iso8601
let jsonData = try encoder.encode(model)
try jsonData.write(to: backupFileURL)
completion(true, nil)
} catch {
completion(false, error)
}
}
} }
//
// CustomContactBacDetailTableViewCell.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import Foundation
class CustomContactBacDetailTableViewCell : UITableViewCell {
var model : ContactModel?
lazy var backView : UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.95, green: 0.96, blue: 0.99, alpha: 1)
view.clipsToBounds = true
view.layer.cornerRadius = 12
return view
}()
lazy var nameLabel : UILabel = {
let label = UILabel()
label.textColor = UIColor(red: 0.2, green: 0.2, blue: 0.2, alpha: 1)
label.font = UIFont.systemFont(ofSize: 16, weight: .bold)
return label
}()
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
self.selectionStyle = .none
self.contentView.addSubview(self.backView)
self.backView.addSubview(self.nameLabel)
self.backView.snp.makeConstraints { make in
make.left.right.top.equalToSuperview()
make.height.equalTo(71)
}
self.nameLabel.snp.makeConstraints { make in
make.left.equalToSuperview().offset(16 * RScreenH())
make.centerY.equalToSuperview()
make.width.equalTo(210)
make.height.equalTo(22)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
//
// ContactBacRestoreAlertView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import Foundation
class ContactBacRestoreAlertView : UIView {
var sureCallBack: ()->Void = {}
// 懒加载背景视图
private lazy var backgroundView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
return view
}()
// 懒加载卡片视图
private lazy var cardView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.layer.cornerRadius = 10
view.clipsToBounds = true
return view
}()
// 懒加载标题标签
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.text = "Are you sure?"
label.font = UIFont.systemFont(ofSize: 17, weight: .bold)
label.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
label.textAlignment = .center
return label
}()
// 懒加载副标题标签
private lazy var subtitleLabel: UILabel = {
let label = UILabel()
label.text = "Your contacts will be removed from your iPhone and iCloud. This process cannot be reversed"
label.font = UIFont.systemFont(ofSize: 13, weight: .regular)
label.textColor = UIColor(red: 0, green: 0, blue: 0, alpha: 1)
label.numberOfLines = 0
label.textAlignment = .center
return label
}()
// 懒加载取消按钮
private lazy var cancelButton: UIButton = {
let button = UIButton()
button.setTitle("Cancel", for: .normal)
button.backgroundColor = .clear
button.setTitleColor(UIColor(red: 0, green: 0.48, blue: 1, alpha: 1), for: .normal)
button.layer.cornerRadius = 5
button.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .regular)
button.addTarget(self, action: #selector(dismissAlert), for: .touchUpInside)
return button
}()
// 懒加载确认按钮
private lazy var yesButton: UIButton = {
let button = UIButton()
button.setTitle("Yes", for: .normal)
button.backgroundColor = .clear
button.setTitleColor(UIColor(red: 0, green: 0.48, blue: 1, alpha: 1), for: .normal)
button.layer.cornerRadius = 5
button.titleLabel?.font = UIFont.systemFont(ofSize: 17, weight: .regular)
button.addTarget(self, action: #selector(sureAlert), for: .touchUpInside)
return button
}()
// 懒加载顶部边线
private lazy var topBorder: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.24, green: 0.24, blue: 0.26, alpha: 0.3600)
return view
}()
// 懒加载中间分割线
private lazy var middleBorder: UIView = {
let view = UIView()
view.backgroundColor = UIColor(red: 0.24, green: 0.24, blue: 0.26, alpha: 0.3600)
return view
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5000)
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
self.addSubview(backgroundView)
backgroundView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
self.addSubview(cardView)
cardView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.width.equalTo(270)
make.height.equalTo(154)
}
cardView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.top.equalToSuperview().offset(16)
make.left.right.equalToSuperview().inset(16)
make.height.equalTo(22)
}
cardView.addSubview(subtitleLabel)
subtitleLabel.snp.makeConstraints { make in
make.top.equalTo(titleLabel.snp.bottom).offset(2)
make.left.right.equalToSuperview().inset(16)
make.height.equalTo(54)
}
cardView.addSubview(cancelButton)
cancelButton.snp.makeConstraints { make in
make.left.equalToSuperview()
make.bottom.equalToSuperview()
make.width.equalTo(cardView.snp.width).multipliedBy(0.5)
make.height.equalTo(44)
}
cardView.addSubview(yesButton)
yesButton.snp.makeConstraints { make in
make.right.equalToSuperview()
make.bottom.equalToSuperview()
make.width.equalTo(cardView.snp.width).multipliedBy(0.5)
make.height.equalTo(44)
}
cardView.addSubview(topBorder)
topBorder.snp.makeConstraints { make in
make.top.equalTo(cancelButton.snp.top)
make.left.right.equalTo(cardView)
make.height.equalTo(0.5)
}
cardView.addSubview(middleBorder)
middleBorder.snp.makeConstraints { make in
make.centerX.equalTo(cardView)
make.top.equalTo(cancelButton.snp.top)
make.bottom.equalTo(cancelButton.snp.bottom)
make.width.equalTo(0.5)
}
}
@objc private func dismissAlert() {
self.removeFromSuperview()
}
@objc private func sureAlert() {
self.removeFromSuperview()
sureCallBack()
}
}
//
// ContactBackUpDeleteCompletedAlertView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import Foundation
class ContactBackUpDeleteCompletedAlertView : UIView {
var sureCallBack: ()->Void = {}
// 懒加载背景视图
private lazy var backgroundView: UIView = {
let view = UIView()
view.backgroundColor = UIColor.black.withAlphaComponent(0.5)
return view
}()
// 懒加载卡片视图
private lazy var cardView: UIView = {
let view = UIView()
view.backgroundColor = .white
view.layer.cornerRadius = 10
view.clipsToBounds = true
return view
}()
private lazy var imageView: UIImageView = {
let view = UIImageView()
view.backgroundColor = .clear
view.image = UIImage(named: "ic_ok_duolicates")
return view
}()
// 懒加载标题标签
private lazy var titleLabel: UILabel = {
let label = UILabel()
label.text = "Done!"
label.font = UIFont.systemFont(ofSize: 14, weight: .regular)
label.textColor = UIColor(red: 0.4, green: 0.4, blue: 0.4, alpha: 1)
label.textAlignment = .center
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.backgroundColor = UIColor(red: 0, green: 0, blue: 0, alpha: 0.5000)
setupViews()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setupViews() {
self.addSubview(backgroundView)
backgroundView.snp.makeConstraints { make in
make.edges.equalToSuperview()
}
self.addSubview(cardView)
cardView.snp.makeConstraints { make in
make.center.equalToSuperview()
make.width.equalTo(175)
make.height.equalTo(95)
}
cardView.addSubview(imageView)
imageView.snp.makeConstraints { make in
make.top.equalToSuperview().offset(20)
make.width.height.equalTo(35)
make.centerX.equalToSuperview()
}
cardView.addSubview(titleLabel)
titleLabel.snp.makeConstraints { make in
make.top.equalTo(self.imageView.snp.bottom).offset(0)
make.left.right.equalToSuperview().inset(20)
make.height.equalTo(20)
}
}
}
//
// RestoreButtonView.swift
// PhoneManager
//
// Created by 赵前 on 2025/4/20.
//
import Foundation
class RestoreButtonView : UIView {
var submitCallBack : (()->Void) = {}
lazy var imageView : UIImageView = {
let imageView = UIImageView()
imageView.image = UIImage(named: "ic_beifen")
return imageView
}()
lazy var titleLabel : UILabel = {
let label = UILabel()
label.textAlignment = .left
label.text = "Restore Backup"
label.textColor = UIColor(red: 1, green: 1, blue: 1, alpha: 1)
return label
}()
override init(frame: CGRect) {
super.init(frame: frame)
self.isUserInteractionEnabled = true
self.backgroundColor = UIColor(red: 0, green: 0.51, blue: 1, alpha: 1)
let tap = UITapGestureRecognizer()
tap.addTarget(self, action: #selector(restoreAction))
self.addGestureRecognizer(tap)
self.addSubview(self.imageView)
self.addSubview(self.titleLabel)
self.imageView.snp.makeConstraints { make in
make.width.height.equalTo(20)
make.centerY.equalToSuperview()
make.left.equalToSuperview().offset(94 * RScreenW())
}
self.titleLabel.snp.makeConstraints { make in
make.left.equalTo(self.imageView.snp.right).offset(8 * RScreenW())
make.centerY.equalToSuperview()
make.height.equalTo(22)
}
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@objc func restoreAction(){
submitCallBack()
}
}
...@@ -61,7 +61,7 @@ class HomeView:UIView { ...@@ -61,7 +61,7 @@ class HomeView:UIView {
super.init(frame: frame) super.init(frame: frame)
setData() // setData()
setupUI() setupUI()
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment