Alat khusus yang tidak akan menghalangi aplikasi Anda

Menjelang awal kursus dasar "pengembang iOS", kami telah menyiapkan terjemahan menarik lainnya untuk Anda.










: WWDC 2020, . , , — - , . , , - WWDC



Sebagian besar dari Anda mungkin pernah bekerja atau sedang mengerjakan aplikasi yang sebagian besar fungsinya bergantung pada komunikasi dengan server melalui HTTP. Ketika hal-hal tidak berfungsi seperti yang diharapkan, atau Anda hanya ingin memahami wilayah kode yang belum Anda kenal, sering kali membantu untuk melihat permintaan HTTP yang terjadi di antara aplikasi dan server. Permintaan apa yang dibuat? Apa sebenarnya pengiriman server? Untuk ini, Anda mungkin menggunakan alat seperti Charles Proxy atau Wireshark .



Namun, alat-alat ini seringkali cukup sulit untuk digunakan dan terutama untuk diatur. Mereka mungkin meminta Anda untuk menyiapkan sertifikat SSL Anda sendiri dan melakukan banyak langkah non-sepele agar perangkat memercayainya. Mereka juga menampilkan banyak informasi yang mungkin tidak pernah Anda perlukan untuk memahami aplikasi Anda. Dan pada saat yang sama, mereka sulit untuk memetakan apa yang terjadi di aplikasi Anda. Bagaimana jika saya memberi tahu Anda bahwa ada alat di luar sana yang dapat melakukan sebagian besar pekerjaan ini, yang memerlukan lebih sedikit kerumitan dari Anda untuk menyiapkannya, dan yang menampilkan informasi dengan cara yang jauh lebih sebanding dengan apa yang sebenarnya terjadi dalam aplikasi Anda? ?



Dalam persiapan untuk WWDC 1 minggu depan , saya (kembali) menyaksikan beberapa pembicaraan dari WWDC sebelumnya. Bagaimanapun, saya benar-benar merindukan bahwa alat inti ditulis ulang untuk menyatukannya dan membuatnya lebih mudah untuk membuat alat khusus untuk Xcode 10. Selain itu, WWDC 2019 ternyata menjadi pengantar yang bagus untuk alat yang telah saya lewatkan selama ini.



Keren, sekarang Anda bisa menulis alat Anda sendiri untuk mengukur hal-hal yang biasanya tidak diukur oleh alat. Tapi apa yang bisa Anda ukur dan seberapa mudah? Saya akan berkata: "hampir semuanya" dan "tidak terlalu sulit, cukup cepat." Biasanya, yang perlu Anda lakukan hanyalah menulis file XML yang memberi tahu Anda cara mengonversi penunjuk penunjuk arah dari kode Anda ke data untuk ditampilkan di alat, dan XML yang diperlukan untuk melakukan ini tidak terlalu mewah. Hambatan utamanya adalah bahwa "kode" yang Anda tulis kemungkinan besar sangat berbeda dari biasanya, hanya ada sedikit contoh, dokumentasi hanya memberikan gambaran umum tentang cara melakukannya, dan meskipun Xcode sebenarnya cukup memvalidasi file XML secara ketat, tidak ada pelengkapan otomatis, dan hanya sedikit yang dapat memudahkan Anda menemukan kesalahan. Tapi setelah menghabiskan sedikit waktuAnda dapat menemukan elemen yang Anda butuhkan, dan jika Anda memiliki contoh untuk menyesuaikan kode, Anda dapat menyelesaikan berbagai hal dengan cukup cepat. Di sini saya hanya akan memberikan contoh dan mencoba mencantumkan semua tautan yang berguna.



Tapi mari kita mulai dari awal: Saya ingin salah satu dari Anda yang pernah menggunakan Charles atau Wireshark sebelumnya men-debug aplikasi Anda, atau telah mengembangkan aplikasi yang membuat banyak permintaan HTTP, dapat membuat alat pelacakan HTTP yang disesuaikan untuk aplikasi Anda, atau setidaknya kerangka kerja. Ini akan terlihat seperti ini:







Saya membutuhkan waktu sekitar satu hari untuk membangun dan men-debug prototipe ini (setelah menonton video WWDC yang relevan). Jika Anda tidak tertarik pada apa pun selain kode, Anda dapat melihatnya di sini .



Gambaran



Cara termudah untuk membuat alat kustom adalah dengan menggunakan os_signpost , itulah yang akan kita lakukan di sini. Anda menggunakannya untuk mencatat penunjuk arah .event atau .begin dan .end . Kemudian Anda menyiapkan alat khusus untuk menganalisis interval os_signpost ini dan mengekstrak nilai tambahan yang Anda masuki, mengatur cara menampilkannya pada grafik, cara mengelompokkannya, mana yang akan difilter, dan cara menyajikan struktur daftar atau pohon / diagram alur di panel detail alat. ...



Kami ingin membuat alat yang menampilkan semua permintaan HTTP yang melewati perpustakaan web kami sebagai interval (mulai + akhir) sehingga kami dapat melihat berapa lama waktu yang dibutuhkan dan menghubungkannya dengan peristiwa lain yang terjadi di aplikasi kami. Pada artikel ini, saya menggunakan Alamofire sebagai perpustakaan jaringan alat dan Wordpress sebagai aplikasi profil saya, hanya karena mereka open source. Tetapi Anda dapat dengan mudah menyesuaikan semua kode ke perpustakaan jaringan Anda.



Langkah 0: Lihat Aplikasi Instrumen



  1. ( 411 WWDC 2019) — . «Orientation», , (instruments), (tracks), (lanes), (traces), (templates), (detail view) . .
  2. ( 410 WWDC 2018), , . , «Architecture» ( , , ) «Intermediate». , , , - . , , . , .




1: signpost-



Kami ingin membangun alat kami di papan penunjuk, yaitu, kami akan mencatat data kami melalui penunjuk arah. Alamofire mengirimkan Notifikasi setiap kali permintaan dimulai atau diakhiri, jadi yang kami butuhkan hanyalah 2 :



NotificationCenter.default.addObserver(forName: Notification.Name.Task.DidResume, object: nil, queue: nil) { (notification) in
    guard let task = notification.userInfo?[Notification.Key.Task] as? URLSessionTask,
        let request = task.originalRequest,
        let url = request.url else {
            return
    }
    let signpostId = OSSignpostID(log: networking, object: task)
    os_signpost(.begin, log: SignpostLog.networking, name: "Request", signpostID: signpostId, "Request Method %{public}@ to host: %{public}@, path: %@, parameters: %@", request.httpMethod ?? "", url.host ?? "Unknown", url.path, url.query ?? "")
}
NotificationCenter.default.addObserver(forName: Notification.Name.Task.DidComplete, object: nil, queue: nil) { (notification) in
    guard let task = notification.userInfo?[Notification.Key.Task] as? URLSessionTask else { return }
    let signpostId = OSSignpostID(log: networking, object: task)
    let statusCode = (task.response as? HTTPURLResponse)?.statusCode ?? 0
    os_signpost(.end, log: SignpostLog.networking, name: "Request", signpostID: signpostId, "Status: %@, Bytes Received: %llu, error: %d, statusCode: %d", "Completed", task.countOfBytesReceived, task.error == nil ? 0 : 1, statusCode)
}




Saat request dimulai, kita log plang .begin, setelah selesai kita tambahkan plang .end. Untuk mencocokkan akhir panggilan dengan awal panggilan yang sesuai digunakan signpostIduntuk memastikan kita menutup interval yang benar jika beberapa permintaan terjadi secara paralel. Idealnya, kita harus menyimpan signpostIddi objek permintaan untuk memastikan kita menggunakan yang sama untuk .begindan .end. Namun, saya tidak ingin mengedit tipe Requestdi Alamofire, jadi saya memutuskan untuk menggunakan OSSignpostID(log:, object:)dan meneruskan objek ID ke sana. Kami menggunakan objek dasar URLSessionTaskkarena dalam kedua kasus itu akan sama, yang memungkinkan OSSignpostID(log:, object:)kami mengembalikan pengenal yang sama ketika dipanggil beberapa kali.



Kami mencatat data menggunakan format string. Anda mungkin harus selalu memisahkan dua argumen dengan beberapa string yang terdefinisi dengan baik untuk mempermudah penguraian di sisi alat dan juga untuk mempermudah penguraian. Harap dicatat bahwa Anda tidak perlu memasukkan data dalam .endpanggilan jika Anda sudah login .begin. Mereka akan digabungkan menjadi satu interval dan Anda akan memiliki akses ke sana.



Langkah 2: Buat proyek alat kustom baru di Xcode.



Ikuti langkah-langkah dari Membuat Instrumen Kustom (Sesi 410 dari WWDC 2018) atau bantuan Aplikasi Instrumen - Membuat Proyek Kotak Alat untuk membuat proyek kotak alat baru di Xcode. Ini akan memberi Anda proyek Xcode dasar dengan .instrpkgfile. Kami akan menunjukkan semua detail di sana.



Langkah 3: lakukan sisanya



Pada dasarnya, Anda akan mengikuti langkah-langkah yang diuraikan dalam bantuan Aplikasi Instrumen - Membuat alat dari data penunjuk arah . Meskipun uraian dari semua langkah di sini benar, namun masih kurang banyak detail, jadi yang terbaik adalah memiliki contoh alat kustom yang nyata di depan Anda. Anda dapat melihat milik saya di sini . Pada dasarnya Anda memerlukan bagian-bagian berikut:



Skema



Ini memberi tahu alat-alat bagaimana mengurai data dari penunjuk arah Anda menjadi variabel yang dapat Anda gunakan. Anda menentukan template yang mengekstrak variabel dari pesan log Anda dan mendistribusikannya ke seluruh kolom.



<os-signpost-interval-schema>
	<id>org-alamofire-networking-schema</id>
	<title>Alamofire Networking Schema</title>

	<subsystem>"org.alamofire"</subsystem>
	<category>"networking"</category>
	<name>"Request"</name>

	<start-pattern>
	    <message>"Request Method " ?http-method " to host: " ?host ", path: " ?url-path ", parameters: " ?query-parameters</message>
	</start-pattern>
	<end-pattern>
	    <message>"Status: " ?completion-status ", Bytes Received: " ?bytes-received ", error: " ?errored ", statusCode: " ?http-status-code</message>
	</end-pattern>

	<column>
	    <mnemonic>column-http-method</mnemonic>
	    <title>HTTP Method</title>
	    <type>string</type>
	    <expression>?http-method</expression>
	</column>
	<!--      -->
</os-signpost-interval-schema>




mnemonicadalah pengenal yang akan Anda rujuk ke kolom ini nanti. Untuk beberapa alasan saya merasa agak aneh memberi nama kolom sama dengan variabel, jadi saya meletakkan awalan di depannya column. Tapi, sejauh yang saya tahu, tidak perlu melakukan ini.



Alat



Alat terdiri dari definisi dasar:



<instrument>
    <id>org.alamofire.networking.instrument</id>
    <title>Alamofire</title>
    <category>Behavior</category>
    <purpose>Trace HTTP calls made via Alamofire, grouped by method, host, path, etc.</purpose>
    <icon>Network</icon>
    
    <create-table>
        <id>alamofire-requests</id>
        <schema-ref>org-alamofire-networking-schema</schema-ref>
    </create-table>

    <!--     -->
</instrument>




Sangat sederhana. Sebagian besar bidang ini adalah teks format bebas atau terkait dengan materi yang Anda tentukan sebelumnya ( schema-ref). Tetapi categoryjuga iconhanya dapat memiliki sekumpulan kecil nilai yang ditentukan di sini dan di sini .



Grafik dalam alat



Grafik menentukan bagian grafis dari antarmuka pengguna alat, representasi visual yang Anda lihat di area trek. Ini terlihat seperti ini:



<instrument>
    <!--    -->
    <graph>
        <title>HTTP Requests</title>
        <lane>
            <title>the Requests</title>
            <table-ref>alamofire-requests</table-ref>
            
            <plot-template>
                <instance-by>column-host</instance-by>
                <label-format>%s</label-format>
                <value-from>column-url-path</value-from>
                <color-from>column-response</color-from>
                <label-from>column-url-path</label-from>
            </plot-template>
        </lane>
    </graph>
    <!--    --> 
</instrument>




Anda dapat memiliki jalur yang berbeda, dan Anda dapat menggunakan templat-plot untuk menerapkan jumlah plot yang dinamis per jalur. Contoh saya berisi contoh grafik sederhana . Saya tidak yakin mengapa graphdan lanememiliki gelar. Selain itu, setiap bagan di plot-templatejuga menerima label dari label-format.



Daftar, agregasi, atau apa pun untuk tampilan mendetail



Hanya dengan bagan, alat akan terlihat agak tidak lengkap. Anda juga ingin menampilkan sesuatu di Tampilan Detail. Anda dapat melakukan ini dengan list, aggregationatau narrative. Mungkin ada lebih banyak opsi yang belum saya temui. Agregasinya terlihat seperti ini:



<instrument>
    <!--    -->
    <aggregation>
        <title>Summary: Completed Requests</title>
        <table-ref>alamofire-requests</table-ref>
        <slice>
                <column>column-completion-status</column>
                <equals><string>Completed</string></equals>
        </slice>
        <hierarchy>
            <level>
                <column>column-host</column>
            </level>
            <level>
                <column>column-url-path</column>
            </level>
        </hierarchy>
        
        <column><count/></column>
        <column><average>duration</average></column>
        <column><max>duration</max></column>
        <column><sum>column-size</sum></column>
        <column><average>column-size</average></column>
    </aggregation>
    <!--    --> 
</instrument>




daftarnya terlihat seperti ini:



<instrument>
    <!--    -->
    <list>
        <title>List: Requests</title>
        <table-ref>alamofire-requests</table-ref>
        <column>start</column>
        <column>duration</column>
        <column>column-host</column>
        <!--   ->
    </list>
    <!--    -->
</instrument>




Materi bonus



Faktanya, ini semua. Namun, Anda belum melakukan lebih dari yang dijelaskan video WWDC, dan saya berjanji untuk mengisi beberapa celah.



Alat contoh saya berisi beberapa hal bagus lainnya. Ekspresi CLIPS



kecil untuk mewarnai interval tergantung pada apakah permintaan itu berhasil atau tidak . Anda dapat menemukan nilai warna dalam Referensi Jenis Rekayasa Instrumen . Dengan templat bagan, Anda dapat menampilkan beberapa bagan dalam satu strip atau, misalnya, memiliki bagan per host, seperti dalam contoh saya. Namun, Anda bisa memiliki lebih dari satu tingkat hierarki dan mengizinkan pengguna untuk memperluas atau menciutkan bagian. Untuk ini, Anda perlu menggunakan elemen ,

<engineering-type-track>untuk menentukan hierarki Anda , lalu tambahkan (augmentasi) untuk berbagai tingkat hierarki untuk menambahkan grafik dan tampilan detail . Juga, jangan lupa untuk mengaktifkan add-on di dalam alatnya masing-masing.



Tindakan selanjutnya



Jika Anda belum menemukannya dari tautan sebelumnya, sebenarnya ada bantuan lengkap untuk semua yang dapat Anda masukkan ke dalam .instrpkgfile. Misalnya, ini akan memberi tahu Anda elemen <instrument>mana atau ikon mana yang dapat Anda pilih untuk alat Anda. Satu hal penting: keteraturan itu penting. Jadi, misalnya, dalam <instrument>, <title>harus muncul lebih awal dari <category>, jika tidak maka deskripsi tidak valid.



Tinjau pembuatan alat khusus (Sesi 410 dari WWDC 2018) lagi untuk mencatat detail yang mungkin Anda perlukan. Ada juga contoh kode dari sesi WWDC 2019 dimana saya menemukan contoh penggunaan <engineering-type-track>.



CLIPS adalah bahasa yang digunakan untuk menulis pemodel kustom (pemodel - kami tidak akan membahasnya di sini), tetapi juga dapat digunakan untuk ekspresi singkat selama deklarasi kolom. Dokumentasi bahasa jauh lebih luas dari yang Anda butuhkan. Hal utama yang mungkin perlu Anda ketahui untuk menulis ekspresi sederhana adalah CLIPS menggunakan notasi awalan, jadi ?a + ?bAnda harus menuliskannya (+ ?a ?b).



Lebih banyak artikel tentang alat kustom



Igor tentang membuat kotak alat khusus di Xcode



Debugging



Itu selalu merupakan ide yang baik untuk menambahkan alat XCodeos_signpostke dokumen jejak Anda. Dengan cara ini, jika ada sesuatu yang tidak berfungsi seperti yang diharapkan, Anda dapat memeriksa apakah data Anda dicatat dengan benar dan apakah alat Anda menafsirkannya dengan benar.



Apa yang belum saya temukan



  • Cara menggunakan nilai yang diberikan Instrumen kepada Anda secara default dan ditampilkan di antarmuka pengguna (misalnya, durasi) dalam ekspresi untuk definisi kolom (misalnya, untuk membuat kolom baud rate dengan membagi byte yang diterima dengan durasi).
  • Bagaimana menampilkan sesuatu di area detail ekstra. Rasanya seperti hanya untuk tumpukan panggilan. Saya ingin menampilkan, misalnya, isi JSON dari permintaan yang dipilih, tetapi belum menemukan contoh yang menjelaskan hal ini.




Kemampuan alat ini



Pekerjaan masih dalam proses



Unduh dan lihat sendiri.



Catatan kaki



  1. Oke, sebenarnya ada alasan lain.
  2. Kode lengkap untuk masuk dalam contoh saya ada di file Logger.swift . Diasumsikan untuk Alamofire 4.8, karena itulah yang digunakan oleh versi aplikasi Wordpress iOS saat ini, meskipun Alamofire 5 sudah dirilis pada saat penulisan. Karena adanya notifikasi, kode logging ini mudah ditambahkan tanpa mengubah Alamofire itu sendiri, namun jika Anda memiliki perpustakaan jaringan khusus, mungkin lebih mudah menambahkan entri ke perpustakaan itu sendiri untuk mengakses detail lebih lanjut.





Awal yang cepat untuk pengembangan iOS (webinar gratis)






Baca lebih banyak






All Articles