[Разработка под iOS, Swift] Пользовательский инструмент, который не помешал бы вам в вашем приложении (перевод)
Автор
Сообщение
news_bot ®
Стаж: 6 лет 9 месяцев
Сообщений: 27286
В преддверии старта базового курса «iOS-разработчик» подготовили для вас еще один интересный перевод.
Примечание: Эта статья был написана незадолго до WWDC 2020, но вам следует читать ее только после просмотра конференции. Все, о чем здесь пойдет речь, уже доступно — вам не нужно скачивать бета-версию или ждать до осени, чтобы использовать это. Также, я собираюсь обновить статью, если что-нибудь относящееся к ней зарелизят на WWDC
Большинство из вас, вероятно, уже работали или в настоящее время работают над приложением, для которого значительная часть функциональности зависит от связи с сервером посредством HTTP. Когда что-то работает не так, как ожидалось, или вы просто хотите понять область кода, с которой вы еще не знакомы, часто бывает полезно посмотреть HTTP-запросы, идущие между приложением и сервером. Какие запросы были сделаны? Что именно отправляет сервер? Для этого вы, вероятно, используете такие инструменты, как Charles Proxy или Wireshark.
Однако эти инструменты часто довольно сложны в использовании и особенно в настройке. Они могут потребовать, чтобы вы настроили собственный SSL сертификат и выполнили множество нетривиальных операций, чтобы заставить устройство доверять ему. Они также отображают очень много информации, которая может вам никогда и не понадобиться для понимания вашего приложения. И в то же время их трудно сопоставить с тем, что происходит в вашем приложении. Что, если я скажу вам, что существуют инструменты, которые могут выполнять большую часть этой работы, требующие от вас значительно меньше мороки с их настройкой, и отображающие информацию в виде, который намного более сопоставим с тем, что на самом деле происходит в вашем приложении?
В качестве подготовки к WWDC на следующей неделе1, я (пере)смотрел пару выступлений из предыдущих WWDC. Так или иначе, я полностью упустил, что ядро инструментов было переписано, чтобы унифицировать их, и сделать его намного проще для создания пользовательских инструментов для Xcode 10. Кроме того, WWDC 2019 оказался отличным введением в инструменты, чего мне не хватало все эти годы.
Круто, теперь вы можете писать собственные инструменты для измерения того, что инструменты обычно не измеряют. Но что вы можете измерить и насколько это легко? Я бы сказал: «почти все» и «не то чтобы очень сложно, достаточно быстро». Как правило, все, что вам нужно — написать XML-файл, в котором будет указано, как преобразовывать signpost-указатели из вашего кода в данные для отображения в инструментах, а XML-код, необходимый для этого, не особо замысловат. Основным препятствием является то, что «код», который вы пишете, вероятно, будет сильно отличаться от того, к чему вы привыкли, примеров очень мало, документация дает только общий обзор того, как это нужно делать, и хотя Xcode на самом деле довольно строго проверяет XML-файлы, автодополнения нет и мало что может упростить вам поиск ошибок. Но, потратив немного времени, можно найти нужные вам элементы, а если у вас есть пример для адаптации кода, вы сможете добиться результата довольно быстро. Здесь я как раз и собираюсь привести такой пример и постараться перечислить все полезные ссылки.
Но давайте начнем с самого начала: я хочу, чтобы каждый из вас, кто раньше использовал Charles или Wireshark для отладки своего приложения, или разрабатывал приложение, которое выполняет множество HTTP-запросов, смог создать инструмент трассировки HTTP, настроенный под ваше приложение или, по крайней мере, фреймворк. Он будет выглядеть так:
У меня ушел приблизительно один день на то, чтобы создать и отладить этот прототип (после просмотра соответствующих видео WWDC). Если вас не интересует ничего кроме кода, вы можете посмотреть его здесь.
Обзор
Самый простой способ создать пользовательский инструмент — это использовать os_signpost, собственно что мы и собираемся здесь делать. Вы используете его для логирования signpost-указателей .event или .begin и .end. Затем вы настраиваете пользовательский инструмент для анализа этих os_signpost интервалов и извлечения дополнительных значений, которые вы логировали в него, настраиваете, как отобразить их на графике, как сгруппировать их, какие отфильтровать и как представлять структуры списков или деревьев/блок-схем в панели подробностей инструмента.
Мы хотим создать инструмент, который отображает все HTTP-запросы, которые проходят через нашу сетевую библиотеку, как интервалы (начало + конец), чтобы мы могли видеть, сколько времени они занимают, и сопоставлять их с другими событиями, происходящими в нашем приложении. В этой статье я использую Alamofire в качестве сетевой библиотеки инструмента и Wordpress в качестве приложения для профилирования, просто потому что у них открытый исходный код. Но вы легко сможете адаптировать весь код к вашей сетевой библиотеке.
Шаг 0: Ознакомьтесь с Instruments App
- Начало работы с инструментами (Сессия 411 из WWDC 2019) — это очень хороший обзор инструментов. Посмотрите хотя бы раздел «Orientation», чтобы ознакомиться с терминологией, такой как инструменты (instruments), треки (tracks), полосы (lanes), трейсы (traces), шаблоны (templates), подробный вид (detail view) и т. д.
- Посмотрите Создание пользовательских инструментов (Сессия 410 из WWDC 2018), чтобы получить представление о том, что мы здесь делаем. Если вы слишком нетерпеливы, достаточно посмотреть разделы «Architecture» (для получения дополнительной информации о том, как работают инструменты, и что вы на самом деле настраиваете) и «Intermediate». Не ожидайте, что поймете все тонкости во время просмотра, там показано слишком много всего для одного сеанса, и они не объясняют каждую деталь из-за временных ограничений. Мне приходилось смотреть это несколько раз и искать дополнительную документацию, прежде чем я действительно смог заставить свой инструмент работать так, как мне было нужно. Тем не менее, я попытаюсь заполнить некоторые пробелы ниже.
Шаг 1: Логирование нужных вам данных в signpost-указатели
Мы хотим построить наш инструмент на signpost-указателях, то есть мы будем логировать наши данные через signpost. Alamofire отправляет Notification каждый раз, когда запрос начинается или завершается, поэтому все, что нам нужно, это что-то вроде этого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)
}
Когда запрос начинается, мы логируем signpost .begin, когда он завершается, мы добавляем signpost .end. Для сопоставления завершения вызова с соответствующим началом вызова используется signpostId, чтобы убедиться, что мы закрываем правильный интервал, если несколько запросов происходят параллельно. В идеале мы должны хранить signpostId в объекте запроса, чтобы быть уверенными, что мы используем один и тот же для .begin и .end. Однако я не хотел править тип Request в Alamofire, поэтому решил использовать OSSignpostID(log:, object:) и передавать ему объект-идентификатор. Мы используем базовый объект URLSessionTask, поскольку в обоих случаях он будет одинаковым, а это позволяет OSSignpostID(log:, object:) возвращать нам один и тот же идентификатор при его многократном вызове.
Мы логируем данные посредством format string. Вам, вероятно, следует всегда разделяете два аргумента некоторой четко определенной строкой, чтобы упростить анализ на стороне инструмента, а также облегчить парсинг. Обратите внимание, что вам не нужно логировать данные в .end вызове, если вы уже логировали их в .begin. Они будут объединены в один интервал и у вас будет к ним доступ.
Шаг 2: Создайте новый проект пользовательского инструмента в Xcode.
Следуйте по шагам из Создания пользовательских инструментов (Сессия 410 из WWDC 2018) или справки Instruments App — Создание проект пакета инструментов, чтобы создать новый проект пакета инструментов в Xcode. В результате вы получите базовый проект Xcode с .instrpkg файлом. Все детали мы укажем там.
Шаг 3: Сделайте все остальное
В основном вы будете следовать шагам, описанным в справке Instruments App — Создание инструмента на основе данных signpost-указателей. Несмотря на то, что описания всех шагов здесь корректны, им все же не хватает множества деталей, поэтому лучше иметь перед собой пример реального пользовательского инструмента. Вы можете посмотреть на мой здесь. В основном вам понадобятся следующие части:
Схема
Она сообщает инструментам, как парсить данные из ваших signpost-указателей в переменные, которые вы сможете использовать. Вы определяете шаблон, который извлекает переменные из ваших лог-сообщений и распределяет их по столбцам.
<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>
mnemonic является идентификатором того, что вы собираетесь ссылаться на этот столбец позже. Мне почему-то было немного странно называть столбцы так же, как переменные, поэтому я поставил перед ними префикс column. Но, насколько я знаю, необходимости это делать нет.
Инструмент
Инструмент состоит из базового определения:
<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>
Все довольно просто. Большинство из этих полей представляют собой текст произвольной формы или относятся к материалам, которые вы определили ранее (schema-ref). Но category и icon могут иметь только небольшой набор значений, определенных здесь и здесь.
График внутри инструмента
График (graph) определяет графическую часть пользовательского интерфейса инструмента, визуальное представление, которое вы видите в области трека. Это выглядит примерно так:
<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>
У вас могут быть разные полосы (lane), и вы можете использовать шаблон графика (plot-template), чтобы реализовать динамическое число графиков в полосе. Мой пример содержит пример простого графика. Я не совсем уверен, почему у graph и lane есть заголовки. В дополнение к этому каждый график в plot-template также получает метку от label-format.
Список, агрегация или что там еще для подробного представления
С одним лишь графиком инструменты выглядели бы несколько неполными. Вы также хотели бы отобразить что-нибудь в подробном представлении (Detail View). Вы можете сделать это с помощью list, aggregation или narrative. Может быть даже больше вариантов, которые я еще не встречал. Агрегация выглядит примерно так:
<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>
список выглядит следующим образом:
<instrument>
<!-- Базовое определение инструмента -->
<list>
<title>List: Requests</title>
<table-ref>alamofire-requests</table-ref>
<column>start</column>
<column>duration</column>
<column>column-host</column>
<!-- Остальные столбцы ->
</list>
<!-- остальные части инструмента -->
</instrument>
Бонусный материал
На этом, по сути, все
===========
Источник:
habr.com
===========
===========
Автор оригинала: Joachim Kurz
===========Похожие новости:
- [Информационная безопасность, Разработка под iOS, Разработка мобильных приложений, Монетизация мобильных приложений] ФАС обвинила Apple в ограничении конкуренции на рынке iOS-приложений
- [Разработка под iOS, Objective C, Swift] Разделяй и властвуй. Модульное приложение из монолита на Objective-C и Swift
- [Программирование, .NET, C#] Что же такого особенного в IAsyncEnumerable в .NET Core 3.0? (перевод)
- [Программирование, Go] Новый API Go для Protocol Buffers (перевод)
- [Разработка под iOS, Смартфоны, IT-компании] Apple подтвердила, что облачные сервисы по типу xCloud и Stadia нарушают условия AppStore и поэтому запрещены
- [Программирование, Java] Интеграционное тестирование в SpringBoot с TestContainers-стартером (перевод)
- [Разработка под iOS, Разработка под Android, Смартфоны, Накопители] Почему iPhone хватает 4 ГБ ОЗУ, а Android — нет?
- [Программирование, Go] Указатель или копия структуры: что выгоднее использовать в Golang?
- [Разработка под iOS, Разработка под Android, Swift, Дизайн мобильных приложений] FigmaExport: как автоматизировать экспорт UI-Kit из Figma в Xcode и Android Studio проекты
- [Разработка под iOS, Тестирование мобильных приложений] Sberbank Online iOS testing
Теги для поиска: #_razrabotka_pod_ios (Разработка под iOS), #_swift, #_wwdc_2020, #_ios, #_swift, #_blog_kompanii_otus._onlajnobrazovanie (
Блог компании OTUS. Онлайн-образование
), #_razrabotka_pod_ios (
Разработка под iOS
), #_swift
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:14
Часовой пояс: UTC + 5
Автор | Сообщение |
---|---|
news_bot ®
Стаж: 6 лет 9 месяцев |
|
В преддверии старта базового курса «iOS-разработчик» подготовили для вас еще один интересный перевод. Примечание: Эта статья был написана незадолго до WWDC 2020, но вам следует читать ее только после просмотра конференции. Все, о чем здесь пойдет речь, уже доступно — вам не нужно скачивать бета-версию или ждать до осени, чтобы использовать это. Также, я собираюсь обновить статью, если что-нибудь относящееся к ней зарелизят на WWDC Большинство из вас, вероятно, уже работали или в настоящее время работают над приложением, для которого значительная часть функциональности зависит от связи с сервером посредством HTTP. Когда что-то работает не так, как ожидалось, или вы просто хотите понять область кода, с которой вы еще не знакомы, часто бывает полезно посмотреть HTTP-запросы, идущие между приложением и сервером. Какие запросы были сделаны? Что именно отправляет сервер? Для этого вы, вероятно, используете такие инструменты, как Charles Proxy или Wireshark. Однако эти инструменты часто довольно сложны в использовании и особенно в настройке. Они могут потребовать, чтобы вы настроили собственный SSL сертификат и выполнили множество нетривиальных операций, чтобы заставить устройство доверять ему. Они также отображают очень много информации, которая может вам никогда и не понадобиться для понимания вашего приложения. И в то же время их трудно сопоставить с тем, что происходит в вашем приложении. Что, если я скажу вам, что существуют инструменты, которые могут выполнять большую часть этой работы, требующие от вас значительно меньше мороки с их настройкой, и отображающие информацию в виде, который намного более сопоставим с тем, что на самом деле происходит в вашем приложении? В качестве подготовки к WWDC на следующей неделе1, я (пере)смотрел пару выступлений из предыдущих WWDC. Так или иначе, я полностью упустил, что ядро инструментов было переписано, чтобы унифицировать их, и сделать его намного проще для создания пользовательских инструментов для Xcode 10. Кроме того, WWDC 2019 оказался отличным введением в инструменты, чего мне не хватало все эти годы. Круто, теперь вы можете писать собственные инструменты для измерения того, что инструменты обычно не измеряют. Но что вы можете измерить и насколько это легко? Я бы сказал: «почти все» и «не то чтобы очень сложно, достаточно быстро». Как правило, все, что вам нужно — написать XML-файл, в котором будет указано, как преобразовывать signpost-указатели из вашего кода в данные для отображения в инструментах, а XML-код, необходимый для этого, не особо замысловат. Основным препятствием является то, что «код», который вы пишете, вероятно, будет сильно отличаться от того, к чему вы привыкли, примеров очень мало, документация дает только общий обзор того, как это нужно делать, и хотя Xcode на самом деле довольно строго проверяет XML-файлы, автодополнения нет и мало что может упростить вам поиск ошибок. Но, потратив немного времени, можно найти нужные вам элементы, а если у вас есть пример для адаптации кода, вы сможете добиться результата довольно быстро. Здесь я как раз и собираюсь привести такой пример и постараться перечислить все полезные ссылки. Но давайте начнем с самого начала: я хочу, чтобы каждый из вас, кто раньше использовал Charles или Wireshark для отладки своего приложения, или разрабатывал приложение, которое выполняет множество HTTP-запросов, смог создать инструмент трассировки HTTP, настроенный под ваше приложение или, по крайней мере, фреймворк. Он будет выглядеть так: У меня ушел приблизительно один день на то, чтобы создать и отладить этот прототип (после просмотра соответствующих видео WWDC). Если вас не интересует ничего кроме кода, вы можете посмотреть его здесь. Обзор Самый простой способ создать пользовательский инструмент — это использовать os_signpost, собственно что мы и собираемся здесь делать. Вы используете его для логирования signpost-указателей .event или .begin и .end. Затем вы настраиваете пользовательский инструмент для анализа этих os_signpost интервалов и извлечения дополнительных значений, которые вы логировали в него, настраиваете, как отобразить их на графике, как сгруппировать их, какие отфильтровать и как представлять структуры списков или деревьев/блок-схем в панели подробностей инструмента. Мы хотим создать инструмент, который отображает все HTTP-запросы, которые проходят через нашу сетевую библиотеку, как интервалы (начало + конец), чтобы мы могли видеть, сколько времени они занимают, и сопоставлять их с другими событиями, происходящими в нашем приложении. В этой статье я использую Alamofire в качестве сетевой библиотеки инструмента и Wordpress в качестве приложения для профилирования, просто потому что у них открытый исходный код. Но вы легко сможете адаптировать весь код к вашей сетевой библиотеке. Шаг 0: Ознакомьтесь с Instruments App
Шаг 1: Логирование нужных вам данных в signpost-указатели Мы хотим построить наш инструмент на signpost-указателях, то есть мы будем логировать наши данные через signpost. Alamofire отправляет Notification каждый раз, когда запрос начинается или завершается, поэтому все, что нам нужно, это что-то вроде этого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) } Когда запрос начинается, мы логируем signpost .begin, когда он завершается, мы добавляем signpost .end. Для сопоставления завершения вызова с соответствующим началом вызова используется signpostId, чтобы убедиться, что мы закрываем правильный интервал, если несколько запросов происходят параллельно. В идеале мы должны хранить signpostId в объекте запроса, чтобы быть уверенными, что мы используем один и тот же для .begin и .end. Однако я не хотел править тип Request в Alamofire, поэтому решил использовать OSSignpostID(log:, object:) и передавать ему объект-идентификатор. Мы используем базовый объект URLSessionTask, поскольку в обоих случаях он будет одинаковым, а это позволяет OSSignpostID(log:, object:) возвращать нам один и тот же идентификатор при его многократном вызове. Мы логируем данные посредством format string. Вам, вероятно, следует всегда разделяете два аргумента некоторой четко определенной строкой, чтобы упростить анализ на стороне инструмента, а также облегчить парсинг. Обратите внимание, что вам не нужно логировать данные в .end вызове, если вы уже логировали их в .begin. Они будут объединены в один интервал и у вас будет к ним доступ. Шаг 2: Создайте новый проект пользовательского инструмента в Xcode. Следуйте по шагам из Создания пользовательских инструментов (Сессия 410 из WWDC 2018) или справки Instruments App — Создание проект пакета инструментов, чтобы создать новый проект пакета инструментов в Xcode. В результате вы получите базовый проект Xcode с .instrpkg файлом. Все детали мы укажем там. Шаг 3: Сделайте все остальное В основном вы будете следовать шагам, описанным в справке Instruments App — Создание инструмента на основе данных signpost-указателей. Несмотря на то, что описания всех шагов здесь корректны, им все же не хватает множества деталей, поэтому лучше иметь перед собой пример реального пользовательского инструмента. Вы можете посмотреть на мой здесь. В основном вам понадобятся следующие части: Схема Она сообщает инструментам, как парсить данные из ваших signpost-указателей в переменные, которые вы сможете использовать. Вы определяете шаблон, который извлекает переменные из ваших лог-сообщений и распределяет их по столбцам. <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> mnemonic является идентификатором того, что вы собираетесь ссылаться на этот столбец позже. Мне почему-то было немного странно называть столбцы так же, как переменные, поэтому я поставил перед ними префикс column. Но, насколько я знаю, необходимости это делать нет. Инструмент Инструмент состоит из базового определения: <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> Все довольно просто. Большинство из этих полей представляют собой текст произвольной формы или относятся к материалам, которые вы определили ранее (schema-ref). Но category и icon могут иметь только небольшой набор значений, определенных здесь и здесь. График внутри инструмента График (graph) определяет графическую часть пользовательского интерфейса инструмента, визуальное представление, которое вы видите в области трека. Это выглядит примерно так: <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> У вас могут быть разные полосы (lane), и вы можете использовать шаблон графика (plot-template), чтобы реализовать динамическое число графиков в полосе. Мой пример содержит пример простого графика. Я не совсем уверен, почему у graph и lane есть заголовки. В дополнение к этому каждый график в plot-template также получает метку от label-format. Список, агрегация или что там еще для подробного представления С одним лишь графиком инструменты выглядели бы несколько неполными. Вы также хотели бы отобразить что-нибудь в подробном представлении (Detail View). Вы можете сделать это с помощью list, aggregation или narrative. Может быть даже больше вариантов, которые я еще не встречал. Агрегация выглядит примерно так: <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> список выглядит следующим образом: <instrument>
<!-- Базовое определение инструмента --> <list> <title>List: Requests</title> <table-ref>alamofire-requests</table-ref> <column>start</column> <column>duration</column> <column>column-host</column> <!-- Остальные столбцы -> </list> <!-- остальные части инструмента --> </instrument> Бонусный материал На этом, по сути, все =========== Источник: habr.com =========== =========== Автор оригинала: Joachim Kurz ===========Похожие новости:
Блог компании OTUS. Онлайн-образование ), #_razrabotka_pod_ios ( Разработка под iOS ), #_swift |
|
Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете голосовать в опросах
Вы не можете прикреплять файлы к сообщениям
Вы не можете скачивать файлы
Текущее время: 22-Ноя 18:14
Часовой пояс: UTC + 5