Προγραμματισμός

Δημιουργήστε εφαρμογές για κινητά χωρίς σύνδεση χωρίς πόνο

Ο Alexander Stigsen είναι συνιδρυτής και διευθύνων σύμβουλος της Realm.

Είναι μια αλήθεια που αναγνωρίζεται παγκοσμίως ότι ένας χρήστης που διαθέτει ένα smartphone πρέπει να θέλει μια καλύτερη σύνδεση. Παρά την επένδυση σε υποδομές δισεκατομμυρίων δολαρίων και την ατελείωτη τεχνολογική καινοτομία, δεν χρειάζεται πολύ περισσότερο από μια σύντομη κίνηση για να παρατηρήσετε μια ουσιαστική πραγματικότητα της συνδεδεμένης εποχής: Δεν μπορείτε να υποθέσετε ότι μια σύνδεση δικτύου θα είναι διαθέσιμη κάθε φορά που το θέλετε. Ως προγραμματιστές κινητής τηλεφωνίας, είναι αλήθεια που είναι εύκολο να αγνοήσετε.

Οι καταστάσεις εκτός σύνδεσης στις εφαρμογές μπορεί να προκαλέσουν σύγχυση, αλλά το πρόβλημα ξεκινά με μια βασική και λανθασμένη υπόθεση - ότι η κατάσταση εκτός σύνδεσης είναι, από προεπιλογή, μια κατάσταση σφάλματος. Αυτό είχε νόημα όταν δημιουργήσαμε εφαρμογές για επιτραπέζιους υπολογιστές με αποκλειστικούς συνδέσμους ethernet. Δεν έχει νόημα όταν το κλείσιμο των θυρών του ασανσέρ καθιστά μια εφαρμογή εντελώς άχρηστη ή όταν είναι λογικό να αναμένεται ότι η εφαρμογή σας θα χρησιμοποιηθεί σε μέρη που δεν διαθέτουν αξιόπιστη κυψελοειδή υποδομή.

Δεν μπορούμε να καλύψουμε τον κόσμο σε κάλυψη, οπότε πρέπει να προσφέρουμε μια εναλλακτική λύση. Πρέπει να σκεφτούμε πρώτα εκτός σύνδεσης. Πρέπει να σχεδιάσουμε εφαρμογές για να είναι χρήσιμες εκτός σύνδεσης. Πρέπει να δημιουργήσουμε εφαρμογές που αξιοποιούν πλήρως το Διαδίκτυο όταν είναι διαθέσιμο, αλλά κατανοούμε ότι η πρόσβαση στο Διαδίκτυο είναι πάντα προσωρινή. Πρέπει να λάβουμε αποφάσεις έξυπνου σχεδιασμού που αφορούν καταστάσεις εκτός σύνδεσης και να καταστήσουμε αυτές τις καταστάσεις εκτός σύνδεσης κατανοητές από τους χρήστες.

Πολλή δουλειά γίνεται για τον καθορισμό του πρώτου μέλλοντος εκτός σύνδεσης. Η Realm, η εταιρεία στην οποία εργάζομαι, κατασκευάζει μια πλατφόρμα σε πραγματικό χρόνο για εφαρμογές για κινητά εκτός σύνδεσης για κάποιο χρονικό διάστημα. Η βάση δεδομένων για κινητά και η πλατφόρμα Realm Mobile διευκολύνουν τη δημιουργία έξυπνων εφαρμογών χωρίς σύνδεση σε σχεδόν οποιαδήποτε κινητή συσκευή. Οι λαοί στο A List Apart έχουν συνεισφέρει τεράστια στην πρώτη βιβλιογραφία εκτός σύνδεσης, ειδικά για εφαρμογές ιστού. Και οι κοινότητες προγραμματιστών των μεγάλων κινητών οικοσυστημάτων έχουν περάσει πολλές ώρες προσφέροντας δικές τους εντυπωσιακές λύσεις ανοιχτού κώδικα.

Αυτό που ακολουθεί είναι μια σύντομη εισαγωγή του τρόπου με τον οποίο μπορείτε να δημιουργήσετε μια πρώτη εφαρμογή για κινητά εκτός σύνδεσης. Θα χρησιμοποιήσω έναν απλό δείγμα κώδικα Swift προς το τέλος για να δείξω πώς φαίνεται μια ελάχιστη εφαρμογή χωρίς σύνδεση, αλλά οι αρχές και τα προβλήματα που προσφέρονται εδώ σχετίζονται με όποιον εργάζεται στην ανάπτυξη εφαρμογών για κινητά.

Σχεδιασμός για πρώτη φορά εκτός σύνδεσης

Προτού δημιουργήσετε την πρώτη χωρίς σύνδεση εφαρμογή που πάντα θέλετε, πρέπει να επανεξετάσουμε τις σχεδιαστικές λύσεις που έχουν νόημα για επιτραπέζιους υπολογιστές με πολύ μεγάλη πιθανότητα να συνδεθείτε στο διαδίκτυο. Εάν η εφαρμογή σας μπορεί να χειριστεί καταστάσεις εκτός σύνδεσης και διαδικτύου, έχουμε ερωτήσεις για να απαντήσουμε σχετικά με το τι μπορεί να κάνει και πώς θα δείξουμε στον χρήστη τι είναι δυνατό.

Ορίστε τι είναι δυνατό εκτός σύνδεσης

Ας πάρουμε το Twitter ως παράδειγμα. Εάν είστε εκτός σύνδεσης και δημοσιεύσετε ένα tweet, ένας πελάτης Twitter πρώτος εκτός σύνδεσης θα μπορούσε να ακολουθήσει δύο διαδρομές. Θα μπορούσε να ουρά το tweet μέχρι να επαναφέρει τη συνδεσιμότητα. Ή θα μπορούσε να αρνηθεί να σας αφήσει να κάνετε tweet - ακόμα κι αν σας επιτρέπει να ουρά άλλες ενέργειες, όπως faves, όπως κάνει το Tweetbot.

Γιατί το Tweetbot θα σας εμπόδιζε να κάνετε tweet εκτός σύνδεσης; Ίσως επειδή τη στιγμή που θα επιστρέψετε στο διαδίκτυο, τα tweet σας μπορεί να μην είναι πλέον σχετικά. Η επίλυση αυτού του προβλήματος συνεπάγεται τη δημιουργία μιας νέας διεπαφής χρήστη για μια λίστα με tweets που δεν έχετε δημοσιεύσει ακόμη, αλλά τα οποία ίσως χρειαστεί να επεξεργαστείτε ή να διαγράψετε πριν συνδεθούν στο διαδίκτυο. Αν θέλετε ένα tweet, από την άλλη πλευρά, είναι απίθανο να το αναιρέσετε εάν αντιμετωπίσετε περισσότερες πληροφορίες - και πολύ λιγότερο προβληματικό να υποδείξετε απλώς ότι είναι στην ουρά για δημοσίευση.

Δεν μπορείτε να κάνετε μια εφαρμογή εκτός σύνδεσης να κάνει ό, τι μπορεί μια εφαρμογή στο διαδίκτυο, αλλά μπορείτε να την κάνετε χρήσιμη.

Σχεδιάστε τις συγκρούσεις

Ανεξάρτητα από τη στρατηγική που χρησιμοποιείτε στο πίσω μέρος για να συνδυάσετε τις αλλαγές, η εφαρμογή σας θα αντιμετωπίσει ένα σημείο όπου έχετε δύο αντικρουόμενα δεδομένα. Ίσως επειδή ο διακομιστής παρουσίασε σφάλμα ή επειδή εσείς και ένα άλλο άτομο κάνατε αλλαγές εκτός σύνδεσης και τώρα θέλετε να τις συγχρονίσετε. Τα πάντα μπορούν να συμβούν!

Έτσι, προβλέψτε τις συγκρούσεις και προσπαθήστε να τις επιλύσετε με προβλέψιμο τρόπο. Προσφέρετε επιλογές. Και προσπαθήστε πρώτα να αποφύγετε τις συγκρούσεις.

Η πρόβλεψη σημαίνει ότι οι χρήστες σας γνωρίζουν τι θα μπορούσε να συμβεί. Εάν μπορεί να προκύψει διένεξη όταν οι χρήστες επεξεργάζονται σε δύο μέρη ταυτόχρονα όταν είναι εκτός σύνδεσης, τότε θα πρέπει να ειδοποιούνται για αυτό όταν είναι εκτός σύνδεσης.

Η προσφορά επιλογών σημαίνει όχι απλώς την αποδοχή της τελευταίας γραφής ή τη συνένωση αλλαγών ή τη διαγραφή του παλαιότερου αντιγράφου. Σημαίνει να αφήσετε τον χρήστη να αποφασίσει τι είναι κατάλληλο.

Τέλος, η καλύτερη λύση είναι να μην αφήσουμε ποτέ τις συγκρούσεις να αναπτυχθούν. Ίσως αυτό σημαίνει να δημιουργήσετε την εφαρμογή σας με τέτοιο τρόπο ώστε νέα και παράξενα δεδομένα από πολλές πηγές να μην οδηγούν σε διένεξη και, αντίθετα, να εμφανίζονται ακριβώς όπως θα θέλατε. Αυτό μπορεί να είναι δύσκολο να γίνει σε μια εφαρμογή γραφής που πηγαίνει στο διαδίκτυο και εκτός σύνδεσης, αλλά μια κοινόχρηστη εφαρμογή σχεδίασης μπορεί να δημιουργηθεί για να προσθέσει νέες διαδρομές στο σχέδιο όποτε συγχρονιστούν.

Να είστε σαφείς

Είναι ένα πράγμα να καθορίσουμε τι μπορεί να κάνει ο χρήστης εκτός σύνδεσης. Ένα άλλο πρόβλημα περιλαμβάνει τη λήψη αυτών των αποφάσεων κατανοητών από τους χρήστες σας. Η αποτυχία κοινοποίησης της κατάστασης των δεδομένων και της συνδεσιμότητάς σας ή η διαθεσιμότητα συγκεκριμένων δυνατοτήτων, ισοδυναμεί με αποτυχία στη δημιουργία μιας πρώτης εφαρμογής χωρίς σύνδεση.

Μια κοινή εφαρμογή λήψης σημειώσεων δείχνει το πρόβλημα. Αν είστε εκτός σύνδεσης, αλλά περιμένετε από τους συνεργάτες να συνεχίσουν να επεξεργάζονται στην εφαρμογή απουσία σας, δεν αρκεί απλώς να επιτρέψετε σε έναν χρήστη να συνεχίσει να πληκτρολογεί έως ότου είναι ικανοποιημένος. Όταν επανασυνδεθούν, θα εκπλαγούν από συγκρούσεις που έχουν αναπτυχθεί.

Αντ 'αυτού, βοηθήστε τον χρήστη σας να πάρει τη σωστή απόφαση. Εάν δείτε ότι η σύνδεση του διακομιστή σας έχει διακοπεί επειδή η επάνω γραμμή της εφαρμογής σας αλλάζει χρώμα, γνωρίζετε τι θα μπορούσε να προκύψει: συγχώνευση διενέξεων! Αυτό μπορεί να είναι καλό τις περισσότερες φορές και η διεπαφή χρήστη της εφαρμογής σας μπορεί να βοηθήσει στην επίλυση απροσδόκητων διενέξεων όταν επιστρέψετε στο διαδίκτυο. Αλλά αν χάσετε τη συνδεσιμότητα όταν πολλά άτομα επεξεργάζονται την εφαρμογή σας, δεν θα ήταν χρήσιμο να γνωρίζετε ότι ο κίνδυνος διενέξεων είναι πολύ μεγαλύτερος; «Χάσατε τη σύνδεση, αλλά άλλοι έκαναν επεξεργασία. Η συνέχιση της επεξεργασίας θα μπορούσε να προκαλέσει διενέξεις. " Ο χρήστης μπορεί να συνεχίσει αλλά γνωρίζει τον κίνδυνο.

Είναι εύκολο να γράφετε ατελείωτα σχετικά με προβλήματα σχεδιασμού και λύσεις, αλλά προτού προχωρήσουμε πολύ μακριά από τα εργαλεία που θα πρέπει να χρησιμοποιήσουμε, θα ήταν χρήσιμο να δούμε πώς είναι να δημιουργήσετε μια εφαρμογή για κινητά εκτός σύνδεσης.

Δημιουργήστε μια πρώτη εφαρμογή εκτός σύνδεσης με το Realm

Η αρχιτεκτονική μιας βασικής εφαρμογής πρώτης εκτός σύνδεσης δεν είναι φανταχτερή. Χρειάζεστε έναν τρόπο για να διατηρήσετε δεδομένα στην εφαρμογή (χρησιμοποιώντας μια βάση δεδομένων στη συσκευή), ένα πρωτόκολλο για επικοινωνία με έναν διακομιστή (συμπεριλαμβανομένου του κωδικού σειριοποίησης και της αποεπιλογίωσης εάν είναι απαραίτητο) και του διακομιστή όπου θα ζουν τα συγχρονισμένα δεδομένα, ώστε να μπορεί να είναι διανέμεται σε όποιον έχει άδεια.

Πρώτον, θα σας καθοδηγήσω πώς να ξεκινήσετε με τη βάση δεδομένων Realm Mobile σε μια εφαρμογή iOS (αν και ο κώδικας δεν θα φαίνεται πολύ διαφορετικός σε μια εφαρμογή Android). Στη συνέχεια, θα παρουσιάσω μια στρατηγική για σειριοποίηση και αποεριοποίηση κώδικα που λαμβάνετε από έναν διακομιστή και αποθηκεύετε στην τοπική βάση δεδομένων Realm. Τέλος, θα σας δείξω πώς να τα κάνετε όλα μαζί σε μια εφαρμογή συλλογής λίστας υποχρεώσεων που συγχρονίζεται σε πραγματικό χρόνο.

Βάση δεδομένων Realm Mobile

Είναι εύκολο να ξεκινήσετε με το Realm. Εγκαθιστάτε τη Realm Mobile Database και, στη συνέχεια, καθορίζετε το σχήμα σας κάνοντας τάξεις. Επειδή το Realm είναι μια βάση δεδομένων αντικειμένων, είναι πραγματικά τόσο απλό όσο η δημιουργία τάξεων, η δημιουργία ορισμένων αντικειμένων και η μεταφορά αυτών των αντικειμένων σε γράφω μπλοκ για να τα διατηρήσετε στο δίσκο. Δεν απαιτείται σειριοποίηση ή ORM, καθώς είναι ταχύτερη από τα βασικά δεδομένα της Apple.

Ακολουθεί ο πυρήνας του μοντέλου μας και η πιο βασική δυνατή λίστα εφαρμογών (την οποία θα πρέπει να μεταγλωττίζετε κάθε φορά που θέλετε να κάνετε μια νέα εργασία):

εισαγωγή RealmSwift

class Task: Object {

δυναμικό όνομα var

}

class TaskList: Object {

αφήστε εργασίες = Λίστα ()

}

let myTask = Εργασία ()

myTask.task

let myTaskList = Λίστα εργασιών ()

myTaskList.tasks.append (myTask)

let realm = Realm ()

δοκιμάστε! realm.write {

realm.add ([myTask, myTaskList])

}

Από εκεί, δεν χρειάζεται πολύς χρόνος για τη δημιουργία μιας πιο πλήρως λειτουργικής εφαρμογής γύρω από ένα TableViewController:

εισαγωγή UIKit

εισαγωγή RealmSwift

class TaskListTableViewController: UITableViewController {

var realm = δοκιμάστε! Βασίλειο()

var taskList = TaskList ()

παράκαμψη func viewDidLoad () {

super.viewDidLoad ()

εκτύπωση (Realm.Configuration.defaultConfiguration.fileURL!)

// Εδώ, θα μπορούσατε να αντικαταστήσετε το self.taskList με ένα αντικείμενο TaskList που είχε αποθηκευτεί στο παρελθόν

δοκιμάστε! realm.write {

realm.add (self.taskList)

       }

// προσθήκη navbar +

navigationItem.setRightBarButton (UIBarButtonItem.init (barButtonSystemItem: UIBarButtonSystemItem.add, target: self, action: #selector (displayTaskAlert)), κινούμενο: false)

   }

func displayTaskAlert () {

// κάντε και εμφανίστε μια ειδοποίηση που θα πάρει ένα όνομα και θα κάνει μια εργασία.

let alert = UIAlertController (τίτλος: "Κάντε μια εργασία", μήνυμα: "Τι θέλετε να το καλέσετε;", προτιμώμενο στυλ: UIAlertControllerStyle.alert)

alert.addTextField (configHandler: nil)

alert.addAction (UIAlertAction (τίτλος: "Ακύρωση", στυλ: UIAlertActionStyle.cancel, χειριστής: μηδέν))

alert.addAction (UIAlertAction (τίτλος: "Δημιουργία εργασίας", στυλ: UIAlertActionStyle.default, χειριστής: {(action) in

let task = Εργασία ()

task.name = (alert.textFields? [0] .text)!

δοκιμάστε! self.realm.write {

self.realm.add (εργασία)

self.taskList.tasks.append (εργασία)

           }

self.tableView.reloadData ()

       }))

self.present (ειδοποίηση, κινούμενη εικόνα: true, ολοκλήρωση: μηδέν)

   }

παράκαμψη func didReceiveMemoryWarning () {

super.didReceiveMemoryWarning ()

   }

παράκαμψη func numberOfSections (στο tableView: UITableView) -> Int {

επιστροφή 1

   }

παράκαμψη func tableView (_ tableView: UITableView, numberOfRowsInSection ενότητα: Int) -> Int {

επιστροφή self.taskList.tasks.count

   }

παράκαμψη func tableView (_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

let cell = tableView.dequeueReusableCell (withIdentifier: "reuseIdentifier", για: indexPath)

cell.textLabel? .text = self.taskList.tasks [indexPath.row]. όνομα

επιστροφή κελιού

   }

}

Αυτό είναι το μόνο που χρειάζεται για να ξεκινήσετε! Μπορείτε να γίνετε πολύ πιο έξυπνοι με τις ειδοποιήσεις συλλογής και αντικειμένων του Realm, ώστε να μπορείτε να φορτώσετε ξανά έξυπνα το tableView όταν ένα αντικείμενο προστίθεται ή διαγράφεται, αλλά προς το παρόν έχουμε επιμονή - το θεμέλιο μιας εφαρμογής για πρώτη φορά εκτός σύνδεσης.

Σειριοποίηση και αποεστεροποίηση

Μια εφαρμογή για πρώτη φορά εκτός σύνδεσης δεν αποτελεί μεγάλη εφαρμογή για πρώτη φορά εκτός σύνδεσης, εκτός εάν μπορεί επίσης να συνδεθεί στο διαδίκτυο και η λήψη δεδομένων από και προς το Realm μπορεί να είναι λίγο δύσκολη.

Πρώτα απ 'όλα, η αντιστοίχιση του σχήματος πελάτη σας με το σχήμα του διακομιστή σας είναι ζωτικής σημασίας. Δεδομένου του τρόπου λειτουργίας των περισσοτέρων βάσεων δεδομένων, αυτό πιθανότατα περιλαμβάνει την προσθήκη ενός πεδίου πρωτεύοντος κλειδιού στην τάξη Realm, καθώς τα αντικείμενα Realm δεν έχουν από προεπιλογή ένα πρωτεύον κλειδί.

Μόλις το σχήμα σας ταιριάζει καλά, χρειάζεστε έναν τρόπο για να αποεπιλέξετε τα δεδομένα που προέρχονται από τον διακομιστή στο Realm και να σειριοποιήσετε τα δεδομένα στο JSON για να τα στείλετε ξανά στον διακομιστή. Η ευκολότερη μέθοδος είναι να επιλέξετε την αγαπημένη σας βιβλιοθήκη χαρτογράφησης μοντέλου και να την αφήσετε να κάνει τη βαριά ανύψωση. Το Swift έχει Argo, Decodable, ObjectMapper και Mapper. Τώρα όταν λαμβάνετε μια απάντηση από τον διακομιστή σας, απλώς αφήνετε το μοντέλο mapper να το αποκωδικοποιήσει σε ένα εγγενές RealmObject.

Ωστόσο, δεν είναι τόσο καλή λύση. Πρέπει ακόμη να γράψετε έναν τόνο κώδικα δικτύωσης για να λάβετε το JSON από και προς τον διακομιστή σας με ασφάλεια, και ο κωδικός χαρτογράφησης του μοντέλου σας θα χρειαστεί επανεγγραφή και εντοπισμό σφαλμάτων οποτεδήποτε αλλάζει το σχήμα σας. Πρέπει να υπάρχει ένας καλύτερος τρόπος και πιστεύουμε ότι το Realm Mobile Platform είναι ακριβώς αυτό.

Εργασία με την πλατφόρμα Realm Mobile

Η πλατφόρμα Realm Mobile (RMP) σάς προσφέρει συγχρονισμό σε πραγματικό χρόνο, ώστε να μπορείτε να εστιάσετε στη δημιουργία μιας εφαρμογής για κινητά και όχι να παλέψετε για να μιλήσετε ο διακομιστής και η εφαρμογή. Απλώς παίρνετε το μοντέλο Realm παραπάνω, προσθέτετε τον έλεγχο ταυτότητας χρηστών του RMP και αφήνετε το RMP να φροντίσει για τον συγχρονισμό δεδομένων μεταξύ του διακομιστή και των τομέων της εφαρμογής σας. Στη συνέχεια, απλώς συνεχίζετε να εργάζεστε με εγγενή αντικείμενα Swift.

Για να ξεκινήσετε, κατεβάστε και εγκαταστήστε το πακέτο Realm Mobile Platform MacOS, το οποίο σας επιτρέπει να έχετε μια παρουσία Realm Object Server σε Mac σας πολύ γρήγορα. Στη συνέχεια, θα προσθέσουμε μερικά στοιχεία στην εφαρμογή λίστας υποχρεώσεων για να συνδεθεί με τον Realm Object Server.

Αφού ολοκληρώσετε τις οδηγίες εγκατάστασης παραπάνω, θα πρέπει να εκτελείται ο διακομιστής και ένας διαχειριστής στη διεύθυνση //127.0.0.1:9080. Θυμηθείτε αυτά τα διαπιστευτήρια και θα επιστρέψουμε στον κωδικό Swift.

Πριν γράψουμε άλλο κώδικα, πρέπει να κάνουμε δύο μικρές αλλαγές στο έργο. Αρχικά, πρέπει να μεταβούμε στο πρόγραμμα επεξεργασίας στόχου της εφαρμογής μας στο Xcode και στην καρτέλα "Ικανότητες", ενεργοποιήστε τον διακόπτη Κοινή χρήση Keychain.

Στη συνέχεια, θα πρέπει να επιτρέψουμε αιτήματα δικτύου εκτός TLS. Μεταβείτε στο αρχείο Info.plist του έργου και προσθέστε τα ακόλουθα μέσα στο ετικέτες:

NSAppTransportSecurity

NSAllowsArbitraryLoads