Результати пошуку за запитом: обучение c
Нові можливості CSS3
Автор: Редакція ITVDN
Введение
CSS3 произвел революцию в мире веб разработки, поскольку он принес много новых функциональных возможностей. Эта технология продолжает развиваться и внедрять новые возможности. В Новом, 2015 году будут добавляться новые свойства, про некоторые из них мы расскажем в этой статье.
CSS - маски
В Webkit браузерах CSS-маски функционируют уже давно. В ноябре 2014 года была опубликована новая спецификация CSS масок, теперь мы ждем, когда поддержку данного свойства получат все браузеры.
Что такое маска? Проще говоря, маской можно назвать изображение с белой или черной фигурой и прозрачным фоном. Применяя маску на изображение или элемент, мы получим маскированное изображение.
Пример:
Маски можно использовать сейчас, но, к сожалению, только в браузерах Webkit отображение будет корректным.
Использование масок в Webkit
На движке Webkit маски выполняются очень легко, просто используйте тег mask.
.element {
-webkit-mask: url('mask.png');
}
Давайте попробуем создать пример. Вот наше изображение маски:
Накладывать маску будем на эту фотографию:
Теперь добавим немного кода:
class="element">
src="image.jpeg" alt="" />
type="text/css">
.element {
width: 500px;
overflow: hidden;
}
.element img {
-webkit-mask: url(mask-image.png);
}
В результате мы получим вот такое изображение:
Кроме того, можно использовать свойства. Например, Вы можете установить позицию:
.element img {
-webkit-mask: url(mask-image.png) 30% 30% repeat-x border-box;
/* .. тоже самое что и.. */
-webkit-mask-image: url(mask-image.png);
-webkit-mask-position: 30% 30%;
-webkit-mask-repeat: repeat-x;
-webkit-mask-box-clip: border-box;
/* Так же можно указать и размер! */
-webkit-mask-size: 30% 30%;
}
CSS-исключения
CSS-исключения (CSS Exclusions) - очень мощная функция, позволяющая изменить отображение контента на странице. Используя только одно свойство, можно поменять весь стиль страницы, это очень похоже на редактирование страницы в редакторе WYSIWYG. Давайте посмотрим на самое интересное свойство - “wrap-flow”.
Wrap-flow
Wrap-flow позволяет определить, какое количество элементов влияет на другие, когда они поверх остальных. Зачастую блоки перекрываются. С помощью wrap-flow все элементы адаптируются под верхний элемент на странице.
Wrap-flow имеет несколько настроек:
auto: обычное состояние, ни один из элементов не регулируется
start: все, что после элемента - удаляется
end: удаляется все, что до элемента
both: удаляется контент под объектом
minimum: удаляется сторона с наибольшим количеством контента
maximum: удаляется сторона с наименьшим количеством контента
clear: c двух сторон от объекта всё содержимое удаляется
Диаграмма для помощи:
Композиции и модели смешивания (Composition and Blending)
Режимы смешивания в CSS стали частью официальной спецификации W3C. Это значит, что Вы можете выполнять затемнения основы (color burn) через CSS. Данная спецификация новая, так что возможны изменения прежде, чем она попадет в другие браузеры. У нее такой принцип работы: есть 2 изображения, они накладываются одно на другое с помощью абсолютного позиционирования.
Это будет выглядеть так:
<div class="blend">
<img src="duck.gif" alt="Duck" class="duck" width="500" height="500" style="position: absolute; top: 0; left: 0" />
<img src="penguin.gif" alt="Penguin" class="penguin" width="500" height="500" style="position: absolute; top: 0; left: 0" />
div>
Пример CSS кода:
.blend {
position: relative;
}
.blend .duck {
mix-blend-mode: overlay;
}
В целом вся конструкция выглядит так:
Если Вам интересно, то можете попробовать режимы наложения прямо сейчас. Для этого Вам необходимо скачать Adobe’s experimental webkit browser
Источник: http://www.inserthtml.com/2013/01/future-css3/
React Поглиблений – новий відео курс для FrontEnd розробників на ITVDN
Автор: Редакція ITVDN
Друзі, привіт!
Сьогодні ділимося приємною новиною з тими, хто націлений на вдосконалення своїх знань у FrontEnd, а саме – на поглиблене вивчення популярної JS-бібліотеки React, – на ITVDN вийшли всі уроки курсу “React Поглиблений”! Курс українською мовою!
React використовували для розробки такі відомі компанії, як Facebook, Instagram, Netflix, Dropbox, GitHub, Discord, Uber, – і це лише декілька прикладів з численних проєктів. Разом із розповсюдженням даної бібліотеки зростає і попит на React розробників різного рівня.
Під час проходження курсу ви розроблятимете вебзастосунок на основі публічного API, використовуючи різноманітні техніки, які пропонує React та його суміжні бібліотеки.
Ви навчитеся впроваджувати роутинг за допомогою бібліотеки React Router, використовувати CSS-препроцесори та UI бібліотеки, публічні API для отримання даних. Також ви будете використовувати Redux Toolkit для спрощеного написання коду та розв’язання багатьох проблем, реалізуєте можливість логіну через сторонній identity provider та багато іншого.
Автор курсу – Андрій Полевий, Software Developer у MindK. Сертифікований розробник Microsoft, 11+ років досвіду, включаючи роботу в компаніях лідерів української ІТ-індустрії – SoftServe та Intellias. Професійний стек: JavaScript, React, C#, SQL, Azure, ASP.NET Core.
Курс складається з 15 уроків загальною тривалістю 10 годин 5 хвилин.
Структура курсу:
Створення проєкту. TypeScript. Типізація в React.
Стилізація. Частина 1.
Стилізація. Частина 2.
Практика 1. Робота з API і стилізація.
Хуки useContext, useRef, портали.
Кастомні хуки та memory leak.
Робота з формами.
Мемоізація.
Оптимізація.
Redux Toolkit, RTK Query.
Практика 2. Міграція на RTK Query.
GraphQL.
JWT token, авторизація, приватні та публічні маршрути.
Server-side Rendering.
Тестування компонентів.
Чого ви навчитеся на даному курсі:
Будувати state management за допомогою Redux і Redux Toolkit.
Розуміти основи популярних CSS-фреймворків для стилізації.
Використовувати бібліотеку Material UI і її компоненти замість ручної стилізації.
Використовувати React hooks і створювати власні (кастомні) хуки.
Досліджувати проблеми швидкодії React-застосунку.
Використовувати React Developer Tools для дослідження дерева компонентів та профайлингу.
Розв’язувати проблеми з memory leak.
Використовувати React.lazy та Suspense для динамічного завантаження модулів, React Router для динамічного завантаження маршрутів.
Використовувати RTK Query для звертання до API.
Додавати автентифікацію для застосунку на основі OAuth2.
Використовувати мову запитів GraphQL для здійснення запитів та зміни даних на сервері.
Працювати з концепцією Server-side Rendering (SSR).
Дізнаєтеся про Jest Testing Framework та його альтернативи, навчитеся тестувати компоненти за допомогою React Testing Library.
Попередні вимоги
Для проходження курсу потрібно мати знання та практичні навички роботи з React на рівні курсу “React Базовий”. Зміст курсу розрахований на веброзробників, котрі вже знайомі з даною бібліотекою і хочуть розширити свої знання.
Дивіться перший урок у вільному доступі. Курс вже доступний на нашому сайті в повному обсязі – до кожного уроку є практичні завдання та опорний конспект. Якщо у вас є активна підписка, ви можете дивитися його прямо зараз.
Курс входить до комплексної програм підготовки за спеціальністю FrontEnd Developer.
Новий курс "Створення сайту на Vue.js"
Автор: Редакція ITVDN
Всем привет! У нас хорошая новость для FrontEnd разработчиков - в каталоге ITVDN появился практический курс "Создание сайта на Vue.js".
Главная задача любого FrontEnd разработчика - оживить макет веб-сайта, вдохнув в него жизнь при помощи HTML, CSS, JavaScript и сопутствующих технологий. Однако, прогресс не стоит на месте - с каждым годом сфера разработки сайтов все больше и больше расширяется и преображается. Как следствие, количество требований к сайтам также увеличивается. Чтобы облегчить разработку девелоперам и реализовать все требования заказчика, создаются специальные фрейморки. Один из популярнейших - Vue.js. Чтобы раскрыть его потенциал и продемонстрировать основной инструментарий этого фреймворка, мы записали для вас практический курс “Создание сайта на Vue.js”. Что полезного вы можете извлечь из него?
Курс “Создание сайта на Vue.js” поможет вам на практике изучить возможности платформы Vue.js, рассматривая процесс создания своего веб-проекта с нуля и постепенно добавляя в него модули и плагины. Данный фреймворк считается гибким, легким в освоении, легко интегрируемым со сторонними технологиями, с кратким и лаконичным синтаксисом, а также прекрасно подходящим для решения простых задач сайтостроения.
Автор курса Максим Сластен - специалист, у которого за спиной 6-ти летний опыт FrontEnd разработки. В записанных видео уроках Максим делится эффективными техниками создания сайта на Vue.js, которые он сам успешно применяет в своей работе.
Структура курса:
Введение в Vue.js.
Авторизация и работа с роутером.
Работа с маршрутизацией и знакомство с компонент фреймворком.
Работа с интернационализацией.
Работа с компонентами и страницами.
Работа с поиском и функциональными элементами страницы.
Работа с е2е тестированием (Cypress).
Тестирование функционала. Jest.
Финальная доработка и деплой.
После успешного прохождения курса вы научитесь:
Выполнять установку VUE CLI и настройку стартового проекта.
Создавать форму логина для входа на сайт. Организовывать настройку и защиту роутера.
Организовывать авторизацию, аутентификацию, используя JWT токен.
Создавать свой собственный сервер, который будет создавать токен и возвращать его пользователю. Выполнять тестирование сервера c использованием Postman.
Использовать компоненты из библиотеки компонентов. Создавать свои компоненты на основе компонентов библиотеки.
Выполнять стилизацию компонента и настраивать адаптивность сайта.
Использовать плагин интернационализации Vue i18n.
Создавать переводы на сайте. Создавать файл переводов, реализовывать переводы для всех компонентов сайта.
Работать со структурой проекта, добавлять новые компоненты, такие как компонент списка статей.
Тестировать проект с помощью Cypress. Модифицировать проект для покрытия компонентов тестами. Оптимизировать тесты модификациями конфига Cypress.
Применять для тестирования инструмент для создания юнит тестов Jest.
Создавать свой репозиторий и использовать для деплоя сервис Heroku.
Выполнять деплой сайта на Netlify.
Какими предварительными знаниями вы должны обладать? Необходимый бэкграунд для успешного прохождения курса: хорошее знание HTML, CSS, JavaScript.
Курс входит в специальность FrontEnd Developer.
Если вас заинтересовало создание сайта на Vue.js и вы хотите ознакомиться с преподавателем, а также его манерой подачи материала, переходите по ссылке и смотрите бесплатный вступительный урок от Максима.
Также можем вам предложить ознакомиться со следующими статьями: “Инструменты Vue.js разработчика” и “Переход с jQuery на Vue.js”.
Lviv IT Outsourcing Forum
Автор: Редакція ITVDN
20 апреля компания Lemberg Tech Business School будет проводить уже одиннадцатый Lviv IT Outsourcing Forum! Наряду с Kyiv IT Outsourcing Forum это уже традиционная конференция для владельцев и C-Level менеджмента украинских IT аутсорсинговых компаний.
Планируется, что в этом году в конференции примут участие около 400 CEO, CTO, COO, CFO директоров из Украины, Германии, Израиля и других стран Европы.
Зарегистрироваться - http://bit.ly/2SbvFxT
Промокод на скидку 15 % - LIOF15ITVDN
Темой следующего LIOF будет "Трансформация IT компании. Quo Vadis?».
Вопросы, которые будут обсуждаться:
Куда развивать собственную IT компанию? Каковы перспективы развития в ближайшие 3-5 лет?
Как перейти в новые технологические ниши? Какие ресурсы и инвестиции это потребует? За какое время они могут окупиться?
Что происходит на мировом рынке IT-сервисов?
Возможна жесткая специализация компании по технологии, домейн, рынка и продукта?
Примеры сервисно - продуктовых компаний которые "взлетели" в 2018 году.
Как построить sales процесс в технологической нише в средней компании?
Возможен ли переход в продукты?
Что делать, чтобы перейти в консалтинговую модель IT бизнеса в выбранной вертикали?
Цели конференции:
изучить опыт передовых компаний к изменению себя в высокопроизводительных игроков глобального рынка
проговорить возможные угрозы внутреннего рынка талантов и существующим легально-налоговым принципам работы
открыть новые возможности наиболее продуктивным владельцам компаний
способствовать обмену опытом среди владельцев ИТ сервисных и полупродуктовых компаний
Ключевые докладчики конференции: эксперты-практики, владельцы и директора IT-аутсорсинговых компаний, представители компаний-заказчиков аутсорсинговых услуг, консалтинговые и продуктовые компании.
Если Вы считаете себя одним из них и хотите подать доклад - https://docs.google.com/forms/d/1b_H_NDS1zz7f2gjulE97XqslbyoGg6mOBSOPLRFW88Q/viewform?edit_requested=true
Конференция традиционно проводится 2 дня.
Программа первого дня - это 4 классических потока:
Outsourcing Business. О стратегических вопросах развития компании, стабильность, возможности рынка в Украине, выход на новые рынки, PDS 2.0.
BDMS (Business development, marketing, sales). Об эффективном маркетинге, организации и реализации процессов продаж, управления финансами и поддержания отношений с клиентами.
Evolution. О новейших рынках и путях развития компании.
Организационная зрелость. Для опытных проектных менеджеров и СЕО аутсорсинговых ИТ компаний об управлении проектами, новинки в области и гибкие методологии. Образование, корпоративная культура, рекрутинг, HR.
"Фишка" Lemberg Tech Business School - частные встречи и консалтинг от опытных и прорывных владельцев IT компаний. Получите консультацию, которая стоит тысячи долларов, почти бесплатно!
Также на события будет постоянно действующая биржа контактов. Частные встречи будут доступны участникам с билетом типа "GOLD".
Второй день конференции только для "GOLD" участников, которые хотят практики и реальных примеров!
Именно для них организовывают:
Тур львовскими офисами крупнейших ИТ аутсорсинговх компаний!
Серию воркшопов от докладчиков-практиков, которые поделятся своими наработками!
Организатор: Lemberg Tech Business School: организация с 10-летней историей проведения успешных конференций: Lviv Mobile Development Day, GameDev Conference, Lviv PM Day, Lviv Freelance Forum и BDMSummit. Также в рамках LemBS действуют следующие школы: jCEO School, PMSchool, IMarketing School, SMM School, Startup School.
Как было на предыдущих конференциях:
Фото с осеннего KIOF 2018 - https://www.facebook.com/media/set/?set=a.1889194937836183&type=1&l=800e5408f9
Фото с весеннего KIOF 2018 - https://www.facebook.com/media/set/?set=a.1658085234280489&type=1&l=2e2fda2139
Фото осеннего LIOF 2017 - https://www.facebook.com/media/set/?set=a.1511898538899160&type=1&l=13e27fa0cb
Презентации докладчиков из прошлых конференций можно найти тут - https://www.slideshare.net/lvivstartup.
Видео - на youtube-канале - https://www.youtube.com/user/StartupLviv/videos
Получите новые знания и нетворк для успешного развития вашей компании на Lviv IT Outsourcing Forum 2019.
Результати акції "130 тисяч передплатників на YouTube каналі ITVDN"
Автор: Редакція ITVDN
Мы рады сообщить, что 23 июля количество подписчиков на нашем YouTube канале достигло знаменательной отметки 130000 пользователей. Благодарим всех, кто выбирает ITVDN.
В период с 18 до 25 июля 2018 года проходила акция 130 тысяч подписчиков на YouTube канале ITVDN» .
Ответы на 10 вопросов прислали 378 человек, но всего 75 участников ответили верно на все вопросы.
Правильные ответы:
Сколько лет YouTube каналу ITVDN?
Ответ: 5 лет, канал существует с 30 апреля 2013 года
Сколько авторов видео курсов и вебинаров на ITVDN?
Ответ: от 50 до 100, так же мы засчитывали за правильный ответ более 100. У нас 56 авторов видео курсов и 44 автора вибинаров.
Какое видео является самым популярным на канале ITVDN?
Ответ: Видео курс Python Starter Урок 1. Введение в Python, который набрал более 524 тыс. просмотров
Какие дополнительные сервисы есть на ITVDN.com?
Ответ: Проверка домашних заданий, тренажер навыков, онлайн тестирование и сертификация, консультации с тренером.
Кто из авторов ITVDN записал самое большое количество видео курсов?
Ответ: Дмитрий Охрименко записал 17 видео курсов.
Кто в 2018 году провел самое большое количество вебинаров на канале ITVDN?
Ответ: Евгений Волосатов, который за 2018 год провел 12 вебинаров.
Как часто на канале ITVDN публикуются новые видео уроки?
Ответ: Ежедневно
По какому из перечисленных языков программирования на канале ITVDN нет видео курсов и вебинаров?
Ответ: Go
Сколько стоит подписка ITVDN c полным доступом к 140 видео курсам на 1 месяц?
Ответ: Подписка на 1 месяц стоит 19,99$
Как расшифровывается аббревиатура ITVDN?
Ответ: IT Video Developers Network
Список победителей акции:
1. Vitaly Balashkov
2. Андрей Горяев
3. Mais Rasulov
4. Константин Прохоров
5. Михаил Ершов
6. Chokan Yesmagambetov
7. Ольга Сучкова
8. Александр Шамрай
9. Анна Шамрай
10. Антон Жарый
11. Андрей Абрашкин
12. Янина Таран
13. Владислав Захлебин
14. Александр Буровцев
15. Lyudmila Nadolina
16. Vadim Ryzhkov
17. Никита, Спесивцев
18. Павел Фиронов
19. Алексей, Булгаков
20. Алексей Гревцев
21. Людмила Лагутина
22. Станислав Башкатов
23. Валерий Каменев
24. Александр Ткаченко
25. Драгун Максим
26. Михаил Путишин
27. Карлен Саакян
28. Alexey Orlov
29. Светлана Кобенкова
30. Александр Скирда
31. Рамиль Абрамов
32. Mustafa Ismail
33. Ирина Исмаил
34. Андрей Кривонос
35. Максим Китица
36. Прошина Ирина
37. Manko Svetlana
38. Алексей Коржаков
39. Веретеник Руслан
40. Городничий Максим
41. Екатерина Щуплова
42. Вячеслав Першин
43. Андрей Воронов
44. Борис Арканов
45. Полина Борисова
46. Максим Овсянников
47. Александр Смольников
48. Острецов Дмитрий
49. Илья Гареев
50. Vadim Romanenko
51. Алексей Ермолаев
52. Антон Максимов
53. Виктория Марьенко
54. Андрей Громовой
55. Влад Красовський
56. Татьяна Кутейкина
57. София Гареева
58. Павел Лобань
59. Алексей Назаренко
60. Yegor Loba
61. Татьяна Притула
62. Олег Шира
63. Татьяна Мурадян
64. Мария Подольская
65. Светлана Королева
66. Анастасия Лазарева
67. Ирина Солокова
68. Ольга Кириленко
69. Владимир Назаренко
70. Богдан Притула
71. Богдан Соколов
72. Матьев Алексей
73. Александр Алчевский
74. Olga Komarova
75. Alex Alex
Благодарим всех за участие в акции!
Вивчай React Advanced безкоштовно
Автор: Редакція ITVDN
Друзі, привіт!
4 квітня (4.04) – День вебмайстрів. Ми вітаємо зі святом усіх, хто обрав напрямок веброзробки, і маємо для вас подарунок!
З 4 до 11 квітня на ITVDN проходить акція – ви можете отримати доступ до нового відео курсу “React Поглиблений” безкоштовно, а також – сертифікат, який буде підтвердженням ваших знань.
React – найпопулярніша FrontEnd-бібліотека для побудови користувацьких інтерфейсів. Її використовують розробники Facebook, Instagram, Netflix, Dropbox, GitHub, Discord, Uber та інші.
Про курс “React Поглиблений”
Автор курсу – Андрій Полевий, Software Developer у MindK. Сертифікований розробник Microsoft, 11+ років досвіду, включаючи роботу в компаніях лідерів української ІТ-індустрії – SoftServe та Intellias. Професійний стек: JavaScript, React, C#, SQL, Azure, ASP.NET Core.
Тривалість відео уроків – 10 годин 5 хвилин.
Під час проходження курсу ви розроблятимете вебзастосунок на основі публічного API, використовуючи різноманітні техніки, які пропонує React та його суміжні бібліотеки.
Ви навчитеся впроваджувати роутинг за допомогою бібліотеки React Router, використовувати CSS-препроцесори та UI бібліотеки, публічні API для отримання даних. Також ви будете використовувати Redux Toolkit для спрощеного написання коду та розв’язання багатьох проблем, реалізуєте можливість логіну через сторонній identity provider та багато іншого.
Структура курсу:
Створення проєкту. TypeScript. Типізація в React.
Стилізація. Частина 1.
Стилізація. Частина 2.
Практика 1. Робота з API і стилізація.
Хуки useContext, useRef, портали.
Кастомні хуки та memory leak.
Робота з формами.
Мемоізація.
Оптимізація.
Redux Toolkit, RTK Query.
Практика 2. Міграція на RTK Query.
GraphQL.
JWT token, авторизація, приватні та публічні маршрути.
Server-side Rendering.
Тестування компонентів.
Чого ви навчитеся на даному курсі:
Будувати state management за допомогою Redux і Redux Toolkit.
Розуміти основи популярних CSS-фреймворків для стилізації.
Використовувати бібліотеку Material UI і її компоненти замість ручної стилізації.
Використовувати React hooks і створювати власні (кастомні) хуки.
Досліджувати проблеми швидкодії React-застосунку.
Використовувати React Developer Tools для дослідження дерева компонентів та профайлингу.
Розв’язувати проблеми з memory leak.
Використовувати React.lazy та Suspense для динамічного завантаження модулів, React Router для динамічного завантаження маршрутів.
Використовувати RTK Query для звертання до API.
Додавати автентифікацію для застосунку на основі OAuth2.
Використовувати мову запитів GraphQL для здійснення запитів та зміни даних на сервері.
Працювати з концепцією Server-side Rendering (SSR).
Дізнаєтеся про Jest Testing Framework та його альтернативи, навчитеся тестувати компоненти за допомогою React Testing Library.
Попередні вимоги
Для проходження курсу потрібно мати знання та практичні навички роботи з React на рівні курсу “React Базовий”. Зміст курсу розрахований на веброзробників, котрі вже знайомі з даною бібліотекою і хочуть розширити свої знання.
Терміни акції
Акція проходить з 4 до 11 квітня 2024 року включно. Доступ до курсу відкривається на 10 днів.
Введення в розробку програм під iOS. Частина 0.
Автор: Volodymyr Bozhek
Здравствуйте, дорогие читатели. Меня зовут Владимир.
Любая технология рано или поздно приедается и рост себя как специалиста затрудняется. Было принято решение что то кардинально поменять в своей жизни. А так как писать различные интересные проекты я просто обожаю, было принято решение начать изучение в корне другой платформы, среды разработки и языка программирования. Поиск этой платформы оказался достаточно прост для меня. Я решил, что это будет мобильная платформа.
У меня было много разных телефонов с разными операционными системами. Но свой выбор я сделал в пользу iOS, так как при железе слабее, чем у других телефонов, софт работает намного быстрее, чем на других платформах. Это не все преимущества этой платформы, но о других я рассказывать я не буду, дабы не раздувать дискуссию на эту тему. Скажу лишь одно, что телефон c iOS меня ни разу не подвел, даже в самые нужные моменты.
Разумеется, что для разработки под iOS необходим mac, и я его купил. Перед покупкой, разумеется, пробовал разработку под мобильные платформы в гибридных платформах типа Xamarin, Ionic, но на то время функционал в них был не так совершенен, как сейчас, да и пользуясь ими, я бы остался на платформе Windows, это нарушало цель, которую я перед собой поставил по поводу другой платформы.
В течение отпуска, где то за месяц я разобрался, как писать под iOS приложения и сразу начал искать проект, на котором смогу потренироваться. Друг предложил такой проект и я взялся.
За 9 месяцев написал серьезное приложение, купил учетную запись разработчика, выкладывал сборки на Test Flight, их тестировали тестировщики, прошел валидацию в App Store и выложил приложение в App Store.
А теперь по сути. Я постараюсь написать серию статей, в которых распишу простым языком, что надо делать, чтобы у вас тоже это получилось и вы таки выложили свое приложение в App Store.
Касаемо разработки под iOS, то это просто мое хобби во вне рабочее время (надо же как то развлекаться), основной хлеб приносит разработка под Windows/Web платформу с технологиями Microsoft.
Итак, приступим.
Включите свой мак, найдите на панели задач иконку App Store и нажмите на нее.
Выглядит эта иконка вот так:
Затем введите в поле поиска, текст “xcode”, вы должны увидеть следующее:
У меня Xcode уже установлен, поэтому на скриншоте отображается кнопка “Open”, у вас будет отображаться кнопка “Install”. Установите Xcode себе на компьютер, версия Xcode с которой мы будет работать с вами в этом примере, будет 8, на текущий момент это последняя версия этой среды разработки.
Язык программирования, который мы будем использовать, называется Swift, по синтаксису он больше похож на JavaScript и где-то даже на C# местами.
Синтаксис языка Swift в этих статьях мы разбирать не будем, в сети интернет есть полно руководств на эту тему. Сам синтаксис языка не сложно изучить, это делается за день, сложность как раз возникнет при попытке разработки приложения под iOS.
Вот именно эту сложность, мы с вами и постараемся одолеть.
Чтобы серия статей была как-то взаимосвязана, мы с вами напишем проект под названием “Warehouse” (склад), в котором можно будет добавлять товары, заполнять их атрибуты, редактировать и удалять товары. Данные будут сохраняться в настройки телефона.
Вы уже установили Xcode 8? Если да, тогда запускайте его, вы увидите следующее:
Нажмите кнопку “Create a new Xcode project”. Вы увидите такой экран:
Выделите проект “Single View Application” и нажмите кнопку “Next”. Вы попадете на экран задания названия проекта:
На данном скриншоте виден пример того, как заполнить название приложения. В поле “Product Name“, введите “Warehouse”, так будет называться наше приложение.
В поле “Organization Name”, введите свои имя и фамилию, или название вашей компании.
В поле “Organization Identifier”, вводится уникальный идентификатор приложения, который будет использоваться как ключ при регистрации данного приложения в iTunes, чтобы была возможность подписывать сборки и отправлять на бета сервер Test Flight для тестирования, но об этом позже. Вкратце “com” - это сокращенно “company”, “bozhek” это название компании, у вас это будет другое название.
В поле Bundle identifier видно полное название вашего приложения в iTunes.
В поле Language, оставьте Swift. В поле Devices, выберите iPhone.
Нажмите кнопку “Next”. Откроется проект, который мы создали:
Обратите внимание на красный кружок в поле Status: “Signing for Warehouse reguires a development team”. Это сообщение говорит нам о том, что приложение надо подписать сертификатом, без сертификата мы не соберем и не запустим это приложение.
Давайте это исправим. В поле Team, откройте выпадающий список и выберите в нем пункт “Add an Account...”, откроются свойства среды разработки Xcode, с предложением ввести логин и пароль от
вашей учетной записи в App Store, под которой вы устанавливаете приложения себе на телефон:
Если же у вас по каким то причинам нет этой учетной записи, создайте ее, нажав на кнопку “Create Apple ID”. Создание этой учетной записи я не буду рассматривать в данной статье, поскольку она создается очень легко и в сети интернет есть полно информации на эту тему.
Итак, вы ввели в поля Apple ID и Password свои данные, нажмите кнопку “Sign In”. После этого красный круг с ошибкой пропадет и вы увидите следующее:
Теперь вы сможете собрать и запустить свой проект.
Заметьте, я рассказываю чисто практически как и что делается, особо не вникая в детали.
Если вам нужна более подробная информация, вбейте в гугл WWDC, и посмотрите официальные видео сессии от компании Apple, в их двухчасовом видео много воды, но зато есть теория, которая будет вам нужна. Я даю только суть.
Нажмите на иконку приложения в проекте:
Выберите симулятор “iPhone 7”.
Затем нажмите на кнопку Собрать и запустить приложение:
Будет запущена сборка проекта и запущен симулятор “iPhone 7”, в котором откроется наше приложение:
Сейчас мы видим только белый экран и больше ничего, так как мы еще ничего не делали.
Чтобы выйти на рабочий стол в симуляторе, выполните сочетание клавиш Shift + Command + H, это сочетание означает нажатие кнопки Home:
Вы увидите на рабочем столе наше приложение "Warehouse".
Теперь давайте остановим выполнение приложения, для этого в Xcode нажмите кнопку:
Теперь давайте посмотрим, что у нас есть внутри проекта.
Выделите в левой панели среды разработки файл “Main.storyboard”, в этом файле содержится представление приложения.
В панели справа отображаются свойства представления.
Разработка под iOS строится через паттерн MVC (Model View Controller), файл Main.storyboard, содержит View, которые вы будете использовать в своем приложении для создания визуального
интерфейса. Теперь давайте выделим в панели свойств вкладку Class:
В поле Class , мы видим класс контроллера, привязанный к данному представлению.
Теперь выделите вкладку Size:
На данной вкладке задаются размеры представления.
Выделите вкладку Events:
На данной вкладке задаются обработчики событий в представлении с привязкой к методам в контроллере.
Теперь выберите в левой панели файл ViewController.swift :
На 9 строке подключено пространство имен UIKit.
На 11 строке объявляется класс с именем ViewController, который наследуется от базового класса контроллера UIViewController.
На 13 строке мы переопределяем метод, загрузки представления, этот метод вызывается когда представление начинает свою загрузку. В этом методе необходимо предварительно проинициализировать данные элементов управления, используемых на вашем представлении.
На строке 14, вызывается метод базового класса ViewController.
Код на строке 18 нам пока не интересен, мы его рассматривать не будем, чтобы не путаться.
На этом урок завершается.
На следующем уроке, в первой части, мы рассмотрим с вами, как пользоваться элементами управления, как привязывать к ним обработчики событий и как взаимодействовать с ними.
Використання HTML Agility Pack та CSS Selectors
Автор: Редакція ITVDN
Введение
В следующих примерах используется HTML Agility Pack (НАР), чтобы загрузить HTML в объект модели документа (DOM) и разбить на узлы. Дополнительно есть случаи, когда приходилось анализировать документ об элементах, которые не являются действительно узлами, такие как комментарии.
В дополнение к наблюдениям около HAP в целом будут указаны методы расширения, предоставляемые пакетом HAP.CSSSelectors, что позволяет значительно проще выбирать.
Задний план
Был успешно использован Html Agility Pack для клиента, проанализированы HTML документы, чтобы извлечь необходимую информацию. Расширения CSSSelector будет добавлять новый мощный уровень абстракции, чтобы собрать необходимые данные.
Использование кода
Пакеты для примера нужно будет импортировать с помощью NuGet. Описания пакетов будут загружены в проекте, но нужно будет установить менеджер пакетов NuGet для восстановления библиотек.
В проект был включен очень простой HTML файл с примерами вопросов, которые необходимы для решения своих проектов.
Чтобы проверить без лишних изменений, необходимо скопировать файл HTML в следующем дисководе и каталоге - C: \ TestData.
HtmlAgility имеет ряд классов, доступных для его добавляемых классов и перечисления, которые представляют различные части DOM, эти классы включают HtmlAttribute, HtmlAttributeCollection, HtmlCommentNode и так далее.
Первый класс, который мы будем изучать, это HTMLDocument класс. Этот класс имеет методы для загрузки и анализа документа в его соответствующих частях.
В исходном коде вызывается каждая секция кода, использующая номенклатуру (часть X), где X представляет собой число.
Чтобы использовать, следующая строка должна быть реализована:
HtmlAgilityPack.agpack = new HtmlAgilityPack.HtmlDocument();
Следующий метод вызывает метод для загрузки документа. Вы можете загрузить его из строки:
agpack.LoadHtml(Html string)
//or from a resource –
agpack.Load(@"c:\testdata\testdat.htm");
Файл в себя включает недостающий закрывающийся тег шрифта и неуместный закрывающий тег. Он прекрасно работает в браузере, не выдает ошибку в HAP, но может быть проверенным на это.
var errors = agpack.ParseErrors;
ParseErrors будет возвращать коллекцию и подсчет ошибок. Достаточно интересная вкладка, закрытие шрифта не выдаст ошибку.
После того, как документ был загружен, двумя основными способами для поиска являются:
SelectNodes(string XPath) // from the DocumentNode
GetElementbyId(string Id) // from the HtmlDocument
Поскольку может быть только один ID, getElementById вернет один узел и SelectNodes вернет коллекцию узлов, потому что с помощью XPath он может соответствовать одному или нескольким элементам.
Находим приложение, где будет добавляться несколько файлов вместе, ограничивающее каждый документ с начальным и конечным комментариями. Ниже показано, как обрабатывать разделения этого документа обратно в его составную часть. Файл, который включен, имеет секцию, которая очерчена с комментариями:
HTML Body
Вы можете использовать следующую команду, чтобы получить комментарий:
var comment = agpack.DocumentNode.SelectNodes("//comment()[contains(., 'Start Table:')]");
Это говорит от всего документа ("//") выбор комментариев, что содержат от текущего местоположения (.) слово Начало табл.
Так как это является комментарием, то не имеет дочерних узлов и внутреннего текста, только текст самого комментария. Это полезно, если то, что вы хотите сделать - это разобрать комментарий, чтобы определить значение в комментарии (номер счета в данном случае), но на самом деле не поможет, если вы хотите видеть текст между комментариями. Чтобы достичь этого, возвращаемся обратно в регулярные выражения и группировки.
var html = Regex.Match(agpack.DocumentNode.InnerHtml,@"(?.*)",RegexOptions.Singleline).Groups[1];
Теперь в html.Value имеется текст между двумя тегами.
Переходим к нахождению элементов в DOM, первый пример находит узел, используя getElementById. Есть три таблицы, но только два идентификатора возложены на них. Одним из них является ID = "abc", другой ID = "table3".
Начнем с таблицы ID = "abc":
var node = agpack.GetElementbyId("abc");
Это вернет один узел, представляющий таблицу. InnerHtml будет содержать весь текст между тегами.
Он также будет содержать набор узлов, представляющих DOM структуру таблицы.
Один из подходов к получению узла строк заключается в использовании Linq, чтобы обнаружить их:
var rownodes = node.ChildNodes.Where(w => w.OriginalName == "tr");
Если проверить подсчет, вы увидите, что у вас есть три строки. Однако, на самом деле существует четыре ряда, первый записанный не будет найден.
Другой подход заключается в использовании SelectNodes на узле, чтобы обнаружить элементы tr.
rownodes = node.SelectNodes("tr");
Но это также проблема - найти все строки, проще найти элементы управления.
Как насчет node.SelectNodes ("/ tr")? Это ничего не возвращает.
Как насчет node.SelectNodes ("// tr")? Хорошая новость состоит в том, что он нашел недостающую строку вместе со всеми строками (12) в документе.
После небольшого углубления нашлись следующие два рабочих решения:
rownodes = node.SelectNodes(node.XPath + "//tr");
//or
// http://www.w3schools.com/xsl/xpath_axes.as
rownodes = node.SelectNodes("descendant::tr");
это возвращает все четыре. Возможно, HAP делал бы SelectNodes от текущего узла "//tr" и работал бы, увы "//" - говорит искать от корня документа. Но второй вариант работает, как потолок от выбранного узла.
Аналогичным образом мы можем найти все td элементы, используя те же процедуры. Отметим, что для таблицы нужно 3 вернуть двенадцать td элементов, даже если они являются дочерними.
node = null;
node = agpack.GetElementbyId("table3")
nodes = node.SelectNodes("descendant::td");
Переходим к HAP.CssSelectors.
Это находится на вершине HtmlAgility пакета и будет на самом деле обеспечивать установку в качестве части пакета NuGet.
Это позволяет выбрать элементы, используя CssSelectors, нежели XPath. Например:
rownodes = agpack.QuerySelectorAll("#abc tr");
В этом случае не нужно искать в узле, просто, выбрав из всего документа, он вернет ожидаемых 4 ряда.
listTDNodes = agpack.QuerySelectorAll("#table3 td");
Ниже приведен пример получения только s (три) во втором ряду.
listTDNodes = agpack.QuerySelectorAll("#table3 tr:nth-child(2) td");
Это вернуло двенадцать пунктов, четыре ряда из 3 колоноки. Одно замечание. Способ QuerySelectorAll возвращается, как список <узлов>, а не коллекция узлов. Это важно знать, если планировать смешивать и сочетать.
В дополнение к выбору по идентификатору (#) можно выбрать по классам (.), это гораздо проще, чем искать атрибут с классом, используя XPath.
listTDNodes = agpack.QuerySelectorAll(".table");
Возвращаем первую и третью таблицу с классом table.
Точки интереса
В заключении скажем, что продление CssSelectors - это еще один полезный инструмент для легкого выбора элементов, без необходимости копать вглубь XPath или перебирать коллекции.
Источник: http://www.codeproject.com/Articles/1038320/Using-HtmlAgility-pack-and-CssSelectors
Идеальное резюме программиста: что писать в резюме IT специалисту
Автор: Влад Сверчков
Всем привет!
Что такое резюме? По сути, это визитная карточка, которая должна убедить рекрутера либо HR-менеджера пригласить вас на собеседование. Однако, она может не только убеждать нанимателей, но и давать отказ разработчикам даже с завидным багажом опыта и знаний. Что написать о себе в резюме IT специалисту? Каким должно быть резюме у программиста, чтобы оно понравилось рекрутеру и стало вашим пропуском в IT-компанию? Чем отличаются резюме опытного разработчика и начинающего программиста (junior)? Давайте разберемся!
Прежде всего отметим, что в вашем резюме должно отсутствовать:
Размытость, неточности. Каждый человек дорожит своим временем. Особенно рекрутер, у которого помимо вашего еще несколько десятков (а бывает даже и сотен) резюме. Никто не захочет тратить время на переспрашивание или уточнение у вас информации, которая важна для той или иной позиции, но при этом которую вы забыли либо не захотели указать.
Вода. Резюме — не сочинение на вольную тему и не автобиография, начиная с пеленок. Этот документ имеет четкую цель и предназначение, а значит пустословие в нем — дурной тон и заодно самый верный путь в корзину рекрутера.
Ложь. Также, не забывайте, что ложь всегда всплывает наружу — либо во время собеседования, либо непосредственно в ходе трудовых будней. Не выдавайте желаемое за действительное и составляйте честное резюме. Мы еще поговорим в этой статье о том, под каким соусом лучше подавать ту или иную информацию, будучи честным и в выигрышном положении одновременно.
Если подытожить эти пункты, то верно следующее: хорошее резюме должно пестрить лаконичностью, быть честным и содержать только важную информацию. Теперь поговорим подробнее, что оно должно в себя включать и как правильно составлять каждый раздел.
Структура
Жестких требований к оформлению резюме для программистов нет. Однако, существуют определенные правила, которых следует придерживаться в процессе его составления. Рекомендуем использовать следующий шаблон (в скобках указано название, которое надо использовать при составлении резюме на английском):
Фамилия, имя (First Name, Last Name)
Возраст (Age)
Контакты (Contacts) — город проживания, телефон, e-mail, Skype. Акцентируем внимание, на том, что название электронной почты и скайпа должно быть в официальном стиле в виде вашего имени и фамилии: a.ivanov@... либо alexander_ivanov@... и т. д. Никаких stasik_ananasik@... и прочих вычурных названий. Почту лучше выбирать из популярных — Gmail, Outlook и подобные. Также, почта не должна быть привязана к предыдущим местам работы.
Здесь же добавьте ссылку на ваш профиль в GitHub, где находятся опубликованные вами проекты. Если имеете хорошо заполненный профиль в LinkedIn (с указанными местам учебы и работы, изученными технологиями, вашим хорошим фото и другой информацией), добавьте ссылку и на него.
Здесь же затронем и вопрос социальных сетей. Если ваше резюме всерьез заинтересовало рекрутера, высока вероятность, что вас найдут через соцсети и ознакомятся с содержимым ваших страничек. Поэтому проведите предварительную ревизию своих профилей в Сети и уберите все то, что будет портить вам имидж (острые политические высказывания, посты, противоречащие общепринятым нормам морали, и другие элементы, которые будут работать против вас).
Цель (Objective) — пункт, в котором вы сообщаете нанимателю, какую позицию желаете занимать в компании.
Резюме квалификации (Summary Of Qualification) — в этом разделе следует разместить основную информацию из резюме, которую будет полезно узнать работодателю в первую очередь (не более пяти ключевых тезисов, которые расскажут о вас и вашем опыте работы в выбранной сфере IT). Если не имеете каких-то сильных аргументов о вашем карьерном пути, пропустите этот пункт.
Профессиональные навыки (Hard Skills) — здесь вы описываете все технологии, которые знаете и умеете использовать. Рядом указывайте уровень владения каждой. Допустим, что-то знаете отлично, что-то базово, но готовы изучать дальше. Главное — пишите честно, ведь за каждую технологию или указанный вами язык программирования спросят.
Личные навыки (Soft Skills) — это нетехнические навыки, которыми вы обладаете. Какие ключевые навыки указать в резюме программиста? Умение работать в команде, решать конфликтные ситуации, быть внимательным к деталям, обладание хорошо развитым критическим мышлением, умение слушать и четко излагать свои мысли, а также другие подобные навыки относятся к софт скиллам, которые важно было бы услышать работодателю. То есть, это те умения, которые помогают нам быть эффективными на работе. Много софт скиллов писать не надо, однако, минимум три наилучших своих качества указать необходимо.
Здесь тоже пишите честно не вводя работодателей в заблуждение — собеседование заставит вас вскрыть карты в любом случае. На помощь придет небольшой совет, который поможет оставаться честным и при этом не касаться ваших недостатков.
Каждый работодатель хочет, чтоб его сотрудник был рабочей лошадкой с отличными коммуникативными навыками, быстрой обучаемостью, прекрасно владел техниками тайм-менеджмента и другими скиллами. Но все знают, что идеальных людей не бывает. Допустим, если вы интроверт и нуждаетесь в определенном времени на раскрытии себя в коллективе, не пускайтесь в обман, мол, вы быстро и с легкостью находите общий язык с командой. Будет разумно поступить иначе — обойти стороной ваши навыки коммуникации и указать другие положительные качества, которыми обладаете — например, умение слушать, анализировать информацию и быстро находить выход из назревшей проблемы.
Опыт (Experience) — следует указывать в обратном порядке, начиная с вашего последнего места работы. Каждое описываемое место работы должно иметь следующую структуру:
даты начала и конца работы (будет плюсом, если добавите в скобках время, в течении которого занимали должность);
название компании;
занимаемая позиция;
краткое описание проекта (по возможности со ссылкой), обязанностей, описание используемых технологий и достижений.
Если вы до этого работали не по специальности, попробуйте в последнем пункте описать какие-то важные навыки, которыми овладели в ходе работы и которые при этом важны в той позиции, на которую вы подаете резюме.
Если вы только выпустились из университета, попробуйте поразмышлять и написать об университетском опыте — наверняка вы занимались чем-то полезным на кафедре, состояли в какой-то университетской организации или с одногруппниками разрабатывали собственные проекты, занимались общественной деятельностью, вследствии чего освоили некоторые умения/навыки или просто получили опыт применения определенных программных или аппаратных средств.
С одной стороны, может показаться, будто опыт работы не по специальности совершенно не интересует работодателя. Отчасти это так, однако, грамотному рекрутеру/HR-менеджеру этот пункт (при правильном его описании) откроет вас как человека, который, имеет опыт работы и коммуникации внутри команды. А если вы еще и указали, что в процессе работы научились рационально распоряжаться своим временем и вовремя выполнять возложенные на вас поручения, это еще один плюсик вам.
Однако, если у вас уже есть определенный IT-бэкграунд, то стоит указывать лишь опыт в IT — какие самые удачные проекты, какой командой руководили (если руководили), какие обязанности выполняли, чего добились и т. д.
Образование (Education) — информация о высшем образовании. Указывайте название ВУЗа, факультет, специальность, полученную степень, годы обучения. Если получили красный диплом — упомяните об этом. Школу упоминать нет нужды. Разве что это ваша первая работа либо стажировка в IT и вы имеете за плечами какой-нибудь крутой технический лицей.
Если недавно окончили учебное заведение, можете написать тему вашей дипломной работы и средний балл за все время обучения.
Дополнительные навыки (Additional Skills) — информация про курсы, семинары, тренинги и другие обучающие программы, которые вы проходили самостоятельно. Тут же расскажите о ваших сертификатах, если они у вас имеются — здесь наступает их звездный час.
Знание языков (Knowledge Of Languages) — простой пункт. Составляется в виде “Язык — уровень владения языком”. Ключевым в данном разделе является знание английского, ведь попасть в IT без него практически нереально. Не будьте профаном и не пишите, например, “English — хороший”. Английский имеет несколько уровней владения: Elementary, Pre-Intermediate, Intermediate, Upper-Intermediate, Advanced, Proficiency, поэтому в данном примере уместно писать “English — Intermediate”. Можете добавить уточнение, мол, без проблем читаете техническую документацию, но разговорный инглиш еще подтягиваете. Допускается указать рядом с уровнем владения языком, что на данный момент вы посещаете соответствующие курсы, если это соответствует действительности.
Объективно оценивайте свой уровень владения английским — это очень легко проверяется в ходе собеседования.
Дополнительная информация (Additional Information) — сведения о вас, которыми вы хотели бы поделиться: ваши интересы, увлечения, либо определенные особенности — наличие маленького ребенка, родственника, за которым вам необходимо присматривать и т. д. В конце концов, на работу берут не шестеренку, которая будет частью бездушного механизма, а личность с определенными знаниями, профессиональными навыками, взглядами на жизнь и чертами характера.
Главное — умело подать информацию. Имеете маленького ребенка и много времени работали из дому — уточните, что данные условия научили вас стрессоустойчивости и многозадачности. Будьте на позитиве, извлекайте из, казалось бы, тупиковых ситуаций положительные стороны и демонстрируйте их тому, кто будет смотреть ваше резюме.
Общие советы
Требования к тексту.
Для резюме выбирайте 12-14 кегль и шрифт Arial либо Times New Roman — текст будет максимально читабелен и без раздражающих элементов. Для новичков оптимальный размер текста — до одной страницы А4, от опытных программистов ожидают текста побольше, но лучше не превышать 2-х страниц. Причем бо́льшую часть должны занимать ваши скиллы и опыт работы.
Сплошной текст читать сложно, утомительно и не интересно. Оформляйте резюме таким образом, чтоб оно было легким и само просилось в глаза. Для этого структурируйте информацию, используйте отступы, абзацы, линии и т. д. К примеру, тот же раздел “Опыт” можно изобразить в виде таблицы. Главное — сгруппировать информацию по блокам. Всё должно быть лаконично, аккуратно и читабельно.
Не забывайте о грамотности написанного текста. Перед отправкой делайте тщательную вычитку резюме — грамматические, орфографические и пунктуационные ошибки прекрасно портят мнение рекрутера о соискателе.
К слову о фото.
Его можно как добавлять, так и нет. Фотография должна быть хорошего качества, но не с вечеринки, шашлыков либо других мест повышенной концентрации отдыхающих. Также, на ней должно быть отчетливо видно ваше лицо. Если верить психологам, лучшее фото — на котором вы в позитивном настроении и с улыбкой. Подходящей фотографии нет? Тогда не добавляйте ее вовсе. В некоторых странах фото в резюме — табу по причине возможной дискриминации по половому, расовому либо иному признаку. Также, отсутствие изображения позволяет оценивать человека по его профессиональным и личностным качествам, а не по внешним данным.
Формат электронного резюме.
На рассмотрение рекрутеру необходимо присылать резюме в формате PDF. Это самый универсальный формат электронных документов, который беспроблемно открывается и читается на всех возможных устройствах.
Соответствие резюме вакансии.
Также, внимательно просматривайте требования к каждой должности и, если необходимо, вносите коррективы в написанное вами резюме таким образом, чтобы было видно, что данное резюме было составлено именно для соответствующей вакансии — и рекрутеру удобнее и вам больше шансов быть замеченным. Ведь резюме, которое рассылается всем без оглядки на требования и пожелания работодателей (резюме-спам) не вызывает симпатий и имеет большие шансы попасть в урну.
Резюме на английском.
Если вакансия составлена на английском языке, значит, работодатель однозначно хочет от кандидата англоязычное резюме. Даже если вакансия русскоязычная, а вы составили и прислали резюме на инглише, это будет солидным плюсом, ведь, как мы говорили ранее, данный язык в IT очень важен. Главное, не забывайте о грамотном написании. После составления резюме дайте его на проверку тому, кто хорошо знает английский.
Неформальность в резюме.
Интересный момент: в IT допускается неформальность в резюме программиста, к примеру — шутки. Однако, это хождение по очень тонкому льду. Если вы и собираетесь в каком-то месте показать остроту своего ума, делайте это умело и уместно, иначе будет только хуже. Но все же арсенал шуток лучше приберечь на само собеседование — там они помогут и виртуозно выйти из затруднительных положений, и зарядить всех позитивом.
Портфолио.
Как мы уже указали, в пункте “Контакты” стоит разместить ссылку на свой GitHub, где располагаются ваши проекты, которые и составляют ваше портфолио. Если вы новичок, там должны быть именно те проекты, которые вы разрабатывали самостоятельно (не содранные с ютуба или прочих ресурсов). Продемонстрируйте работодателю все свои навыки и умения в них. Дайте понять, какими технологиями и языками владеете.
Навигация по портфолио также должна быть интуитивно понятной и удобной.
Сопроводительное письмо.
В Украине практика написания сопроводительного письма не особо популярна, однако, правильное его составление может дать вам дополнительное преимущество перед другими кандидатами-конкурентами. Это письмо, которое дополняет резюме. Его цель — заинтересовать рекрутера/работодателя и создать хорошее первое впечатление о себе. Структура сопроводительного письма следующая:
Приветствие, обращение к работодателю.
Источник информации о вакансии.
Сведения, которые характеризуют вас как специалиста.
Демонстрация заинтересованности в вакансии.
Контактные данные.
Фривольностей здесь лучше не допускать — придерживайтесь официального стиля изложения.
Встаньте на место рекрутера/работодателя.
При составлении резюме время от времени абстрагируйтесь и смотрите на него с разных сторон. Нравится ли вам то, что написано? Есть ли последовательность и логичность в написанном? Что можно сократить? Как лучше выделить ту или иную способность / умение / качество / технологию? Подобная рефлексия поможет объективно рассматривать резюме и на выходе получить действительно качественный экземпляр.
Ресурсы для автогенерации резюме
Фишка двадцать первого века — повсеместная автоматизация различных рутинных процессов. Коснулась эта тенденция и сферы поиска работы. На данный момент существует множество сервисов, которые предоставляют услуги по созданию качественного резюме. Мы делим их на два типа: встроенные и независимые.
К первому типу относятся сервисы, которые находятся на сайтах поиска работы. Как пример, такая функциональность реализована на сайтах work.ua, grc.ua и т. д. Весь необходимый костяк резюме уже создан, ваша задача — грамотно заполнить разделы. Если вдруг где-то запутаетесь — каждый пункт содержит подсказки, что очень удобно.
Также, вы можете скачать созданное резюме, однако, оно не будет таким стильным и красочным, как то, которое предлагают ресурсы генерации “визитки” второго типа.
Независимые сервисы создания резюме — специализированные сайты, которые имеют множество инструментов для создания эффектного внешнего вида резюме. Вам необходимо только выбрать понравившийся шаблон, настроить его под себя и заполнить разделы. Расскажем о некоторых из них.
LinkedIn — социальная сеть для делового общения, которая ориентирована на поиск сотрудников и вакансий. При создании аккаунта вы указываете различные данные о себе: места учебы и работы, технологии и языки программирования, которыми владеете, дополнительную информацию о себе, фото и т. д. LinkedIn имеет встроенный инструмент генерации резюме исходя из информации, опубликованной в вашем профиле, однако, хорошо заполненный профиль уже в некотором роде является вашей визитной карточкой. И все же, рекрутеры будут его рассматривать лишь во вторую очередь в качестве прикрепленной ссылки в разделе резюме “Контакты”.
При этом LinkedIn обладает одной особенностью: в будущем, когда вы станете разработчиком уровня Middle+ и будете иметь широкую сеть знакомств на этом ресурсе (400+ человек), никакое резюме вам более не понадобится — рекрутеры будут сами вас находить и предлагать вакантные должности. А пока вы джуниор с нулевым опытом работы, LinkedIn не сможет заменить вам полноценное резюме.
Canva.com — сервис, позволяющий бесплатно создать стильное и привлекательное резюме при помощи сотен различных дизайнерских шаблонов на любой вкус. Выбираете один из них, настраиваете цвета, шрифты, фон и сам макет, а затем вносите вашу информацию и фото. Удобно и просто.
Cvmaker.com — бесплатный ресурс, который дает возможность создавать резюме, используя один из девяти классических шаблонов, отличающихся своей лаконичностью и отсутствием излишеств. Хороший вариант для поклонников легкого минимализма.
Также существует множество других сервисов создания резюме — используйте гугл и вы найдете для себя тот вариант, который вам идеально подойдет.
Ну а самой оригинальной и эффективной анкетой для работодателя может быть резюме фронтенд разработчика. Данный специалист по профессии разрабатывает веб-интерфейсы, а потому может реализовать своё CV в виде веб-сайта. Демонстрируете свои скиллы и одновременно подаёте необходимую информацию о себе – очень удобно и практично.
Итоги
Резюме разработчика — это пригласительное письмо на собеседование в IT-компанию, которое вы сами и составляете. Оно должно быть структурированным, информативным и при этом не содержать ничего лишнего. Самое главное — резюме должно произвести приятное впечатление на того, кто будет его просматривать, и принести желанное приглашение на собеседование. Пишите лаконично, избегайте воды, неточностей и неправды — обман все равно вскроется во время встречи. Откровенную ложь никто терпеть не станет. Прежде всего будьте честны с самим собой, объективно оценивая свои знания и способности. Заинтересовывайте при помощи креатива, нестандартного подхода — эти качества всегда ценятся нанимателями.
Резюме опытного программиста должно удерживать акцент на опыте и проектах, над которыми разработчик трудился: какие технологии были задействованы, какие обязанности выполнялись, какие результаты были достигнуты и т. д. Резюме начинающего программиста (junior) должно опираться больше на самостоятельно разработанные проекты, амбиции, личные качества и навыки соискателя, которые помогут ему развиваться в IT направлении.
Составлять резюме можете самостоятельно либо при помощи специализированных сервисов, которые помогут добавить эффектности и заметности вашему документу. Главное — не переборщить и все будет окей. Для дополнительного эффекта напишите хорошее сопроводительное письмо, которое поможет вам выделиться среди других кандидатов.
Следуйте нашим советам, и вы непременно преуспеете!
Желаем здоровья и успехов на вашем карьерном пути!
Оставайтесь на ITVDN!
Введення в розробку програм під iOS. Частина 7
Автор: Volodymyr Bozhek
Здравствуйте, дорогие читатели.
В этом уроке мы:
выполним рефакторинг проекта “Warehouse” под “iOS”. Создадим удобную структуру расположения модулей в проекте.
научимся пользоваться библиотекой “Alamofire”.
научимся сохранять объекты в настройки телефона и извлекать их.
реализуем функциональность для работы со всеми сервисами, созданными в данном уроке.
Откройте проект “Warehouse” под iOS, который мы делали на протяжении всех уроков.
Запросы на сервер можно отправлять синхронно и асинхронно. Основное требование Apple, чтобы приложение не зависало и большие операции выполнялись в фоновом режиме.
Представим ситуацию: у нас мобильный интернет “GPRS EDGE”, скорость соединения около 54 кб/сек. Если отправлять запрос на получение данных на сервер синхронно, мы блокируем работу приложения и пользователь вынужден ждать. Наша задача - дать пользователю выбор, ждать или нет. Поэтому лучше всего отправлять такой запрос асинхронно.
На сегодняшний день существует такая библиотека “Alamofire”, где собраны лучшие практики асинхронного программирования и все оптимизировано за нас.
Откройте браузер и перейдите по адресу: “https://github.com/Alamofire/Alamofire”. На сайте нажмите кнопку “Clone of download” и в появившемся окне нажмите “Download Zip”.
Когда скачается архив, распакуйте его.
Выделите файл “Alamofire.xcodeproj” и папку “Source” и скопируйте их в папку проекта “Warehouse”.
Перейдите в проект “Warehouse”.
В панели навигации выполните контекстное меню по папке “Warehouse” и в контекстном меню выберите “Add files to 'Warehouse'...”. В открывшемся диалоговом окне выбора файлов выберите файл “Alamofire.xcodeproj”.
Выполните в меню “Product -> Build”, чтобы собрать проект.
Затем выделите в панели навигации папку “Warehouse”, в области содержимого откроются свойства проекта. Откройте вкладку “General”, пролистайте область содержимого в самый низ.
Установите свойство “Embedded binaries”, нажмите плюсик. В появившемся диалоговом окне, выберите “Alamofire.Framework.iOS” и нажмите кнопку “Add”.
Результат должен получиться таким.
Выполните в меню “Product -> Build”, чтобы собрать проект.
Итак, что мы только что сделали. Мы подключили исходники библиотеки “Alamofire” в проект “Warehouse”. Можно было это сделать и отдельным проектом, но так проще для восприятия. Затем мы подключили сборку “Alamofire.framework.iOS” в приложение “Warehouse” для возможности обращения к классам данной библиотеки из нашего проекта.
Теперь нам надо создать модели данных, в которые мы будем сохранять JSON объекты, полученные с сервера. Также необходимо предусмотреть удобство сохранения и извлечения данных, поскольку запросы будут асинхронными и просто вернуть нужный экземпляр из метода будет проблематично.
Именно поэтому мы поступим следующим образом.
Отправляем запрос на сервер асинхронно. В метод отправки добавляем callback метод, который вызовется после того, как модель была успешно сохранена в настройки телефона.
Ждем ответа. Когда ответ пришел, десериализуем объект JSON в нужную модель данных, объявленную в приложении.
Сохраняем заполненную модель в настройки телефона.
В контроллере, из которого был отправлен запрос, в callback методе извлекаем модель из настроек телефона и инициализируем данными элементы управления.
Создайте следующую структуру папок в панели навигации.
В папку “Warehouse” были добавлены папки “Controllers”, “Protocols”, “Models”, “Services”.
В папку “Controllers” были добавлены папки “Users”, “Registration”, “Authorization”, “Supplies”.
В папке “Controllers” будут храниться модули контроллеров.
В папке “Protocols” будут храниться модули протоколов.
В папке “Models” будут храниться модули моделей данных.
В папке “Services” будут храниться модули обращения к REST сервисам.
Сейчас нам необходимо провести некоторую подготовку, перед тем как начать реализовывать приложение. Пока, давайте, добавим нужные модули. Сам по себе добавленный модуль ничего не делает.
Перетащите в папку “Controllers / Supplies” модули “SuppliesViewController.swift”, “ProductViewController.swift”.
Перетащите в папку “Controllers / Authorization” модуль “ViewController.swift”.
Добавьте в папку “Controllers / Registration” модуль “RegistrationViewController.swift”.
Добавьте в папку “Controllers / Supplies” модуль “ImageCollectionViewController.swift”.
Добавьте в папку “Controllers / Users” модули “UsersViewController.swift”, “UserItemViewController.swift”.
Добавьте в папку “Protocols” модуль “SelectedImageProtocol.swift”.
Добавьте в папку “Models” модули “ProductModel.swift”, “UserModel.swift”.
Добавьте в папку “Services” модули “UserData.swift”, “ProductData.swift”, “Services.swift”, “AuthorizationService.swift”, “ProductService.swift”, “UserService.swift”.
У вас должна получиться следующая структура.
Как видите, проект стал больше. Он станет еще больше, как только мы заполним добавленные модули.
Откройте модуль “Models / UserModel.swift”. Заполните его, как показано ниже.
В этом модуле мы создаем модель пользователя, в которую будем десериализовывать JSON объект пользователя, полученный от сервера.
В классе “UserModel” мы добавляем поля модели “_id”, “userName”, “userPwd”, “userDesc”, которые декларировали при объявлении схемы базы данных “Mongo DB” на сервере.
На 9 строке мы подключаем пространство имен “Foundation”.
На 11 строке мы объявляем класс с именем “UserModel”, который наследует класс “NSObject”, являющийся базовым классом для всех классов в iOS платформе. Наследуемся от протокола “NSCoding”, данный протокол необходимо реализовать, чтобы объект можно было сохранять в настройках телефона и извлекать оттуда.
Рассмотрим протокол “NSCoding”.
Протокол содержит метод “encode” и инициализатор.
Экземпляр класса “NSCoder” позволяет кодировать и раскодировать свойства класса, значения которых могут сохраняться в хранилище настроек телефона.
В методе “encode” данные извлекаются из свойств и кодируются в формат, нужный для сохранения в настройки телефона.
В инициализаторе данные извлекаются и раскодируются из настроек телефона, затем сохраняются в нужные свойства класса.
Вот так это работает.
Теперь вернемся и рассмотрим дальше модуль “UserModel.swift”.
На 12 строке мы объявляем поле “_id” типа “String” и инициализируем его значением по умолчанию, пустая строка.
На 13 строке мы объявляем поле “userName” типа “String” и инициализируем его значением по умолчанию, пустая строка.
На 14 строке мы объявляем поле “userPwd” типа “String” и инициализируем его значением по умолчанию, пустая строка.
На 15 строке мы объявляем поле “userDesc” типа “String” и инициализируем его значением по умолчанию, пустая строка.
На 17 строке мы переопределяем инициализатор по умолчанию для класса “NSObject”, тем самым мы говорим, что создание объекта без передачи аргументов в инициализатор будет возможно.
На 18 строке мы вызываем базовый инициализатор из класса “NSObject”.
На 21 строке мы объявляем параметризированный инициализатор. Данный инициализатор инициализирует поля класса “_id”, “userName”, “userPwd”, “userDesc” значениями, переданными в аргументы инициализатора.
На 31 строке мы реализуем конструктор протокола “NSCoding”. Ключевое слово “required” обозначает, что вызов этого инициализатора обязателен в первую очередь. Ключевое слово “convenience” гарантирует то, что после вызова этого инициализатора будут вызваны остальные инициализаторы классов, связанных с этим классом по цепочке вверх.
На 32 строке мы раскодируем из настроек телефона значение свойства “_id” путем вызова на экземпляре “aDecoder” типа “NSCoder” метода “decodeObject”, аргумент “forKey” которого принимает название поля/свойства, которое было сохранено в настройки телефона.
Этот метод возвращает значение “Any?”, т.е. неопределенный тип (аналог в C# - это Object, в Visual Basic - это Variant). Нам необходимо это значение вручную привести к нужному типу поля.
В настройках телефона содержится большой файл, который имеет древовидную структуру словаря ключ и значение.
Чтобы привести к нужному значению, мы используем конструкцию приведения к типу “as”. Причем, мы можем управлять этой конструкцией.
Например, нам надо привести тип “Any?” к типу “String”. Для этого мы используем конструкцию “as!”.
Если же нам надо привести к типу “String?” (nullable тип), тогда мы используем конструкцию “as?”. Зачем мы это делаем.
Настройки телефона разбиваются на разные файлы, для каждого приложения используется свой файл с настройками.
Когда приложения устанавливаются на macOS или iOS платформу, они устанавливаются в виде папки и имеют тип “Bundle”.
Apple довольно кардинально подошла к этому вопросу, она сделала так, что все настройки для каждого приложения хранятся внутри “Bundle” данного приложения. И когда приложение удаляется, удаляется “Bundle” со всеми настройками с диска операционной системы и не остается никаких следов после удаления.
Чего не скажешь о таких платформах, как Windows и Android, которые засоряют все пространство на диске операционной системы вокруг папки, в которую было установлено приложение, и выше. И когда приложение удаляешь, есть риск, что после этого будет необходимо еще и переустановить операционную систему.
Отчасти именно из-за этого подхода техника Apple пользуется такой популярностью и их устройства выигрывают по отказоустойчивости программного обеспечения по сравнению с конкурентами.
Если приложение обновляется, то файл настроек остается старый. Чтобы обновить его, надо выполнить запись в него, тогда старые конструкции удалятся, а новые добавятся. Представим себе ситуацию, сейчас в нашей модели “UserModel” всего 4 поля. Мы сохранили эту модель в файл настроек телефона. Отправили в магазин, пользователи скачали, установили приложение.
Вышла новая версия приложения, в которой мы добавили новое поле в эту модель с именем “userRole” типа “String”.
Разумеется, первая операция, которая будет выполнена как обычно - это запрос данных из настроек телефона, но для поля “userRole” установлено значение “nil” (аналог в C# null) и произойдет ошибка и креш приложения, так как мы не обработали эту ситуацию, а пытаемся через метод “decodeObject” получить значение этого поля и еще и явно привести его к типу “String” через, например, оператор “as!”.
Но в поле “userRole” - значение “nil” и оно не приведется к типу “String” через конструкцию “as!”, но может привестись без ошибок к типу “String?” через “as?”.
Надеюсь, я прояснил понятно, зачем нужна данная проверка. Продолжим.
На 32 строке мы проверяем, доступно ли нам значение поля “_id”. Чтобы проверить, равно ли возвращаемое значение “nil”, можно было бы использовать такую конструкцию: “aDecoder.decodeObject(..) == nil”, но такая конструкция не слишком информативна.
Поэтому мы используем конструкцию “(aDecoder.decodeObject(..) as? String) == nil”. Далее, если данная конструкция возвращает значение “true”, тогда мы через тернарный оператор присваиваем константе “_id” значение по умолчанию пустая строка, иначе присваиваем реальное значение поля “_id” из настроек телефона.
С 33 по 35 строку мы выполняем те же операции проверок для полей “userName”, “userPwd”, “userDesc”.
На 36 строке мы вызываем параметризированный конструктор и инициализируем его аргументы объявленными ранее константами.
На 47 строке объявлен вспомогательный метод “Populate”, который переносит данные из экземпляра “dictionary” типа “NSDictionary” в поля класса “UserModel”. Этот метод мы будем использовать, когда будем создавать запросы к серверу и получать ответы. В ответе содержится словарь типа “NSDictionary”, в котором находятся свойства с теми же именами, что и поля нашего класса.
С 48 по 51 строку мы инициализируем поля класса “UserModel” значениями из экземпляра “dictionary” c теми же проверками, что мы рассматривали выше.
На 53 строке объявлен вспомогательный метод “PopulateArray”, который переносит данные из экземпляра “array” типа “NSArray” в массив объектов типа “UserModel”. Этот метод мы будем использовать, когда в ответе от сервера придет массив JSON объектов типа “User”, чтобы сконвертировать массив типа “[NSDictionary]” в массив типа “[UserModel]”.
На 55 строке мы объявляем пустой массив типа “[UserModel]” c именем “result”.
На 56 строке мы выполняем цикл “foreach” по элементам массива “array”.
На 58 строке мы создаем новый экземпляр типа “UserModel” с именем “newItem”.
На 59 строке мы проверяем, содержит ли элемент массива значение “nil”.
На 60 строке мы вызываем на экземпляре “newItem” метод “Populate”, который перенесет данные из словаря типа “NSDictionary” в поля экземпляра “newItem”.
На 62 строке мы обращаемся к экземпляру “result” и вызываем у него метод “append”, чтобы добавить новый элемент в массив, и добавляем проинициализированный выше экземпляр “newItem”.
На 64 строке мы возвращаем сконвертированный массив типа “[UserModel]” из метода “PopulateArray”.
Откройте модуль “Models / ProductModel.swift”, заполните его в соответствии с содержимым ниже.
В этом модуле мы создаем модель пользователя, в которую будем десериализовывать JSON объект пользователя, полученный от сервера.
В классе “UserModel” мы добавляем поля модели “_id”, “userName”, “userPwd”, “userDesc”, которые декларировали при объявлении схемы базы данных “Mongo DB” на сервере.
На 9 строке мы подключаем пространство имен “Foundation”.
На 11 строке мы объявляем класс с именем “UserModel”, который наследует класс “NSObject”, являющийся базовым классом для всех классов в iOS платформе. Наследуемся от протокола “NSCoding”, данный протокол необходимо реализовать, чтобы объект можно было сохранять в настройках телефона и извлекать оттуда.
Рассмотрим протокол “NSCoding”.
Данный модуль не нуждается в объяснении, поскольку он по образу и подобию такой же, как и модуль “UserModel.swift”, с разницей лишь в том, что он построен на модели “Product” и содержит соответствующие поля.
Итак, модели данных мы создали, теперь мы сможем с уверенностью сохранять результаты ответа от сервера в нормальном виде и потом использовать их при инициализации элементов управления в соответствующих представлениях :)
Теперь приступаем к реализации классов для отправки запросов на сервер и сохранения/загрузки полученных данных в настройки телефона.
Откройте модуль “Services / Services.swift”, заполните его в соответствии с содержимым ниже.
На 11 строке объявлен класс с именем “Services”. Данный класс будет содержать вспомогательные свойства и методы, которые мы будем часто использовать при работе с ответом от сервера.
На 12 строке объявлено статическое свойство “host” типа “String” и мы ограничили его функциональность только одним аксессором доступа “get”. Т.е. значение свойства получить можно, но изменить нельзя. В данном свойстве содержится адрес, по которому доступен сервер.
В прошлом уроке, когда мы делали сервер, мы использовали адрес “http://localhost:3000” , внутри приложения клиента имеется свой “localhost”, именно поэтому мы используем явный IP адрес “127.0.0.1”, чтобы запрос шел именно на сервер, а не внутрь приложения.
На 18 строке объявлен статический метод “ejectJsonArray”, который принимает аргумент “data” типа “NSData?” и возвращает массив типа “NSArray?”. Данный метод конвертирует экземпляр класса “NSData” в экземпляр класса “NSArray”. В экземпляре “data” будет содержаться массив JSON объектов, полученных от сервера.
На 19 строке объявлена переменная “json” типа “NSArray?” и инициализировано значение по умолчанию “nil”.
На 20 строке мы используем конструкцию “do .. try .. catch” (аналог в C# - “try .. catch”). Символ “_” в блоке “catch” на месте аргумента используется потому, что мы не будем использовать этот аргумент в блоке “catch”.
В случае возникновения исключения мы не будем завершать аварийно приложение, а просто вернем значение “nil” по умолчанию, которое будет говорить о том, что конвертация не удалась, поскольку в NSData не содержится JSON объект.
Аналог JSON объекта в Swift - это класс “NSDictionary”.
На 21 строке мы правым операндом обращаемся к классу “JSONSerialization” и вызываем от его экземпляра статический метод “jsonObject”, который первым аргументом принимает данные типа “Data” для конвертации, вторым аргументом принимает опции конвертации.
Метод “jsonObject” возвращает экземпляр типа “Any”. Далее мы приводим это значение к нужному нам типу “NSArray?”, если приведение было проведено не успешно, будет возвращено значение “nil”.
Результат конвертации присваивается объявленной выше переменной “json”. Обратите внимание на ключевое слово “try” перед конструкцией “JSONSerialization.jsonObject(..)”, использование этого ключевого слова является обязательным, так как метод “jsonObject” имеет в своей сигнатуре ключевое слово “throws”, это означает, что данный метод может генерировать исключения и их необходимо обрабатывать.
На 23 строке в случае исключения вызванного методом “jsonObject” возвращается значение “nil”.
На 25 строке в случае успеха операции возвращается экземпляр типа “NSArray?”.
На 28 строке объвлен метод “ejectJsonDictionary” с той же сигнатурой, что и метод “ejectJsonArray”, но с разницей в возвращаемом значении.
В этом методе возвращается экземпляр типа “NSDictionary?”. Метод подразумевает, что в экземпляре “data” типа “NSData?” содержится единичный JSON объект и пытается его сконвертировать в тип “NSDictionary” , являющийся аналогом JSON объектов в Swift. Реализацию метода смысла описывать не вижу, она такая же, как и в методе “ejectJsonArray”.
Реализуем сохранение моделей данных “UserModel” и “ProductModel” в настройки телефона.
Откройте модуль “Services / UserData.swift”, заполните его в соответствии с содержимым ниже.
Модуль большой, поэтому будем разбирать его, разбив на две части по функциональности.
В первой его части будут описаны методы сохранения / извлечения единичного экземпляра типа “UserModel” и экземпляра типа массив “[UserModel]”.
Во второй его части будут описаны вспомогательные методы для обработчиков ошибок ответа от сервера и сохранения данных в настройки телефона.
Данные методы были созданы для того, чтобы не копипастить один и тот же код много раз, а стандартизировать и сделать его повторно используемым.
На 9 строке подключено пространство имен “UIKit”, необходимое для классов “UserDefaults”, “NSKeyedArchiver”, “NSKeyedUnarchiver”. В пространстве имен уже содержится подключенное пространство имен “Foundation”, поэтому нет смысла его тоже подключать для классов “NSArray”, “NSDictionary”, “NSData”.
На 10 строке подключено пространство имен “Alamofire”, необходимое для класса “DataResponse”.
На 12 строке объявлен класс с именем “UserData”.
На 13 строке объявлен метод “saveUserModel”, который принимает аргумент “userModel” типа “UserModel”. Метод будет сохранять поля модели “UserModel” в настройки телефона.
На 14 строке правым операндом мы обращаемся от экземпляра “UserDefaults” к его статическому свойству “standard”, это свойство является источником данных по отношению к файлу настроек телефона и содержит необходимые методы для сохранения / извлечения данных.
На 15 строке правым операндом мы обращаемся к экземпляру “NSKeyedArchiver” и вызываем статический метод “archivedData”. Этот метод принимает один аргумент “withRootObject” типа “Any” и возвращает экземпляр типа “Data”. Метод упаковывает экземпляр типа “UserModel” в экземпляр типа “Data” (аналог NSData) и возвращает его.
На 16 строке мы от экземпляра “userDefaults” вызываем метод “set”, который принимает два аргумента. Первый аргумент “_” типа “Any?” принимает экземпляр, который необходимо сохранить в настройках телефона. Второй аргумент “forKey” типа “String” необходим, чтобы задать название ключа в словаре настроек телефона. По этому ключу будет произведено сохранение экземпляра “UserModel”.
На 17 строке мы обращаемся к экземпляру “userDefaults”, вызываем от него метод “synchronize”. Данный метод выполняет сохранение экземпляра модели “UserModel” в настройки телефона (аналог в C#, например, 'using(StreamWriter sw = File.CreateText(“test.txt”)) { sw.Write(“some text”); sw.Flush(); }', из этого примера метод “Write” аналогичен методу “set”, а метод “Flush” аналогичен методу “synchronize”).
На 20 строке мы объявили статический метод “getUserModel”, который не принимает аргументов и возвращает экземпляр типа “UserModel”. В этом методе мы излекаем модель “UserModel” из файла настроек телефона по ключу, указанному в предыдущем методе при сохранении этой модели.
На 21 строке мы получаем экземпляр источника данных настроек телефона.
На 22 строке мы проверяем, если модель “UserModel” ранее не сохранялась в настройки телефона, тогда необходимо создать пустую модель по умолчанию.
Вызываем на экземпляре “userDefaults” метод “object”, который принимает аргумент “forKey” типа “String” и возвращает значение типа “Any?”. В качестве аргумента мы передаем ключ, под которым сохраняется данная модель в настройках телефона.
Если значение было найдено в словаре, будет возвращен экземпля , который надо будет привести у нужному типу.
Если значение не было найдено, будет возвращено значение “nil”.
На 23 строке мы создаем пустой экземпляр типа “UserModel”.
На 24 строке мы возвращаем этот экземпляр из метода.
На 26 строке код будет выполнен при наличии записи по ключу в словаре. Правым операндом мы обращаемся к экземпляру “userDefaults”, вызываем метод “object” и передаем в аргумент “forKey” ключ, по которому надо извлечь значение. Полученное значение приводим к типу “NSData”.
На 27 строке мы обращаемся к экземпляру “NSKeyedUnarchiver” и вызываем от него статический метод “unarchiveObject”, который принимает аргумент “with” типа “Data” и возвращает значение типа “Any”. Метод конвертирует экземпляр типа “Data” в экземпляр типа “Any”. Возращаемое значение метода мы явно приводим к типу “UserModel”.
На 28 строке мы возвращаем из метода полученный из словаря экземпляр типа “UserModel”.
На 31 строке объявлен метод “saveListOfUsersModel”, который принимает аргумент “listOfUsersModel” типа “[UserModel]” и ничего не возвращает. Метод сохраняет массив “[UserModel]” в файл настроек телефона. Описывать данный метод не имеет смысла, его работа аналогична методу “saveUserModel”.
На 38 строке объявлен метод “getListOfUsersModel”, который не принимает аргументов и возвращает экземпляр типа массив “[UserModel]”. Метод извлекает из настроек телефона массив типа “[UserModel]” по ключу, указанному в методе “saveListOfUsersModel”. Описывать данный метод не имеет смысла, его работа аналогична методу “getUserModel”.
Откройте модуль “ProductData.swift”, заполните его в соответствии с содержимым ниже.
В первой части описано сохранение / извлечение моделей типа “ProductModel”, “[ProductModel]” в настройки телефона. Описывать код не имеет смысла, его работа точно такая же, как и в модуле “UserData.swift”.
Во второй части описаны вспомогательные методы для обработки запросов от сервера и сохранения данных. Описывать код не имеет смысла, его работа точно такая же, как и в модуле “UserData.swift”.
Теперь, наконец то, мы можем реализовать первый класс для работы с сервисом авторизации пользователя и разобрать работу с библиотекой “Alamofire”.
Откройте модуль “Services / AuthorizationService.swift”, заполните его в соответствии с содержимым ниже.
На 12 строке объявлен класс с именем “AuthorizationService”.
На 13 строке объявлен метод “login”, который принимает три аргумента и ничего не возвращает.
Первый аргумент “userName” типа “String” - это имя пользователя (логин).
Второй аргумент “userPwd” типа “String” - это пароль пользователя.
Третий аргумент - это “callback” метод, который принимает аргумент типа “Bool” и ничего не возвращает.
Метод с такой сигнатурой, переданный в третий аргумент, будет вызван по завершению обработки ответа от сервера. В случае наличия ошибок в аргумент этого метода будет передано значение “false”. В случае успешно проведенной операции - значение “true”.
Да, можно было сделать этот аргумент другим типом, например, отдельным классом ошибок, в который можно было сохранять подробно, что за ошибка произошла.
Но это учебный пример, он итак очень большой. Я решил не усложнять этим жизнь ни себе, ни вам :)
На 14 строке правым операндом мы вызываем метод “request” из библиотеки “Alamofire”.
Метод принимает 5 аргументов и возвращает значение типа “DataRequest”.
Данный метод используется для отправки HTTP/HTTPS запросов на сервер.
Первый аргумент “_” типа “URLConvertible” принимает адрес, по которому необходимо отправить запрос. Мы его инициализируем значением “\(Services.host)/auth”, которое после подстановки свойства “host” будет выглядеть вот так: “http://127.0.0.1:3000/auth”.
Второй аргумент “method” типа “HTTPMethod” принимает HTTP глагол. Тип “HTTPMethod” является перечислением и может принимать следующие значения.
Мы инициализируем данный аргумент значением “.post” (это сокращенная запись, полная запись “HTTPMethod.post”)
Третий аргумент “parameters” типа “Parameters?”. Принимает словарь, ключ - значение, мы его заполняем теми же данными, что отправляли в прошлом уроке через утилиту “Postman”. Конкретно, мы передаем значение имени пользователя и его пароль.
Четвертый аргумент “encoding” типа “ParameterEncoding”. Этим параметром задается заголовок запроса “Content-Type”, т.е. указывается тип данных, который будет отправлен на сервер, сами данные задаются в третьем аргументе “parameters”. Мы инициализируем аргумент значением “JSONEncoding.default”, что аналогично записи “application/json”. Тип “ParameterEncoding” является протоколом и имеет следующие реализации себя в классах “URLEncoding”, “JSONEncoding”, “PropertyListEncoding”. Про эти классы вы можете почитать в официальной документации на сайте “Alamofire”.
Пятый аргумент “headers” типа “HTTPHeaders?” имеет значение по умолчанию “nil”, в нашем вызове метода он не используется. Данный аргумент задается, если вы желаете отправить в заголовках запроса на сервер какую- либо информацию, например, “cookie”. Если у вас сервер написан на Web API и вы используете для авторизации OWin , с настройкой надо использовать “cookie” как ключ авторизации пользователя. Тогда при отправке запросов вам будет необходимо заполнять этот аргумент. Пример его заполнения может выглядеть вот так:
Этот пример взят из моего приложения “Smart Payment”, написанного на Swift 2.2 c минимальной версией iOS 8.3 библиотекой “Alamofire” версии 2. Чтобы этот пример работал на Swift 3, надо заменить значение параметра “encoding” на “JSONEncoding.default”. Этот пример не относится к нашему приложению и его переписывать не нужно.
На 16 строке мы вызываем от экземпляра “r” типа “DataRequest” метод “responseJSON”. Этот метод выполняет запрос на сервер и содержит три аргумента.
Первый аргумент “queue” типа “DispatchQueue?” по умолчанию содержит значение “nil”. Используется при переопределении потока выполнения запроса.
Второй аргумент “options” типа “JSONSerialization.ReadingOptions” по умолчанию содержит значение “.allowFragments”. Используется для задания опция отправки запроса. Тип “ReadingOptions” является структурой и имеет такое объявление.
Третий аргумент “completionHandler” типа делегат “@escaping (DataResponse) -> Void”. Данная сигнатура принимает один аргумент типа “DataResponse” и ничего не возвращает. В этом аргументе содержится ответ от сервера. Сам метод вызывается после запроса, когда сервер отправил ответ на клиент.
Обратите внимание, на 16 строке, когда мы вызываем метод “responseJSON”, у нас нет круглых скобок после метода, а идут сразу фигурные скобки, это называется “closure” подход. В фигурных скобках мы объявляем лямбда метод с сигнатурой, соответствующей третьему аргументу метода “responseJSON”.
Запись “response in” означает следующее: “response” - это аргумент лямбда метода, а само тело метода начинается после ключевого слова “in”. Аргумент “response” имеет тип “DataResponse”.
На 17 строке мы проверяем, если ответ пришел с ошибкой, то это означает, что данных нет и пришло пустое значение типа “nil”. Мы обращаемся к экземпляру “response” и вызываем свойство “result” типа “Result” и от свойства “result” вызываем свойство “value” типа “Value?”. Если в свойстве “value” пришло пустое значение, значит запрос не был выполнен, возможно, по причине недоступности сервера или отсутствия подключения к интернету.
На 18 строке мы вызываем “callback” метод “completion” со значением “false”.
На 21 строке, в случае если проблем с подключением к серверу не возникло, мы правым операндом вызываем от экземпляра “Services” метод “ejectJsonDictionary”, который ранее уже подробно рассматривали. В аргумент “data” мы передаем значение свойства “data”, вызванного от экземпляра “response”. Свойство “data” имеет тип “Data?”. Левому операнду “json” присваивается экземпляр “NSDictionary”, в котором содержится JSON объект пользователя, прошедшего авторизацию, который был отправлен сервером на клиент.
На 22 строке мы проверяем, если пришел JSON объект с ошибкой, тогда возвращаем нужный флаг в “callback” методе “completion”. Помним, что в предыдущем уроке мы создавали JSON объект с ошибкой на сервере, в случае если пользователь ввел неверные данные авторизации, JSON выглядел вот так '{ “Error”: “Authorization error”}'.
У словаря “json” есть возможность получить все ключи, для этого надо вызвать свойство “allKeys”, которое имеет тип “[Any]”. Но, поскольку выполнить поиск строки в массиве объектов нельзя, мы оборачиваем массив объектов в массив типа “Array” и явно приводим его к нужному нам типу массива “[String]”. Мы это делаем, поскольку знаем наверняка, что ключи JSON объекта имеют тип “String”. Затем от полученного экземпляра типа “[String]” мы вызываем метод “contains”, в аргумент которого передает название свойства JSON объекта ошибки, значение “Error”. Если такой JSON объект пришел в ответе, значит пользователь ввел неправильные логин или пароль, или ввел несуществующего пользователя.
На 23 строке мы вызываем “callback” метод “completion” с аргументом “false”.
На 25 строке мы создаем пустой экземпляр “userModel” типа “UserModel”.
На 26 строке мы вызываем на экземпляре “userModel” метод “Populate” в аргумент “dictionary”, передаем экземпляр “json”. Метод “Populate” перенесет данные из экземпляра “json” типа “NSDictionary” в поля экземпляра “userModel”.
На 27 строке мы обращаемся к экземпляру “UserData” и вызываем статический метод “saveUserModel”, чтобы сохранить данные экземпляра “userModel” в настройки телефона. В аргумент “userModel” мы передаем экземпляр “userModel”.
На 28 строке мы вызываем “callback” метод “completion” и передаем в него результат операции “true”.
Позже в контроллере, где мы будем вызывать метод “login”, будет передан “callback” метод “completion”, объявленный в этом контроллере. Тем самым решается проблема ожидания ответа от сервера в контроллере, так как есть “callback” метод. Внутри этого метода мы проверим результат операции и затем обратимся к экземпляру “UserData” и вызовем метод “getUserModel”, который вернет нам экземпляр “UserModel”, с которым мы сможем работать на стороне контроллера.
Откройте модуль “Services / UserService.swift”, заполните его, как показано ниже.
На 12 строке объявлен класс “UserService”.
На 13 строке объявлен метод “get”, который принимает два аргумента и ничего не возвращает.
Первый аргумент “id” типа “String?” принимает идентификатор пользователя “_id”. Если передать в аргумент значение “nil”, будет возвращен весь список пользователей, если передать конкретный идентификатор, будет возвращен конкретный пользователь.
Второй аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
На 29 строке объявлен метод “create”, который принимает 4 аргумента и ничего не возвращает. Метод отправляет запрос на создание пользователя на сервер.
Первые три аргумента “userName”, “userPwd”, “userDesc” имеют тип “String” и содержат данные пользователя. Идентификатор пользователя в операции создания не нужен. Так как идентификатор пользователю присваивается на стороне сервера и данный метод выполняет как раз эту операцию.
Четвертый аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
На 37 строке объявлен метод “update”, который принимает 5 аргументов и ничего не возвращает. Данный метод отправляет запрос на обновление данных пользователя на сервер.
Первые 4 аргумента “id”, “userName”, “userPwd”, “userDesc” имеют тип “String” и содержат данные пользователя.
Пятый аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
На 45 строке мы объявляем метод “delete”, который принимает два аргумента. Этот метод отправляет запрос на удаление пользователя на сервер.
Первый аргумент “id” типа “String?” принимает идентификатор пользователя “_id”.
Второй аргумент “completion” типа делегат “(Bool) -> Void”, используется для получения сигнала, что ответ был получен и основные операции были выполнены.
Откройте модуль “Services / ProductService.swift”, заполните его, как показано ниже
На 12 строке объявлен класс “ProductService”.
На 13 строке объявлен метод “get”, который принимает два аргумента и ничего не возвращает.
Первый аргумент “id” типа “String?” принимает идентификатор товара “_id”. Если передать в аргумент значение “nil”, будет возвращен весь список товаров, если передать конкретный идентификатор, будет возвращен конкретный товар.
Второй аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
На 29 строке объявлен метод “create”, который принимает 4 аргумента и ничего не возвращает. Метод отправляет запрос на создание товара на сервер.
Первые три аргумента “productImage”, “productName”, “productDescription” имеют тип “String” и содержат данные товара. Идентификатор товара в операции создания не нужен. Так как идентификатор товару присваивается на стороне сервера и данный метод выполняет как раз эту операцию.
Четвертый аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
На 37 строке объявлен метод “update”, который принимает 5 аргументов и ничего не возвращает. Данный метод отправляет запрос на обновление данных товара на сервер.
Первые 4 аргумента “id”, “productImage”, “productName”, “productDescription” имеют тип “String” и содержат данные пользователя.
Пятый аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
На 45 строке мы объявляем метод “delete”, который принимает два аргумента. Этот метод отправляет запрос на удаление товара на сервер.
Первый аргумент “id” типа “String?” принимает идентификатор товара “_id”.
Второй аргумент “completion” типа делегат “(Bool) -> Void” используется для получения сигнала, что ответ был получен и основные операции были выполнены.
Заметьте, адреса запросов, используемых нами при отправке на сервер, совпадают с теми, что мы использовали в прошлом уроке в утилите “Postman”.
На этом урок завершен.
На следующем уроке мы продолжим разработку клиента, создадим контроллеры и представления для редактирования пользователей, подключим работу сервисов к странице входа в систему, создадим форму регистрации пользователя.