Bladeren bron

数据库模型基本搭建成型

100Years 2 maanden geleden
bovenliggende
commit
91e359ce99
24 gewijzigde bestanden met toevoegingen van 895 en 157 verwijderingen
  1. 52 0
      AIEmoji.xcodeproj/project.pbxproj
  2. 6 0
      AIEmoji/Assets.xcassets/AIChat/Contents.json
  3. 22 0
      AIEmoji/Assets.xcassets/AIChat/aichat_history.imageset/Contents.json
  4. BIN
      AIEmoji/Assets.xcassets/AIChat/aichat_history.imageset/aichat_history@2x.png
  5. BIN
      AIEmoji/Assets.xcassets/AIChat/aichat_history.imageset/aichat_history@3x.png
  6. 22 0
      AIEmoji/Assets.xcassets/AIChat/nav_title_aichat.imageset/Contents.json
  7. BIN
      AIEmoji/Assets.xcassets/AIChat/nav_title_aichat.imageset/nav_title_chat@2x.png
  8. BIN
      AIEmoji/Assets.xcassets/AIChat/nav_title_aichat.imageset/nav_title_chat@3x.png
  9. 132 2
      AIEmoji/Business/AIChat/TSAIChatContainerVC.swift
  10. 12 0
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/M/TSAIChatHistoryModel.swift
  11. 129 0
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/TSAIChatHistoryVC.swift
  12. 79 0
      AIEmoji/Business/AIChat/TSAIChatHistoryVC/VM/TSAIChatHistoryVM.swift
  13. 2 114
      AIEmoji/Business/AIChat/TSChatViewController/Models/MockMessage.swift
  14. 8 5
      AIEmoji/Business/AIChat/TSChatViewController/Models/TSChatUser.swift
  15. 180 0
      AIEmoji/Business/AIChat/TSChatViewController/Models/TSDBAIChatList.swift
  16. 17 9
      AIEmoji/Business/AIChat/TSChatViewController/TSChatViewController.swift
  17. 49 10
      AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift
  18. 1 1
      AIEmoji/Business/LaunchVC/TSLaunchVC.swift
  19. 2 1
      AIEmoji/Business/TSGenmojiVC/TSGenmojiGennerateVC/TSGenmojiGennerateViewModel.swift
  20. 9 1
      AIEmoji/Common/Ex/Date+Ex.swift
  21. 1 1
      AIEmoji/Common/GlobalImports/GlobalImports.swift
  22. 147 0
      AIEmoji/Common/TSRealmManager/TSRealmManager.swift
  23. 4 2
      Podfile
  24. 21 11
      Podfile.lock

+ 52 - 0
AIEmoji.xcodeproj/project.pbxproj

@@ -57,6 +57,11 @@
 		A89EA67D2D59F1AF000EB181 /* StreamPostRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA67C2D59F1AC000EB181 /* StreamPostRequest.swift */; };
 		A89EA6812D59F44D000EB181 /* TSAIChatVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6802D59F440000EB181 /* TSAIChatVC.swift */; };
 		A89EA6832D59F4F9000EB181 /* TSChatViewController+Ex.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6822D59F4F1000EB181 /* TSChatViewController+Ex.swift */; };
+		A89EA6A32D5B26E3000EB181 /* TSDBAIChatList.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6A22D5B26E3000EB181 /* TSDBAIChatList.swift */; };
+		A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6AB2D5B3EFA000EB181 /* TSRealmManager.swift */; };
+		A89EA6B12D5C9D0C000EB181 /* TSAIChatHistoryVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B02D5C9D0B000EB181 /* TSAIChatHistoryVC.swift */; };
+		A89EA6B42D5C9D43000EB181 /* TSAIChatHistoryVM.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B32D5C9D3D000EB181 /* TSAIChatHistoryVM.swift */; };
+		A89EA6B82D5D7EE9000EB181 /* TSAIChatHistoryModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = A89EA6B72D5D7EE4000EB181 /* TSAIChatHistoryModel.swift */; };
 		A8EEADD42D3E6C660032C5A0 /* Flower💐.json in Resources */ = {isa = PBXBuildFile; fileRef = A8EEADD32D3E6C610032C5A0 /* Flower💐.json */; };
 		A8EEADD62D3E6CD80032C5A0 /* Fish🐠.json in Resources */ = {isa = PBXBuildFile; fileRef = A8EEADD52D3E6CD30032C5A0 /* Fish🐠.json */; };
 		A8EEADD82D3E74D20032C5A0 /* Pink🩷.json in Resources */ = {isa = PBXBuildFile; fileRef = A8EEADD72D3E74CB0032C5A0 /* Pink🩷.json */; };
@@ -202,6 +207,11 @@
 		A89EA67C2D59F1AC000EB181 /* StreamPostRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamPostRequest.swift; sourceTree = "<group>"; };
 		A89EA6802D59F440000EB181 /* TSAIChatVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatVC.swift; sourceTree = "<group>"; };
 		A89EA6822D59F4F1000EB181 /* TSChatViewController+Ex.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TSChatViewController+Ex.swift"; sourceTree = "<group>"; };
+		A89EA6A22D5B26E3000EB181 /* TSDBAIChatList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSDBAIChatList.swift; sourceTree = "<group>"; };
+		A89EA6AB2D5B3EFA000EB181 /* TSRealmManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSRealmManager.swift; sourceTree = "<group>"; };
+		A89EA6B02D5C9D0B000EB181 /* TSAIChatHistoryVC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatHistoryVC.swift; sourceTree = "<group>"; };
+		A89EA6B32D5C9D3D000EB181 /* TSAIChatHistoryVM.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatHistoryVM.swift; sourceTree = "<group>"; };
+		A89EA6B72D5D7EE4000EB181 /* TSAIChatHistoryModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TSAIChatHistoryModel.swift; sourceTree = "<group>"; };
 		A8EEADD32D3E6C610032C5A0 /* Flower💐.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Flower💐.json"; sourceTree = "<group>"; };
 		A8EEADD52D3E6CD30032C5A0 /* Fish🐠.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Fish🐠.json"; sourceTree = "<group>"; };
 		A8EEADD72D3E74CB0032C5A0 /* Pink🩷.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "Pink🩷.json"; sourceTree = "<group>"; };
@@ -477,6 +487,7 @@
 		A80E74222D5996BF00C64288 /* AIChat */ = {
 			isa = PBXGroup;
 			children = (
+				A89EA6AF2D5C9861000EB181 /* TSAIChatHistoryVC */,
 				A89EA6772D59D224000EB181 /* TSChatViewController */,
 				A89EA6752D59C932000EB181 /* TSAIChatContainerVC.swift */,
 			);
@@ -494,6 +505,7 @@
 		A89EA6532D59A9F4000EB181 /* Models */ = {
 			isa = PBXGroup;
 			children = (
+				A89EA6A22D5B26E3000EB181 /* TSDBAIChatList.swift */,
 				A89EA64E2D59A9F4000EB181 /* CustomLayoutSizeCalculator.swift */,
 				A89EA64F2D59A9F4000EB181 /* CustomTextLayoutSizeCalculator.swift */,
 				A89EA6502D59A9F4000EB181 /* MockMessage.swift */,
@@ -537,6 +549,40 @@
 			path = ViewModel;
 			sourceTree = "<group>";
 		};
+		A89EA6AA2D5B3EE8000EB181 /* TSRealmManager */ = {
+			isa = PBXGroup;
+			children = (
+				A89EA6AB2D5B3EFA000EB181 /* TSRealmManager.swift */,
+			);
+			path = TSRealmManager;
+			sourceTree = "<group>";
+		};
+		A89EA6AF2D5C9861000EB181 /* TSAIChatHistoryVC */ = {
+			isa = PBXGroup;
+			children = (
+				A89EA6B62D5D7ED2000EB181 /* M */,
+				A89EA6B22D5C9D36000EB181 /* VM */,
+				A89EA6B02D5C9D0B000EB181 /* TSAIChatHistoryVC.swift */,
+			);
+			path = TSAIChatHistoryVC;
+			sourceTree = "<group>";
+		};
+		A89EA6B22D5C9D36000EB181 /* VM */ = {
+			isa = PBXGroup;
+			children = (
+				A89EA6B32D5C9D3D000EB181 /* TSAIChatHistoryVM.swift */,
+			);
+			path = VM;
+			sourceTree = "<group>";
+		};
+		A89EA6B62D5D7ED2000EB181 /* M */ = {
+			isa = PBXGroup;
+			children = (
+				A89EA6B72D5D7EE4000EB181 /* TSAIChatHistoryModel.swift */,
+			);
+			path = M;
+			sourceTree = "<group>";
+		};
 		A8F774602D38E8B000AA6E93 = {
 			isa = PBXGroup;
 			children = (
@@ -718,6 +764,7 @@
 		A8F774D82D38EA8C00AA6E93 /* Common */ = {
 			isa = PBXGroup;
 			children = (
+				A89EA6AA2D5B3EE8000EB181 /* TSRealmManager */,
 				A80E73E32D533EB000C64288 /* Purchase */,
 				A8F7749B2D38EA8C00AA6E93 /* BaseClass */,
 				A8F774B32D38EA8C00AA6E93 /* Ex */,
@@ -1138,6 +1185,7 @@
 				A8F774D92D38EA8C00AA6E93 /* UICollectionView+More.swift in Sources */,
 				A80E726C2D409E8300C64288 /* TSDiyTLPinkAnimalView.swift in Sources */,
 				A80E72652D409B0D00C64288 /* DiyStaticElement.swift in Sources */,
+				A89EA6B42D5C9D43000EB181 /* TSAIChatHistoryVM.swift in Sources */,
 				A8F774DA2D38EA8C00AA6E93 /* UIFont+Ex.swift in Sources */,
 				A80E72532D3F985E00C64288 /* TSWallpaperVC.swift in Sources */,
 				A8FB02B32D3E39A40031A396 /* TSEmojisModel.swift in Sources */,
@@ -1183,6 +1231,7 @@
 				A8F7763F2D3B68E100AA6E93 /* TSGenmojiGennerateViewModel.swift in Sources */,
 				A80E72352D3F473400C64288 /* DiyPaperTemplateBaseView.swift in Sources */,
 				A80E72362D3F473400C64288 /* DiyPaperTemplate.swift in Sources */,
+				A89EA6B82D5D7EE9000EB181 /* TSAIChatHistoryModel.swift in Sources */,
 				A80E72722D40F86000C64288 /* TSLaunchVC.swift in Sources */,
 				A8F775352D38FC9A00AA6E93 /* TSViewTool.swift in Sources */,
 				A80E72592D3FA67800C64288 /* TSWallpaperViewModel.swift in Sources */,
@@ -1197,6 +1246,7 @@
 				A8F774F42D38EA8C00AA6E93 /* TSBaseNavigationBarView.swift in Sources */,
 				A8F774F52D38EA8C00AA6E93 /* Array+Ex.swift in Sources */,
 				A80E72672D409C7D00C64288 /* Template+More.swift in Sources */,
+				A89EA6AC2D5B3EFB000EB181 /* TSRealmManager.swift in Sources */,
 				A8F775172D38EB7400AA6E93 /* TSTabBarController.swift in Sources */,
 				A8F774F62D38EA8C00AA6E93 /* UIImageView+Ex.swift in Sources */,
 				A8F776272D3A6EC200AA6E93 /* TSGenmojiTextView.swift in Sources */,
@@ -1245,6 +1295,7 @@
 				A8F7762D2D3A74A100AA6E93 /* TSGenmojiGennerateCell.swift in Sources */,
 				A8F775322D38FA5E00AA6E93 /* UITextView+Ex.swift in Sources */,
 				A89EA6832D59F4F9000EB181 /* TSChatViewController+Ex.swift in Sources */,
+				A89EA6A32D5B26E3000EB181 /* TSDBAIChatList.swift in Sources */,
 				A8F7753F2D39340E00AA6E93 /* TSSetingVC.swift in Sources */,
 				A8F7762B2D3A70B200AA6E93 /* PaddedLabel.swift in Sources */,
 				A80E73E62D5348D000C64288 /* SettingPurchaseTopView.swift in Sources */,
@@ -1252,6 +1303,7 @@
 				A8F775382D390C3C00AA6E93 /* TSNetworkManager.swift in Sources */,
 				A89EA65F2D59AA11000EB181 /* TSChatViewController.swift in Sources */,
 				A8F7750B2D38EA8C00AA6E93 /* TSBaseTabViewCell.swift in Sources */,
+				A89EA6B12D5C9D0C000EB181 /* TSAIChatHistoryVC.swift in Sources */,
 				A8F7750D2D38EA8C00AA6E93 /* TSBaseVC.swift in Sources */,
 				A8FB02B72D3E3A3D0031A396 /* TSEmojisChildViewModel.swift in Sources */,
 				A8F7754B2D39376800AA6E93 /* TSSettingListView.swift in Sources */,

+ 6 - 0
AIEmoji/Assets.xcassets/AIChat/Contents.json

@@ -0,0 +1,6 @@
+{
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

+ 22 - 0
AIEmoji/Assets.xcassets/AIChat/aichat_history.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "aichat_history@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "aichat_history@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIEmoji/Assets.xcassets/AIChat/aichat_history.imageset/aichat_history@2x.png


BIN
AIEmoji/Assets.xcassets/AIChat/aichat_history.imageset/aichat_history@3x.png


+ 22 - 0
AIEmoji/Assets.xcassets/AIChat/nav_title_aichat.imageset/Contents.json

@@ -0,0 +1,22 @@
+{
+  "images" : [
+    {
+      "idiom" : "universal",
+      "scale" : "1x"
+    },
+    {
+      "filename" : "nav_title_chat@2x.png",
+      "idiom" : "universal",
+      "scale" : "2x"
+    },
+    {
+      "filename" : "nav_title_chat@3x.png",
+      "idiom" : "universal",
+      "scale" : "3x"
+    }
+  ],
+  "info" : {
+    "author" : "xcode",
+    "version" : 1
+  }
+}

BIN
AIEmoji/Assets.xcassets/AIChat/nav_title_aichat.imageset/nav_title_chat@2x.png


BIN
AIEmoji/Assets.xcassets/AIChat/nav_title_aichat.imageset/nav_title_chat@3x.png


+ 132 - 2
AIEmoji/Business/AIChat/TSAIChatContainerVC.swift

@@ -6,9 +6,62 @@
 //
 
 class TSAIChatContainerVC: TSBaseVC {
-    
-    
 
+    lazy var vipBtn: UIButton = {
+        let vipBtn = UIButton.createButton(image: UIImage(named: "nav_vip")) { [weak self]  in
+            guard let self = self else { return }
+            TSPurchaseVC.show(target: self) {
+      
+            }
+        }
+        return vipBtn
+    }()
+    
+    lazy var navBarView: TSBaseNavContentBarView = {
+        let navBarView = TSBaseNavContentBarView()
+        
+        let titleImageView = UIImageView.createImageView(imageName: "nav_title_aichat",contentMode: .scaleToFill)
+        navBarView.barView.addSubview(titleImageView)
+        titleImageView.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.left.equalTo(16)
+        }
+        
+        let setBtn = UIButton.createButton(image: UIImage(named: "setting")) { [weak self]  in
+            guard let self = self else { return }
+            let setingVC = TSSetingVC()
+            setingVC.hidesBottomBarWhenPushed = true
+            navigationController?.pushViewController(setingVC, animated: true)
+        }
+        navBarView.barView.addSubview(setBtn)
+        setBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-16)
+            make.width.height.equalTo(24)
+        }
+        
+        let historyBtn = UIButton.createButton(image: UIImage(named: "aichat_history")) { [weak self]  in
+            guard let self = self else { return }
+            let historyVC = TSAIChatHistoryVC()
+            historyVC.hidesBottomBarWhenPushed = true
+            navigationController?.pushViewController(historyVC, animated: true)
+        }
+        navBarView.barView.addSubview(historyBtn)
+        historyBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-60)
+            make.width.height.equalTo(24)
+        }
+        
+        navBarView.barView.addSubview(vipBtn)
+        vipBtn.snp.makeConstraints { make in
+            make.centerY.equalToSuperview()
+            make.trailing.equalTo(-104)
+            make.width.height.equalTo(24)
+        }
+        
+        return navBarView
+    }()
     
     lazy var chatVC: TSChatViewController = {
         let chatVC = TSChatViewController()
@@ -17,6 +70,12 @@ class TSAIChatContainerVC: TSBaseVC {
     
     
     override func createView() {
+        edgesForExtendedLayout = []
+        navBarContentView.addSubview(navBarView)
+        navBarView.snp.makeConstraints { make in
+            make.edges.equalToSuperview()
+        }
+        
         
         addChild(chatVC)
         contentView.addSubview(chatVC.view)
@@ -24,5 +83,76 @@ class TSAIChatContainerVC: TSBaseVC {
         chatVC.view.snp.makeConstraints { make in
             make.edges.equalToSuperview()
         }
+        
+        
+        
+//        let user = TSChatUser(senderId: "user123", displayName: "Alice")
+//        let chatList = TSDBAIChatList(sessionId: UUID().uuidString, message: [TSChatMessage(kind: .text("Hello"), user: user, messageId:  "msg123", date: Date())])
+//        do {
+//            try TSDBAIChatListDAO().insertChatList(chatList)
+//        } catch {
+//            print("Error inserting chat list: \(error)")
+//        }
+        
+//        do {
+//            try TSDBAIChatListDAO().deleteChatList(sessionId: "chatLists")
+//        }catch {
+//            print("Error deleteChatList lists: \(error)")
+//        }
+//        
+//        // 获取所有数据
+//        do {
+//            let allChatLists = try TSDBAIChatListDAO().fetchChatLists()
+//            print("Fetched \(allChatLists.count) chat lists.")
+//        } catch {
+//            print("Error fetching chat lists: \(error)")
+//        }
+
+//        // 删除数据
+//        do {
+//            try TSDBAIChatListDAO().deleteChatList(sessionId: chatList.sessionId)
+//            print("Deleted chat list.")
+//        } catch {
+//            print("Error deleting chat list: \(error)")
+//        }
+        
+        
+//        // 初始化数据库
+//        TSDBAIChatListDAO.initializeDatabase()
+//
+//        
+//        let user = TSChatUser(senderId: "1", displayName: "Alice1")
+//        let chatList = TSDBAIChatList(sessionId: "1", message: [TSChatMessage(kind: .text("Hello1"), user: user, messageId: "msg1", date: Date())])
+//        // 插入数据
+//        let insertResult = TSDBAIChatListDAO.insertChatList(chatList)
+//        print(insertResult ? "Insert succeeded" : "Insert failed")
+//
+//        // 更新数据
+//        let updatedChatList = TSDBAIChatList(sessionId: "2", message: [TSChatMessage(kind: .text("Hello2"), user: user, messageId: "msg2", date: Date())])
+//        let updateResult = TSDBAIChatListDAO.updateChatList(updatedChatList)
+//        print(updateResult ? "Update succeeded" : "Update failed")
+
+        // 删除数据
+//        let deleteResult = TSDBAIChatListDAO.deleteChatList(sessionId: "12345")
+//        print(deleteResult ? "Delete succeeded" : "Delete failed")
+        
+        
+        // 创建数据
+//        let person = Person()
+//        person.name = "John"
+//        person.age = 30
+//        TSRealmManager.shared.create(person)
+        // 读取数据
+//        let allPersons = TSRealmManager.shared.read(Person.self)
+//        for person in allPersons {
+//            print("Name: \(person.name), Age: \(person.age)")
+//        }
+        // 更新数据
+//        if let firstPerson = allPersons.first {
+//            TSRealmManager.shared.update(firstPerson) { person in
+//                person.age = 31
+//            }
+//        }
+
     }
 }

+ 12 - 0
AIEmoji/Business/AIChat/TSAIChatHistoryVC/M/TSAIChatHistoryModel.swift

@@ -0,0 +1,12 @@
+//
+//  TSAIChatHistoryModel.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/12.
+//
+
+
+class TSAIChatHistoryModel {
+    var title:String = ""
+    var chatList:[TSDBAIChatList] = []
+}

+ 129 - 0
AIEmoji/Business/AIChat/TSAIChatHistoryVC/TSAIChatHistoryVC.swift

@@ -0,0 +1,129 @@
+//
+//  TSAIChatHistoryVC.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/12.
+//
+
+import SwipeCellKit
+
+class TSAIChatHistoryVC: TSBaseVC {
+    
+    lazy var viewModel : TSAIChatHistoryVM = {
+        let viewModel = TSAIChatHistoryVM()
+        return viewModel
+    }()
+    
+    
+    lazy var layout: UICollectionViewFlowLayout = {
+        let layout = UICollectionViewFlowLayout()
+        layout.scrollDirection = .vertical
+        layout.itemSize = CGSize(width: 40, height: 40)
+        layout.minimumInteritemSpacing = 16.0
+        layout.minimumLineSpacing = 0.0
+        return layout
+    }()
+    
+//    lazy var collectionView: UICollectionView = {
+//        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: layout)
+//        collectionView.delegate = self
+//        collectionView.dataSource = self
+//        collectionView.showsVerticalScrollIndicator = false
+//        collectionView.showsHorizontalScrollIndicator = false
+//        collectionView.backgroundColor = .clear
+//        collectionView.register(TSAIChatHistoryCell.self, forCellWithReuseIdentifier: TSAIChatHistoryCell.cellID)
+//        if #available(iOS 11.0, *) {
+//            collectionView.contentInsetAdjustmentBehavior = .never
+//        }
+//        return collectionView
+//    }()
+    
+    
+    override func createView() {
+//        addSubview(collectionView)
+//        collectionView.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
+    }
+
+    
+}
+
+//extension TSAIChatHistoryVC: UICollectionViewDataSource ,UICollectionViewDelegate {
+//    
+//    public func numberOfSections(in collectionView: UICollectionView) -> Int {
+//        return 1
+//    }
+//    
+//    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+//        return dataArray.count
+//    }
+//    
+//    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
+//        
+//        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: TSAIChatHistoryCell.cellID, for: indexPath)
+//        if let cell = cell as? TSAIChatHistoryCell,let colorModel = dataArray.safeObj(At: indexPath.item){
+//            cell.colorModel = colorModel
+//        }
+//        return cell
+//    }
+//
+//    public func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
+//        if let colorModel = dataArray.safeObj(At: indexPath.item){
+//            selectedColorComplete?(colorModel)
+//            currentIndexPath = indexPath
+//        }
+//    }
+//}
+//
+//
+//class TSAIChatHistoryCell: SwipeCollectionViewCell {
+//    
+//    static let cellID = "TSAIChatHistoryCell"
+//
+//    override var isSelected: Bool{
+//        didSet{
+//            imageView.isHidden = !isSelected
+//        }
+//    }
+//    
+//    
+//    lazy var imageView: UIImageView = {
+//        let imageView = UIImageView.createImageView(imageName: "select")
+//        imageView.isHidden = true
+//        return imageView
+//    }()
+//    
+//    lazy var shapeImageView: UIImageView = {
+//        let imageView = UIImageView.createImageView(imageName: "")
+//        imageView.isHidden = true
+//        return imageView
+//    }()
+//
+//    lazy var colorView: UIView = {
+//        let colorView = UIView()
+//        return colorView
+//    }()
+//    
+//    override func creatUI() {
+//        
+//        contentView.addSubview(shapeImageView)
+//        shapeImageView.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
+//
+//        contentView.addSubview(colorView)
+//        colorView.snp.makeConstraints { make in
+//            make.edges.equalToSuperview()
+//        }
+//        
+//        colorView.cornerRadius = self.bounds.size.width/2
+//        
+//        bgContentView.addSubview(imageView)
+//        imageView.snp.makeConstraints { make in
+//            make.width.height.equalTo(24.0)
+//            make.center.equalToSuperview()
+//        }
+//        
+//    }
+//}

+ 79 - 0
AIEmoji/Business/AIChat/TSAIChatHistoryVC/VM/TSAIChatHistoryVM.swift

@@ -0,0 +1,79 @@
+//
+//  TSAIChatHistoryVM.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/12.
+//
+
+class TSAIChatHistoryVM {
+    
+    lazy var historyChatList: [TSDBAIChatList] = {
+        let list = TSDBAIChatList.getAll()
+        return list
+    }()
+    
+    
+    
+    
+    
+    func getTimeCategorieslist(list:[TSDBAIChatList]) -> Void {
+        
+//        let categorizedDates = categorizeDates(sampleDates)
+//        print("今天: \(categorizedDates.today)")
+//        print("昨天: \(categorizedDates.yesterday)")
+//        print("一周内: \(categorizedDates.withinWeek)")
+//        print("30 天内: \(categorizedDates.within30Days)")
+        
+        
+        
+        
+        
+        
+        
+        
+        
+        
+    }
+    
+    
+    
+    
+//    func categorizeDates(_ dates: [Date]) -> (today: [TSDBAIChatList], yesterday: [TSDBAIChatList], withinWeek: [TSDBAIChatList], within30Days: [TSDBAIChatList]) {
+//        let calendar = Calendar.current
+//        let now = Date()
+//        let todayStart = calendar.startOfDay(for: now)
+//        let yesterdayStart = calendar.date(byAdding: .day, value: -1, to: todayStart)!
+//        let oneWeekAgo = calendar.date(byAdding: .day, value: -7, to: todayStart)!
+//        let thirtyDaysAgo = calendar.date(byAdding: .day, value: -30, to: todayStart)!
+//        
+//        var todayDates: [TSDBAIChatList] = []
+//        var yesterdayDates: [TSDBAIChatList] = []
+//        var withinWeekDates: [TSDBAIChatList] = []
+//        var within30DaysDates: [TSDBAIChatList] = []
+//        
+//        for model in historyChatList {
+//            if let date = model.creatDate {
+//                let dateStart = calendar.startOfDay(for: date)
+//                if dateStart == todayStart {
+//                    todayDates.append(model)
+//                } else if dateStart == yesterdayStart {
+//                    yesterdayDates.append(model)
+//                } else if dateStart > oneWeekAgo {
+//                    withinWeekDates.append(model)
+//                } else if dateStart > thirtyDaysAgo {
+//                    within30DaysDates.append(model)
+//                }
+//            }
+//        }
+//        
+//        todayDates = todayDates.sorted { $0.creatDate ?? Date() > $1.creatDate ?? Date()}
+//        yesterdayDates = yesterdayDates.sorted { $0.creatDate > $1.creatDate }
+//        withinWeekDates = withinWeekDates.sorted { $0.creatDate > $1.creatDate }
+//        within30DaysDates = within30DaysDates.sorted { $0.creatDate > $1.creatDate }
+//        
+//        return (today: todayDates, yesterday: yesterdayDates, withinWeek: withinWeekDates, within30Days: within30DaysDates)
+//    }
+    
+    
+    
+}

+ 2 - 114
AIEmoji/Business/AIChat/TSChatViewController/Models/MockMessage.swift

@@ -20,94 +20,14 @@
 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 // SOFTWARE.
 
-import AVFoundation
-import CoreLocation
 import Foundation
 import MessageKit
 import UIKit
-
-// MARK: - CoordinateItem
-
-private struct CoordinateItem: LocationItem {
-  var location: CLLocation
-  var size: CGSize
-
-  init(location: CLLocation) {
-    self.location = location
-    size = CGSize(width: 240, height: 240)
-  }
-}
-
-// MARK: - ImageMediaItem
-
-private struct ImageMediaItem: MediaItem {
-  var url: URL?
-  var image: UIImage?
-  var placeholderImage: UIImage
-  var size: CGSize
-
-  init(image: UIImage) {
-    self.image = image
-    size = CGSize(width: 240, height: 240)
-    placeholderImage = UIImage()
-  }
-
-  init(imageURL: URL) {
-    url = imageURL
-    size = CGSize(width: 240, height: 240)
-    placeholderImage = UIImage(imageLiteralResourceName: "image_message_placeholder")
-  }
-}
-
-// MARK: - MockAudioItem
-
-private struct MockAudioItem: AudioItem {
-  var url: URL
-  var size: CGSize
-  var duration: Float
-
-  init(url: URL) {
-    self.url = url
-    size = CGSize(width: 160, height: 35)
-    // compute duration
-    let audioAsset = AVURLAsset(url: url)
-    duration = Float(CMTimeGetSeconds(audioAsset.duration))
-  }
-}
-
-// MARK: - MockContactItem
-
-struct MockContactItem: ContactItem {
-  var displayName: String
-  var initials: String
-  var phoneNumbers: [String]
-  var emails: [String]
-
-  init(name: String, initials: String, phoneNumbers: [String] = [], emails: [String] = []) {
-    displayName = name
-    self.initials = initials
-    self.phoneNumbers = phoneNumbers
-    self.emails = emails
-  }
-}
-
-// MARK: - MockLinkItem
-
-struct MockLinkItem: LinkItem {
-  let text: String?
-  let attributedText: NSAttributedString?
-  let url: URL
-  let title: String?
-  let teaser: String
-  let thumbnailImage: UIImage
-}
-
 // MARK: - TSChatMessage
-
 internal class TSChatMessage: MessageType {
   // MARK: Lifecycle
 
-    private init(kind: MessageKind, user: TSChatUser, messageId: String, date: Date) {
+    init(kind: MessageKind, user: TSChatUser, messageId: String, date: Date) {
         self.kind = kind
         self.user = user
         self.messageId = messageId
@@ -126,39 +46,6 @@ internal class TSChatMessage: MessageType {
         self.init(kind: .attributedText(attributedText), user: user, messageId: messageId, date: date)
     }
 
-    convenience init(image: UIImage, user: TSChatUser, messageId: String, date: Date) {
-        let mediaItem = ImageMediaItem(image: image)
-        self.init(kind: .photo(mediaItem), user: user, messageId: messageId, date: date)
-    }
-
-    convenience init(imageURL: URL, user: TSChatUser, messageId: String, date: Date) {
-        let mediaItem = ImageMediaItem(imageURL: imageURL)
-        self.init(kind: .photo(mediaItem), user: user, messageId: messageId, date: date)
-    }
-
-    convenience init(thumbnail: UIImage, user: TSChatUser, messageId: String, date: Date) {
-        let mediaItem = ImageMediaItem(image: thumbnail)
-        self.init(kind: .video(mediaItem), user: user, messageId: messageId, date: date)
-    }
-
-    convenience init(location: CLLocation, user: TSChatUser, messageId: String, date: Date) {
-        let locationItem = CoordinateItem(location: location)
-        self.init(kind: .location(locationItem), user: user, messageId: messageId, date: date)
-    }
-
-    convenience init(emoji: String, user: TSChatUser, messageId: String, date: Date) {
-        self.init(kind: .emoji(emoji), user: user, messageId: messageId, date: date)
-    }
-
-    convenience init(audioURL: URL, user: TSChatUser, messageId: String, date: Date) {
-        let audioItem = MockAudioItem(url: audioURL)
-        self.init(kind: .audio(audioItem), user: user, messageId: messageId, date: date)
-    }
-
-    convenience init(contact: MockContactItem, user: TSChatUser, messageId: String, date: Date) {
-        self.init(kind: .contact(contact), user: user, messageId: messageId, date: date)
-    }
-
     convenience init(linkItem: LinkItem, user: TSChatUser, messageId: String, date: Date) {
         self.init(kind: .linkPreview(linkItem), user: user, messageId: messageId, date: date)
     }
@@ -173,3 +60,4 @@ internal class TSChatMessage: MessageType {
     }
     var sendState: TSProgressState = .none
 }
+

+ 8 - 5
AIEmoji/Business/AIChat/TSChatViewController/Models/TSChatUser.swift

@@ -22,10 +22,13 @@
 
 import Foundation
 import MessageKit
-
-struct TSChatUser: SenderType, Equatable {
-    var senderId: String
-    var displayName: String
+struct TSChatUser: SenderType {
+    var senderId: String = ""
+    var displayName: String = ""
+    
+    init(senderId: String, displayName: String) {
+        self.senderId = senderId
+        self.displayName = displayName
+    }
 }
 
-let kUserSender = TSChatUser(senderId: "001", displayName: "001")

+ 180 - 0
AIEmoji/Business/AIChat/TSChatViewController/Models/TSDBAIChatList.swift

@@ -0,0 +1,180 @@
+//
+//  TSDBAIChatList.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/10.
+//
+
+import RealmSwift
+import MessageKit
+
+//MARK: TSDBAIChatList - 用于存储会话及消息列表
+class TSDBAIChatList: Object {
+    @objc dynamic var sessionId = UUID().uuidString
+    dynamic var messages = List<TSDBChatMessage>()
+    dynamic var creatDate:Int = 0
+    
+    
+    
+    lazy var messageList: [TSChatMessage] = {
+        return getMessageList()
+    }()
+    
+    override static func primaryKey() -> String? {
+        return "sessionId"
+    }
+
+    //获取 App 层的 最新的 TSChatMessage 数组
+    func getMessageListLatestData() {
+        messageList = getMessageList()
+    }
+    
+    //获取 App 层的 TSChatMessage 数组
+    func getMessageList() -> [TSChatMessage] {
+        var msgModel:[TSChatMessage] = []
+        for msgDBModel in messages {
+            msgModel.append(msgDBModel.getTSChatMessage())
+        }
+        return msgModel
+    }
+    
+    //添加 App 层的 TSChatMessage 数组
+    func updateMessageList(list:[TSChatMessage]){
+        messages.removeAll()
+        for model in list {
+            messages.append(getTSDBChatMessage(chatMsg: model))
+        }
+        TSRMShared.update(self)
+    }
+    
+    func delete() {
+        TSRMShared.delete(self)
+    }
+    
+    
+    func updateMessage(msgModel:TSChatMessage){
+        TSRMShared.writeThread {
+            if creatDate == 0 {
+                creatDate = Date.timestampInt
+            }
+            let dbModel = getTSDBChatMessage(chatMsg: msgModel)
+            if let index = messages.firstIndex(where: { $0.messageId == dbModel.messageId }) {
+                messages[index] = dbModel// 如果找到,替换该元素
+            } else {
+                messages.append(dbModel)// 如果没有找到,添加到末尾
+            }
+        }
+        TSRMShared.update(self)
+    }
+    
+}
+
+
+extension TSDBAIChatList {
+    
+    static func getOneDB() -> TSDBAIChatList{
+        let dbModel = TSDBAIChatList()
+//        TSRMShared.create(dbModel)
+        return dbModel
+    }
+    
+    //获取所有储存的 TSDBAIChatList
+    static func getAll() -> [TSDBAIChatList] {
+        var list:[TSDBAIChatList] = []
+        let allPersons = TSRMShared.read(TSDBAIChatList.self)
+        for person in allPersons {
+            list.append(person)
+        }
+        return list
+    }
+}
+
+extension TSDBAIChatList {
+    
+    func getTSDBChatMessage(chatMsg:TSChatMessage) -> TSDBChatMessage {
+        let dbModel = TSDBChatMessage()
+        dbModel.messageId = chatMsg.messageId
+        dbModel.sentDate = chatMsg.sentDate
+        dbModel.kind = chatMsg.kind.kindString
+        dbModel.user = TSDBChatUser(senderId: chatMsg.user.senderId, displayName: chatMsg.user.displayName)
+        dbModel.messageId = chatMsg.messageId
+        
+        return dbModel
+    }
+    
+}
+
+
+//MARK: extension
+extension MessageKind {
+    static func fromString(_ string: String) -> MessageKind {
+        if string == "text" {
+            return .text("")
+        } else if string == "attributedText" {
+            return .attributedText(NSAttributedString())
+        } else if string == "emoji" {
+            return .emoji("")
+        } else {
+            return .custom(nil)
+        }
+    }
+    
+    
+    var kindString:String{
+        switch self {
+            case .text(let text), .emoji(let text): return text
+            default: return ""
+        }
+    }
+    
+    
+    static func textKind(_ string: String) -> MessageKind {
+        return .text("")
+    }
+    
+}
+
+
+// TSChatMessage - 用于存储聊天消息
+class TSDBChatMessage: Object {
+    @objc dynamic var messageId: String = UUID().uuidString
+    @objc dynamic var sentDate: Date = Date()
+    @objc dynamic var kind: String = ""
+    @objc dynamic var user: TSDBChatUser? = TSDBChatUser(senderId: "", displayName: "")
+
+    override static func primaryKey() -> String? {
+        return "messageId"
+    }
+    
+    func getTSChatMessage() -> TSChatMessage {
+        let model = TSChatMessage(kind: .textKind(kind), user: user!.getTSChatUser(), messageId: messageId, date: sentDate)
+        return model
+    }
+    
+    override init() {
+        super.init()
+    }
+    
+}
+
+class TSDBChatUser: Object {
+    @objc dynamic var senderId: String = ""
+    @objc dynamic var displayName: String = ""
+    
+    func getTSChatUser() -> TSChatUser {
+        let user = TSChatUser(senderId: senderId, displayName: displayName)
+        return user
+    }
+    
+    init(senderId: String, displayName: String) {
+        self.senderId = senderId
+        self.displayName = displayName
+    }
+    
+    override init() {
+        super.init()
+    }
+}
+
+
+

+ 17 - 9
AIEmoji/Business/AIChat/TSChatViewController/TSChatViewController.swift

@@ -72,7 +72,9 @@ class TSChatViewController: MessagesViewController, MessagesDataSource {
 
   func loadFirstMessages() {
       //获取消息数量
-
+      self.messageList = viewModel.getHistoryChatMessage()
+      self.messagesCollectionView.reloadData()
+      self.messagesCollectionView.scrollToLastItem(animated: false)
   }
 
   @objc
@@ -143,7 +145,7 @@ class TSChatViewController: MessagesViewController, MessagesDataSource {
 extension TSChatViewController {
 
     var currentSender: SenderType {
-        return kUserSender
+        return viewModel.kUserSender
     }
     
     func numberOfSections(in _: MessagesCollectionView) -> Int {
@@ -248,16 +250,18 @@ extension TSChatViewController: InputBarAccessoryViewDelegate {
     // MARK: Private
 
     private func sendMessages(_ data: [Any]) {
-        let user = kUserSender
+        let user = viewModel.kUserSender
         for component in data {
           if let str = component as? String {
               let message = TSChatMessage(text: str, user: user, messageId: UUID().uuidString, date: Date())
               insertMessage(message)
+              //保存这条消息到本地数据库
+              viewModel.updateMessage(msgModel: message)
               //发送消息后,进行AI 对话生成
               generativeAIChat(message: message)
           } else if let img = component as? UIImage {
-              let message = TSChatMessage(image: img, user: user, messageId: UUID().uuidString, date: Date())
-              insertMessage(message)
+//              let message = TSChatMessage(image: img, user: user, messageId: UUID().uuidString, date: Date())
+//              insertMessage(message)
           }
         }
     }
@@ -275,8 +279,8 @@ extension TSChatViewController: InputBarAccessoryViewDelegate {
             return
         }
         
-        let aiUser = TSChatUser(senderId: "000", displayName: "AI")
-        let message = TSChatMessage(text: "...", user: aiUser, messageId: UUID().uuidString, date: Date())
+
+        let message = TSChatMessage(text: "...", user: viewModel.kAIUser, messageId: UUID().uuidString, date: Date())
         message.sendState = .start
         insertMessage(message)
         
@@ -291,9 +295,13 @@ extension TSChatViewController: InputBarAccessoryViewDelegate {
             guard let self = self else { return }
             if let netData = data {
                 message.sendState = .success("netData")
+                
+                //保存这条消息到本地数据库
+                viewModel.updateMessage(msgModel: message)
             }else {
                 message.kind = .text(kAIErrorString)
                 message.sendState = .failed(kAIErrorString)
+                viewModel.updateMessage(msgModel: message)
             }
             
             updataAIChatCellUI()
@@ -302,7 +310,7 @@ extension TSChatViewController: InputBarAccessoryViewDelegate {
     
     func updataAIChatCell(string:String){
         
-        guard var generativeAIMessage = messageList.last else { return }
+        guard let generativeAIMessage = messageList.last else { return }
         var message = ""
         if case let .text(msg) = generativeAIMessage.kind {
             message = msg + string
@@ -324,7 +332,7 @@ extension TSChatViewController: InputBarAccessoryViewDelegate {
             }
             
             if self.isLastSectionVisible() == true {
-                self.messagesCollectionView.scrollToLastItem(animated: true)
+                self.messagesCollectionView.scrollToLastItem(animated: false)
             }
         }
     }

+ 49 - 10
AIEmoji/Business/AIChat/TSChatViewController/ViewModel/TSAIChatVM.swift

@@ -4,23 +4,40 @@
 //
 //  Created by 100Years on 2025/2/9.
 //
-import Alamofire
+
+
+
+let kAIErrorString = "Server is busy, please try again later".localized
 class TSAIChatVM {
-    
-    
+
+    enum UIStype {
+        case chat
+        case onlyRead
+    }
+        
+    lazy var dbAIChatList: TSDBAIChatList = {
+        let dbAIChatList = TSDBAIChatList.getOneDB()
+        return dbAIChatList
+    }()
+
+    var uiStyle:UIStype = UIStype.chat
     var streamRequest:StreamPostRequest?
     
-    var sessionId = "001"
+    let kAIUser = TSChatUser(senderId: "000", displayName: "AI")
+    let kUserSender = TSChatUser(senderId: "001", displayName: "001")
+}
+
 
+//MARK: AI 聊天请求
+extension TSAIChatVM {
+    
     func sendChatMessage(
         message:String,
         streamHandler:@escaping (String) -> Void,
         completion: @escaping (Any?, Error?) -> Void
     ) {
-        // URL 和请求参数
-        let url = "http://ai.100yearslater.com/api/text/chat"
         let parameters: [String: String] = [
-            "sessionId": sessionId,
+            "sessionId": dbAIChatList.sessionId,
             "message": message
         ]
         streamRequest = TSNetworkShared.postStream(urlType: .chat,parameters: parameters) { string in
@@ -38,9 +55,31 @@ class TSAIChatVM {
     func stopAiGenerate () {
         streamRequest?.stopRequest()
     }
-
 }
 
+//MARK: 数据存储
+extension TSAIChatVM {
+    
+    func getHistoryChatMessage() -> [TSChatMessage] {
+        if uiStyle == .onlyRead {
+            return self.dbAIChatList.messageList
+        }else {
+            let aiString = "I can tackle your questions, my skillset includes, but is not limited to:\n\n📧 Composing high-quality emails  \n🇺🇸 Facilitating language learning  \n📑 Assisting in your studies  \n💡 Brainstorming ideas and much more!"
+            let msg = TSChatMessage(kind: .text(aiString), user: kAIUser, messageId: "", date: Date())
+            
+            return [msg]
+        }
+    }
+    
+    func updateMessage(msgModel:TSChatMessage){
+        
+        kExecuteOnMainThread {
+            //保存数据库
+            self.dbAIChatList.updateMessage(msgModel: msgModel)
+            //保存服务器
+        }
+        
 
-
-let kAIErrorString = "Server is busy, please try again later".localized
+    }
+   
+}

+ 1 - 1
AIEmoji/Business/LaunchVC/TSLaunchVC.swift

@@ -15,7 +15,7 @@ class TSLaunchVC: UIViewController {
     private var timer: DispatchSourceTimer?
     // 闪屏页剩余显示时长
     #if DEBUG
-        private var remindTimeInterval: TimeInterval = 2.0
+    private var remindTimeInterval: TimeInterval = 0.5
     #else
         private var remindTimeInterval: TimeInterval = 2.0
     #endif

+ 2 - 1
AIEmoji/Business/TSGenmojiVC/TSGenmojiGennerateVC/TSGenmojiGennerateViewModel.swift

@@ -7,13 +7,14 @@
 
 import Combine
 
-enum TSProgressState {
+enum TSProgressState  {
     case none
     case start
     case pending
     case progress(CGFloat)
     case success(Any?)
     case failed(String)
+
 }
 
 class TSGenmojiGennerateViewModel {

+ 9 - 1
AIEmoji/Common/Ex/Date+Ex.swift

@@ -18,7 +18,15 @@ extension Date {
     }
     
     static var timestampString: String {
-        return String(Int(Date().timeIntervalSince1970))
+        return String(timestampInt)
     }
 
+    
+    static var timestampInt: Int {
+        return Int(Date().timeIntervalSince1970)
+    }
+    
+    var timestampInt: Int {
+        return Int(self.timeIntervalSince1970)
+    }
 }

+ 1 - 1
AIEmoji/Common/GlobalImports/GlobalImports.swift

@@ -5,7 +5,7 @@
 //  Created by 100Years on 2024/12/20.
 //
 
-@_exported import Foundation
+//@_exported import Foundation
 @_exported import UIKit
 @_exported import SnapKit
 

+ 147 - 0
AIEmoji/Common/TSRealmManager/TSRealmManager.swift

@@ -0,0 +1,147 @@
+//
+//  TSRealmManager.swift
+//  AIEmoji
+//
+//  Created by 100Years on 2025/2/11.
+//
+
+import RealmSwift
+
+let TSRMShared = TSRealmManager.shared
+
+
+
+
+class TSRealmManager {
+    static let shared = TSRealmManager()
+    var realm: Realm
+
+    private init() {
+//        do {
+//            realm = try Realm()
+//        } catch {
+//            fatalError("Failed to initialize Realm: \(error)")
+//        }
+//        
+        
+        // 设置新的版本号
+        let newSchemaVersion: UInt64 = 3
+        // 获取默认配置
+        var config = Realm.Configuration.defaultConfiguration
+        // 设置新版本号
+        config.schemaVersion = newSchemaVersion
+        // 设置迁移块
+        config.migrationBlock = { migration, oldSchemaVersion in
+            if oldSchemaVersion < newSchemaVersion {
+                // 执行迁移操作
+            }
+        }
+        // 将修改后的配置设置为默认配置
+        Realm.Configuration.defaultConfiguration = config
+        
+        
+        do {
+            // 使用新配置打开 Realm 数据库
+            realm = try Realm()
+            print("Realm 数据库已成功打开,版本号: \(realm.configuration.schemaVersion)")
+        } catch {
+            fatalError("打开 Realm 数据库时出错: \(error)")
+        }
+        
+        
+    }
+
+    // 创建数据
+    func create<T: Object>(_ object: T) {
+        do {
+            try realm.write {
+                realm.add(object,update: .modified)
+            }
+        } catch {
+            print("Failed to create object: \(error)")
+        }
+    }
+
+    // 读取数据
+    func read<T: Object>(_ type: T.Type) -> Results<T> {
+        return realm.objects(type)
+    }
+
+    // 更新数据
+//    func update<T: Object>(_ object: T, with block: (T) -> Void) {
+//        do {
+//            try realm.write {
+//                block(object)
+//            }
+//        } catch {
+//            print("Failed to update object: \(error)")
+//        }
+//    }
+    
+    
+    func update<T: Object>(_ object: T) {
+        do {
+            try realm.write {
+                realm.add(object,update: .modified)
+            }
+        } catch {
+            print("Failed to update object: \(error)")
+        }
+    }
+
+    // 删除数据
+    func delete<T: Object>(_ object: T) {
+        do {
+            try realm.write {
+                realm.delete(object)
+            }
+        } catch {
+            print("Failed to delete object: \(error)")
+        }
+    }
+    
+    
+    func writeThread(wt: ()->Void) {
+ 
+//            do {
+//                try self.realm.write {
+//                    wt()
+//                }
+//            } catch {
+//                print("Failed to writeThread: \(error)")
+//            }
+        
+        do {
+            try Realm().write {
+                wt()
+            }
+        } catch {
+            print("Failed to writeThread: \(error)")
+        }
+        
+    }
+}
+
+
+/*
+// 创建数据
+let person = Person()
+person.name = "John"
+person.age = 30
+RealmManager.shared.create(person)
+// 读取数据
+let allPersons = RealmManager.shared.read(Person.self)
+for person in allPersons {
+    print("Name: \(person.name), Age: \(person.age)")
+}
+// 更新数据
+if let firstPerson = allPersons.first {
+    RealmManager.shared.update(firstPerson) { person in
+        person.age = 31
+    }
+}
+// 删除数据
+if let firstPerson = allPersons.first {
+    RealmManager.shared.delete(firstPerson)
+}
+*/

+ 4 - 2
Podfile

@@ -11,8 +11,8 @@ target 'AIEmoji' do
   pod 'ObjectMapper'
   pod 'SnapKit'
   pod 'SVProgressHUD'
-  pod 'Kingfisher'
-  pod 'Alamofire', '~> 5.4.4'
+  pod 'Kingfisher', '7.10.0'
+  pod 'Alamofire', '5.6.4'
   pod 'MJRefresh'
   pod 'IQKeyboardManagerSwift'
   pod 'JXSegmentedView'
@@ -20,6 +20,8 @@ target 'AIEmoji' do
   pod 'Masonry'
   pod 'SwiftyMarkdown'
   pod 'RealmSwift', '~>10'
+  pod 'SwipeCellKit'
+#  pod 'TSSmalCoacopods', :path => '../TSSmalCoacopods'
 end
 
 

+ 21 - 11
Podfile.lock

@@ -1,5 +1,5 @@
 PODS:
-  - Alamofire (5.4.4)
+  - Alamofire (5.6.4)
   - IQKeyboardCore (1.0.5)
   - IQKeyboardManagerSwift (8.0.0):
     - IQKeyboardManagerSwift/Appearance (= 8.0.0)
@@ -42,30 +42,36 @@ PODS:
     - IQKeyboardToolbar/Placeholderable
   - JXPagingView/Paging (2.1.3)
   - JXSegmentedView (1.4.1)
-  - Kingfisher (8.1.3)
-  - MarkdownView (1.9.1)
+  - Kingfisher (7.10.0)
   - Masonry (1.1.0)
   - MJRefresh (3.7.9)
   - ObjectMapper (4.4.2)
+  - Realm (10.54.2):
+    - Realm/Headers (= 10.54.2)
+  - Realm/Headers (10.54.2)
+  - RealmSwift (10.54.2):
+    - Realm (= 10.54.2)
   - SnapKit (5.7.1)
   - SVProgressHUD (2.3.1):
     - SVProgressHUD/Core (= 2.3.1)
   - SVProgressHUD/Core (2.3.1)
   - SwiftyMarkdown (1.2.4)
+  - SwipeCellKit (2.7.1)
 
 DEPENDENCIES:
-  - Alamofire (~> 5.4.4)
+  - Alamofire (= 5.6.4)
   - IQKeyboardManagerSwift
   - JXPagingView/Paging
   - JXSegmentedView
-  - Kingfisher
-  - MarkdownView
+  - Kingfisher (= 7.10.0)
   - Masonry
   - MJRefresh
   - ObjectMapper
+  - RealmSwift (~> 10)
   - SnapKit
   - SVProgressHUD
   - SwiftyMarkdown
+  - SwipeCellKit
 
 SPEC REPOS:
   trunk:
@@ -81,16 +87,18 @@ SPEC REPOS:
     - JXPagingView
     - JXSegmentedView
     - Kingfisher
-    - MarkdownView
     - Masonry
     - MJRefresh
     - ObjectMapper
+    - Realm
+    - RealmSwift
     - SnapKit
     - SVProgressHUD
     - SwiftyMarkdown
+    - SwipeCellKit
 
 SPEC CHECKSUMS:
-  Alamofire: f3b09a368f1582ab751b3fff5460276e0d2cf5c9
+  Alamofire: 4e95d97098eacb88856099c4fc79b526a299e48c
   IQKeyboardCore: 28c8bf3bcd8ba5aa1570b318cbc4da94b861711e
   IQKeyboardManagerSwift: 0c6fbbaa2e60739e48d7cf59f25661471a7a3a65
   IQKeyboardNotification: d7382c4466c5a5adef92c7452ebf861b36050088
@@ -101,15 +109,17 @@ SPEC CHECKSUMS:
   IQTextView: ae13b4922f22e6f027f62c557d9f4f236b19d5c7
   JXPagingView: afdd2e9af09c90160dd232b970d603cc6e7ddd0e
   JXSegmentedView: cd73555ce2134d1656db2cb383ba9c2f36fb5078
-  Kingfisher: f2af9028b16baf9dc6c07c570072bc41cbf009ef
-  MarkdownView: 22249778219cc22901f1454e8355298dd0bda7f0
+  Kingfisher: a18f05d3b6d37d8650ee4a3e61d57a28fc6207f6
   Masonry: 678fab65091a9290e40e2832a55e7ab731aad201
   MJRefresh: ff9e531227924c84ce459338414550a05d2aea78
   ObjectMapper: e6e4d91ff7f2861df7aecc536c92d8363f4c9677
+  Realm: 16852517a207e98cc6acba9336b56c30d06d84ad
+  RealmSwift: bca777b3904ee58a9b16036e1840012f03348060
   SnapKit: d612e99e678a2d3b95bf60b0705ed0a35c03484a
   SVProgressHUD: 4837c74bdfe2e51e8821c397825996a8d7de6e22
   SwiftyMarkdown: 7cdec87c6ab5cd9ea0e22ced288e889960649ba5
+  SwipeCellKit: 3972254a826da74609926daf59b08d6c72e619ea
 
-PODFILE CHECKSUM: fb3b545ddff07a5339fc12bcf8e3efd3833a4eb7
+PODFILE CHECKSUM: 2affa4be0aabb44f2aef33dbf27a56e7e3259a25
 
 COCOAPODS: 1.16.2