I'm encountering a memory leak issue in my SwiftUI app when using the Map view. Every time I navigate to the Map screen, the memory consumption spikes by approximately 120MB. I suspect there might be a problem with how I'm handling the Map view or its associated state variables.
Here's a simplified version of my code:
struct MapView: View {
@State private var mapRegion: MKCoordinateRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 51.507222, longitude: -0.1275), span: MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5))
var viewModel: MapVM?
var body: some View {
VStack(alignment: .leading) {
Text("Map")
.foregroundStyle(.black)
Map(coordinateRegion: $mapRegion, interactionModes: [.zoom, .pan])
.frame(height: 300)
.cornerRadius(10)
.clipped()
// Buttons for changing the delta
// Buttons for dismissing the viewController via delegate.
// viewModel.delegate.dissmissViewController()
}
}
}
// Root VC:
protocol HomeDelgate: AnyObject {
func navigateForSearch()
func navigateForMapView()
}
class HomeVC: UIViewController {
var viewModel: HomeVM?
override func viewDidLoad() {
super.viewDidLoad()
viewModel?.delegate = self
guard let viewModel else {return}
let homeView = HomeView(viewModel: viewModel)
let homeHC = UIHostingController(rootView: homeView)
homeHC.view.translatesAutoresizingMaskIntoConstraints = false
self.addChild(homeHC)
self.view.addSubview(homeHC.view)
homeHC.didMove(toParent: self)
homeHC.view.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
homeHC.view.topAnchor.constraint(equalTo: view.topAnchor),
homeHC.view.leadingAnchor.constraint(equalTo: view.leadingAnchor),
homeHC.view.trailingAnchor.constraint(equalTo: view.trailingAnchor),
homeHC.view.bottomAnchor.constraint(equalTo: view.bottomAnchor)
])
}
class func instantiate() -> HomeVC {
let vc = UIStoryboard.home.instanceOf(viewController: self)!
vc.viewModel = HomeVM()
return vc
}
}
extension HomeVC: HomeDelgate {
func navigateForSearch() {
let vc = SearchVC.instantiate()
self.navigationController?.pushViewController(vc, animated: true)
}
func navigateForPropertiesDetails() {
let vc = MapVC.instantiate()
self.present(vc, animated: true)
}
}
// RootViewModel
class HomeVM: ObservableObject {
weak var delegate: HomeDelgate?
}
// HomeView
struct HomeView: View {
@ObservedObject var viewModel: HomeVM
var body: some View {
ZStack {
Color.white
ScrollView(.vertical, showsIndicators: false) {
ZStack {
Color.primary.opacity(0.05)
VStack {
HomeHeaderView(location: "A123, North Street, Southern West")
HomePropertisView()
.onTapGesture {
// Navigation call for MapView
viewModel.delegate?.navigateForMapView()
}
RecommendedCardContainerView()
Spacer()
}
}
.ignoresSafeArea(.all, edges: .bottom)
}
.clipped()
}
}
}
Upon further investigation, I've found that each time I navigate away from the Map view, the memory isn't being released properly, leading to this gradual increase in memory consumption.
I tried to create a singleton view for map but swift is not allowing me to that. Probably my approach was wrong.
Can anyone help me identify the source of this memory leak and provide guidance on how to fix it? Any insights or alternative approaches to handle the Map view in SwiftUI would be greatly appreciated. Thank you!