{"id":2583,"date":"2021-12-27T00:00:00","date_gmt":"2021-12-27T00:00:00","guid":{"rendered":"https:\/\/appvinio.runbyit.com\/https-appvinio-com-pl-aktualnosci-historia-pewnego-buga-natywne-krainy-tam-i-z-powrotem\/"},"modified":"2023-11-07T14:42:11","modified_gmt":"2023-11-07T14:42:11","slug":"historia-pewnego-buga-natywne-krainy-tam-i-z-powrotem","status":"publish","type":"post","link":"https:\/\/appvinio.com\/pl\/historia-pewnego-buga-natywne-krainy-tam-i-z-powrotem\/","title":{"rendered":"Historia pewnego buga &#8211; natywne krainy: tam i z powrotem"},"content":{"rendered":"<p data-renderer-start-pos=\"8\">W Flutterowym \u015bwiecie nierzadko zdarza nam si\u0119 korzysta\u0107 z funkcjonalno\u015bci, kt\u00f3rych implementacja jest stricte zale\u017cna od platformy na kt\u00f3rej jest uruchamiana. Przyk\u0142ad\u00f3w jest wiele, jak cho\u0107by bohater dzisiejszej opowie\u015bci &#8211; Niebieski Z\u0105b, w szerokim \u015bwiecie znany pod przydomkiem Bluetooth. Tego Pana, a raczej tej technologii nikomu przestawia\u0107 nie trzeba. Na ten moment wa\u017cnym podkre\u015blenia jest tylko fakt, \u017ce,<span id=\"a1b3ed26-5d41-4686-9554-051a6e4d7be1\" data-renderer-mark=\"true\" data-mark-type=\"annotation\" data-mark-annotation-type=\"inlineComment\" data-id=\"a1b3ed26-5d41-4686-9554-051a6e4d7be1\"> wykorzystali\u015bmy t\u0119 technologi\u0119 w jednym z projekt\u00f3w do po\u0142\u0105czenia si\u0119 fizycznym urz\u0105dzeniem. <\/span><\/p>\n<p data-renderer-start-pos=\"518\"><span id=\"a1b3ed26-5d41-4686-9554-051a6e4d7be1\" data-renderer-mark=\"true\" data-mark-type=\"annotation\" data-mark-annotation-type=\"inlineComment\" data-id=\"a1b3ed26-5d41-4686-9554-051a6e4d7be1\">Tyle s\u0142owem wst\u0119pu. Jak mawia m\u00f3j ulubiony szachowy Youtuber &#8211; \u201ckawka, herbatka w d\u0142o\u0144\u201d i ruszamy.<\/span> Uwaga &#8211; historia zawiera elementy fantastyki i mimo licznych opis\u00f3w bitew &#8211; \u017caden programista, ani jego klawiatura nie ucierpieli.<\/p>\n<p data-renderer-start-pos=\"749\">Dawno, dawno temu, a nadmieni\u0107 nale\u017cy, \u017ce w \u015bwiecie technologii oznacza to oko\u0142o paru miesi\u0119cy, pewien znamienity rycerz zg\u0142osi\u0142 si\u0119 do nas z pro\u015bb\u0105 o stworzenie aplikacji kt\u00f3ra z pomoc\u0105 Niebieskiego Z\u0119ba by\u0142aby w stanie konfigurowa\u0107 pewien sprz\u0119t. Nieistotnym jest czy chodzi o cz\u0119\u015b\u0107 pancerza, czy mo\u017ce o zestaw ultranowoczesnych okular\u00f3w. Jako \u017ce jeste\u015bmy do\u015bwiadczeni w obr\u00f3bce damasce\u0144skiego kodu Darta, zdecydowali\u015bmy si\u0119 na wykorzystanie Fluttera.<\/p>\n<p data-renderer-start-pos=\"1204\">Rozpalili\u015bmy magiczny piec projektu i pocz\u0119li\u015bmy co rusz dorzuca\u0107 do niego commity. Hartowanie aplikacji sz\u0142o g\u0142adko i co chwila z dum\u0105 obserwowali\u015bmy jak nowe funkcjonalno\u015bci \u015bwietnie dzia\u0142aj\u0105.<\/p>\n<p data-renderer-start-pos=\"1400\">A\u017c tu kt\u00f3rego\u015b dnia, ni st\u0105d, ni zow\u0105d, apka \u015bmiga sobie na Androidzie, a na iOS b\u0142\u0105d. Jak to jest mo\u017cliwe? Przecie\u017c Flutter wsz\u0119dzie dzia\u0142a tak samo! Co to za czary. \u017badne czary, tylko pradawna, troch\u0119 w \u015bwiecie Fluttera zapomniana, <span id=\"d4840312-238b-49d0-95c9-d7f6f0ca5058\" data-renderer-mark=\"true\" data-mark-type=\"annotation\" data-mark-annotation-type=\"inlineComment\" data-id=\"d4840312-238b-49d0-95c9-d7f6f0ca5058\">natywn<\/span>a magia &#8211; taka co to w zale\u017cno\u015bci od platformy inaczej dzia\u0142a.<\/p>\n<p data-renderer-start-pos=\"1705\">Niejeden adept gildii Fluttera przel\u0105k\u0142by si\u0119 s\u0142ysz\u0105c s\u0142owa ni to zakl\u0119cia, ni to kl\u0105twy jakiej\u015b:<\/p>\n<div class=\"fabric-editor-breakout-mark fabric-editor-block-mark sc-jnlKLf dtFzaF\" data-mode=\"full-width\">\n<div class=\"code-block sc-kUaPvJ knitUr\"><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"\">The characteristic 44A78CE3-E653-4827-8AAD-8A08268056BA of the service 0EF881BC-6EC4-11EA-BC55-0242AC130003 of the peripheral 57FD66C2-0FE4-78CA-D719-F13AC93CECF7 is not writable\u00a0<\/span><\/code><\/span><\/div>\n<div>\n<p data-renderer-start-pos=\"1985\">No ale nie my. Paramy si\u0119 t\u0105 magi\u0105 ju\u017c wystarczaj\u0105co d\u0142ugo, by bez strachu stawi\u0107 czo\u0142a wyzwaniu i ubi\u0107 <span id=\"d5e5120a-5759-4d91-973f-9d98b7816dfb\" data-renderer-mark=\"true\" data-mark-type=\"annotation\" data-mark-annotation-type=\"inlineComment\" data-id=\"d5e5120a-5759-4d91-973f-9d98b7816dfb\">smoka\u2026 czy tam robala, ku uciesze gawiedzi\u2026 czy tam klienta<\/span>.<\/p>\n<p data-renderer-start-pos=\"2152\">Zebra\u0142a si\u0119 rada starszych i szybko obmy\u015bli\u0142a plan. Wy\u015blemy poselstwo do ziemi githubowej by tam, w rejonie znanym jako <em><strong>flutter_reactive_blue<\/strong><\/em>, zasi\u0119gn\u0105\u0107 j\u0119zyka. Rozpoczynamy poszukiwania. Wybieramy z tre\u015bci naszego zakl\u0119cia najbardziej istotn\u0105, naszym zdaniem, cz\u0119\u015b\u0107. W naszym przypadku by\u0142o to: <em><strong>&#8222;is not writable&#8221;<\/strong><\/em>. Korzystaj\u0105c z dobrodziejstwa githuba szukamy rzeczonej frazy. I oto jest, w jednej z ksi\u0105g znajdujemy wzmiank\u0119 o zakl\u0119ciu. Szybko j\u0105 otwieram i widzimy \u017ce napisana zosta\u0142a w j\u0119zyku Swift. Tutaj troszeczk\u0119 cieszymy si\u0119, \u017ce to nie prastary j\u0119zyk Objective-C, chocia\u017c i z tym daliby\u015bmy sobie rad\u0119. Wracamy do do ksi\u0119gi. Na ostatniej stronie, na samym dole znajdujemy tre\u015b\u0107 zakl\u0119cia:<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\"><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"comment linenumber react-syntax-highlighter-line-number\">1. <\/span><span class=\"\">case .notWritable(let qualifiedCharacteristic):<br \/>\n<\/span><span class=\"comment linenumber react-syntax-highlighter-line-number\">2.<\/span>                return \"The characteristic (qualifiedCharacteristic.id) of the service (qualifiedCharacteristic.serviceID) of the peripheral (qualifiedCharacteristic.peripheralID) is not writable\"<br \/>\n<span class=\"comment linenumber react-syntax-highlighter-line-number\">3.<\/span>            }<br \/>\n<\/code><\/span><\/div>\n<p data-renderer-start-pos=\"3112\">Pozostaje tylko znale\u017a\u0107 miejsce jego, w sensie czaru, wywo\u0142ania. Szybko odnajdujemy w tej samej ksi\u0119dze dwa wywo\u0142ania:<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div class=\"code-block sc-kUaPvJ knitUr\"><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"\">1. guard characteristic.properties.contains(.write)<br \/>\n<\/span><span class=\"comment linenumber react-syntax-highlighter-line-number\">2.<\/span>        else { throw Failure.notWritable(qualifiedCharacteristic) }<br \/>\n<\/code><\/span><\/div>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div role=\"presentation\">\n<div><\/div>\n<\/div>\n<p><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"comment linenumber react-syntax-highlighter-line-number\">1. <\/span><span class=\"\">guard characteristic.properties.contains(.writeWithoutResponse)<br \/>\n<\/span><span class=\"comment linenumber react-syntax-highlighter-line-number\">2.<\/span>        else { throw Failure.notWritable(qualifiedCharacteristic) }<\/code><\/span><\/p>\n<\/div>\n<\/div>\n<p data-renderer-start-pos=\"3483\">Wiemy ju\u017c czego szuka\u0107, czas u\u017cy\u0107 wehiku\u0142u kompilowania. Odpalamy Xcode\u2019a. Odnajdujemy te dwa wywo\u0142ania w kodzie i wstawiamy breakpointy. Dodajemy kosmyk z grzywy jednoro\u017cca i uruchamiamy kompilacj\u0119. Lotem b\u0142yskawicy (takie skojarzenie &#8211; akurat burza za oknem \ud83d\ude09 ) przenosimy si\u0119 w miejsce wyst\u0119powania SmokoRobala. Klikamy\u2026 i jest. Kod si\u0119 zatrzymuje dok\u0142adnie tam gdzie tego oczekiwali\u015bmy.<\/p>\n<p data-renderer-start-pos=\"3876\">Lotem innej b\u0142yskawicy przeskakujemy po kolejnych liniach kodu i oto jest. Drugie z wywo\u0142a\u0144, kt\u00f3re wcze\u015bniej znale\u017ali\u015bmy, okazuje si\u0119 by\u0107 trafionym. Widzimy, \u017ce Swiftowy stra\u017cnik wykrywa i udaremnia wszelkie zakusy ku nieprawemu u\u017cyciu peryferi\u00f3w urz\u0105dzenia.<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div role=\"presentation\"><\/div>\n<\/div>\n<div class=\"code-block sc-kUaPvJ knitUr\"><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code>1. guard characteristic.properties.contains(.writeWithoutResponse)<br \/>\n2. else { throw Failure.notWritable(qualifiedCharacteristic) }<br \/>\n<\/code><\/span><\/div>\n<p data-renderer-start-pos=\"4270\">No dobra, nie dzia\u0142a &#8211; wiemy gdzie, ale nie wiemy czemu. Widzimy, \u017ce jest jaka\u015b charakterystyka, kt\u00f3ra nie posiada odpowiednich w\u0142a\u015bciwo\u015bci. Sprawd\u017amy zatem jakie w\u0142a\u015bciwo\u015bci owa charakterystyka posiada. Naszym oczom ukazuje si\u0119 niewiele wyja\u015bniaj\u0105ca warto\u015b\u0107.<\/p>\n<p data-renderer-start-pos=\"4575\">Upewnijmy si\u0119 czego oczekujemy poprzez sprawdzenie warto\u015bci <em><strong>writeWithoutResponse<\/strong><\/em>. Ogromnej ksi\u0119dze, kt\u00f3r\u0105 zwiemy dokumentacj\u0105 widzimy wzmiank\u0119:<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div role=\"presentation\">\n<div><\/div>\n<\/div>\n<p><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"comment linenumber react-syntax-highlighter-line-number\">1. <\/span><span class=\"\">static var writeWithoutResponse: CBCharacteristicProperties { get }<\/span><\/code><\/span><\/p>\n<\/div>\n<p data-renderer-start-pos=\"4790\">Niewiele nam ona m\u00f3wi. Lecz jednak, je\u015bli si\u0119gniemy do t\u0142umaczenia napisanego w <em><strong>Objective-C<\/strong><\/em>\u00a0naszym oczom uka\u017ce si\u0119 co\u015b du\u017co bardziej przydatnego.<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div role=\"presentation\">\n<div><\/div>\n<\/div>\n<p><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"comment linenumber react-syntax-highlighter-line-number\">1. <\/span><span class=\"\">CBCharacteristicPropertyWriteWithoutResponse = 0x04<\/span><\/code><\/span><\/p>\n<\/div>\n<p data-renderer-start-pos=\"4990\">Wiemy \u017ce charakterystyka kt\u00f3r\u0105 u\u017cywamy ma warto\u015b\u0107 <em><strong>4<\/strong><\/em>. Sprawd\u017amy zatem jaka\u017c to charakterystyka ma warto\u015b\u0107 <em><strong>10<\/strong><\/em>. Niech nikogo nie zdziwi i nie za\u0142amie fakt, \u017ce nie ma takiej charakterystyki, kt\u00f3rej warto\u015b\u0107 wynosi\u0142aby rzeczone <em><strong>10<\/strong><\/em>. Ju\u017c b\u0119d\u0105c m\u0142odym adaptem magii, w gildii mag\u00f3w, uczymy si\u0119 o bitach i maskach bitowych. Korzystaj\u0105c z tej wiedzy mo\u017cemy warto\u015b\u0107 <em><strong>10<\/strong><\/em> zapisa\u0107 bitowo jako <em><strong>00001010<\/strong><\/em>. Poszczeg\u00f3lne bity, ustawione na <code class=\"code css-9z42f9\" data-renderer-mark=\"true\">1<\/code> odpowiadaj\u0105 liczbom <em><strong>2<\/strong><\/em>\u00a0i <em><strong>8<\/strong><\/em>\u00a0&#8211; sumarycznie <em><strong>10<\/strong><\/em>. Na brod\u0119 Merlina! mamy to i powiedzmy to g\u0142o\u015bno: \u017badna z dost\u0119pnych charakterystyk urz\u0105dzenia nie ma warto\u015bci <em><strong>4<\/strong><\/em>, kt\u00f3ra odpowiada charakterystyce u\u017cywanej przez nas. Zobaczmy zatem jakie\u017c to charakterystyki kryj\u0105 si\u0119 pod warto\u015bciami <em><strong>2<\/strong><\/em>\u00a0i <em><strong>8<\/strong><\/em>.<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div role=\"presentation\">\n<div><\/div>\n<\/div>\n<p><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"comment linenumber react-syntax-highlighter-line-number\">1. <\/span><span class=\"\">CBCharacteristicPropertyRead = 0x02<br \/>\n<\/span><span class=\"comment linenumber react-syntax-highlighter-line-number\">2<\/span>CBCharacteristicPropertyWrite = 0x08<br \/>\n<\/code><\/span><\/p>\n<\/div>\n<p data-renderer-start-pos=\"5769\">Wiedzeni do\u015bwiadczeniem, wspomagani przez rezultat rzutu kostk\u0105 K20, wybieramy do dalszych test\u00f3w:<\/p>\n<div class=\"code-block sc-kUaPvJ knitUr\">\n<div role=\"presentation\">\n<div><\/div>\n<\/div>\n<p><span class=\"prismjs css-1xfvm4v\" data-code-lang=\"\" data-ds--code--code-block=\"\"><code><span class=\"comment linenumber react-syntax-highlighter-line-number\">1. <\/span><span class=\"\">CBCharacteristicPropertyWrite = 0x08<\/span><\/code><\/span><\/p>\n<\/div>\n<p data-renderer-start-pos=\"5907\">Dzia\u0142a!<\/p>\n<p data-renderer-start-pos=\"5917\">Urz\u0105dzamy ma\u0142\u0105 uczt\u0119. Chcia\u0142oby si\u0119 napisa\u0107, \u017ce ta\u0144com nie by\u0142o ko\u0144ca. Niestety, zwiadowcy donosz\u0105, \u017ce na wschodnich rubie\u017cach, kto\u015b pocz\u0105\u0142 atakowa\u0107 nasze zapytania do zamorskich serwer\u00f3w. Wyprawiamy konie, czas rusza\u0107.<\/p>\n<\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>W Flutterowym \u015bwiecie nierzadko zdarza nam si\u0119 korzysta\u0107 z funkcjonalno\u015bci, kt\u00f3rych implementacja jest stricte zale\u017cna od platformy na kt\u00f3rej jest uruchamiana. Przyk\u0142ad\u00f3w jest wiele, jak cho\u0107by bohater dzisiejszej opowie\u015bci &#8211; Niebieski Z\u0105b, w szerokim \u015bwiecie znany pod przydomkiem Bluetooth. Tego Pana, a raczej tej technologii nikomu przestawia\u0107 nie trzeba. Na ten moment wa\u017cnym podkre\u015blenia jest [&hellip;]<\/p>\n","protected":false},"author":5,"featured_media":2662,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[60],"tags":[],"class_list":["post-2583","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-aktualnosci"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/posts\/2583","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/comments?post=2583"}],"version-history":[{"count":1,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/posts\/2583\/revisions"}],"predecessor-version":[{"id":2603,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/posts\/2583\/revisions\/2603"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/media\/2662"}],"wp:attachment":[{"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/media?parent=2583"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/categories?post=2583"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/appvinio.com\/pl\/wp-json\/wp\/v2\/tags?post=2583"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}