仿微信朋友圈demo
仿微信朋友圈demo
1.项目介绍本项目是一个简化的微信朋友圈demo,主要功能包括用户登录、发布动态、评论、点赞等。该项目使用Swift编写,并且基于Xcode11.4进行开发。
2.项目结构```swiftCircleDemo/
CircleDemo.xcodeproj Assets.xcassets Images/
LoginBackground.png LoginLogo.png ...
Models/
User.swift Post.swift Comment.swift ...
Networking/
APIManager.swift Request.swift Response.swift ...
Services/
UserService.swift PostService.swift CommentService.swift ...
Views/
LoginViewController.swift HomeViewController.swift PostDetailViewController.swift ...
Controllers/
LoginController.swift HomeController.swift PostController.swift ...
Helpers/
Extensions.swift Utilities.swift ...
Resources/
Info.plist LaunchScreen.storyboard Main.storyboard ...
```
3.登录界面3.1 登录背景和Logo```swift// LoginBackground.png// LoginLogo.png```
3.2 登录表单```swiftimport UIKitclass LoginViewController: UIViewController {
@IBOutlet weak var usernameTextField: UITextField!
@IBOutlet weak var passwordTextField: UITextField!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
}
@IBAction func loginButtonTapped(_ sender: UIButton) {
guard let username = usernameTextField.text, !username.isEmpty,
let password = passwordTextField.text, !password.isEmpty else { return }
// Login logic here }
}
```
4.主界面4.1 动态列表```swiftimport UIKitclass HomeViewController: UIViewController {
@IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Load posts from API PostService.shared.loadPosts { [weak self] (posts, error) in if let error = error {
print("Error loading posts: (error)")
return }
DispatchQueue.main.async {
self?.tableView.reloadData()
}
}
}
@IBAction func addPostButtonTapped(_ sender: UIButton) {
// Show post creation view controller }
}
```
4.2 动态详情```swiftimport UIKitclass PostDetailViewController: UIViewController {
@IBOutlet weak var postImageView: UIImageView!
@IBOutlet weak var postTextView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Load post data from API PostService.shared.loadPost(postId) { [weak self] (post, error) in if let error = error {
print("Error loading post: (error)")
return }
DispatchQueue.main.async {
self?.postImageView.image = post.image self?.postTextView.text = post.text }
}
}
@IBAction func likeButtonTapped(_ sender: UIButton) {
// Like post logic here }
}
```
5.评论和点赞```swiftimport UIKitclass PostController: UIViewController {
@IBOutlet weak var commentTextView: UITextView!
@IBOutlet weak var likeButton: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
// Load comments from API CommentService.shared.loadComments(postId) { [weak self] (comments, error) in if let error = error {
print("Error loading comments: (error)")
return }
DispatchQueue.main.async {
self?.commentTextView.text = comments.map { $0.text }.joined(separator: "
")
}
}
}
@IBAction func commentButtonTapped(_ sender: UIButton) {
// Create new comment logic here }
@IBAction func likeButtonTapped(_ sender: UIButton) {
// Like post logic here }
}
```
6.网络请求```swiftimport Foundationclass APIManager {
static let shared = APIManager()
private init() {}
func loadPosts(completion: @escaping ([Post], Error?) -> Void) {
guard let url = URL(string: " else { return }
URLSession.shared.dataTask(with: url) { data, response, error in if let error = error {
completion([], error)
return }
do {
let posts = try JSONDecoder().decode([Post].self, from: data!)
completion(posts, nil)
} catch {
completion([], error)
}
}.resume()
}
func loadPost(postId: Int, completion: @escaping (Post?, Error?) -> Void) {
guard let url = URL(string: " else { return }
URLSession.shared.dataTask(with: url) { data, response, error in if let error = error {
completion(nil, error)
return }
do {
let post = try JSONDecoder().decode(Post.self, from: data!)
completion(post, nil)
} catch {
completion(nil, error)
}
}.resume()
}
func loadComments(postId: Int, completion: @escaping ([Comment], Error?) -> Void) {
guard let url = URL(string: " else { return }
URLSession.shared.dataTask(with: url) { data, response, error in if let error = error {
completion([], error)
return }
do {
let comments = try JSONDecoder().decode([Comment].self, from: data!)
completion(comments, nil)
} catch {
completion([], error)
}
}.resume()
}
}
```
7.服务类```swiftimport Foundationclass PostService {
static let shared = PostService()
private init() {}
func loadPosts(completion: @escaping ([Post], Error?) -> Void) {
APIManager.shared.loadPosts { [weak self] (posts, error) in if let error = error {
completion([], error)
return }
DispatchQueue.main.async {
self?.processPosts(posts, completion: completion)
}
}
}
func loadPost(postId: Int, completion: @escaping (Post?, Error?) -> Void) {
APIManager.shared.loadPost(postId: postId) { [weak self] (post, error) in if let error = error {
completion(nil, error)
return }
DispatchQueue.main.async {
self?.processPost(post, completion: completion)
}
}
}
func loadComments(postId: Int, completion: @escaping ([Comment], Error?) -> Void) {
APIManager.shared.loadComments(postId: postId) { [weak self] (comments, error) in if let error = error {
completion([], error)
return }
DispatchQueue.main.async {
self?.processComments(comments, completion: completion)
}
}
}
private func processPosts(_ posts: [Post], completion: @escaping ([Post], Error?) -> Void) {
// Process posts here completion(posts, nil)
}
private func processPost(_ post: Post?, completion: @escaping (Post?, Error?) -> Void) {
// Process post here completion(post, nil)
}
private func processComments(_ comments: [Comment], completion: @escaping ([Comment], Error?) -> Void) {
// Process comments here completion(comments, nil)
}
}
```
8.模型类```swiftimport Foundationclass Post: Codable {
var id: Int var text: String var image: UIImage?
init(id: Int, text: String) {
self.id = id self.text = text }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
text = try container.decode(String.self, forKey: .text)
}
}
class Comment: Codable {
var id: Int var text: String init(id: Int, text: String) {
self.id = id self.text = text }
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
id = try container.decode(Int.self, forKey: .id)
text = try container.decode(String.self, forKey: .text)
}
}
```
9.扩展类```swiftimport Foundationextension Post {
convenience init(id: Int, text: String, image: UIImage?) {
self.init(id: id, text: text)
self.image = image }
}
extension Comment {
convenience init(id: Int, text: String) {
self.init(id: id, text: text)
}
}
```
10.其他类```swiftimport Foundationclass UserService {
static let shared = UserService()
private init() {}
func loadUser(completion: @escaping