Leggere in inglese

Condividi tramite


App Center Distribute : aggiornamenti in-app per iOS

Importante

Visual Studio App Center è pianificato per il ritiro il 31 marzo 2025. Anche se è possibile continuare a usare Visual Studio App Center fino a quando non viene completamente ritirato, esistono diverse alternative consigliate a cui è possibile prendere in considerazione la migrazione.

Altre informazioni sulle sequenze temporali di supporto e sulle alternative.

App Center Distribute consentirà agli utenti di installare una nuova versione dell'app quando la distribuisci tramite App Center. Con una nuova versione dell'app disponibile, l'SDK presenterà una finestra di dialogo di aggiornamento per gli utenti per scaricare o posticipare la nuova versione. Dopo aver scelto di eseguire l'aggiornamento, l'SDK inizierà ad aggiornare l'applicazione.

Nota

Quando si usano gli aggiornamenti in-app, è necessario considerare alcuni aspetti:

  1. Se l'app è stata rilasciata nel App Store, gli aggiornamenti in-app verranno disabilitati.
  2. Se si eseguono test automatizzati dell'interfaccia utente, gli aggiornamenti in-app abilitati bloccano i test automatizzati dell'interfaccia utente man mano che proveranno a eseguire l'autenticazione nel back-end di App Center. È consigliabile non abilitare App Center Distribute per la destinazione di test dell'interfaccia utente.

Nota

4.0.0 Nella versione di App Center sono state introdotte modifiche di rilievo. Seguire la sezione Eseguire la migrazione ad App Center SDK 4.0.0 e versioni successive per eseguire la migrazione di App Center dalle versioni precedenti.

Importante

App Center SDK non supporta più app finestra introdotte in iOS 13.

Aggiungere aggiornamenti in-app all'app

Se l'SDK non è stato configurato nell'applicazione, seguire la sezione Introduzione .

1. Aggiungere il modulo App Center Distribute

App Center SDK è progettato con un approccio modulare. È sufficiente integrare i moduli dei servizi a cui si è interessati.

Integrazione tramite Cocoapods

Se si sta integrando App Center nell'app tramite Cocoapods, aggiungere la dipendenza seguente al podfile ed eseguire pod install.

pod 'AppCenter/Distribute'

Integrazione tramite Carthage

  1. Aggiungere la dipendenza seguente a per Cartfile includere App Center Distribute.

    # Use the following line to get the latest version of App Center
    github "microsoft/appcenter-sdk-apple"
    
    # Use the following line to get the specific version of App Center
    github "microsoft/appcenter-sdk-apple" ~> X.X.X
    
  2. Eseguire carthage update.

  3. Aprire la scheda Impostazioni generali della destinazione dell'applicazione. Trascinare e rilasciare il file AppCenterDistribute.framework dalla cartella Carthage/Build/iOS alla sezione Framework e librerie collegate in XCode.

  4. Trascinare AppCenterDistributeResources.bundle da AppCenterDistribute.framework in Project Navigator di XCode.

  5. Verrà visualizzata una finestra di dialogo, assicurarsi che la destinazione dell'app sia selezionata. Fare clic su Fine.

Integrazione tramite Swift Package Manager

  1. Scegliere File > Swift Packages > Add Package Dependency dal menu Xcode.
  2. Nella finestra di dialogo visualizzata immettere l'URL del repository: https://github.com/microsoft/appcenter-sdk-apple.git.
  3. In Versione selezionare Fino al successivo principale e scegliere l'opzione predefinita.
  4. Scegliere AppCenterDistribute nella colonna Pacchetto prodotto .

Integrazione tramite copia dei file binari nel progetto

Se non si vuole usare Cocoapods, è possibile integrare i moduli copiando i file binari nel progetto. Seguire la procedura descritta di seguito:

Nota

App Center SDK supporta l'uso di XCframework. Per integrare XCframeworks nel progetto, scaricare il AppCenter-SDK-Apple-XCFramework.zip dalla pagina delle versioni e decomprimerlo. Il contenuto della cartella risultante non è specifico della piattaforma, ma contiene XCframeworks per ogni modulo. Possono essere integrati allo stesso modo dei normali framework, come descritto di seguito.

  1. Scaricare i framework di App Center SDK forniti come file ZIP.

  2. Decomprimere il file e verrà visualizzata una cartella denominata AppCenter-SDK-Apple/iOS che contiene framework diversi per ogni servizio App Center. Il framework chiamato AppCenter è necessario nel progetto perché contiene codice condiviso tra i diversi moduli.

  3. [Facoltativo] Creare una sottodirectory per le librerie di terze parti.

    • Come procedura consigliata, le librerie di terze parti si trovano in genere all'interno di una sottodirectory, spesso denominata Vendor. Se il progetto non è organizzato con una sottodirectory per le librerie, creare ora una sottodirectory Vendor .
    • Creare un gruppo denominato Vendor all'interno del progetto Xcode per simulare la struttura di file su disco.
  4. Aprire Finder e copiare la cartella AppCenter-SDK-Apple/iOS decompressa nella cartella del progetto nel percorso desiderato.

  5. Aggiungere il framework SDK al progetto in Xcode:

    • Assicurarsi che Lo strumento di spostamento progetti sia visibile (⌘+1).
    • Trascinare quindi AppCenter.framework, AppCenterDistribute.framework e AppCenterDistributeResources.bundle dal Finder (quelli all'interno della cartella Vendor ) in Project Navigator di Xcode. AppCenter.framework è necessario per avviare l'SDK. Assicurarsi che venga aggiunto al progetto. In caso contrario, gli altri moduli non funzioneranno e il progetto non verrà compilato correttamente.
    • Verrà visualizzata una finestra di dialogo, assicurarsi che la destinazione dell'app sia selezionata. Fare clic su Fine.

2. Avviare App Center Distribute

App Center usa solo i moduli specifici richiamati nell'applicazione. È necessario chiamare in modo esplicito ognuno di essi all'avvio dell'SDK.

2.1 Aggiungere l'importazione per App Center Distribute

Aprire il file AppDelegate.m del progetto nel file Objective-C o AppDelegate.swift in Swift e aggiungere le istruzioni import seguenti:

@import AppCenter;
@import AppCenterDistribute;
import AppCenter
import AppCenterDistribute

2.2 Aggiungere il start:withServices: metodo

Aggiungere Distribute al start:withServices: metodo per avviare il servizio App Center Distribute.

Inserire la riga seguente per avviare l'SDK nella classe AppDelegate.m del progetto per la classe Objective-C o AppDelegate.swift per Swift nel didFinishLaunchingWithOptions metodo .

[MSACAppCenter start:@"{Your App Secret}" withServices:@[[MSACDistribute class]]];
AppCenter.start(withAppSecret: "{Your App Secret}", services: [Distribute.self])

Assicurarsi di aver sostituito {Your App Secret} nell'esempio di codice precedente con il segreto dell'app. Vedere anche la sezione Introduzione se l'SDK non è stato configurato nell'applicazione.

2.3 Modificare info.plist del progetto

  1. Nel file Info.plist del progetto aggiungere una nuova chiave per URL types facendo clic sul pulsante "+" accanto a "Elenco proprietà informazioni" nella parte superiore. Se Xcode visualizza info.plist come codice sorgente, fare riferimento al suggerimento seguente.
  2. Modificare il tipo di chiave in Matrice.
  3. Aggiungere una nuova voce alla matrice (Item 0) e modificare il tipo in Dizionario.
  4. In Item 0aggiungere una URL Schemes chiave e modificare il tipo in Matrice.
  5. Sotto la URL Schemes chiave aggiungere una nuova voce (Item 0).
  6. In URL Schemes>Item 0modificare il valore appcenter-{APP_SECRET} in e sostituire {APP_SECRET} con il segreto dell'app.

Suggerimento

Se si vuole verificare che l'info.plist sia stato modificato correttamente, aprirlo come codice sorgente. Deve contenere la voce seguente con il segreto dell'app anziché {APP_SECRET}:

<key>CFBundleURLTypes</key>
<array>
  <dict>
  	<key>CFBundleURLSchemes</key>
  	<array>
  		<string>appcenter-{APP_SECRET}</string>
  	</array>
  </dict>
</array>

Usare un gruppo di distribuzione privato

Per impostazione predefinita, Distribute usa un gruppo di distribuzione pubblico. Se si vuole usare un gruppo di distribuzione privato, è necessario impostarlo in modo esplicito tramite updateTrack la proprietà .

MSACDistribute.updateTrack = MSACUpdateTrackPrivate;
Distribute.updateTrack = .private

Nota

Il valore predefinito è UpdateTrack.public. Questa proprietà può essere aggiornata solo prima della chiamata al AppCenter.start metodo. Le modifiche apportate alla traccia di aggiornamento non vengono mantenute al riavvio del processo dell'applicazione, pertanto se la proprietà non viene sempre aggiornata prima della AppCenter.start chiamata, sarà pubblica per impostazione predefinita.

Dopo questa chiamata, verrà aperta una finestra del browser per autenticare l'utente. Tutti i controlli di aggiornamento successivi otterranno la versione più recente sulla traccia privata.

Se un utente è sulla traccia privata, significa che dopo l'autenticazione completata, otterrà la versione più recente da qualsiasi gruppo di distribuzione privato di cui è membro. Se un utente è sulla traccia pubblica, significa che otterrà la versione più recente da qualsiasi gruppo di distribuzione pubblico.

Disabilitare il controllo automatico per l'aggiornamento

Per impostazione predefinita, l'SDK verifica automaticamente la presenza di nuove versioni:

  • All'avvio dell'applicazione.
  • Quando l'applicazione entra in background, in primo piano.
  • Quando si abilita il modulo Distribuisci se in precedenza è disabilitato.

Se si vuole verificare manualmente la disponibilità di nuove versioni, è possibile disabilitare il controllo automatico per l'aggiornamento. A tale scopo, chiamare il metodo seguente prima dell'avvio dell'SDK:

[MSACDistribute disableAutomaticCheckForUpdate];
Distribute.disableAutomaticCheckForUpdate()

Nota

Questo metodo deve essere chiamato prima della chiamata al AppCenter.start metodo.

È quindi possibile usare l'API checkForUpdate descritta nella sezione seguente.

Controllare manualmente la disponibilità di aggiornamenti

[MSACDistribute checkForUpdate];
Distribute.checkForUpdate()

In questo modo viene inviata una richiesta ad App Center e viene visualizzata una finestra di dialogo di aggiornamento nel caso in cui sia disponibile una nuova versione.

Nota

Un controllo manuale della chiamata di aggiornamento funziona anche quando sono abilitati gli aggiornamenti automatici. Un controllo manuale per l'aggiornamento viene ignorato se è già in corso un altro controllo. Il controllo manuale per l'aggiornamento non verrà elaborato se l'utente ha posticipato gli aggiornamenti (a meno che la versione più recente non sia un aggiornamento obbligatorio).

Personalizzare o localizzare la finestra di dialogo di aggiornamento in-app

1. Personalizzare o localizzare il testo

È possibile specificare facilmente stringhe di risorse personalizzate se si vuole localizzare il testo visualizzato nella finestra di dialogo di aggiornamento. Esaminare questo file di stringhe. Usare la stessa stringa nome/chiave e specificare il valore localizzato da riflettere nella finestra di dialogo nei file di stringhe dell'app.

2. Personalizzare la finestra di dialogo di aggiornamento

È possibile personalizzare l'aspetto della finestra di dialogo di aggiornamento predefinita implementando il DistributeDelegate protocollo. È necessario registrare il delegato prima di avviare l'SDK, come illustrato nell'esempio seguente:

[MSACDistribute setDelegate:self];
Distribute.delegate = self;

Di seguito è riportato un esempio dell'implementazione del delegato che sostituisce la finestra di dialogo SDK con un'implementazione personalizzata:

- (BOOL)distribute:(MSACDistribute *)distribute releaseAvailableWithDetails:(MSACReleaseDetails *)details {

  // Your code to present your UI to the user, e.g. an UIAlertController.
  UIAlertController *alertController = [UIAlertController
      alertControllerWithTitle:@"Update available."
                       message:@"Do you want to update?"
                preferredStyle:UIAlertControllerStyleAlert];

  [alertController
      addAction:[UIAlertAction actionWithTitle:@"Update"
                                         style:UIAlertActionStyleCancel
                                       handler:^(UIAlertAction *action) {
                                         [MSACDistribute notifyUpdateAction:MSACUpdateActionUpdate];
                                       }]];

  [alertController
      addAction:[UIAlertAction actionWithTitle:@"Postpone"
                                         style:UIAlertActionStyleDefault
                                       handler:^(UIAlertAction *action) {
                                         [MSACDistribute notifyUpdateAction:MSACUpdateActionPostpone];
                                       }]];

  // Show the alert controller.
  [self.window.rootViewController presentViewController:alertController animated:YES completion:nil];
  return YES;
}
func distribute(_ distribute: Distribute, releaseAvailableWith details: ReleaseDetails) -> Bool {

  // Your code to present your UI to the user, e.g. an UIAlertController.
  let alertController = UIAlertController(title: "Update available.",
                                        message: "Do you want to update?",
                                 preferredStyle:.alert)

  alertController.addAction(UIAlertAction(title: "Update", style: .cancel) {_ in
    Distribute.notify(.update)
  })

  alertController.addAction(UIAlertAction(title: "Postpone", style: .default) {_ in
    Distribute.notify(.postpone)
  })

  // Show the alert controller.
  self.window?.rootViewController?.present(alertController, animated: true)
  return true;
}

Nel caso in cui venga restituito YES/true nel metodo precedente, l'app deve ottenere la scelta dell'utente e invitare l'SDK con il risultato usando l'API seguente.

// Depending on the user's choice, call notifyUpdateAction: with the right value.
[MSACDistribute notifyUpdateAction:MSACUpdateActionUpdate];
[MSACDistribute notifyUpdateAction:MSACUpdateActionPostpone];
// Depending on the user's choice, call notify() with the right value.
Distribute.notify(.update);
Distribute.notify(.postpone);

Se non chiami il metodo precedente, il releaseAvailableWithDetails:metodo -si ripeterà ogni volta che l'app entra in primo piano.

3. Eseguire il codice se non vengono trovati aggiornamenti

Nei casi in cui l'SDK controlla la disponibilità di aggiornamenti e non trova aggiornamenti disponibili più recenti di quelli attualmente usati, viene richiamato un distributeNoReleaseAvailable: callback da MSACDistributeDelegate delegato. In questo modo è possibile eseguire codice personalizzato in tali scenari.

Ecco alcuni esempi che illustrano come visualizzare l'interfaccia utente degli avvisi quando non vengono trovati aggiornamenti:

- (void)distributeNoReleaseAvailable:(MSACDistribute *)distribute {
  UIAlertController *alert = [UIAlertController alertControllerWithTitle:nil
                                                                 message:NSLocalizedString(@"No updates available", nil)
                                                          preferredStyle:UIAlertControllerStyleAlert];
  [alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"OK", nil) style:UIAlertActionStyleDefault handler:nil]];
  [self.window.rootViewController presentViewController:alert animated:YES completion:nil];
}
  func distributeNoReleaseAvailable(_ distribute: Distribute) {
    let alert = UIAlertController(title: nil, message: "No updates available", preferredStyle: .alert)
    alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
    self.window?.rootViewController?.present(alert, animated: true)
  }

Abilitare o disabilitare App Center Distribute in fase di esecuzione

È possibile abilitare e disabilitare App Center Distribute in fase di esecuzione. Se la si disabilita, l'SDK non fornirà alcuna funzionalità di aggiornamento in-app, ma è comunque possibile usare il servizio Distribuisci nel portale di App Center.

[MSACDistribute setEnabled:NO];
Distribute.enabled = false

Per abilitare di nuovo App Center Distribute, usare la stessa API ma passare YES/true come parametro.

[MSACDistribute setEnabled:YES];
Distribute.enabled = true

Lo stato viene salvato in modo permanente nella risorsa di archiviazione del dispositivo tra i lanci dell'applicazione.

Nota

Questo metodo deve essere utilizzato solo dopo Distribute l'avvio.

Controllare se App Center Distribute è abilitato

È anche possibile controllare se App Center Distribute è abilitato o meno:

BOOL enabled = [MSACDistribute isEnabled];
var enabled = Distribute.enabled

Nota

Questo metodo deve essere utilizzato solo dopo Distribute l'avvio, ma restituirà false sempre prima dell'avvio.

Non inizializzare App Center Distribute durante lo sviluppo

Se in modalità privata, App Center Distribute aprirà l'interfaccia utente o il browser all'avvio dell'applicazione. Anche se si tratta di un comportamento previsto per gli utenti finali, potrebbe comportare interruzioni durante la fase di sviluppo dell'applicazione. Non è consigliabile inizializzare Distribute per la DEBUG configurazione.

#if DEBUG
    [MSACAppCenter start:@"{Your App Secret}" withServices:@[[MSACAnalytics class], [MSACCrashes class]]];
#else
    [MSACAppCenter start:@"{Your App Secret}" withServices:@[[MSACAnalytics class], [MSACCrashes class], [MSACDistribute class]]];
#endif
#if DEBUG
    AppCenter.start(withAppSecret: "{Your App Secret}", services: [Analytics.self, Crashes.self])
#else
    AppCenter.start(withAppSecret: "{Your App Secret}", services: [Analytics.self, Crashes.self, Distribute.self])
#endif

Eseguire la pulizia subito prima della chiusura dell'applicazione per l'aggiornamento

Implementare il DistributeDelegate protocollo e registrare il delegato come illustrato nell'esempio seguente:

[MSACDistribute setDelegate:self];
Distribute.delegate = self;

Il distributeWillExitApp: metodo delegato verrà chiamato subito prima che l'app venga terminata per l'installazione dell'aggiornamento:

- (void)distributeWillExitApp:(MSACDistribute *)distribute {
  // Perform the required clean up here.
}
func distributeWillExitApp(_ distribute: Distribute) {
  // Perform the required clean up here.
}

Come funzionano gli aggiornamenti in-app?

Nota

Per il funzionamento degli aggiornamenti in-app, è necessario scaricare una compilazione dell'app dal collegamento. Non funzionerà se installato da un IDE o manualmente.

La funzionalità aggiornamenti in-app funziona come segue:

  1. Questa funzionalità funzionerà SOLO con le compilazioni distribuite tramite il servizio Distribuzione App Center . Non funzionerà quando il debugger è collegato o se la funzionalità accesso guidato iOS è attivata.

  2. Dopo aver integrato l'SDK, compilare una versione di rilascio dell'app e caricarla in App Center, gli utenti del gruppo di distribuzione riceveranno una notifica per la nuova versione tramite posta elettronica.

  3. Quando ogni utente apre il collegamento nel messaggio di posta elettronica, l'applicazione verrà installata nel dispositivo. È importante che usino il collegamento di posta elettronica per installare l'app: App Center Distribute non supporta gli aggiornamenti in-app per le app installate da altre origini,ad esempio il download dell'app da un allegato di posta elettronica. Quando un'applicazione viene scaricata dal collegamento, l'SDK salva informazioni importanti dai cookie per verificare la disponibilità di aggiornamenti in un secondo momento, altrimenti l'SDK non dispone di tali informazioni chiave.

  4. Se l'applicazione imposta la traccia su privata, verrà aperto un browser per autenticare l'utente e abilitare gli aggiornamenti in-app. Il browser non si riaprirà finché le informazioni di autenticazione rimangono valide anche quando si torna alla traccia pubblica e si torna nuovamente a privato in un secondo momento. Se l'autenticazione del browser ha esito positivo, l'utente viene reindirizzato automaticamente all'applicazione. Se la traccia è pubblica (ovvero l'impostazione predefinita), il passaggio successivo viene eseguito direttamente.

    • In iOS 9 e 10, un'istanza di SFSafariViewController verrà aperta all'interno dell'app per autenticare l'utente. Si chiuderà automaticamente dopo l'esito positivo dell'autenticazione.
    • In iOS 11 l'esperienza utente è simile a iOS 9 e 10, ma iOS 11 chiederà all'utente l'autorizzazione per accedere alle informazioni di accesso. Si tratta di una finestra di dialogo a livello di sistema che non può essere personalizzata. Se l'utente annulla la finestra di dialogo, può continuare a usare la versione che sta testando, ma non otterrà gli aggiornamenti in-app. Verrà chiesto di accedere di nuovo alle informazioni di accesso quando avviano l'app la volta successiva.
  5. Una nuova versione dell'app mostra la finestra di dialogo di aggiornamento in-app che chiede agli utenti di aggiornare l'applicazione se è:

    • un valore superiore di CFBundleShortVersionString o
    • un valore uguale di CFBundleShortVersionString ma un valore superiore di CFBundleVersion.
    • le versioni sono uguali, ma l'identificatore univoco della compilazione è diverso.

Suggerimento

Se si carica lo stesso ipa una seconda volta, la finestra di dialogo NON verrà visualizzata come i file binari sono identici. Se si carica una nuova compilazione con le stesse proprietà di versione, verrà visualizzata la finestra di dialogo di aggiornamento. Il motivo è che si tratta di un file binario diverso .

Ricerca per categorie testare gli aggiornamenti in-app?

È necessario caricare le build di versione (che usano il modulo Distribuisci di App Center SDK) nel portale di App Center per testare gli aggiornamenti in-app, aumentando i numeri di versione ogni volta.

  1. Creare l'app nel portale di App Center, se non è già stato fatto.
  2. Creare un nuovo gruppo di distribuzione e denominarlo in modo da poterlo riconoscere per testare la funzionalità di aggiornamento in-app.
  3. Aggiungi te stesso (o tutte le persone che vuoi includere nel test della funzionalità di aggiornamento in-app). Usare un indirizzo di posta elettronica nuovo o eliminato per questo, che non è stato usato per l'app in App Center. Ciò garantisce che l'esperienza sia vicina all'esperienza dei tester reali.
  4. Creare una nuova build dell'app che include App Center Distribute e contiene la logica di configurazione, come descritto di seguito. Se il gruppo è privato, non dimenticare di impostare la traccia di aggiornamento in-app privata prima di iniziare a usare la proprietà updateTrack.
  5. Fare clic sul pulsante Distribuisci nuova versione nel portale e caricare la compilazione dell'app.
  6. Al termine del caricamento, fare clic su Avanti e selezionare il gruppo di distribuzione creato come Destinazione della distribuzione dell'app.
  7. Esaminare la distribuzione e distribuire la compilazione nel gruppo di test in-app.
  8. Persone in tale gruppo riceverà un invito a essere tester dell'app. Dopo aver accettato l'invito, può scaricare l'app dal portale di App Center dal dispositivo mobile. Dopo aver installato gli aggiornamenti in-app, si è pronti per testare gli aggiornamenti in-app.
  9. Modificare il nome della versione (CFBundleShortVersionString) dell'app.
  10. Compilare la versione di rilascio dell'app e caricare una nuova build dell'app come nel passaggio precedente e distribuirla al gruppo di distribuzione creato in precedenza. I membri del gruppo di distribuzione verranno richiesti per una nuova versione alla successiva avvio dell'app.

Suggerimento

Per informazioni più dettagliate sui gruppi di distribuzione e così via, vedere le informazioni su come usare App Center Distribute. Anche se è possibile usare App Center Distribute per distribuire una nuova versione dell'app senza aggiungere codice, l'aggiunta di App Center Distribute al codice dell'app comporterà un'esperienza più semplice per i tester e gli utenti man mano che ottengono l'esperienza di aggiornamento in-app.

Disabilitare l'inoltro delle chiamate dei metodi del delegato dell'applicazione ai servizi di App Center

App Center SDK usa lo scorrimento rapido per migliorarne l'integrazione inoltrando se stesso alcune delle chiamate ai metodi del delegato dell'applicazione. Lo scorrimento rapido del metodo è un modo per modificare l'implementazione dei metodi in fase di esecuzione. Se per qualsiasi motivo non si vuole usare lo scorrimento rapido (ad esempio a causa di un criterio specifico), è possibile disabilitare l'inoltro per tutti i servizi di App Center seguendo la procedura seguente:

  1. Aprire il file Info.plist del progetto.
  2. Aggiungere AppCenterAppDelegateForwarderEnabled la chiave e impostare il valore su 0. In questo modo viene disabilitato l'inoltro del delegato dell'applicazione per tutti i servizi di App Center.
  3. Aggiungere il openURL callback nel file del AppDelegate progetto.
- (BOOL)application:(UIApplication *)application
            openURL:(NSURL *)url
  sourceApplication:(NSString *)sourceApplication
         annotation:(id)annotation {

  // Pass the url to MSACDistribute.
  return [MSACDistribute openURL:url];
}
func application(_ application: UIApplication, open url: URL, sourceApplication: String?, annotation: Any) -> Bool {

  // Pass the URL to App Center Distribute.
  return Distribute.open(url)
}