βέλτιστες πρακτικές και εργαλεία του έργου iOS

Με ένα πρότυπο έργου Xcode ανοιχτού κώδικα

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

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

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

Cocoapods

Δεν νομίζω ότι αυτό χρειάζεται μια εισαγωγή. Αυτή είναι η βιβλιοθήκη για τη διαχείριση εξωτερικών εξαρτήσεων για έργα iOS. Έχει περάσει εδώ και πολύ καιρό και είναι ανθεκτικό και δοκιμασμένο σε χιλιάδες (αν όχι εκατομμύρια) έργα. Υπάρχουν εναλλακτικοί διαχειριστές εξάρτησης εκεί έξω όπως η Καρχηδόνα, αλλά αποφάσισα να πάω με τα Cocoapods επειδή έχει το μεγαλύτερο εύρος έργου ανοιχτού κώδικα που υποστηρίζει. Χρησιμοποιώντας Cocoapods είναι πολύ εύκολο και έρχεται με ένα ευρετήριο αναζήτησης που σας επιτρέπει να ανακαλύψετε εύκολα πακέτα που μπορεί να χρειαστείτε.

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

Swiftlint

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

R.swift

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

  • Πλήρης πληκτρολόγηση - λιγότερο χύτευση και μαντέψει τι θα επιστρέψει μια μέθοδος
  • Συμπληρώστε το χρόνο ελέγχου - δεν υπάρχουν πλέον λανθασμένες συμβολοσειρές που καταστροφή της εφαρμογής σας κατά το χρόνο εκτέλεσης
  • Αυτόματη ολοκλήρωση - δεν πρέπει ποτέ να μαντέψετε ξανά αυτό το όνομα εικόνας / μίσχου / storyboard

Σκεφτείτε τον παρακάτω κώδικα χρησιμοποιώντας το επίσημο API συμβολοσειράς:

ας εικονίδιο = UIImage (με όνομα: "προσαρμοσμένο εικονίδιο")

Εάν αναγγείλετε λάθος το όνομα της εικόνας, θα πάρετε ένα μηδέν εδώ. Εάν κάποιο μέλος της ομάδας σας αλλάξει το όνομα της πηγής εικόνας, αυτός ο κωδικός θα επιστρέψει σε μηδέν ή θα διακοπεί αν αναγκαστεί να αναδιπλωθεί η εικόνα. Όταν χρησιμοποιείτε το R.swift αυτό γίνεται:

αφήστε το εικονίδιο = R.image.customIcon ()

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

Το R.swift εγκαθίσταται μέσω Cocoapods και ενσωματώνεται στο πρότυπο ως φάση κατασκευής και παράγει τις κλάσεις περιτύλιξης Swift σε κάθε κατασκευή. Αυτό σημαίνει ότι αν προσθέσετε ένα αρχείο / εικόνα / localization / font / color / nib κ.λπ., θα είναι διαθέσιμο σε σας χρησιμοποιώντας το R.swift μόλις συντάξετε το έργο.

Ξεχωριστό AppDelegate για δοκιμές

Μια συχνά παραβλεφθείσα καλή πρακτική είναι να έχετε μια ξεχωριστή κλάση TestAppDelegate κατά τη διεξαγωγή δοκιμών. Γιατί είναι καλή ιδέα; Λοιπόν, συνήθως η κλάση AppDelegate κάνει πολλή δουλειά κατά την εκκίνηση της εφαρμογής. Θα μπορούσε να δημιουργήσει ένα παράθυρο, να δημιουργήσει τη βασική δομή του UI της εφαρμογής, να καταχωρίσει τις ειδοποιήσεις, να ρυθμίσει μια βάση δεδομένων και ακόμη και κάποιες φορές να κάνει κλήσεις API σε κάποια υπηρεσία backend. Οι δοκιμές μονάδας δεν πρέπει να έχουν παρενέργειες. Πραγματικά δεν θέλετε να κάνετε τυχαίες κλήσεις API και να ρυθμίσετε όλη τη δομή του UI της εφαρμογής σας μόνο για να εκτελέσετε ορισμένες δοκιμές μονάδων;

Το TestAppDelegate είναι επίσης ένα εξαιρετικό μέρος για να έχετε κώδικα που θέλετε μόνο να εκτελεστεί μία φορά κατά τη διάρκεια της εκτέλεσης της δοκιμαστικής σουίτας. Θα μπορούσε να περιέχει κώδικα που δημιουργεί mocks, stubs απαιτήσεις δικτύου κ.λπ.

Το πρότυπο περιέχει ένα αρχείο main.swift που αποτελεί το κύριο σημείο εισόδου για την εφαρμογή. Αυτό το αρχείο έχει μεθόδους που ελέγχουν ποιο είναι το περιβάλλον που εκτελείται αυτή τη στιγμή η εφαρμογή και αν είναι το περιβάλλον δοκιμής, καλεί το TestAppDelegate.

Παράμετροι προφίλ επιδόσεων του μεταγλωττιστή

Το Swift είναι μια μεγάλη γλώσσα, πιο εύκολη στη χρήση και πολύ πιο ασφαλής από τον Στόχο-C (IMO). Αλλά όταν εισήχθη για πρώτη φορά είχε ένα μεγάλο μειονέκτημα - καταρτίζει φορές. Πίσω στο Swift 2 ημέρες, δούλευα σε ένα έργο το οποίο είχε γραμμές 40k Swift κώδικα (μεσαίου μεγέθους έργο). Ο κώδικας ήταν πολύ βαρύς με συμπεράσματα τύπου generics και τύπου και χρειάστηκαν περίπου 5 λεπτά για να μεταγλωττίσει μια καθαρή κατασκευή. Όταν κάνατε και μια μικρή αλλαγή, το έργο θα ανασυνταχθεί και χρειάστηκε περίπου 2 λεπτά για να δει την αλλαγή. Αυτή ήταν μια από τις χειρότερες εμπειρίες ανάπτυξης που είχα ποτέ και σχεδόν σταμάτησα να χρησιμοποιώ το Swift εξαιτίας αυτού.

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

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

Διαμόρφωση Dev / Staging / Παραγωγή

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

Ένας τρόπος υποστήριξης πολλαπλών περιβαλλόντων σε ένα έργο iOS είναι η προσθήκη διαμορφώσεων επιπέδου έργου.

Ρυθμίσεις επιπέδου έργου

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

Configuration.plist

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

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

Όλα αυτά είναι προκαθορισμένα για εσάς στο πρότυπο.

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

Readme

Κάθε έργο πρέπει να έχει ένα βασικό στοιχείο Readme που έχει τουλάχιστον οδηγίες για τον τρόπο εγκατάστασης εξαρτήσεων και την εκτέλεση του έργου. Θα πρέπει επίσης να περιέχει περιγραφές της αρχιτεκτονικής και των ενοτήτων του έργου. Δυστυχώς, οι προγραμματιστές δεν επιθυμούν να γράψουν τεκμηρίωση (ένα readme είναι μέρος αυτού) και έχω δει έργα που αναπτύχθηκαν εδώ και μήνες και είχαν ακόμη και ένα βασικό Readme. Για να αφαιρέσετε το βάρος της σύνταξης αυτού του βασικού readme, το πρότυπο περιέχει ένα πρότυπο readme που καλύπτει την εγκατάσταση και τη δομή του έργου. Όταν ρυθμίζετε ένα νέο έργο χρησιμοποιώντας το πρότυπο, θα συμπεριληφθεί αυτόματα το Readme.

Gitignore

Σήμερα, τα περισσότερα έργα χρησιμοποιούν το GIT ως σύστημα ελέγχου έκδοσης. Όταν χρησιμοποιείτε το GIT, συνήθως δεν θέλετε να αγνοήσετε ορισμένα αρχεία ή φακέλους του έργου, όπως το φάκελο δημιουργίας ή ο φάκελος των παραγόμενων δεδομένων. Για να σας εξοικονομήσει το πρόβλημα της αναζήτησης ενός αρχείου gitignore που ταιριάζει στο έργο iOS, το πρότυπο περιλαμβάνει ένα τυπικό gitignore που παρέχεται από τους συνδρομητές της Github.

Κλάσεις βάσης για χειρισμούς αποτυχιών και ειδοποιήσεων

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

Περίληψη

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

PS: Εάν έχετε οποιαδήποτε ζητήματα ή αιτήματα χαρακτηριστικών για το πρότυπο απλά αφήστε μου ένα ζήτημα στο Github. Θα προσπαθήσω να το επιλύσω στον ελεύθερο χρόνο μου.