Creazione di un'applicazione di appuntamenti con Sinch Integrating Sinch

Le app di incontri sono diventate recentemente uno dei generi più popolari nell'App Store. A causa della loro natura, tuttavia, lo sviluppo di un'app di appuntamenti con funzionalità complete può essere difficile. Nella seconda parte di questa serie, vedremo come possiamo sfruttare la piattaforma Sinch in un'app iOS per implementare chiamate vocali e messaggistica. Queste sono due caratteristiche fondamentali per le app di appuntamenti e sono sorprendentemente facili da implementare con Sinch.

1. Panoramica

Prima di iniziare la codifica, esaminiamo l'app che stiamo creando. La nostra app per appuntamenti avrà alcune caratteristiche fondamentali su cui ci concentreremo in questo tutorial. Per gli account, gli utenti potranno accedere utilizzando Facebook. Dopo aver effettuato l'accesso, potranno vedere gli altri utenti dell'app che si trovano nelle vicinanze.

Gli utenti vengono memorizzati sul server con cui comunichiamo dall'API restful creata nella prima parte di questo tutorial. Una volta ottenute le informazioni dell'utente da Facebook, un nuovo utente viene pubblicato sul server e viene creata una sessione. Successivamente, verrà recuperato un elenco di utenti registrati tra cui scegliere.

Quando l'utente trova qualcuno con cui desidera parlare, sarà in grado di inviare messaggi o avviare una chiamata vocale. È qui che entrerà in gioco Sinch. Useremo il loro SDK per fare tutto il duro lavoro di gestione delle chiamate vocali e della messaggistica.

Ora che sappiamo cosa stiamo sviluppando, è ora di iniziare.

2. Progetto iniziale

Inizia scaricando il progetto iniziale da GitHub. L'app è rivolta a iPhone e contiene l'interfaccia utente, l'autenticazione di Facebook e la comunicazione con l'API RESTful già presente. Questo ci permetterà di concentrarci sull'integrazione con Sinch.

Prima di continuare, vorrei discutere dell'architettura di base dell'app e del modo in cui comunica con il server. Il codice che comunica con il resto dell'API risiede nel UsersAPIClient classe. Utilizza la famosa libreria AFNetworking per semplificare la logica di rete. Se hai già utilizzato AFNetworking, ti sembrerà molto familiare. Se non lo hai fatto, il nostro tutorial su AFNetworking è un ottimo punto di partenza.

Nel file di intestazione, vedrai alcuni metodi per comunicare con vari endpoint dell'API RESTful, come la creazione di un utente, l'avvio di una sessione, l'eliminazione di un utente e altro.

- (void) createUser: (User *) completamento utente: (void (^) ()) action; - (void) beginUserSession: (Utente *) completamento utente: (azione void (^) ()); - (void) deleteUser: (User *) completamento utente: (void (^) ()) action; - (void) getRegisteredUsersWithMeters: (double) meters completion: (void (^) (NSArray * users)) azione;

Quando una risposta ritorna dal server, il JSON viene analizzato e utilizzato per inizializzare un modello.

Parlando di modelli, c'è un modello utilizzato nel progetto, Utente. Contiene informazioni di base su un utente, come nome, posizione, id, ecc. L'ID utente è particolarmente importante poiché ne abbiamo bisogno per identificare in modo univoco con chi stiamo comunicando quando ci integriamo con Sinch.

Prenditi qualche minuto per sfogliare il progetto per capire meglio la sua struttura. Proprio come con le librerie di terze parti, è estremamente utile consultare la documentazione e il codice sorgente prima di utilizzarlo.

3. Costruisci ed esegui 

Se costruisci ed esegui il progetto demo, ti verrà chiesto di accedere tramite Facebook.

Vai avanti e controlla se riesci ad accedere con Facebook. Dopo l'accesso, l'app demo fa tre cose:

  • Crea un record utente sul back-end se uno non è presente.
  • Avvia una sessione utente e crea un token di accesso per la sessione.
  • Recupera un elenco di utenti nel sistema.

Successivamente, quando hai creato alcuni account di prova, puoi trovare utenti all'interno di un determinato intervallo. Per impostazione predefinita, ogni utente nel sistema viene restituito poiché è improbabile che altri utenti si trovino nelle vicinanze durante il test.

4. Crea un account di Sinch

Per utilizzare Sinch SDK, devi prima creare un account sviluppatore. Andare al sito Web di Sinch e fare clic Inizia gratuitamente in alto a destra per iscriverti.

Inserisci il tuo indirizzo email e la password e accetta i termini e le condizioni. Sinch avvierà automaticamente un processo di installazione dopo la registrazione. A questo punto, tutto ciò che devi fare è assegnare un nome alla tua app e aggiungere una breve descrizione. Puoi saltare il resto della guida di avvio per ora.

Successivamente, visita la dashboard per recuperare la chiave API e il segreto della tua app. Tu dovresti vedere Cruscotto nella parte superiore del sito Web di Sinch dopo aver eseguito l'accesso con il tuo nuovo account. Selezionare applicazioni a sinistra, seleziona l'app che hai creato e fai clic sull'icona a forma di chiave sulla destra per mostrare la chiave e il segreto. Ti consigliamo di tenere traccia di questi valori per inizializzare in seguito il client Sinch.


5. Aggiungi Sinch SDK

Ci sono due modi per aggiungere il Sinch SDK al tuo progetto. L'approccio più semplice di gran lunga è attraverso CocoaPods. Aggiungi la seguente riga al tuo Podfile:

pod 'SinchService', '~> 1.0'

Quindi, esegui il seguente comando per integrare Sinch SDK nel tuo spazio di lavoro:

aggiornamento pod

In questo tutorial, tuttavia, ti mostrerò come aggiungere l'SDK se non stai utilizzando CocoaPods. Inizia scaricando Sinch SDK per iOS. Visita la sezione download del sito Web di Sinch e scarica l'SDK per iOS. L'SDK Sinch dipende da tre framework, quindi dovremo collegare il nostro progetto a quelli per primi. Nel Project Navigator, scegliere SinchTutorial e selezionare il SinceTutorial bersaglio.

 Selezionare Crea fasi> Collega binario con le librerie e fare clic sul pulsante più in basso.

Aggiungi i seguenti framework all'elenco di framework da collegare con:

  • Sicurezza
  • AudioToolbox
  • AVFoundation

Abbiamo anche bisogno di aggiungere tre flag linker. Nel bersaglio Costruisci le impostazioni, Cercare Altre bandiere Linker.

Aggiungi i seguenti flag del linker sotto mettere a punto:

-ObjC -Xlinker -lc++

Infine, trascina il framework Sinch che hai scaricato in precedenza nel Frameworks cartella nel Project Navigator. Costruisci il tuo progetto per assicurarti che non ci siano errori. Ora sei pronto per iniziare a usare il Sinch SDK.

6. Impostazione del client Sinch

Il cliente di Sinch è la forza motrice responsabile della comunicazione con la piattaforma Sinch. Prima di poter utilizzare le funzioni di messaggistica o chiamata, sarà necessario inizializzare un'istanza del client Sinch. Per fare questo, abbiamo bisogno della chiave e del segreto che abbiamo recuperato in precedenza dopo aver creato il nostro account Sinch.

Aperto AppDelegate.h e importare il framework Sinch come mostrato di seguito.

#importare 

Successivamente, abbiamo bisogno di creare una proprietà per il client Sinch e un prototipo di metodo per inizializzarlo. Aggiungi il seguente snippet di codice sotto il finestra proprietà.

@property (strong, nonatomic) id cliente; - (void) sinchClientWithUserId: (NSString *) userId;

Useremo questo riferimento al client Sinch per ottenere facilmente chiamate e messaggi in corso. Il SINClientDelegate il protocollo ci informerà se il collegamento con il backend Sinch ha avuto successo.

Conformare il AppDelegate classe al SINClientDelegate protocollo come mostrato di seguito.

// Conforme a SINClientDelegate @interface AppDelegate: UIResponder 

Passare al file di implementazione di AppDelegate classe e implementare il sinchClientWithUserId: metodo come mostrato di seguito.

#pragma mark - Sinch - (void) sinchClientWithUserId: (NSString *) userId if (! _client) _client = [Sinch clientWithApplicationKey: @ ""applicationSecret: @""environmentHost: @" sandbox.sinch.com "userId: userId]; _client.delegate = self; [_client setSupportCalling: YES]; [_client setSupportMessaging: YES]; [_client start]; [_client startListeningOnActiveConnection];

Utilizzeremo questo metodo in seguito per comunicare con il backend Sinch dopo che l'utente ha effettuato l'accesso. Ricordarsi di inserire la chiave dell'applicazione e il segreto. Altrimenti non sarai in grado di connetterti al backend Sinch.

Dopo aver inizializzato il client, diciamo a Sinch che utilizzeremo le funzioni di messaggistica e chiamata. Iniziamo quindi il client e stabiliamo una connessione con i servizi Sinch per ricevere le chiamate in arrivo.

Quindi, implementare i seguenti metodi delegati di SINClientDelegate protocollo nel AppDelegate classe:

- (Void) clientDidStart: (id) client NSLog (@ "Sinch client avviato correttamente (versione:% @)", [versione Sinch]);  - (void) clientDidFail: (id) errore del client: errore (NSError *) NSLog (@ "Errore client Sinch:% @", [error localizedDescription]);  - client (vuoto): (id) client logMessage: (NSString *) area messaggi: (NSString *) severità area: (SINLogSeverity) data e ora di gravità: (NSDate *) data / ora if (severity == SINLogSeverityCritical) NSLog (@ "% @", messaggio); 

Questi metodi delegati registreranno errori nella console Xcode qualora dovessero verificarsi e ci informano anche quando siamo riusciti a connettersi con Sinch.

7. Inizializzazione del client di Sinch

Aperto FindUsersViewController.m e scorrere fino a beginUserSession metodo. In questo metodo, se una sessione è stata avviata senza errori, viene eseguito il blocco di completamento. Questo è un buon momento per inizializzare il client di Sinch. Sostituisci il //FARE commentare con il seguente blocco di codice:

// Init sinch client AppDelegate * delegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; [delegate sinchClientWithUserId: self.curUser.userID];

Questo chiama il metodo per avviare il client Sinch e ci consente di iniziare a utilizzare le sue funzionalità. Costruisci ed esegui l'app. Dopo aver recuperato un elenco di utenti, verifica che il collegamento con il back-end di Sinch sia riuscito controllando i log nella console Xcode.

8. Implementare la messaggistica

Ora stiamo arrivando alla parte divertente, aggiungendo un componente di messaggistica con pochissimo codice usando il Sinch SDK. Inizia aprendo MessagingViewController.m e importa il framework di Sinch.

#importare 

Molto simile al SINClientDelegate protocollo fornisce metodi utili che ci aiutano a tenere traccia dello stato del cliente, il SINMessageClientDelegate il protocollo ci tiene informati sui messaggi in entrata e in uscita, sul loro stato e altro ancora.

Inizia conformando il MessagingViewController classificare questo protocollo aggiornando l'interfaccia della classe.

@interface MessagingViewController () 

Per implementare la messaggistica, avremo anche bisogno di un SINMessageClient istanza per gestire le responsabilità della messaggistica. Aggiungi una proprietà per il SINMessageClient esempio.

@property (strong, nonatomic) id sinchMessageClient;

Possiamo creare un'istanza di un client di messaggistica dal client Sinch già presente nel delegato dell'app. Quando viene caricato il controller di visualizzazione, è necessario inizializzarne uno e impostare il controller di visualizzazione come delegato. Aggiungere il seguente blocco di codice al controller della vista viewDidLoad metodo:

// Setup Sinch message client self.sinchMessageClient = [((AppDelegate *) [[UIApplication sharedApplication] delegate]) client messageClient]; self.sinchMessageClient.delegate = self;

Ora che abbiamo un oggetto per inviare e ricevere messaggi e un delegato per gestirli, aggiungiamo il codice per comporre un messaggio. Trovare la invia messaggio: metodo nella parte inferiore del controller della vista e aggiungere la seguente implementazione:

[self dismissKeyboard]; SINOutgoingMessage * outgoingMessage = [SINOutgoingMessage messageWithRecipient: self.selectedUser.userID text: self.messageTextField.text]; [self.sinchMessageClient sendMessage: outgoingMessage];

UN SINOutgoingMessage l'istanza contatterà Sinch e trasferirà il messaggio al destinatario. Noi designiamo il destinatario fornendo il proprio ID utente dal modello dell'utente. Sinch saprà dove andare con il messaggio instradandolo attraverso la sua API usando una combinazione della chiave dell'applicazione, segreta, e l'ID utente unico passato ad esso.

Poiché un messaggio può essere in entrata o in uscita, aggiungere un enum nella parte superiore del controller di visualizzazione per tenere conto di entrambi gli scenari. Aggiungilo sotto le dichiarazioni di importazione.

typedef NS_ENUM (int, MessageDirection) Incoming, Outgoing;

Infine, avremo bisogno del client di messaggistica per elaborare e inviare effettivamente il messaggio. In questo controller di visualizzazione, dovremo gestire entrambi gli invii e ricevere messaggi. Aggiungi il seguente snippet di codice per ricevere un messaggio:

#pragma mark SINMessageClient // Ricezione di un messaggio in arrivo. - (vuoto) messageClient: (id) messageClient didReceiveIncomingMessage: (id) messaggio NSLog (@ "Ricevuto un messaggio"); [self.messages addObject: @ [message, @ (Incoming)]]; [self.tableView reloadData]; 

Ogni volta che riceviamo un messaggio, lo aggiungeremo al messaggi array e ricaricare la vista tabella per visualizzarla. È importante notare che il SINMessage oggetto è composto da due elementi, l'oggetto messaggio stesso e la sua direzione (in entrata o in uscita).

Ora che possiamo inviare e ricevere messaggi, dobbiamo sapere quando un messaggio ha finito di inviare se siamo l'autore in modo che possiamo aggiornare l'origine dati e ricaricare la vista tabella. Per realizzare ciò, implementiamo il messageSent: recipientId: come mostrato di seguito.

// Termina l'invio di un messaggio - (vuoto) messageSent: (id) message recipientId: (NSString *) recipientId NSLog (@ "Fine invio di un messaggio"); self.messageTextField.text = @ ""; [self.messages addObject: @ [message, @ (Outgoing)]]; [self.tableView reloadData]; 

Possiamo anche implementare alcuni dei restanti metodi delegati per aiutarci a risolvere il problema del processo di messaggistica se qualcosa dovesse andare storto. Aggiungere i seguenti metodi delegati sotto il messageSent: recipientId: metodo.

// Impossibile inviare un messaggio - (void) messageFailed: (id) informazioni sul messaggio: (id) messageFailureInfo NSLog (@ "Impossibile inviare un messaggio:% @", messageFailureInfo.error.localizedDescription);  - (void) messageDelivered: (id) info NSLog (@ "Il messaggio è stato consegnato");  - (vuoto) messaggio: (id) messaggio shouldSendPushNotifications: (NSArray *) pushPairs NSLog (@ "Destinatario non in linea. \ nStabilizza il destinatario utilizzando push (non implementato in questo tutorial). \ nFare riferimento alla documentazione."); 

A questo punto, la messaggistica con Sinch è pronta per l'uso. L'ultima cosa che dovremo fare è modificare il tableView: cellForRowAtIndexPath: metodo per visualizzare i messaggi. Questo è l'aspetto che dovrebbe avere l'implementazione:

- (UITableViewCell *) tableView: (UITableView *) tableView cellForRowAtIndexPath: (NSIndexPath *) indexPath UITableViewCell * cell; id message = [self.messages [indexPath.row] firstObject]; MessageDirection direction = (MessageDirection) [[self.messages [indexPath.row] lastObject] intValue]; if (direction == Incoming) cell = [self.tableView dequeueReusableCellWithIdentifier: CELL_ID_RECIPIENT]; ((RecipientTableViewCell *) cell) .message.text = message.text;  else cell = [self.tableView dequeueReusableCellWithIdentifier: CELL_ID_USER]; ((UsersTableViewCell *) cell) .message.text = message.text;  restituisci cella; 

9. Test di messaggistica

Costruisci ed esegui l'app per assicurarti che non ci siano errori. Sei pronto a testare la funzione di messaggistica. Per provarlo, avrai bisogno di accedere a un altro account Facebook.

Sul tuo dispositivo iOS, crea ed esegui l'app e accedi con il primo account. Su iOS Simulator, esegui un'altra istanza dell'app e accedi con il secondo account. Passare al rispettivo profilo su ciascun dispositivo e toccare Messaggio.

A questo punto, è possibile inserire un messaggio e premere Inviare. Arriverà quasi immediatamente sul dispositivo del destinatario. Hai finito di implementare un client di messaggistica funzionante per la tua app di appuntamenti utilizzando la piattaforma Sinch.

Se l'utente non è online, il client proverà a inviare il messaggio, ma non arriverà all'altro utente. In questo caso, potresti voler implementare le notifiche push per far sapere al destinatario che hanno ricevuto un messaggio.

10. Chiamata VoIP

L'ultima funzionalità che utilizzeremo Sinch per è la chiamata VoIP (Voice over IP). Aperto CallingViewController.m e importa il framework Sinch un'ultima volta.

#importare 

Come prima, faremo uso di alcuni protocolli per gestire le chiamate. Il SINCallClientDelegate e SINCallDelegate i protocolli ci forniscono i metodi per avviare e ricevere una chiamata e per essere aggiornati sullo stato di una chiamata. Aggiorna l'interfaccia del  CallingViewController classe per conformarlo ad entrambi i protocolli.

@interface CallingViewController () 

Per implementare le chiamate VoIP, avremo bisogno di accedere al client Sinch e a SINCall oggetto. Aggiungi una proprietà per il SINCall istanza come mostrato di seguito.

@property (strong, nonatomic) id sinchCall;

Nel viewDidLoad, impostare il controller di visualizzazione come delegato del client di chiamata Sinch.

// Assegna questo VC come delegato alla chiamata di Sinch self.delegate = (AppDelegate *) [[UIApplication sharedApplication] delegate]; self.delegate.client.callClient.delegate = self;

Per comprendere meglio la sezione successiva, è utile analizzare gli scenari che gli utenti dovranno affrontare quando utilizzano la funzione di chiamata. Un utente potrebbe essere:

  • ricevere una chiamata
  • fare una chiamata
  • riagganciare una chiamata esistente
  • rifiutare una chiamata in arrivo

Affrontiamoci prima di effettuare e ricevere una chiamata. Aggiungi il seguente codice al makeOrAcceptCallFromSelectedUser: metodo:

#pragma mark - Initiate or Accept Call - (IBAction) makeOAccepetCallFromSelectedUser: (UIButton *) mittente if ([sender.titleLabel.text isEqualToString: @ "Call"]) self.sinchCall = [self.delegate.client.callClient callUserWithId : self.selectedUser.userID]; self.sinchCall.delegate = self; self.lblCallStatus.text = [NSString stringWithFormat: @ "- calling% @ -", self.selectedUser.userName]; self.btnDeny.hidden = NO; [self.btnDeny setTitle: @ "Hang Up" forState: UIControlStateNormal];  else [self.sinchCall answer]; self.lblCallStatus.text = [NSString stringWithFormat: @ "- parlando con% @ -", self.selectedUser.userName]; 

Controlliamo per vedere se stiamo facendo una chiamata o ne abbiamo una in arrivo. Se stiamo iniziando la chiamata, callUserWithId: avvierà il processo di chiamata e inizializzerà il sinchCall proprietà.

Se stiamo rispondendo a una chiamata, il sinchCall la proprietà sarà già inizializzata e iniziamo semplicemente la chiamata chiamando risposta su di esso.

Successivamente, implementeremo il rifiuto e la sospensione di una chiamata. Aggiungi il seguente codice al rejectOrHangUpCallFromSelectedUser: metodo:

#pragma mark - Nega o Hang Up Call - (IBAction) rejectOrHangUpCallFromSelectedUser: (UIButton *) mittente [self.sinchCall hangup]; self.lblCallStatus.text = [NSString stringWithFormat: @ "- chiama con% @ ended -", self.selectedUser.userName]; 

Questo codice è più facile da digerire, perché, indipendentemente dalla situazione, viene gestito chiamando Appendere sul sinchCall proprietà.

Tutto ciò che resta da fare è implementare i metodi di delega richiesti. Questo sarà un bel po 'di codice, ma è semplice da capire e i nomi dei metodi sono molto descrittivi.

#pragma mark - SINCall / Client - (void) client: (id) client didReceiveIncomingCall: (id) call self.sinchCall = call; self.sinchCall.delegate = self; self.lblCallStatus.text = [NSString stringWithFormat: @ "- chiamata in arrivo da% @ -", self.selectedUser.userName]; [self.btnAcceptOrCall setTitle: @ "Accept Call" forState: UIControlStateNormal]; self.btnDeny.hidden = NO;  - (void) callDidEstablish: (id) chiama NSLog (@ "Chiama connessa."); self.btnDeny.hidden = NO; [self.btnDeny setTitle: @ "Hang Up" forState: UIControlStateNormal]; self.lblCallStatus.text = @ "- call connected -"; self.btnAcceptOrCall.hidden = YES;  - (void) callDidEnd: (id) chiama NSLog (@ "Call finished"); self.sinchCall = nil; self.lblCallStatus.text = @ "- call ended -"; self.btnDeny.hidden = YES; dispatch_after (dispatch_time (DISPATCH_TIME_NOW, (int64_t) (1 * NSEC_PER_SEC)), dispatch_get_main_queue (), ^ [self.navigationController popViewControllerAnimated: YES];);  - (void) callDidProgress: (id) call // In questo metodo è possibile riprodurre il tono di chiamata e aggiornare ui per visualizzare lo stato della chiamata. 

Il primo metodo, didReceiveIncomingCall:, gestisce la ricezione di una chiamata e la configurazione del sinchCall proprietà. Sapremo anche quando inizia e finisce la chiamata callDidEstablish: e callDidEnd:.

L'ultimo metodo, callDidProgress:, è vuoto al momento, ma sarebbe utile per aggiornare l'interfaccia utente con informazioni utili, come la durata della chiamata. Potresti usare SINCallDetail e la sua establishedTime proprietà per fare facilmente questo calcolo.

11. Test di chiamata

Esegui due istanze dell'app utilizzando due account Facebook come hai fatto in precedenza. Passa al rispettivo profilo e tocca Chiamata.

Colpisci il green Chiamata pulsante sul dispositivo o in iOS Simulator. Una volta che la chiamata viene inviata a Sinch, l'interfaccia utente verrà aggiornata per consentire all'utente di sapere che la chiamata è in corso.

Allo stesso modo, se uno degli utenti sta ricevendo una chiamata, l'interfaccia utente sarà simile a questa:

Infine, quando la chiamata è in corso, l'interfaccia utente rifletterà lo stato della chiamata. Un pulsante etichettato Appendere sarà visibile per terminare la chiamata.

Simile alla messaggistica, il tentativo di chiamare un utente che non è online non è supportato dall'app. Come con la messaggistica, è possibile risolvere questo problema utilizzando le notifiche push per notificare all'utente che qualcuno ha provato a chiamarti.

12. Dove andare Avanti

Ci sono diverse parti dell'app che possono essere migliorate. Il più notevole è l'integrazione delle notifiche push. Recentemente, Sinch ha aggiunto il supporto nativo per le notifiche push al proprio SDK iOS, sottraendosi agli sviluppatori. Con le notifiche push, è possibile notificare agli utenti che attualmente non utilizzano l'app di aver ricevuto una chiamata o un messaggio.

Un'altra aggiunta utile potrebbe essere quella di archiviare messaggi e conversazioni su un back-end remoto. In questo modo, gli utenti potrebbero tornare indietro nel tempo e visualizzare le conversazioni passate che hanno avuto. Rende anche l'esperienza di messaggistica più fluida dal momento che potrebbero riprendere una conversazione da dove avevano lasciato.

Queste sono solo alcune idee. Sono sicuro che puoi pensare ad altri ancora che renderebbero l'app più completa e coinvolgente.

Conclusione

Il potente SDK di Sinch rende accessibili due compiti intimidatori, facili e convenienti. Come hai visto in questo tutorial, Sinch consente agli sviluppatori di integrare la messaggistica e chiamare le loro app in pochi minuti. Sinch SDK non è limitato a iOS. Ad esempio, se la tua app per appuntamenti ha un componente del sito web, puoi utilizzare la loro API JavaScript per implementare le stesse funzionalità.

Se ti sei bloccato lungo la strada, non ti preoccupare, puoi trovare il progetto finito su GitHub. Ora puoi prendere ciò che hai imparato in questo tutorial e andare a creare il prossimo Tinder.