swift
151 lines · 2 tabs
Sofia Martinez
Jan 2026
2 tabs
import UIKit
class SceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
var appCoordinator: AppCoordinator?
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
guard let windowScene = scene as? UIWindowScene else { return }
let window = UIWindow(windowScene: windowScene)
self.window = window
// Initialize app coordinator
let coordinator = AppCoordinator(window: window)
self.appCoordinator = coordinator
coordinator.start()
// Handle URL if app opened via deep link
if let urlContext = connectionOptions.urlContexts.first {
handleDeepLink(url: urlContext.url)
}
// Handle notification if app opened from notification
if let notification = connectionOptions.notificationResponse {
handleNotification(response: notification)
}
}
func sceneDidDisconnect(_ scene: UIScene) {
// Scene disconnected - release resources
print("Scene disconnected")
}
func sceneDidBecomeActive(_ scene: UIScene) {
// Scene became active - resume tasks, refresh UI
print("Scene became active")
NotificationCenter.default.post(name: .appDidBecomeActive, object: nil)
}
func sceneWillResignActive(_ scene: UIScene) {
// Scene about to become inactive - pause tasks
print("Scene will resign active")
}
func sceneWillEnterForeground(_ scene: UIScene) {
// Scene entering foreground - refresh data
print("Scene will enter foreground")
}
func sceneDidEnterBackground(_ scene: UIScene) {
// Scene entered background - save data
print("Scene did enter background")
CoreDataStack.shared.saveContext()
}
func scene(_ scene: UIScene, openURLContexts URLContexts: Set<UIOpenURLContext>) {
guard let url = URLContexts.first?.url else { return }
handleDeepLink(url: url)
}
private func handleDeepLink(url: URL) {
// Parse deep link and navigate
// Example: myapp://post/123
if url.scheme == "myapp",
url.host == "post",
let postId = Int(url.lastPathComponent) {
NotificationCenter.default.post(
name: .navigateToPost,
object: nil,
userInfo: ["postId": postId]
)
}
}
private func handleNotification(response: UNNotificationResponse) {
let userInfo = response.notification.request.content.userInfo
if let postId = userInfo["post_id"] as? Int {
NotificationCenter.default.post(
name: .navigateToPost,
object: nil,
userInfo: ["postId": postId]
)
}
}
}
extension Notification.Name {
static let appDidBecomeActive = Notification.Name("appDidBecomeActive")
}
import SwiftUI
@main
struct MyApp: App {
@StateObject private var appState = AppState()
@Environment(\.scenePhase) private var scenePhase
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(appState)
.onOpenURL { url in
handleDeepLink(url: url)
}
}
.onChange(of: scenePhase) { oldPhase, newPhase in
switch newPhase {
case .active:
print("App became active")
appState.refreshData()
case .inactive:
print("App became inactive")
case .background:
print("App entered background")
appState.saveData()
@unknown default:
break
}
}
}
private func handleDeepLink(url: URL) {
// Handle deep linking
appState.handleDeepLink(url: url)
}
}
class AppState: ObservableObject {
@Published var selectedTab = 0
@Published var deepLinkPost: Int?
func refreshData() {
// Refresh app data when becoming active
}
func saveData() {
// Persist data when entering background
CoreDataStack.shared.saveContext()
}
func handleDeepLink(url: URL) {
if url.scheme == "myapp",
url.host == "post",
let postId = Int(url.lastPathComponent) {
deepLinkPost = postId
}
}
}
2 files · swift
Explain with highlit
iOS 13 introduced scene-based lifecycle for multi-window support on iPad. The App and Scene delegates handle different lifecycle events. SceneDelegate manages individual scenes—windows on iPad or the single window on iPhone. It responds to state transitions like foreground, background, and disconnect. AppDelegate handles app-level events like launch and termination. For SwiftUI apps, I use @main with App protocol and scene modifiers like .onOpenURL() for deep links. Background tasks require specific capabilities and scheduling with BGTaskScheduler. Understanding the lifecycle prevents bugs around state restoration, data persistence, and resource management.
Related snips
swift
import Combine
import Foundation
class SearchViewModel: ObservableObject {
@Published var searchQuery = ""
@Published var results: [SearchResult] = []
Combine operators for data transformation
swift
combine
reactive
by Sofia Martinez
1 tab
swift
import SwiftUI
struct ContentView: View {
@State private var username = ""
@State private var isLoggedIn = false
@StateObject private var viewModel = LoginViewModel()
SwiftUI declarative UI with state management
swift
swiftui
ios
by Sofia Martinez
2 tabs
swift
import SwiftUI
struct CardModifier: ViewModifier {
var backgroundColor: Color = .white
var cornerRadius: CGFloat = 12
var shadowRadius: CGFloat = 5
Custom SwiftUI view modifiers for reusability
swift
swiftui
ios
by Sofia Martinez
2 tabs
swift
import Foundation
import UIKit
class ImageProcessor {
// Background processing with main thread updates
func processImage(_ image: UIImage, completion: @escaping (UIImage?) -> Void) {
Grand Central Dispatch for concurrency
swift
gcd
concurrency
by Sofia Martinez
1 tab
swift
import SwiftUI
enum Route: Hashable {
case postDetail(id: Int)
case userProfile(id: Int)
case settings
Navigation patterns with NavigationStack
swift
swiftui
navigation
by Sofia Martinez
2 tabs
swift
import UIKit
import WebKit
class WebViewController: UIViewController {
private var webView: WKWebView!
private var progressView: UIProgressView!
WKWebView for web content display
swift
wkwebview
webkit
by Sofia Martinez
1 tab
Share this code
Here's the card — post it anywhere.