MVVM vs The Composable Architecture (TCA)
Deux des patterns architecturaux les plus populaires en iOS s'affrontent : le MVVM traditionnel face au TCA fonctionnel de Point-Free. Comment choisir la bonne architecture ?
L'avenir d'Apple : déclaratif, réactif, multiplateforme
15 ans de robustesse éprouvée au combat, un framework puissant et mature
| Catégorie | SwiftUI | UIKit |
|---|---|---|
| Performance | 8/10 | 10/10 |
| Facilité d'apprentissage | 8/10 | 5/10 |
| Écosystème | 8/10 | 9/10 |
| Communauté | 8/10 | 9/10 |
| Marché de l'emploi | 8/10 | 9/10 |
| Pérennité | 10/10 | 6/10 |
// SwiftUI - Carte de profil utilisateur
import SwiftUI
struct ProfileCard: View {
@StateObject private var viewModel = ProfileViewModel()
@State private var isFollowing = false
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HStack {
AsyncImage(url: viewModel.user.avatarURL) { image in
image.resizable().scaledToFill()
} placeholder: {
ProgressView()
}
.frame(width: 64, height: 64)
.clipShape(Circle())
VStack(alignment: .leading) {
Text(viewModel.user.name)
.font(.headline)
Text(viewModel.user.title)
.font(.subheadline)
.foregroundStyle(.secondary)
}
Spacer()
Button(isFollowing ? "Takipten Çık" : "Takip Et") {
withAnimation(.spring(response: 0.3)) {
isFollowing.toggle()
}
}
.buttonStyle(.bordered)
.tint(isFollowing ? .gray : .blue)
}
}
.padding()
.background(.regularMaterial)
.clipShape(RoundedRectangle(cornerRadius: 16))
}
}// UIKit - Carte de profil utilisateur
import UIKit
class ProfileCardViewController: UIViewController {
private let avatarImageView: UIImageView = {
let iv = UIImageView()
iv.contentMode = .scaleAspectFill
iv.clipsToBounds = true
iv.layer.cornerRadius = 32
iv.translatesAutoresizingMaskIntoConstraints = false
return iv
}()
private let nameLabel: UILabel = {
let label = UILabel()
label.font = .preferredFont(forTextStyle: .headline)
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
private lazy var followButton: UIButton = {
var config = UIButton.Configuration.bordered()
config.title = "Takip Et"
let btn = UIButton(configuration: config)
btn.addTarget(self, action: #selector(followTapped), for: .touchUpInside)
btn.translatesAutoresizingMaskIntoConstraints = false
return btn
}()
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
loadUserData()
}
private func setupUI() {
view.addSubview(avatarImageView)
view.addSubview(nameLabel)
view.addSubview(followButton)
NSLayoutConstraint.activate([
avatarImageView.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 16),
avatarImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor),
avatarImageView.widthAnchor.constraint(equalToConstant: 64),
avatarImageView.heightAnchor.constraint(equalToConstant: 64)
])
}
@objc private func followTapped() {
UIView.animate(withDuration: 0.3) {
self.followButton.alpha = 0.5
} completion: { _ in
UIView.animate(withDuration: 0.3) { self.followButton.alpha = 1 }
}
}
}En 2025, SwiftUI devrait être privilégié pour les nouveaux projets ; tout l'investissement d'Apple va dans cette direction. Cependant, des exigences personnalisées complexes, un support en dessous d'iOS 13 ou une grande base de code legacy imposent encore UIKit. Approche idéale : essayer SwiftUI en premier, et intégrer un composant UIKit via UIViewRepresentable si nécessaire.
Obtenir une consultation gratuiteOui. UIHostingController permet d'intégrer une vue SwiftUI dans UIKit, et UIViewRepresentable permet d'intégrer une vue UIKit dans SwiftUI. L'approche hybride est courante sur les grands projets.