{"id":347579,"date":"2023-05-17T09:01:26","date_gmt":"2023-05-17T09:01:26","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=347579"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=347579","title":{"rendered":"<span>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Command Line Tool \u043d\u0430 Swift \u0432 iOS \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/span>"},"content":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<p>\u041d\u0435&nbsp;\u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u043d\u0430&nbsp;\u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0412&nbsp;\u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e&nbsp;\u0431\u044b\u043b \u0444\u0430\u0439\u043b\u2011\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0432&nbsp;\u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439\u0441\u044f \u0432&nbsp;Bundle \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0435\u0449\u0451 Info.plist \u0432&nbsp;\u043f\u0440\u0438\u0434\u0430\u0447\u0443. \u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e&nbsp;\u0442\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0432&nbsp;\u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u043c iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0414\u0430&nbsp;\u0438 \u0432\u043e\u043e\u0431\u0449\u0435, \u0432\u044b\u0437\u043e\u0432\u044b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432&nbsp;\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0436\u0435 \u0432&nbsp;\u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u043c\u0435\u043d\u044f \u043d\u0435&nbsp;\u0441\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0434\u043e\u0432\u0430\u043b\u0438&nbsp;\u2014 \u0432&nbsp;\u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0431\u043e\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443&nbsp;\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0430\u043b\u0438\u0432\u0430\u043b\u0441\u044f \u043a\u0443\u0441\u043e\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u041a\u0430\u043a&nbsp;\u0431\u044b \u0432\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u0432&nbsp;\u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435? \u0412\u044b\u043d\u0435\u0441\u043b\u0438&nbsp;\u0431\u044b \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430&nbsp;\u0432\u0430\u0448 \u0431\u044d\u043a? \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b&nbsp;\u0431\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c, \u043d\u043e&nbsp;\u0447\u0442\u043e&nbsp;\u0434\u0435\u043b\u0430\u0442\u044c \u0441&nbsp;Info.plist?<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e&nbsp;\u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432&nbsp;\u0433\u043e\u043b\u043e\u0432\u0443&nbsp;\u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c Shell\u2011\u0441\u043a\u0440\u0438\u043f\u0442. \u041d\u043e&nbsp;\u044d\u0442\u043e \u043c\u043e\u0433\u043b\u043e \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a&nbsp;\u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c \u0441&nbsp;\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 iOS \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443&nbsp;\u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u043d\u0430&nbsp;Swift.<\/p>\n<p>\u0412&nbsp;\u0441\u0435\u0442\u0438 \u043c\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043f\u043e&nbsp;\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e Command Line Tool \u043d\u0430&nbsp;Swift, \u043d\u043e&nbsp;\u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0441\u0440\u0430\u0437\u0443 \u0432&nbsp;\u0441\u0432\u044f\u0437\u043a\u0435 \u0441&nbsp;iOS \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c.<\/p>\n<h3>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0434\u043b\u044f&nbsp;\u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437&nbsp;HTTPS.<\/p>\n<blockquote>\n<p>&#8230; \u043a\u0430\u043a&nbsp;\u0431\u0443\u0434\u0442\u043e \u043c\u044b \u043d\u0435&nbsp;\u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u043b\u0430\u0433 Allow Arbitrary Loads. \u041d\u043e&nbsp;\u043d\u0430&nbsp;\u0442\u043e \u043e\u043d \u0438 \u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<\/blockquote>\n<p>\u0414\u043b\u044f&nbsp;\u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 NSAppTransportSecurity&nbsp;\u2014 NSExceptionDomains \u0432&nbsp;Info.plist, \u0430&nbsp;\u0442\u0430\u043a\u0436\u0435 \u0444\u0430\u0439\u043b\u2011\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e&nbsp;\u0434\u043e\u043c\u0435\u043d\u0430\u0445. \u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0430 \u0432&nbsp;\u0432\u0438\u0434\u0435 JSON \u043f\u0443\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432&nbsp;\u0441\u0430\u043c\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<pre><code class=\"json\">[    {       \"name\":\"dev.app_main.com\",       \"allowsInsecureHTTPLoads\":true,       \"description\":\"DEV environment for app testing\"    },    ... ]<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/Streetmage\/DomainsList\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>. \u041f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0432\u0430 \u0442\u0430\u0440\u0433\u0435\u0442\u0430: iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 DomainsList, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0434\u043e\u043c\u0435\u043d\u043e\u0432, \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 DomainsUpdater.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/bfa\/169\/23e\/bfa16923eb0e4084e2234e2fb921b923.png\" width=\"1470\" height=\"1378\"><\/figure>\n<p>iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u044c Domain \u0434\u043b\u044f&nbsp;\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u044b\u0445 \u0438\u0437&nbsp;JSON \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0430:<\/p>\n<pre><code class=\"swift\">struct Domain: Decodable { let name: String let description: String let allowsInsecureHTTPLoads: Bool }<\/code><\/pre>\n<p>\u0412&nbsp;\u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u043c\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e&nbsp;\u0448\u0430\u0433\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u041d\u0430\u0447\u043d\u0435\u043c!<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430<\/h2>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0432&nbsp;\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0430\u0440\u0433\u0435\u0442\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0443\u043a\u0430\u0437\u0430\u0432 \u0442\u0438\u043f Command Line Tool. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0430\u0436\u0430\u0432 \u043d\u0430&nbsp;\u043f\u043b\u044e\u0441 \u0432&nbsp;\u0431\u043b\u043e\u043a\u0435 Targets.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/64f\/e29\/ddc\/64fe29ddce3f53b27455ecbc1969cc29.png\" alt=\"\" title=\"\" width=\"1600\" height=\"1201\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0444\u0430\u0439\u043b main.swift, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u043e&nbsp;\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432&nbsp;\u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u0412\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c enum \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"swift\">@main enum DomainsUpdater { static func main() {} }<\/code><\/pre>\n<p>\u0412&nbsp;\u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/866\/596\/a9a\/866596a9ad55e595c7e14ed735c5806e.png\" alt=\"\" title=\"\" width=\"538\" height=\"284\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f main \u0431\u0443\u0434\u0435\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f&nbsp;\u043d\u0430\u0448\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<blockquote>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e enum \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0438\u043f\u044b, \u043d\u043e&nbsp;\u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432&nbsp;\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443&nbsp;\u0431\u044b\u043b\u0430 \u043e\u0434\u043d\u0430. \u0412&nbsp;\u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0434\u043b\u044f&nbsp;\u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043a\u0430\u043a&nbsp;\u043d\u0430\u0448\u0430 \u043c\u043e\u0436\u043d\u043e&nbsp;\u0431\u044b\u043b\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0444\u0430\u0439\u043b\u043e\u043c main.swift, \u043d\u043e&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 main \u0431\u043e\u043b\u0435\u0435 <a href=\"https:\/\/github.com\/apple\/swift-evolution\/blob\/main\/proposals\/0281-main-attribute.md\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/a>.<\/p>\n<\/blockquote>\n<p>\u0412\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c \u0448\u0430\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0442\u0430\u0440\u0433\u0435\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c Domain \u0441\u0440\u0430\u0437\u0443 \u0434\u043b\u044f&nbsp;\u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0438 iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"swift\">struct Domain: Decodable { let name: String let description: String let allowsInsecureHTTPLoads: Bool }<\/code><\/pre>\n<figure class=\"\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/765\/f6b\/ba0\/765f6bba07e3bf94286ab28622959a5b.png\" alt=\"\" title=\"\" width=\"510\" height=\"746\"><\/figure>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d! \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438.<\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c<\/h2>\n<p>\u0417\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e&nbsp;\u0432&nbsp;\u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435&nbsp;\u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434 \u0441&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/apple.github.io\/swift-argument-parser\/documentation\/argumentparser\/\" rel=\"noopener noreferrer nofollow\">ArgumentParser<\/a>. \u041c\u044b \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438, \u0442\u0430\u043a \u043a\u0430\u043a&nbsp;\u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430&nbsp;\u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0445\u044d\u043b\u043f\u0435\u0440, \u0430&nbsp;\u043d\u0435&nbsp;\u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 CLI \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 SPM \u0432&nbsp;\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c ArgumentParser, \u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u00ab\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438\u00bb \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 CommandLine&nbsp;\u2014 \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437&nbsp;\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u0438\u0437\u0432\u043d\u0435. \u0423&nbsp;\u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e arguments \u0432&nbsp;\u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/daf\/0e7\/1f9\/daf0e71f97811fe8ee1061204438cd62.png\" alt=\"\" title=\"\" width=\"1600\" height=\"777\"><\/figure>\n<p>\u041d\u043e&nbsp;\u0442\u0443\u0442 \u043d\u0430\u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u0434\u043d\u043e\u0436\u043a\u0430 \u043e\u0442&nbsp;Apple. \u0414\u043b\u044f&nbsp;\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0437\u0430\u0431\u044b\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043a\u0443, \u0430&nbsp;\u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 arguments \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0430\u0448\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b!<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043b\u0430\u0441\u0441&nbsp;\u2014 ProcessInfo, \u0432&nbsp;\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e&nbsp;\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u041d\u0415&nbsp;\u0437\u0430\u0431\u044b\u043b\u0438. \u0423&nbsp;\u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0435&nbsp;\u0436\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e arguments, \u0430&nbsp;\u0442\u0430\u043a\u0436\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e environment \u0434\u043b\u044f&nbsp;\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e&nbsp;\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0420\u0430\u0437\u043d\u0438\u0446\u0443, \u043a\u0430\u043a\u043e\u0439 \u0438\u0437&nbsp;\u043a\u043b\u0430\u0441\u0441\u043e\u0432 CommandLine \u0438\u043b\u0438&nbsp;ProcessInfo \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u044f \u043d\u0435&nbsp;\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b. \u0427\u0442\u043e\u0431\u044b \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441&nbsp;\u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443:<\/p>\n<pre><code class=\"swift\">typealias ArgumentType = RawRepresentable &amp; Hashable  struct ArgumentsProvider&lt;T: ArgumentType&gt; { private let arguments: [T: String]    init(_ argumentsArray: [String]) { var argumentsDictionary: [T: String] = [:] argumentsArray.enumerated().forEach { index, arg in guard let index = index as? T.RawValue,                    let argKey = T(rawValue: index) else {                return              } argumentsDictionary[argKey] = arg } self.arguments = argumentsDictionary }  subscript(arg: T) -&gt; String { guard let arg = arguments[arg], !arg.isEmpty else {            fatalError(.argumentNotFound(arg))          } return arg } }<\/code><\/pre>\n<p>\u0414\u043b\u044f&nbsp;\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430\u0434\u043e \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e&nbsp;\u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b: update \u0438 clean. update&nbsp;\u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 domains.json (\u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0444\u0430 \u043e&nbsp;\u0434\u043e\u043c\u0435\u043d\u0430\u0445) \u0438 Info.plist, \u0430&nbsp;clean \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u043d\u0451\u0442 \u0444\u0430\u0439\u043b\u0430\u043c \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0438\u0434.<\/p>\n<pre><code class=\"swift\">static func main() {     let args = ArgumentsProvider&lt;CommandArgument&gt;(ProcessInfo.processInfo.arguments)     guard let command = Command(rawValue: args[.command]) else {        fatalError(.unrecognizedCommand)      }      switch command {     case .update:         update()     case .clean:         clean()     } }  static func update() {     let args = ArgumentsProvider&lt;UpdateArgument&gt;(ProcessInfo.processInfo.arguments)     let domains = fetchDomainsJson(remotePath: args[.remotePath])     updateLocalFile(at: args[.localPath], domains: domains)     updateInfoPlist(at: args[.infoPlistPath], domains: domains) }  static func clean() {     let args = ArgumentsProvider&lt;CleanArgument&gt;(ProcessInfo.processInfo.arguments)     updateLocalFile(at: args[.localPath], domains: [])     updateInfoPlist(at: args[.infoPlistPath], domains: []) }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 fetchDomainsJson, updateLocalFile \u0438 updateInfoPlist \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 <a href=\"https:\/\/github.com\/Streetmage\/DomainsList\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0438\u043f CommandArgument \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0430&nbsp;\u0441\u0430\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0438\u043c\u0435\u0435\u0442 2&nbsp;\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: update \u0438\u043b\u0438&nbsp;clean.<\/p>\n<pre><code class=\"swift\">enum CommandArgument: Int { case command = 1 }  enum Command: String, CaseIterable { case update case clean }<\/code><\/pre>\n<p>\u0422\u0438\u043f\u044b UpdateArgument, CleanArgument \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<pre><code class=\"swift\">enum UpdateArgument: Int { case remotePath = 2 case localPath case infoPlistPath }  enum CleanArgument: Int { case localPath = 2 case infoPlistPath }<\/code><\/pre>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f ProcessInfo.processInfo.environment. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 domains.json \u0438\u043b\u0438 Info.plist.<\/p>\n<pre><code class=\"swift\">guard let srcRoot = ProcessInfo.processInfo.environment[\"SRCROOT\"] else {    fatalError(\"SRCROOT not found\")  }  let resources = \"\\(srcRoot)\/DomainsList\/Resources\" let localPath = \"\\(resources)\/domains.json\" let infoPlistPath = \"\\(resources)\/Info.plist\"<\/code><\/pre>\n<p>\u0412\u0410\u0416\u041d\u041e!!! \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0438\u0437&nbsp;\u0441\u0435\u043a\u0446\u0438\u0438 Build Phases \u043f\u0440\u0438&nbsp;\u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e&nbsp;\u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0434\u0430\u043d\u044b. \u041e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0442\u0430\u043a\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u043f\u0440\u0438&nbsp;\u0437\u0430\u043f\u0443\u0441\u043a\u0435 Debug \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u043e&nbsp;\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u0420\u0430\u0437 \u043c\u044b \u0443\u0436\u0435 \u0437\u0430\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043f\u0440\u043e&nbsp;\u043e\u0442\u043b\u0430\u0434\u043a\u0443, \u0442\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043a&nbsp;\u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0430&nbsp;\u0438\u043c\u0435\u043d\u043d\u043e \u043a&nbsp;\u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a \u0443\u0442\u0438\u043b\u0438\u0442\u044b<\/h2>\n<h4>\u041e\u0442\u043b\u0430\u0434\u043a\u0430<\/h4>\n<p>\u0414\u043b\u044f&nbsp;\u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0441\u0445\u0435\u043c\u044b. \u0422\u0443\u0442 \u0443&nbsp;\u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u041e!!! \u0411\u0443\u0434\u044c\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e&nbsp;\u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a&nbsp;INFOPLIST_FILE, \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432&nbsp;\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442&nbsp;\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f&nbsp;\u0441\u0445\u0435\u043c\u044b DomainsUpdater \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u044b\u043c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u0438\u043f\u0430 SRCROOT.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/59a\/e60\/ba7\/59ae60ba70ca4e391c8c0fead383c888.png\" alt=\"\" title=\"\" width=\"1600\" height=\"943\"><\/figure>\n<h4>Pre-compile \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 Build Phases<\/h4>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0432 \u044f\u0432\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 iOS \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/7a1\/d72\/3e2\/7a1d723e238fe5e04ac45916fa732ba7.png\" alt=\"\" title=\"\" width=\"642\" height=\"270\"><\/figure>\n<p>\u0412\u0410\u0416\u041d\u041e!!! \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0444\u043b\u0430\u0433 Skip install \u0432 Build Settings.&nbsp;\u0418\u043d\u0430\u0447\u0435 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u0440\u0435\u043b\u0438\u0437\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0430\u0440\u0445\u0438\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 2 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 AppStore Connect.<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/f1c\/660\/ec7\/f1c660ec7d006327c1f115d42a19535c.png\" alt=\"\" title=\"\" width=\"1298\" height=\"354\"><\/figure>\n<p>\u0417\u0430\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0430\u043c \u0441\u043a\u0440\u0438\u043f\u0442, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u043f\u0435\u0440\u0435\u0434 \u0444\u0430\u0437\u043e\u0439 Compile Sources:<\/p>\n<pre><code class=\"bash\">if [ $CONFIGURATION = 'Debug' ]  then $CONFIGURATION_BUILD_DIR\/..\/$CONFIGURATION\/DomainsUpdater update \\ \"https:\/\/raw.githubusercontent.com\/Streetmage\/DomainsList\/main\/remote_domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/Info.plist\" fi<\/code><\/pre>\n<p>\u041a\u0430\u043a&nbsp;\u0432\u0438\u0434\u043d\u043e, \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f&nbsp;Debug \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043d\u043e&nbsp;\u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e Release, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0430\u0440\u0445\u0438\u0432\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p><s>Pre\u2011actions \u0432&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0441\u0445\u0435\u043c\u044b<\/s><\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c&nbsp;\u0431\u044b, \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u044b&nbsp;\u2014 \u0447\u0435\u0440\u0435\u0437 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u043e&nbsp;\u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><img loading=\"lazy\" decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/073\/3c0\/ed8\/0733c0ed896965abc5980dce53d1f03c.png\" alt=\"\" title=\"\" width=\"1600\" height=\"943\"><\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, pre\u2011action \u0441\u043a\u0440\u0438\u043f\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438, \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 (\u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0432\u0430) \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b.<\/p>\n<h4>Shell-\u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/h4>\n<p>\u0412\u0441\u0451\u2011\u0442\u0430\u043a\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442&nbsp;Shell \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043d\u0435&nbsp;\u043e\u0442\u043a\u0430\u0436\u0435\u0448\u044c\u0441\u044f. \u041d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430&nbsp;\u0441\u0442\u043e\u0440\u043e\u043d\u0435 CI. \u0422\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438&nbsp;\u043f\u043e\u043c\u043e\u0449\u0438 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/p>\n<pre><code class=\"bash\"># Build utility TARGET=\"DomainsUpdater\" CONFIG=\"Debug\" xcodebuild -project DomainsList.xcproject -scheme $TARGET -configuration $CONFIG -destination 'generic\/platform=macOS' # Get BUILD_ROOT and SRCROOT from utility project settings BUILD_SETTINGS=`xcodebuild -project DomainsList.xcproject -scheme $TARGET -showBuildSettings` BUILD_ROOT=`echo \"$BUILD_SETTINGS\" | grep BUILD_ROOT | sed -e \"s\/^    BUILD_ROOT = \/\/\"` SRCROOT=`echo \"$BUILD_SETTINGS\" | grep SRCROOT | sed -e \"s\/^    SRCROOT = \/\/\"` # Start utility $BUILD_ROOT\/$CONFIG\/$TARGET update \\ \"https:\/\/raw.githubusercontent.com\/Streetmage\/DomainsList\/main\/domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/Info.plist\"<\/code><\/pre>\n<p>\u0412\u0410\u0416\u041d\u041e!!! \u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0444\u0430\u0439\u043b .sh \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c:<\/p>\n<pre><code class=\"bash\">chmod +x DomainsUpdater.sh<\/code><\/pre>\n<h2>\u0412\u044b\u0432\u043e\u0434\u044b<\/h2>\n<p>\u041f\u0440\u0438&nbsp;\u043f\u043e\u043c\u043e\u0449\u0438 Command Line Tool \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0442\u044c \u0440\u0435\u0434\u043a\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u044b\u0435 \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0435&nbsp;\u0437\u0430\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u044f \u043f\u0440\u0438&nbsp;\u044d\u0442\u043e\u043c \u0432\u0430\u0448 \u0431\u044d\u043a\u0435\u043d\u0434. \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u043e\u0439\u2011\u043b\u0438\u0431\u043e \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0432\u044b \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u0442\u0435 \u0443&nbsp;\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430, \u0441\u043f\u043e\u0441\u043e\u0431\u043d\u043e\u0433\u043e \u0443\u043f\u0430\u0441\u0442\u044c \u0432&nbsp;\u043d\u0435\u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 \u043c\u043e\u043c\u0435\u043d\u0442, \u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435, \u0447\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u044b\u0437\u043e\u0432 \u0438\u0437&nbsp;\u0441\u0430\u043c\u043e\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<h4>\u041a\u043e\u0433\u0434\u0430 \u043b\u0443\u0447\u0448\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Swift-\u0443\u0442\u0438\u043b\u0438\u0442\u0443, \u0430 \u043a\u043e\u0433\u0434\u0430 \u043b\u0443\u0447\u0448\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0441\u043a\u0440\u0438\u043f\u0442<\/h4>\n<p>\u0423\u0442\u0438\u043b\u0438\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>\u043a\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u044b\u0435 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441&nbsp;\u0444\u0430\u0439\u043b\u0430\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0430&nbsp;\u0438\u0437\u0443\u0447\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b \u043d\u0435&nbsp;\u0445\u043e\u0447\u0435\u0442\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u043f\u0440\u043e\u0441\u0442\u043e\u0442\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0432&nbsp;Xcode<\/p>\n<\/li>\n<li>\n<p>\u0448\u0430\u0440\u0438\u043d\u0433 \u043a\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439<\/p>\n<\/li>\n<li>\n<p>\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0434\u0440\u0443\u0433\u0438\u043c\u0438 iOS \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442:<\/p>\n<ul>\n<li>\n<p>\u0443&nbsp;\u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u0433\u043e\u0442\u043e\u0432\u044b\u0439 \u043d\u0430\u0431\u043e\u0440 \u0443\u0442\u0438\u043b\u0438\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0447\u0435\u0440\u0435\u0437 Shell<\/p>\n<\/li>\n<li>\n<p>\u0432\u044b \u0432\u043b\u0430\u0434\u0435\u0435\u0442\u0435 \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u044b\u043c\u0438 \u043a\u043e\u043c\u0430\u043d\u0434\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u043e \u0441\u043e\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0430\u0434 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c \u043d\u0435&nbsp;\u0442\u0440\u0435\u0431\u0443\u044e\u0442 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0437\u043d\u0430\u043d\u0438\u0439 \u043f\u043e&nbsp;iOS, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0430 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043c\u043e\u0433\u043b\u0430 \u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043b\u044f\u0442\u044c\u0441\u044f DevOps \u0438\u043d\u0436\u0435\u043d\u0435\u0440\u0430\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>P.&nbsp;S. \u0412 <a href=\"https:\/\/github.com\/Streetmage\/DomainsList\" rel=\"noopener noreferrer nofollow\">\u0434\u0435\u043c\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/a> \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043f\u0440\u0438&nbsp;\u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f DomainsList. \u0414\u043b\u044f&nbsp;\u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043e\u0447\u0438\u0441\u0442\u0438\u0442\u044c domains.json \u0438 Info.plist, \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 DomainsUpdater \u0432&nbsp;\u0434\u0435\u0431\u0430\u0433 \u0440\u0435\u0436\u0438\u043c\u0435: \u0432&nbsp;\u043d\u0451\u043c \u043f\u043e&nbsp;\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u044b \u043d\u0430&nbsp;\u043a\u043e\u043c\u0430\u043d\u0434\u0443 clean. \u0415\u0441\u043b\u0438 \u0443&nbsp;\u0432\u0430\u0441 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0441&nbsp;\u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u0441\u043a\u0440\u0438\u043f\u0442\u0430 DomainsUpdater.sh, \u0442\u043e \u0432&nbsp;README \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u044f \u0432\u044b, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e, \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435. <\/p>\n<\/p>\n<\/div>\n<\/div>\n<p> <!----> <!----><\/div>\n<p> <!----> <!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/732576\/\"> https:\/\/habr.com\/ru\/articles\/732576\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<p>\u041d\u0435&nbsp;\u0442\u0430\u043a \u0434\u0430\u0432\u043d\u043e \u043d\u0430&nbsp;\u043f\u0440\u043e\u0435\u043a\u0442\u0435 \u0432\u043e\u0437\u043d\u0438\u043a\u043b\u0430 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0441\u0435\u0440\u0432\u0438\u0441\u0430. \u0412&nbsp;\u043c\u043e\u0435\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u044d\u0442\u043e&nbsp;\u0431\u044b\u043b \u0444\u0430\u0439\u043b\u2011\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a \u0432&nbsp;\u0444\u043e\u0440\u043c\u0430\u0442\u0435 JSON, \u0445\u0440\u0430\u043d\u044f\u0449\u0438\u0439\u0441\u044f \u0432&nbsp;Bundle \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0438 \u0435\u0449\u0451 Info.plist \u0432&nbsp;\u043f\u0440\u0438\u0434\u0430\u0447\u0443. \u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e&nbsp;\u0442\u0430\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u043d\u0435\u043b\u044c\u0437\u044f \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0432&nbsp;\u0437\u0430\u043f\u0443\u0449\u0435\u043d\u043d\u043e\u043c iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u0414\u0430&nbsp;\u0438 \u0432\u043e\u043e\u0431\u0449\u0435, \u0432\u044b\u0437\u043e\u0432\u044b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432&nbsp;\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0439 \u0441\u0435\u0440\u0432\u0438\u0441 \u0443\u0436\u0435 \u0432&nbsp;\u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u043c\u0435\u043d\u044f \u043d\u0435&nbsp;\u0441\u0438\u043b\u044c\u043d\u043e \u0440\u0430\u0434\u043e\u0432\u0430\u043b\u0438&nbsp;\u2014 \u0432&nbsp;\u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0431\u043e\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0443&nbsp;\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043e\u0442\u0432\u0430\u043b\u0438\u0432\u0430\u043b\u0441\u044f \u043a\u0443\u0441\u043e\u043a \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e\u0441\u0442\u0438.<\/p>\n<p>\u041a\u0430\u043a&nbsp;\u0431\u044b \u0432\u044b \u043f\u043e\u0441\u0442\u0443\u043f\u0438\u043b\u0438 \u0432&nbsp;\u044d\u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435? \u0412\u044b\u043d\u0435\u0441\u043b\u0438&nbsp;\u0431\u044b \u043a\u044d\u0448\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0442\u0430\u043a\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432 \u043d\u0430&nbsp;\u0432\u0430\u0448 \u0431\u044d\u043a? \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043c\u044b&nbsp;\u0431\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0443 \u0441\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u043c \u043d\u0435\u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u043e\u043c, \u043d\u043e&nbsp;\u0447\u0442\u043e&nbsp;\u0434\u0435\u043b\u0430\u0442\u044c \u0441&nbsp;Info.plist?<\/p>\n<p>\u041f\u0435\u0440\u0432\u043e\u0435, \u0447\u0442\u043e&nbsp;\u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0432&nbsp;\u0433\u043e\u043b\u043e\u0432\u0443&nbsp;\u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c Shell\u2011\u0441\u043a\u0440\u0438\u043f\u0442. \u041d\u043e&nbsp;\u044d\u0442\u043e \u043c\u043e\u0433\u043b\u043e \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u043a&nbsp;\u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430\u043c \u0441&nbsp;\u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u043e\u0439 \u0434\u0440\u0443\u0433\u0438\u043c\u0438 iOS \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443&nbsp;\u0431\u044b\u043b\u043e \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u043d\u0430&nbsp;Swift.<\/p>\n<p>\u0412&nbsp;\u0441\u0435\u0442\u0438 \u043c\u043d\u043e\u0433\u043e \u043c\u0430\u0442\u0435\u0440\u0438\u0430\u043b\u0430 \u043f\u043e&nbsp;\u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e Command Line Tool \u043d\u0430&nbsp;Swift, \u043d\u043e&nbsp;\u043c\u044b \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u0430\u0431\u0441\u0442\u0440\u0430\u043a\u0442\u043d\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0442\u0430\u043a\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0441\u0440\u0430\u0437\u0443 \u0432&nbsp;\u0441\u0432\u044f\u0437\u043a\u0435 \u0441&nbsp;iOS \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u043c.<\/p>\n<h3>\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h3>\n<p>\u0418\u0442\u0430\u043a, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043a\u043e\u043d\u0441\u043e\u043b\u044c\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443, \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u044e\u0449\u0443\u044e \u0441\u043f\u0438\u0441\u043e\u043a \u0434\u043e\u043c\u0435\u043d\u043e\u0432 \u0434\u043b\u044f&nbsp;\u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0431\u0435\u0437&nbsp;HTTPS.<\/p>\n<blockquote>\n<p>&#8230; \u043a\u0430\u043a&nbsp;\u0431\u0443\u0434\u0442\u043e \u043c\u044b \u043d\u0435&nbsp;\u043c\u043e\u0433\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0444\u043b\u0430\u0433 Allow Arbitrary Loads. \u041d\u043e&nbsp;\u043d\u0430&nbsp;\u0442\u043e \u043e\u043d \u0438 \u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u0440\u0435\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f.<\/p>\n<\/blockquote>\n<p>\u0414\u043b\u044f&nbsp;\u044d\u0442\u043e\u0433\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043e\u0431\u043d\u043e\u0432\u0438\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 NSAppTransportSecurity&nbsp;\u2014 NSExceptionDomains \u0432&nbsp;Info.plist, \u0430&nbsp;\u0442\u0430\u043a\u0436\u0435 \u0444\u0430\u0439\u043b\u2011\u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e&nbsp;\u0434\u043e\u043c\u0435\u043d\u0430\u0445. \u041f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0430 \u0432&nbsp;\u0432\u0438\u0434\u0435 JSON \u043f\u0443\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432&nbsp;\u0441\u0430\u043c\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438.<\/p>\n<pre><code class=\"json\">[    {       \"name\":\"dev.app_main.com\",       \"allowsInsecureHTTPLoads\":true,       \"description\":\"DEV environment for app testing\"    },    ... ]<\/code><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u043d\u0438\u043a\u0438 \u0432\u0441\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0435\u0441\u0442\u044c <a href=\"https:\/\/github.com\/Streetmage\/DomainsList\" rel=\"noopener noreferrer nofollow\">\u0442\u0443\u0442<\/a>. \u041f\u0440\u043e\u0435\u043a\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0434\u0432\u0430 \u0442\u0430\u0440\u0433\u0435\u0442\u0430: iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 DomainsList, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0432\u043e\u0434\u0438\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0438\u043c\u0435\u044e\u0449\u0438\u0445\u0441\u044f \u0434\u043e\u043c\u0435\u043d\u043e\u0432, \u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 DomainsUpdater.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u043c\u043e\u0434\u0435\u043b\u044c Domain \u0434\u043b\u044f&nbsp;\u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445, \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c\u044b\u0445 \u0438\u0437&nbsp;JSON \u0441\u043f\u0440\u0430\u0432\u043e\u0447\u043d\u0438\u043a\u0430:<\/p>\n<pre><code class=\"swift\">struct Domain: Decodable { let name: String let description: String let allowsInsecureHTTPLoads: Bool }<\/code><\/pre>\n<p>\u0412&nbsp;\u044d\u0442\u043e\u043c \u0433\u0430\u0439\u0434\u0435 \u043c\u044b \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e&nbsp;\u0448\u0430\u0433\u0430\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0442\u0438\u043b\u0438\u0442\u044b. \u041d\u0430\u0447\u043d\u0435\u043c!<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430<\/h2>\n<p>\u0414\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0432&nbsp;\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0442\u0430\u0440\u0433\u0435\u0442\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0443\u043a\u0430\u0437\u0430\u0432 \u0442\u0438\u043f Command Line Tool. \u0421\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0438\u0437&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0430\u0436\u0430\u0432 \u043d\u0430&nbsp;\u043f\u043b\u044e\u0441 \u0432&nbsp;\u0431\u043b\u043e\u043a\u0435 Targets.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u043b\u0435\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0444\u0430\u0439\u043b main.swift, \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043f\u043e&nbsp;\u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0432&nbsp;\u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442. \u0412\u043c\u0435\u0441\u0442\u043e \u043d\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c enum \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0433\u043e \u0432\u0438\u0434\u0430:<\/p>\n<pre><code class=\"swift\">@main enum DomainsUpdater { static func main() {} }<\/code><\/pre>\n<p>\u0412&nbsp;\u0438\u0442\u043e\u0433\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f main \u0431\u0443\u0434\u0435\u0442 \u044f\u0432\u043b\u044f\u0442\u044c\u0441\u044f \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0434\u043b\u044f&nbsp;\u043d\u0430\u0448\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<blockquote>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e enum \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u0438\u0435 \u0442\u0438\u043f\u044b, \u043d\u043e&nbsp;\u0433\u043b\u0430\u0432\u043d\u043e\u0435, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u0447\u043a\u0430 \u0432\u0445\u043e\u0434\u0430 \u0432&nbsp;\u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u0443&nbsp;\u0431\u044b\u043b\u0430 \u043e\u0434\u043d\u0430. \u0412&nbsp;\u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0435 \u0434\u043b\u044f&nbsp;\u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b \u043a\u0430\u043a&nbsp;\u043d\u0430\u0448\u0430 \u043c\u043e\u0436\u043d\u043e&nbsp;\u0431\u044b\u043b\u043e \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0444\u0430\u0439\u043b\u043e\u043c main.swift, \u043d\u043e&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430 main \u0431\u043e\u043b\u0435\u0435 <a href=\"https:\/\/github.com\/apple\/swift-evolution\/blob\/main\/proposals\/0281-main-attribute.md\" rel=\"noopener noreferrer nofollow\">\u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0439 \u043f\u043e\u0434\u0445\u043e\u0434<\/a>.<\/p>\n<\/blockquote>\n<p>\u0412\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u0441\u044f \u043f\u0440\u0435\u0438\u043c\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u043c \u0448\u0430\u0440\u0438\u043d\u0433\u0430 \u043a\u043e\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u0442\u0430\u0440\u0433\u0435\u0442\u0430\u043c\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043c\u043e\u0434\u0435\u043b\u044c Domain \u0441\u0440\u0430\u0437\u0443 \u0434\u043b\u044f&nbsp;\u0443\u0442\u0438\u043b\u0438\u0442\u044b \u0438 iOS \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f<\/p>\n<pre><code class=\"swift\">struct Domain: Decodable { let name: String let description: String let allowsInsecureHTTPLoads: Bool }<\/code><\/pre>\n<figure class=\"\"><\/figure>\n<p>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 \u044d\u0442\u0430\u043f \u0437\u0430\u0432\u0435\u0440\u0448\u0435\u043d! \u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c \u043a \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438.<\/p>\n<h2>\u0420\u0430\u0431\u043e\u0442\u0430 \u0441 \u0432\u0445\u043e\u0434\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435\u043c<\/h2>\n<p>\u0417\u0430\u0440\u0430\u043d\u0435\u0435 \u0441\u043a\u0430\u0436\u0443, \u0447\u0442\u043e&nbsp;\u0432&nbsp;\u0441\u0442\u0430\u0442\u044c\u0435 \u043d\u0435&nbsp;\u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434 \u0441&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/apple.github.io\/swift-argument-parser\/documentation\/argumentparser\/\" rel=\"noopener noreferrer nofollow\">ArgumentParser<\/a>. \u041c\u044b \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u043e\u0431\u043e\u0439\u0442\u0438\u0441\u044c \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u044b\u043c\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438, \u0442\u0430\u043a \u043a\u0430\u043a&nbsp;\u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u0437\u0430\u0434\u0430\u0447\u0430&nbsp;\u2014 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0445\u044d\u043b\u043f\u0435\u0440, \u0430&nbsp;\u043d\u0435&nbsp;\u043f\u043e\u043b\u043d\u043e\u0446\u0435\u043d\u043d\u043e\u0435 CLI \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435. \u0422\u0430\u043a\u0436\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u043d\u0435&nbsp;\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 SPM \u0432&nbsp;\u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440\u0430 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0435\u0439, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c ArgumentParser, \u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0440\u0435\u0434\u0441\u0442\u0432 \u00ab\u0438\u0437 \u043a\u043e\u0440\u043e\u0431\u043a\u0438\u00bb \u043c\u043e\u0436\u0435\u0442 \u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u043c \u0440\u0435\u0448\u0435\u043d\u0438\u0435\u043c.<\/p>\n<p>\u041a\u043b\u0430\u0441\u0441 CommandLine&nbsp;\u2014 \u044d\u0442\u043e \u043e\u0434\u0438\u043d \u0438\u0437&nbsp;\u0432\u0430\u0440\u0438\u0430\u043d\u0442\u043e\u0432 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u0443\u0442\u0438\u043b\u0438\u0442\u043e\u0439 \u0438\u0437\u0432\u043d\u0435. \u0423&nbsp;\u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e arguments \u0432&nbsp;\u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0441\u0442\u0440\u043e\u043a.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041d\u043e&nbsp;\u0442\u0443\u0442 \u043d\u0430\u0441 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 \u043f\u043e\u0434\u043d\u043e\u0436\u043a\u0430 \u043e\u0442&nbsp;Apple. \u0414\u043b\u044f&nbsp;\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u0430 \u0437\u0430\u0431\u044b\u043b\u0438 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u043e\u043a\u0443, \u0430&nbsp;\u0435\u0441\u0442\u044c \u043e\u0434\u0438\u043d \u043e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u044b\u0439 \u043c\u043e\u043c\u0435\u043d\u0442: \u043d\u0443\u043b\u0435\u0432\u043e\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 arguments \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043c\u0435\u043d\u0435\u043c \u043d\u0430\u0448\u0435\u0439 \u0443\u0442\u0438\u043b\u0438\u0442\u044b!<\/p>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u043b\u0430\u0441\u0441&nbsp;\u2014 ProcessInfo, \u0432&nbsp;\u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u043e&nbsp;\u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044e \u041d\u0415&nbsp;\u0437\u0430\u0431\u044b\u043b\u0438. \u0423&nbsp;\u043d\u0435\u0433\u043e \u0435\u0441\u0442\u044c \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0435&nbsp;\u0436\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e arguments, \u0430&nbsp;\u0442\u0430\u043a\u0436\u0435 \u0441\u0432\u043e\u0439\u0441\u0442\u0432\u043e environment \u0434\u043b\u044f&nbsp;\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e&nbsp;\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0420\u0430\u0437\u043d\u0438\u0446\u0443, \u043a\u0430\u043a\u043e\u0439 \u0438\u0437&nbsp;\u043a\u043b\u0430\u0441\u0441\u043e\u0432 CommandLine \u0438\u043b\u0438&nbsp;ProcessInfo \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u044f \u043d\u0435&nbsp;\u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u043b. \u0427\u0442\u043e\u0431\u044b \u043e\u0431\u043b\u0435\u0433\u0447\u0438\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441&nbsp;\u043c\u0430\u0441\u0441\u0438\u0432\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u044f \u0441\u0434\u0435\u043b\u0430\u043b \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0443\u044e \u043e\u0431\u0435\u0440\u0442\u043a\u0443:<\/p>\n<pre><code class=\"swift\">typealias ArgumentType = RawRepresentable &amp; Hashable  struct ArgumentsProvider&lt;T: ArgumentType&gt; { private let arguments: [T: String]    init(_ argumentsArray: [String]) { var argumentsDictionary: [T: String] = [:] argumentsArray.enumerated().forEach { index, arg in guard let index = index as? T.RawValue,                    let argKey = T(rawValue: index) else {                return              } argumentsDictionary[argKey] = arg } self.arguments = argumentsDictionary }  subscript(arg: T) -&gt; String { guard let arg = arguments[arg], !arg.isEmpty else {            fatalError(.argumentNotFound(arg))          } return arg } }<\/code><\/pre>\n<p>\u0414\u043b\u044f&nbsp;\u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u0442\u0435\u0441\u0442\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430\u0434\u043e \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e&nbsp;\u0442\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043a\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u043d\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0430 \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b: update \u0438 clean. update&nbsp;\u2014 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f \u043a\u043e\u043c\u0430\u043d\u0434\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u043c\u0435\u043d\u0438\u0442 \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 domains.json (\u0433\u0434\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043f\u043e\u043b\u043d\u0430\u044f \u0438\u043d\u0444\u0430 \u043e&nbsp;\u0434\u043e\u043c\u0435\u043d\u0430\u0445) \u0438 Info.plist, \u0430&nbsp;clean \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0432\u0435\u0440\u043d\u0451\u0442 \u0444\u0430\u0439\u043b\u0430\u043c \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0438\u0434.<\/p>\n<pre><code class=\"swift\">static func main() {     let args = ArgumentsProvider&lt;CommandArgument&gt;(ProcessInfo.processInfo.arguments)     guard let command = Command(rawValue: args[.command]) else {        fatalError(.unrecognizedCommand)      }      switch command {     case .update:         update()     case .clean:         clean()     } }  static func update() {     let args = ArgumentsProvider&lt;UpdateArgument&gt;(ProcessInfo.processInfo.arguments)     let domains = fetchDomainsJson(remotePath: args[.remotePath])     updateLocalFile(at: args[.localPath], domains: domains)     updateInfoPlist(at: args[.infoPlistPath], domains: domains) }  static func clean() {     let args = ArgumentsProvider&lt;CleanArgument&gt;(ProcessInfo.processInfo.arguments)     updateLocalFile(at: args[.localPath], domains: [])     updateInfoPlist(at: args[.infoPlistPath], domains: []) }<\/code><\/pre>\n<details class=\"spoiler\">\n<summary>Hidden text<\/summary>\n<div class=\"spoiler__content\">\n<p>\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u043c\u0435\u0442\u043e\u0434\u043e\u0432 fetchDomainsJson, updateLocalFile \u0438 updateInfoPlist \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0439\u0442\u0438 \u0432 <a href=\"https:\/\/github.com\/Streetmage\/DomainsList\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<\/div>\n<\/details>\n<p>\u0422\u0438\u043f CommandArgument \u0445\u0440\u0430\u043d\u0438\u0442 \u0438\u043d\u0434\u0435\u043a\u0441 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u044b, \u0430&nbsp;\u0441\u0430\u043c\u0430 \u043a\u043e\u043c\u0430\u043d\u0434\u0430 \u0438\u043c\u0435\u0435\u0442 2&nbsp;\u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: update \u0438\u043b\u0438&nbsp;clean.<\/p>\n<pre><code class=\"swift\">enum CommandArgument: Int { case command = 1 }  enum Command: String, CaseIterable { case update case clean }<\/code><\/pre>\n<p>\u0422\u0438\u043f\u044b UpdateArgument, CleanArgument \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0445 \u043a\u043e\u043c\u0430\u043d\u0434.<\/p>\n<pre><code class=\"swift\">enum UpdateArgument: Int { case remotePath = 2 case localPath case infoPlistPath }  enum CleanArgument: Int { case localPath = 2 case infoPlistPath }<\/code><\/pre>\n<p>\u0412\u043c\u0435\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0438 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u043c\u0438 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f ProcessInfo.processInfo.environment. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 domains.json \u0438\u043b\u0438 Info.plist.<\/p>\n<pre><code class=\"swift\">guard let srcRoot = ProcessInfo.processInfo.environment[\"SRCROOT\"] else {    fatalError(\"SRCROOT not found\")  }  let resources = \"\\(srcRoot)\/DomainsList\/Resources\" let localPath = \"\\(resources)\/domains.json\" let infoPlistPath = \"\\(resources)\/Info.plist\"<\/code><\/pre>\n<p>\u0412\u0410\u0416\u041d\u041e!!! \u0434\u0430\u043d\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0435 \u0432\u0430\u0448\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0438\u0437&nbsp;\u0441\u0435\u043a\u0446\u0438\u0438 Build Phases \u043f\u0440\u0438&nbsp;\u0441\u0431\u043e\u0440\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e&nbsp;\u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u0434\u0430\u043d\u044b. \u041e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0442\u0430\u043a\u0438\u043c \u0441\u043f\u043e\u0441\u043e\u0431\u043e\u043c \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e, \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0432 \u043f\u0440\u0438&nbsp;\u0437\u0430\u043f\u0443\u0441\u043a\u0435 Debug \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0443\u0436\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u043e&nbsp;\u044f \u043f\u0440\u0435\u0434\u043f\u043e\u0447\u0438\u0442\u0430\u044e \u0431\u043e\u043b\u0435\u0435 \u043d\u0430\u0433\u043b\u044f\u0434\u043d\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0447\u0435\u0440\u0435\u0437 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0443 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<p>\u0420\u0430\u0437 \u043c\u044b \u0443\u0436\u0435 \u0437\u0430\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043f\u0440\u043e&nbsp;\u043e\u0442\u043b\u0430\u0434\u043a\u0443, \u0442\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0435\u043c, \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435, \u043a&nbsp;\u0441\u0430\u043c\u043e\u0439 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0439 \u0447\u0430\u0441\u0442\u0438, \u0430&nbsp;\u0438\u043c\u0435\u043d\u043d\u043e \u043a&nbsp;\u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u044b.<\/p>\n<h2>\u0417\u0430\u043f\u0443\u0441\u043a \u0443\u0442\u0438\u043b\u0438\u0442\u044b<\/h2>\n<h4>\u041e\u0442\u043b\u0430\u0434\u043a\u0430<\/h4>\n<p>\u0414\u043b\u044f&nbsp;\u043e\u0442\u043b\u0430\u0434\u043a\u0438 \u043d\u0430\u043c \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b \u0432&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0441\u0445\u0435\u043c\u044b. \u0422\u0443\u0442 \u0443&nbsp;\u043d\u0430\u0441 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u041e!!! \u0411\u0443\u0434\u044c\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u0442\u0435\u043b\u044c\u043d\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e&nbsp;\u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0442\u0430\u043a\u0438\u0435 \u043a\u0430\u043a&nbsp;INFOPLIST_FILE, \u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u0432&nbsp;\u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442&nbsp;\u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0434\u043b\u044f&nbsp;\u0441\u0445\u0435\u043c\u044b DomainsUpdater \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0443\u0441\u0442\u044b\u043c. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0431\u043e\u043b\u0435\u0435 \u0443\u043d\u0438\u0432\u0435\u0440\u0441\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0442\u0438\u043f\u0430 SRCROOT.<\/p>\n<figure class=\"full-width\"><\/figure>\n<h4>Pre-compile \u0441\u043a\u0440\u0438\u043f\u0442 \u0432 Build Phases<\/h4>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430\u0448\u0443 \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0432 \u044f\u0432\u043d\u044b\u0435 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 iOS \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0412\u0410\u0416\u041d\u041e!!! \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 \u0444\u043b\u0430\u0433 Skip install \u0432 Build Settings.&nbsp;\u0418\u043d\u0430\u0447\u0435 \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u0440\u0435\u043b\u0438\u0437\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u043c \u043d\u0430 \u0432\u044b\u0445\u043e\u0434\u0435 \u0430\u0440\u0445\u0438\u0432, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 2 \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0445 \u0444\u0430\u0439\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432 AppStore Connect.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0417\u0430\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u0430\u043c \u0441\u043a\u0440\u0438\u043f\u0442, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u0439 \u0441\u043e\u0431\u0440\u0430\u043d\u043d\u0443\u044e \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u0441 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438 \u043f\u0435\u0440\u0435\u0434 \u0444\u0430\u0437\u043e\u0439 Compile Sources:<\/p>\n<pre><code class=\"bash\">if [ $CONFIGURATION = 'Debug' ]  then $CONFIGURATION_BUILD_DIR\/..\/$CONFIGURATION\/DomainsUpdater update \\ \"https:\/\/raw.githubusercontent.com\/Streetmage\/DomainsList\/main\/remote_domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/Info.plist\" fi<\/code><\/pre>\n<p>\u041a\u0430\u043a&nbsp;\u0432\u0438\u0434\u043d\u043e, \u043d\u0430\u0448 \u0441\u043a\u0440\u0438\u043f\u0442 \u0437\u0430\u043f\u0443\u0441\u0442\u0438\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u044f&nbsp;Debug \u043a\u043e\u043d\u0444\u0438\u0433\u0443\u0440\u0430\u0446\u0438\u0438, \u043d\u043e&nbsp;\u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e Release, \u0447\u0442\u043e\u0431\u044b \u0441\u043a\u0440\u0438\u043f\u0442 \u0441\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b \u043f\u0435\u0440\u0435\u0434 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435\u043c \u0430\u0440\u0445\u0438\u0432\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<p><s>Pre\u2011actions \u0432&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0435 \u0441\u0445\u0435\u043c\u044b<\/s><\/p>\n<p>\u041a\u0430\u0437\u0430\u043b\u043e\u0441\u044c&nbsp;\u0431\u044b, \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0441\u043f\u043e\u0441\u043e\u0431 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0443\u0442\u0438\u043b\u0438\u0442\u044b&nbsp;\u2014 \u0447\u0435\u0440\u0435\u0437 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0443 \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u0434\u043e&nbsp;\u0441\u0442\u0430\u0440\u0442\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u041e\u0434\u043d\u0430\u043a\u043e, pre\u2011action \u0441\u043a\u0440\u0438\u043f\u0442 \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0435\u0442\u0441\u044f \u0443\u0436\u0435 \u043d\u0435\u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u043e\u0441\u043b\u0435 \u0441\u0431\u043e\u0440\u043a\u0438, \u0438 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430 (\u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0430\u0440\u0445\u0438\u0432\u0430) \u0444\u0430\u0439\u043b\u044b \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u044b.<\/p>\n<h4>Shell-\u0441\u043a\u0440\u0438\u043f\u0442 \u0434\u043b\u044f \u0441\u0431\u043e\u0440\u043a\u0438 \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430<\/h4>\n<p>\u0412\u0441\u0451\u2011\u0442\u0430\u043a\u0438 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043e\u0442&nbsp;Shell \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043d\u0435&nbsp;\u043e\u0442\u043a\u0430\u0436\u0435\u0448\u044c\u0441\u044f. \u041d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u0442\u0440\u0435\u0431\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0443\u0442\u0438\u043b\u0438\u0442\u0443 \u043f\u0435\u0440\u0438\u043e\u0434\u0438\u0447\u0435\u0441\u043a\u0438 \u0441&nbsp;\u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u043e\u0439 \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u043d\u0430&nbsp;\u0441\u0442\u043e\u0440\u043e\u043d\u0435 CI. \u0422\u043e\u0433\u0434\u0430 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u043f\u0440\u0438&nbsp;\u043f\u043e\u043c\u043e\u0449\u0438 \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0433\u043e \u0441\u043a\u0440\u0438\u043f\u0442\u0430:<\/p>\n<pre><code class=\"bash\"># Build utility TARGET=\"DomainsUpdater\" CONFIG=\"Debug\" xcodebuild -project DomainsList.xcproject -scheme $TARGET -configuration $CONFIG -destination 'generic\/platform=macOS' # Get BUILD_ROOT and SRCROOT from utility project settings BUILD_SETTINGS=`xcodebuild -project DomainsList.xcproject -scheme $TARGET -showBuildSettings` BUILD_ROOT=`echo \"$BUILD_SETTINGS\" | grep BUILD_ROOT | sed -e \"s\/^    BUILD_ROOT = \/\/\"` SRCROOT=`echo \"$BUILD_SETTINGS\" | grep SRCROOT | sed -e \"s\/^    SRCROOT = \/\/\"` # Start utility $BUILD_ROOT\/$CONFIG\/$TARGET update \\ \"https:\/\/raw.githubusercontent.com\/Streetmage\/DomainsList\/main\/domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/domains.json\" \\ \"$SRCROOT\/DomainsList\/Resources\/Info.plist\"<\/code><\/pre>\n<p>\u0412\u0410\u0416\u041d\u041e!!! \u041d\u0435 \u0437\u0430\u0431\u0443\u0434\u044c\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0444\u0430\u0439\u043b .sh \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u043c:<\/p>\n<pre><code class=\"bash\">chmod +x<\/code><\/pre>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-347579","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/347579","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=347579"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/347579\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=347579"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=347579"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=347579"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}