Comprendere il ruolo dei delegati delle app e delle delegazioni sceniche nello sviluppo di iOS

Dal momento che le prime versioni di iOS, il UIApplicationDelegate protocollo è stato la spina dorsale di iOS app lifecycle gestione. Tuttavia, l'introduzione di multi-fine supporto in iOS 13 fondamentalmente cambiato come gli sviluppatori gestire le interfacce utente.

Cos'è un Delegato di App?

Il App Delegate[[]] è il punto di ingresso e coordinatore centrale per un'applicazione iOS. Si conforme al protocollo [] ed è responsabile per la gestione di eventi di app di alto livello che interessano l'intera applicazione.

Metodi del ciclo di vita del nucleo

L'App Delegate definisce diversi metodi critici che il sistema chiama in risposta alle modifiche dello stato dell'app:

  • ][] – Chiamato dopo che l'app ha lanciato. Questo è dove inizializzi SDK di terze parti, configura gli stack di dati di base, imposta l'aspetto globale e ripristina lo stato dell'applicazione.
  • ][] – Invocato quando l'applicazione passa da stato inattivo a stato attivo.
  • [][] – Chiamato quando l'applicazione sta per diventare inattiva (ad esempio, chiamata in arrivo, l'utente preme il pulsante Lock).
  • ][] — Inviare quando l'applicazione si sposta sullo sfondo. Eseguire la pulizia finale, rilasciare risorse condivise e pianificare le attività di sfondo.
  • ][] – Chiamato poco prima che l'app ritorni in primo piano dopo essere stato sottofondo.
  • ][] – Invocato quando l'applicazione sta per essere terminata. Salvare i dati critici e le risorse di rilascio. Nota: questo non è chiamato sulle versioni iOS moderne per le applicazioni in background a meno che non specificamente ucciso.

Responsabilità aggiuntive

Oltre alla gestione del ciclo di vita, l'App Delegate gestisce diversi servizi app-wide:

  • Notifiche locali e remoti:[] Registrati per le notifiche remote tramite []] e gestisci le notifiche in arrivo con .
  • Handling URLs and Handoff:[] L'App Delegate risponde a schemi URL personalizzati e Link universali attraverso e gestisce l'attività di Handoff tramite .
  • Avvertenze di memoria:[] permette all'app di rilasciare cache, immagini e altre risorse monouso.
  • Background Fetch:[] Implementazione ] per scaricare i contenuti periodicamente mentre l'applicazione è in background.
  • Gruppi di connessione e app:[]] Coordinate la condivisione dei dati tra l'app iOS e il compagno Watch app attraverso l'App Delegata.

Contesto storico

Prima di iOS 13, l'App Delegate è stato anche responsabile della gestione dell'istanza singola finestra dell'app. Gli sviluppatori hanno impostato il controller di visualizzazione root all'interno . Questo design era semplice ma limitante - non poteva supportare più finestre simultanee. L'introduzione di scene in iOS 13 ha spostato la gestione delle finestre per separare gli oggetti del delegato, lasciando l'App Delegate libero di concentrarsi esclusivamente su domande app.

Cos'è un delegato della scena?

Con iOS 13 e iPadOS 13, Apple ha introdotto il protocollo UISceneDelegate[] per supportare più finestre per app. Una scena rappresenta un’istanza dell’interfaccia utente della tua app, solitamente sostenuta da un oggetto . Ogni scena ha il suo ciclo di vita e può essere visualizzata su un display separato o in uno spazio separato su iPad.

Abilitare il supporto multi-Window

Per utilizzare le scene, è necessario optare per configurare la vostra app con il tasto “Application Scene Manifest” . Questo manifesto definisce le configurazioni della scena, inclusi i nomi delle classi delegate e i ruoli di sessione. Senza questo manifesto, iOS tratta l'applicazione come singola finestra e continua ad utilizzare l'eredità App Delegate finestra gestione.

Metodi del ciclo di vita della scena core

Il Delegato di scena implementa metodi analoghi al Delegato di App ma indirizzati ad una scena:

  • ][] – Chiamato quando una nuova scena sta per essere aggiunta all'app. Questo è dove si imposta il controllore di visualizzazione della scena e l'interfaccia utente iniziale. Si riceve un oggetto che fornisce informazioni sull'URL, l'attività, o la scorciatoia che ha innescato la scena.
  • [] – La scena diventa attiva (in primo piano e in focus).
  • ][] – La scena sta per diventare inattiva (ad esempio, gesto multitasking, app switcher).
  • [] – La scena si sposta sullo sfondo.
  • [] – La scena sta per diventare attiva in primo piano.
  • [] – Chiamato quando il sistema rimuove la scena dall'app (ad esempio, l'utente chiude una finestra su iPad, o l'applicazione si sposta su sfondo e il sistema decide di scartare la scena).

Sessioni e ruoli scenici

Ogni scena è associata ad un oggetto ] che persiste tra i lanci. Le sessioni possono essere riutilizzate o create di nuovo. La sessione contiene una proprietà [ che indica se la scena è per l'interfaccia principale dell'app ()]) o un display esterno (]).

Delegato di scena in SwiftUI

Per le app SwiftUI, il Delegato di scena è spesso auto-generato quando si avvia un nuovo progetto di destinazione iOS 14+. Tuttavia, è possibile ancora creare un Delegato di scena personalizzato utilizzando il wrapper di proprietà nella vostra struttura .

Differenze chiave tra Delegato di App e Delegato di scena

Mentre entrambi i delegati gestiscono il ciclo di vita, la loro portata e le loro responsabilità differiscono in modo significativo:

  • Scope:[] L'App Delegate opera a livello di processo di applicazione; c'è solo uno per app. Il Delegato di scena opera a livello di scena (o finestra); si può avere più delegati di scena in esecuzione simultanea.
  • Introduzione:[[] App Delegate esiste da iOS 2. Scene Delegate è stato introdotto in iOS 13 per consentire il supporto multi-finestra.
  • Window Management:[] Nelle app legacy, l'App Delegate possiede la finestra. Nelle app basate sulla scena, ogni Delegato di scena possiede la finestra della sua scena. L'App Delegate non accede più direttamente alla finestra.
  • Conservazione degli stati:[[]] Le applicazioni che utilizzano le scene dovrebbero implementare la conservazione e il restauro dello stato a livello della scena (tramite []] o ]), non solo attraverso il Delegato dell'App.
  • Attività di sfondo:[ In generale, le attività di sfondo possono essere attivate a livello app (via App Delegate) o per-scene (via Scene Delegate). Tuttavia, alcune modalità di sfondo come fetch di sfondo sono ancora gestite dal Delegato dell'App.

Come funzionano insieme in un'app moderna

In una app iOS basata su scene, l'App Delegate and Scene Delegate forma un'architettura a strati. L'App Delegate inizializza l'infrastruttura condivisa - registrazione, analisi, database core - e gestisce eventi che non appartengono a una scena particolare. Quando il sistema ha bisogno di visualizzare nuovi contenuti, crea una scena e associa un Delegato di scena. La scena del Delegato costruisce quindi l'interfaccia utente e si collega alla scena.

Coordinamento durante il lancio

Quando un utente apre l'app, il sistema chiama l'App Delegate []. Dopo questo ritorno, il sistema crea una scena e chiama sul Delegato della scena. Se l'applicazione viene riaperta tramite Handoff o una scorciatoia, il fornisce l'attività, URL o attività utente all'appropriata Scene Delegate.

Restauro di Stato Tra le scene

Ogni scena dovrebbe codificare il suo stato utilizzando nel metodo del Delegato della scena []. Il Delegato dell'App è responsabile della fornitura di tipi di attività tramite quando si crea una sessione di scena. Questo coordinamento assicura che le scene riaperte restituiscano i loro contenuti, ad esempio, un'applicazione di documento può riaprire il file esatto dell'utente.

Gestione di display esterni

Su iPad, una scena può essere creata su un monitor esterno tramite “AirPlay” o “Sidecar”. Controllando il ruolo [, il Delegato di scena può regolare la sua interfaccia utente per abbinare la risoluzione e le funzionalità del display esterno.

Esempio pratico: Impostare un'App iOS basata su scene

Passiamo attraverso i passaggi per configurare una nuova app UIKit con i delegati della scena. Assumiamo che si sta partendo da un progetto Xcode vuoto con l'opzione "Use Scene Delegate" abilitata.

Passo 1: Configurazione Info.plist

Xcode automatically adds the “Application Scene Manifest” entry. Open the Info.plist and verify it contains a dictionary with:

  • Abilita Windows Multipla[]: Sì (se vuoi consentire più finestre; altrimenti NO).
  • Configurazioni sceniche[[[]: Una serie di dizionari, ciascuno definendo un ruolo di scena (ad esempio, “Window Application”) e un nome di classe delegata (ad esempio, “$(PRODUCT MODULE NAME).SceneDelegate”).

Per un'app a finestra singola, è possibile lasciare più finestre disattivate, ma è ancora necessario la configurazione della scena per utilizzare Scene Delegate.

Passo 2: App di implementazione Delegato

In , rimuovere qualsiasi proprietà finestra. Invece, implementare solo metodi app-wide:

import UIKit

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
 func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
 // Configure analytics, core data, third-party SDKs
 return true
 }

 func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
 // Return a scene configuration to use for the new scene
 return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
 }

 func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
 // Called when the user discards a scene (e.g., closing a window)
 }
}

Passo 3: Esecuzione Scena Delegato

, gestire il ciclo di vita della finestra e della scena:

import UIKit

class SceneDelegate: UIResponder, UIWindowSceneDelegate {
 var window: UIWindow?

 func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
 guard let windowScene = (scene as? UIWindowScene) else { return }
 let window = UIWindow(windowScene: windowScene)
 let viewController = ViewController()
 window.rootViewController = viewController
 self.window = window
 window.makeKeyAndVisible()
 }

 func sceneDidDisconnect(_ scene: UIScene) {
 // Called when the scene is being removed from the app
 }

 func sceneDidBecomeActive(_ scene: UIScene) {
 // Resume tasks
 }

 func sceneWillResignActive(_ scene: UIScene) {
 // Pause tasks
 }
}

Passo 4: Gestione delle opzioni di connessione delle scene

in ] fornisce collegamenti, contesti URL e attività utente. Ad esempio, per aprire un documento specifico quando l'utente tocca un file:

if let urlContext = connectionOptions.urlContexts.first {
 // Intialize a document viewer with the URL
 urlContext.url.startAccessingSecurityScopedResource()
 // Load document and set root view controller
}

Questa separazione mantiene la magra App Delegate e ogni Delegato di scena si concentra sulla propria finestra.

Migliori Pratiche e Pitfalls Comuni

Quando utilizzare App Delegato vs. Scene Delegato

  • Utilizzare l'App Delegate per l'inizializzazione che deve accadere esattamente una volta per il lancio di app, come il reporting di crash, l'autenticazione degli utenti o la migrazione di database.
  • Utilizzare il Delegato di scena per l'installazione dell'interfaccia utente, l'istantanea del controller di vista e la gestione dello stato specifica della scena.
  • non]] accedere alla finestra condivisa ; invece, recuperare la finestra dal delegato della scena attiva.

Migrazione da Legacy Apps

Se hai un'applicazione a finestra esistente che utilizza l'App Delegate per la gestione delle finestre, puoi adottare scene aggiungendo il codice relativo alla scena e alla finestra in movimento a un nuovo Scene Delegate.

Considerazioni di memoria e performance

Su iPad, il sistema può disconnettere le scene quando la memoria è bassa. Implement [] per rilasciare risorse specifiche della scena. Evitare di memorizzare grandi cache o dati nel Delegato della scena; utilizzare l'App Delegate per le cache di tutto l'app che possono sopravvivere alla disconnessione della scena.

Delegati di gestione in SwiftUI

In SwiftUI, è possibile allegare un Delegato App personalizzato tramite []. Tuttavia, per la gestione della scena, SwiftUI utilizza automaticamente la configurazione della scena predefinita. Se avete bisogno di comportamenti personalizzati (ad esempio, gestire contesti URL per finestra), creare una classe conforme a e assegnarlo nel manifesto o tramite il

Conclusioni

[Segui] [Scegli] [Scegli] [[Scegli]]] [L'Applicata] fornisce un unico punto di controllo per gli eventi a livello di applicazione, mentre i Delegati Scene gestiscono il ciclo di vita e l'interfaccia utente per-finestra.