<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Anıl taşkıran on Medium]]></title>
        <description><![CDATA[Stories by Anıl taşkıran on Medium]]></description>
        <link>https://medium.com/@aniltaskiran?source=rss-1ba92a98028------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/2*MyAsNXgXuZAw9p6oAdxZxA.jpeg</url>
            <title>Stories by Anıl taşkıran on Medium</title>
            <link>https://medium.com/@aniltaskiran?source=rss-1ba92a98028------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sun, 15 Nov 2026 16:45:39 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@aniltaskiran/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com/" rel="hub"/>
        <item>
            <title><![CDATA[Ben kimim, Nasıl iOS Developer oldum. Neden bu yolu seçtim ve sektöre nasıl katkı sağlayabilirim?]]></title>
            <link>https://aniltaskiran.medium.com/ben-kimim-nas%C4%B1l-ios-developer-oldum-neden-bu-yolu-se%C3%A7tim-ve-sekt%C3%B6re-nas%C4%B1l-katk%C4%B1-sa%C4%9Flayabilirim-a613261c89f5?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/a613261c89f5</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[developer]]></category>
            <category><![CDATA[software]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Sat, 23 Jul 2022 20:28:20 GMT</pubDate>
            <atom:updated>2022-07-23T20:28:20.378Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*pP_kd76RYm_ipylNHak2_g.png" /></figure><p>Anıl ben, iOS Developer olarak 2019&#39;dan beri Trendyol’da çalışıyorum. Niyetim geçmişte tanıştığım insanlar sayesinde bıraktığım noktaları anlatmak, onları birleştirebilmek.</p><p>Neden sorusuyla başlamak istiyorum, neden sektöre. bir katkı vermem gerektiğini hissettiğimi anlatmadan yaptıklarımın söylediklerimin bir anlamı olmaz gibi geliyor. Bu yazı aynı zamanda 2017 yılından 2022 yılına kadar hayatıma dokunmuş insanlara teşekkür niyetindedir. 💐</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/452/1*3psuClJ8uCm-0WgJQhuC4Q@2x.png" /></figure><p>Aslında serüvenim 2017 yılında <a href="https://www.meetup.com/cocoaist/">Cocoaist</a>’in düzenlediği <a href="https://www.meetup.com/cocoaist/events/239997408/">WWDC 2017 Keynote</a> ile başladı. Orada <a href="https://twitter.com/bilgehanisikli">Bilgehan Işıklı</a> ile tanıştım. Ve kariyerimin şekillenmesi orada başladı. Benim için bir sadece bir jr. sr. ilişkisi değil adeta bir mentördü kendisi. Konulara teknik yaklaşımım dışında soft skillerime de çok katkısı oldu. Beni sabırla dinleyip, yazdığım kodları nasıl iyileştirebiliriz diye tek tek anlatması hala benim hatırladığım nadir anlardandır. Geriye dönüp sence en önemli ne kazandırdı diye soracak olursanız, soruyu sorma biçiminin önemi diye cevaplarım. Aslında yaptığımız işin tamamen iletişim olduğunu ve kendini açıklayabildiğin kadar etki bıraktığını o zamanlar anladım. Karşımızdaki her şeyi biliyor olsa bile ben ona açıklayamıyorsam aslında hiçbir şekilde problemi çözemeyiz.</p><blockquote><a href="https://github.com/eric-s-raymond">@eric-s-raymond</a>’ın <a href="http://www.catb.org/~esr/faqs/smart-questions.html">How To Ask Questions The Smart Way</a> ‘ini okumanızı veya göz gezdirmenizi öneririm.</blockquote><p>2017 yılında katılabildiğim tüm etkinliklere katılmaya çalışıyordum ve o sene Okulumun Bilişim Kulübü başkanlığını alarak neden etkinlik düzenlemiyoruz ki dedim? İşte o zaman bazı olaylara daha farklı bakmaya başlamıştım. O yıllarda kimi sunum yapmaya, konu anlatmaya çağırsak herkes sorgusuz sualsiz geliyordu. Ve düşünüyodum insanlar bunu neden yapıyor diye? Maksimum verebileceğimiz bir kahve ısmarlamaktı ki öyle de oldu. Zaten hiçbir şey de talep etmediler :) Bugün bu satırları yazıyorsam o isimlerin tek tek üzerimde emeği vardır. O emeği anlatabilmek için bazılarından bahsetmek istiyorum.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/496/1*FIeX8k9_uaJOUN6-DVtJdg@2x.png" /></figure><p>İkisi de sektöre çok katkı sağlamış insanlardı. Gelip yaşadıklarını, deneyimlerini bize anlatmaları çok anlamlıydı. Bazı şeylerin karşılığını parayla alamazsın ya o da bunlardan biriydi. Sektörün nasıl bir yer olduğunu, girince bizi neler bekleyeceğini göstermişlerdi. Güzel bir deneyimdi. <a href="https://medium.com/u/de6463fbfc80">Fatih Kadir Akın</a> &amp; <a href="https://medium.com/u/30c3af76f942">Doğukan Güven Nomak</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/900/1*JGGzwtt2xTl__kn6Al3TjA.jpeg" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/1*ROdjHEXIjCazCIOoWy9vrw@2x.png" /></figure><p>Ardından Hüseyin Mert’ten sadece yazılıma bakışı değil de karpuz satmayı da öğrenmek istiyorduk 😛 Eğer Geliştirici Sohbetlerini izlemediyseniz kesinlikle izlemenizi tavsiye ederim. <a href="https://medium.com/u/22b47deed2f4">Hüseyin Mert</a></p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FmXDEpJ5N4dw%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DmXDEpJ5N4dw&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FmXDEpJ5N4dw%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/b9d18cd8e30f985eacbac4e7ebc4dade/href">https://medium.com/media/b9d18cd8e30f985eacbac4e7ebc4dade/href</a></iframe><p>Ardından <a href="https://medium.com/u/1e2acc5cc170">Bora Kaşmer</a> ve <a href="https://medium.com/u/db4fb850f807">Engin Polat</a>’i davet etmiştik. Sadece yazılım değil aslında bakış açısı kazandırıyorlardı. Onların kendilerini, yaptıkları işi anlatışları bana ilham vermişti. Yaptıkları işi ne kadar sevdiklerini onlarla konuştuğunuzda anlayabiliyordunuz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/516/1*PT9xWADdSwPuw8Lbp-McKA@2x.png" /></figure><p>Ardından <a href="https://twitter.com/_denizparlak">Deniz Parlak</a> ile tanışmıştık. Bize gelip GNU/Linux’tan bahsetmişti ve artık her şey daha farklıydı. Kendisinin enerjisi, gelip hiç tanımadığı bizlere katkı sağlamaya çalışması… O zamanlar anlamıyordum fakat şimdi neden bunu yapıyorlar sorusunu anlayabiliyorum. Bunu bu yazının sonunda bir duyuruyla beraber açıklayacağım :)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*mLdhqzSHbEAbYuSdesyg5Q@2x.png" /></figure><p>Her bir sunumda tanıştığımız kişiler bizim için çok değerliydi. Ve hepsi geride birleştirilmeyi bekleyen noktalar bıraktılar, insanların hayatına dokundular.</p><p>2 Yıl Blesh’te çalıştıktan sonra artık iOS Development alanında kendimi daha çok geliştirmek istiyordum ve UI’a yönelebileceğim müşteriye dokunabileceğim bir firmaya geçmek istiyordum. Fakat süreç böyle işlemedi 😅 Tamamen sağ yanımda oturan ve ne zaman ihtiyacım olsa orada olan <a href="https://medium.com/u/ad39cc964302">Belfu Öğretir</a>’in ben Trendyol’a girmeyi istiyorum demesiyle oldu. <a href="https://medium.com/u/ff21569a637b">Ahmet Keskin</a>’i Daha önce medium’da yazdığı yazılardan biliyordum. Ve Belfu’nun da ilk kurşunu atmasıyla iş değiştirmeye karar vermiştim. Trendyol serüvenim iddialı bir şekilde başlamıştı 🤦🏻‍♂️</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KVDigv0HcF5FJ8rmP9Titw.jpeg" /></figure><p>İlk olarak Trendyol’un demirbaşlarından <a href="https://twitter.com/EfekanEgeli">Efekan Egeli</a> ile başlamak istiyorum. Bir insan her zaman mı vizyoner olur? lead’im diye demiyorum ama öyledir 😛 Ben kendisinin proje çocuk olduğuna inanıyorum. Her adımının önceden planlanmış olduğuna kalıbımı basarım. Sana ne kattım diye soracak olsa, “küçük düşünme global düşün” derdim. Vizyonerliği benim için her zaman ilham verici olmuştu.</p><p>Ardından <a href="https://twitter.com/_Ahmettkeskin">Ahmet Keskin</a> ve <a href="https://twitter.com/isikcenkdev">Cenk Işık</a>. Ahmet lead’im olmuştu ve ikisinden de teknik bilginin dışında hayatıma katacağım çok fazla soft skill öğrenmiştim. Sadece iş yapmıyorduk, bir ürün çıkarıyorduk, değer katıyorduk. Ahmet ile karşındakine her zaman sevgi ve şefkat gösterebileceğini öğrenmiştim, bir konuyu tartışırken bunu göz önünde bulundurmak gerektiğini hissettirmişti. Galiba bu benim için teknik bilgilerden önemliydi.</p><p>Cenk dışarıdan bakıldığında sert gözükebiliyor ama tanısanız çok seversiniz denir ya tam olarak öyle bir adam. Bana öğrettiği şey bence duruşuydu. Kendisini anlatışı, sınırlarını belli edişi bir konuda çekinmeden fikrini beyan etmen gerektiğini anlamıştım.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*9PvUF0wf4n9sJFjclKI6xQ.jpeg" /></figure><p>Böyle anlatınca hep soft skill geliştirmeye çalışmışım gibi oldu. Ama öyle değil. Mesela Emre Ergün 2019–2020 corona öncesi zamanlarda gözümde hep şöyle canlanırdı, bir işi ver, geriye yaslan, taksın kulaklığını sen şov’u bekle. Şiir gibi pr’ını açar, her pr’da yeni bir şey öğrenirdiniz. Pr’ını review ettiğinde o gün mutlaka sana yeni bir konuda bir bilgi aktarımı olması garantiydi.</p><p>Ben hayatımda <a href="https://twitter.com/mustafa_ysf">Mustafa Yusuf</a> gibi teknik konulara göz bebeği gibi bakan biriyle tanışmadık. Herkes kod yazabilir, herkes gündemi takip edebilir ama Mustafa’nın yaptığı bambaşka bir şey 😅 O sana bir konu anlattığında sen de şevkleniyorsun. Anlatmıyor yaşıyor adeta.</p><p>Daha sayamayacağım nice ekip arkadaşlarım mevcut şuan Trendyol iOS Ekibi 62 kişi. Her geçen gün birbirimize bir şeyler katıyoruz.</p><p>Peki, ben şimdiye kadar neler yaptım? Elimden geldiğince Yazı yazıp, sunum yapıp deneyimlerimi aktarmaya çalıştım. (Aşağıdan sunumlarıma ulaşabilirsiniz. )</p><p>Şimdi daha fazlasını yapmak istiyorum. Adeta bir yelkenli gibi sektördeki önemli kişilerden rüzgarımı aldım. Bir limana yaklaşıyorum. O limana geldiğimde ben de başka yelkenlere rüzgar olmak istediğime karar verdim. Kodluyoruz ekibi ile beraber Bir mentörlük programı başlattık. Gelen başvurular arasından 1–1 Mentörlük verebileceğim 4 kişiyi seçmem gerekiyordu. Ve destek verebileceğim kişilere davet mailleri atıldı 🥳</p><h3>Kodluyoruz on Twitter: &quot;#Laflıyoruz&#39;un son yayınında yazılım alanında #mentor &amp; #mentee olmanın önemi üzerine konuştuk.🚀Katılan ve dinleyen herkese çok teşekkürler!🎙️Sen de birbirinden değerli yazılımcılardan bire bir mentorluk desteği almak istersen hemen formu doldur!👉https://t.co/zHHmEBv38c / Twitter&quot;</h3><p>Laflıyoruz&#39;un son yayınında yazılım alanında #mentor &amp; #mentee olmanın önemi üzerine konuştuk.🚀Katılan ve dinleyen herkese çok teşekkürler!🎙️Sen de birbirinden değerli yazılımcılardan bire bir mentorluk desteği almak istersen hemen formu doldur!👉https://t.co/zHHmEBv38c</p><p>Birbirinden farklı deneyimdeki insanlara elimden geldiğince destek olmaya çalışacağım. Bu serüveni github’da log’lamayı düşünüyorum. Umarım güzel bir kaynak olur.</p><p>İlerleyen zamanlarda gerçekleştirmeyi istediğim hedeflerim;</p><ul><li>Youtube’a içerik üretmek</li><li>Mentörlük programına devam etmek</li><li>Open Source Live Session ile bir app yazmak</li></ul><p>kısaca özetleyecek olursam, sektörü çok tükettim. Artık üretmek istiyorum 🚀</p><p>Gelecek içeriklerden, duyurlardan haberdar olmak için twitter’dan takipte kalabilirsin 🤙🏼</p><h3>ANIL T. on Twitter: &quot;Pazartesi mesaiye başlarken ben pic.twitter.com/vqVw8GF9Sz / Twitter&quot;</h3><p>Pazartesi mesaiye başlarken ben pic.twitter.com/vqVw8GF9Sz</p><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FO2-fJqJ_alY%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DO2-fJqJ_alY&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FO2-fJqJ_alY%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/6234f71bcb87c69147d25f079349868e/href">https://medium.com/media/6234f71bcb87c69147d25f079349868e/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FKhHO9LYSS6c%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DKhHO9LYSS6c&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FKhHO9LYSS6c%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/072da692c4550034bb06cb079894f0f8/href">https://medium.com/media/072da692c4550034bb06cb079894f0f8/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FfCe8HlnTSZo%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DfCe8HlnTSZo&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FfCe8HlnTSZo%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/80ab25e8502daab449093ba655e77c33/href">https://medium.com/media/80ab25e8502daab449093ba655e77c33/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FwlGInAIRGiU%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DwlGInAIRGiU&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FwlGInAIRGiU%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/cb58378dc6274bcb579ca2bf38aa45a7/href">https://medium.com/media/cb58378dc6274bcb579ca2bf38aa45a7/href</a></iframe><iframe src="https://cdn.embedly.com/widgets/media.html?src=https%3A%2F%2Fwww.youtube.com%2Fembed%2FUKs5HYlTXOM%3Ffeature%3Doembed&amp;display_name=YouTube&amp;url=https%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3DUKs5HYlTXOM&amp;image=https%3A%2F%2Fi.ytimg.com%2Fvi%2FUKs5HYlTXOM%2Fhqdefault.jpg&amp;key=a19fcc184b9711e1b4764040d3dc5c07&amp;type=text%2Fhtml&amp;schema=youtube" width="854" height="480" frameborder="0" scrolling="no"><a href="https://medium.com/media/33d2f813c3d6a77013f4f7a855b993ad/href">https://medium.com/media/33d2f813c3d6a77013f4f7a855b993ad/href</a></iframe><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=a613261c89f5" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Property Wrapper on Production iOS E-commerce App How did we find solutions to Decoding…]]></title>
            <link>https://medium.com/trendyol-tech/using-property-wrapper-on-production-ios-e-commerce-app-how-did-we-find-solutions-to-decoding-d2cdf13d99cd?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/d2cdf13d99cd</guid>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[development]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Sat, 20 Mar 2021 19:03:34 GMT</pubDate>
            <atom:updated>2023-01-05T11:27:42.801Z</atom:updated>
            <content:encoded><![CDATA[<h3>Using Property Wrapper on Production iOS E-commerce App How did we find solutions to Decoding Errors?</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8CivFviCwho1FZGIhD7NaA.png" /></figure><p>How did we get rid of a structure that we are repeatedly building by using the Property Wrapper in Production? In order not to get decoding errors, we started thinking about how we can assign a default value instead of defining an optional value, and the property wrapper did our job. You will find the answer to how we solved our needs at the end of this article.</p><p>Property Wrapper entered our lives as a backward compatible feature with swift 5.1. It is a structure that automatically enables new operations to be performed, which facilitates the addition of new features, filters or calculations, including the creation process of a feature and setter / getter stages. Let’s picture it in our minds with a simple example.If you want the value that holds a string to be kept in uppercased characters when a new value is stored in it, you can easily do this with the property wrapper.</p><p>Doug Gregor and Joe Groff offered an alternative approach to this issue, <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md">which was first addressed in 2015–2016</a>. It introduced it at Swift Evolution 0258 Proposal on September 16, 2020. Compared to the proposal presented in 2015, Doug and Joe’s approach was simpler, more efficient to the compiler, and easier to understand for developers.</p><p><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md">apple/swift-evolution</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zu2JpIRj15GB9VW165khbA.jpeg" /></figure><p>You can activate the Property wrapper by typing “<a href="http://twitter.com/propertyWrapper">@propertyWrapper</a>” at the beginning of the enum, struct or class you want to create, and you can manage your logics on the wrappedValue property.</p><p>For example, as in the example I mentioned above, let’s convert all letters to capital letters regardless of the value set into it.</p><pre>@propertyWrapper<br>struct Uppercased {<br>    var wrappedValue: String {<br>        didSet { wrappedValue = wrappedValue.uppercased() }<br>    }</pre><pre>init(wrappedValue: String) {<br>        self.wrappedValue = wrappedValue.uppercased()<br>    }<br>}</pre><p>In the above figure we created a struct named Uppercased. We showed that this is property Wrapper by typing @propertyWrapper. So he forced us to add wrappedValue. You can pass type according to the type of property you will use here. Now i will use string value to be capitalized.</p><pre>struct Article {<br>    <a href="http://twitter.com/Uppercased">@Uppercased</a> var title: String<br>}</pre><p>Then you just need to write this wrapper at the beginning of which property you want to use. I want to capitalized the title of each article I created. That’s why I added it to the title property.</p><pre>let article = Article(title: &quot;property Wrapper&quot;)<br>print(article.title) // PROPERTY WRAPPER</pre><p>and now every time you call it, the article in title will be changed to a capital letter.</p><p>Okay, but what kind of problem did we encounter, and the property wrapper solved our problem? Our only concern was not to make a properties uppercased. Let’s take a look at this issue now.</p><p>Let’s say you will keep the userType in your DTO. And now there are 3 types. You can keep it as int or string equivalents, or you can even write enum if you know all the future equivalents. But when you use enum, and a new type is added, your project will start getting decoding errors, unless you do not assign a default value on your custom init method. In order to avoid decoding, we wrote our custom inits for values that could be enum equivalent throughout the project.</p><pre>enum UserType: String, Codable {<br>    case admin, user, none<br>    <br>    public init(from decoder: Decoder) throws {<br>        self = try UserType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .none<br>    }<br>}</pre><p>For example, looking at the example above, if a new UserType is added, the old client will not be able to decode it. But it will be set to the default value you will continue your life without getting decoding error.</p><p>So how about using a wrapper that can set the default value when decoding is received?</p><pre>public protocol DefaultCodableInterface {<br>    associatedtype RawValue: Codable<br>    <br>    static var defaultValue: RawValue { get }<br>}</pre><pre><a href="http://twitter.com/propertyWrapper">@propertyWrapper</a><br>public struct DefaultCodable&lt;T: DefaultCodableInterface&gt;: Codable {<br>    public var wrappedValue: T.RawValue<br>    <br>    public init(wrappedValue: T.RawValue) {<br>        self.wrappedValue = wrappedValue<br>    }<br>    <br>    public init(from decoder: Decoder) throws {<br>        let container = try decoder.singleValueContainer()<br>        self.wrappedValue = (try? container.decode(T.RawValue.self)) ?? T.defaultValue<br>    }<br>    <br>    public func encode(to encoder: Encoder) throws {<br>        try wrappedValue.encode(to: encoder)<br>    }<br>}</pre><pre>extension DefaultCodable: Equatable where T.RawValue: Equatable { }<br>extension DefaultCodable: Hashable where T.RawValue: Hashable { }</pre><p>First, let’s create our Property Wrapper. Let us have an interface for this and it will easily do our operations in a generic structure. If you want, make a structure that will assign the last case of enum as the Default value, or create a structure that will set false / true when a bool value when null.<br>In the example above, the type of our wrappedValue comes from the interface. In this way, we give it to the decoder and if it does not return a value, we pass the default value we have.</p><p>When we look at the UserType example above, we said that we can actually make an development to give the last case by default. First of all, we started by creating a protocol called <em>EnumDefaultValueSelectable</em>. This protocol will determine the action to be taken. For example let’s create a structure that will select the last value in the Enum case when we get decoding error. For this example; We have created a protocol conforming to <em>Codable &amp; CaseIterable &amp; RawRepresentable</em>. And we returned lastCase by browsing through allCases we have.</p><pre>public protocol <strong>EnumDefaultValueSelectable</strong>: Codable &amp; CaseIterable &amp; RawRepresentable where RawValue: Decodable, AllCases: BidirectionalCollection { }</pre><pre>public struct <strong>LastCase</strong>&lt;T&gt;: DefaultCodableInterface where T: <strong>EnumDefaultValueSelectable</strong> {<br>    public static var defaultValue: T { T.allCases.last! }<br>}</pre><p>Imagine clearing it all over the project and decorating it with a property wrapper. So clean :)</p><pre>enum UserType: String, EnumDefaultValueSelectable {<br>    case admin, user, none<br>}</pre><pre>struct UserResponse: Codable {<br>    @DefaultCodable&lt;LastCase&gt; var user: UserType<br>}</pre><p>You may be making your properties optional in order not to get decoding errors in the responses you create, but a bool value that comes in null must have a meaning for you.</p><p>In addition to the example above, we also have an isAdmin property. If the value of isAdmin comes to null, we can actually assign it false by default. So let’s create a struct called DefaultFalse. And all we have to do is create a struct that conforms to our interface and return our default value.</p><pre>public struct DefaultFalse: DefaultCodableInterface {<br>    public static var defaultValue: Bool { return false }<br>}</pre><p>Then we can construct our Boolean property to be false when it is null.</p><pre>struct UserResponse: Codable {<br>    <a href="http://twitter.com/DefaultCodable">@DefaultCodable</a>&lt;DefaultFalse&gt; var isAdmin: Bool<br>}</pre><p>If you want to use this Property Wrapper, you can easily access it from the link below.</p><p><a href="https://github.com/Trendyol/ios-components">Trendyol/ios-components</a></p><p>By using the Property Wrapper in the Production code in this way, we got rid of the custom inits we made in many places. If there are structures you use, you can specify them in the comments section.</p><h3>If you like it, you can share it to more people with your applause. 👏🏼</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*QnW6Db80O-NsfJOsal96eQ.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=d2cdf13d99cd" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trendyol-tech/using-property-wrapper-on-production-ios-e-commerce-app-how-did-we-find-solutions-to-decoding-d2cdf13d99cd">Using Property Wrapper on Production iOS E-commerce App How did we find solutions to Decoding…</a> was originally published in <a href="https://medium.com/trendyol-tech">Trendyol Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Property Wrapper’ı Trendyol Kodunda nasıl kullandık? Decoding Hatalarına nasıl çözüm Bulduk?]]></title>
            <link>https://aniltaskiran.medium.com/property-wrapper%C4%B1-trendyol-kodunda-nas%C4%B1l-kulland%C4%B1k-decoding-hatalar%C4%B1na-nas%C4%B1l-%C3%A7%C3%B6z%C3%BCm-bulduk-9e99f47146f4?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/9e99f47146f4</guid>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[apple]]></category>
            <category><![CDATA[development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[swift]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Tue, 09 Mar 2021 10:22:19 GMT</pubDate>
            <atom:updated>2021-03-09T10:22:19.048Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*8CivFviCwho1FZGIhD7NaA.png" /></figure><p>Production’da Property Wrapper’ı kullanarak sürekli yaptığımız bir yapıdan nasıl mı kurtulduk? Decoding hatası almamak için optional değer tanımlamak yerine default value nasıl atayabiliriz diye düşünmeye başladık ve property wrapper bizim işimizi gördü. Bu yazının sonunda ihtiyacımızı nasıl çözdüğümüzün cevabını bulacaksınız.</p><p>Property Wrapper, swift 5.1 ile backward compatible (alt sürümlere uyumlu) bir özellik olarak hayatımıza girdi. Bir özelliğin yaratılma süreci ve setter/getter aşamaları dahil olmak üzere yeni özellikler, filtreler veya hesaplamalar eklenmesini kolaylaştıran otomatik olarak yeni işlemlerin yapılmasını sağlayan bir yapıdır. En basit bir örnekle zihnimizde canlandıracaksak bir string tutan değerin içine ne setlenirse setlensin büyük karakterlerle tutulmasını istiyorsanız, bunu property wrapper ile kolayca yapabilirsiniz.</p><p>İlk olarak <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md">2015–2016 yıllarında ele alınan bu konuya</a> alternatif bi yaklaşım sunan <a href="https://github.com/DougGregor">Doug Gregor</a> ve <a href="https://github.com/jckarter">Joe Groff</a> 16 Eylül 2020&#39;de Swift Evolution 0258 Proposal olarak tanıttı. <a href="https://github.com/apple/swift-evolution/blob/master/proposals/0030-property-behavior-decls.md">2015&#39;te sunulan teklife</a> kıyasla Doug and Joe’nun yaklaşımı daha basit, derleyiciyi daha verimli kullanan ve yazılımcılar için anlaşılması daha kolay bir yaklaşım sundu.</p><p><a href="https://github.com/apple/swift-evolution/blob/master/proposals/0258-property-wrappers.md">apple/swift-evolution</a></p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*zu2JpIRj15GB9VW165khbA.jpeg" /></figure><p>Property wrapper, oluşturmak istediğiniz enum, struct veya class’ın başına “@propertyWrapper” yazarak aktifleştirebilirsiniz ve zorunlu olarak eklememiz gereken wrappedValue propertysi üzerinde logic’lerinizi yönetebilirsiniz.</p><p>Mesela Yukarıda bahsettiğim örnekteki gibi içine setlenen değer ne olursa olsun tamamını büyük harfe çevirelim.</p><pre>@propertyWrapper<br>struct Uppercased {<br>    var wrappedValue: String {<br>        didSet { wrappedValue = wrappedValue.uppercased() }<br>    }</pre><pre>init(wrappedValue: String) {<br>        self.wrappedValue = wrappedValue.uppercased()<br>    }<br>}</pre><p>Yukarıdaki şekilde Uppercased adında bir struct oluşturduk. Bunun property Wrapper olduğunu @propertyWrapper yazarak göstermiş olduk. Bu yüzden bize zorunlu olarak wrappedValue’yu ekletti. Siz burada kullanacağınız property’nin tipine göre type geçebilirsiniz. Ben şimdi string değerlerin her setlendiğinde büyük harfe geçirilmesi için bu örneği verdim.</p><pre>struct Article {<br>    <a href="http://twitter.com/Uppercased">@Uppercased</a> var title: String<br>}</pre><p>Ardından bu wrapper’ı hangi property’de kullanmak isterseniz başına yazmanız yeterli. Ben bu örnekte yarattığım her article’ın title’ı büyük oluşsun istiyorum. O yüzden title propertysine ekledim.</p><pre>let article = Article(title: &quot;property Wrapper&quot;)<br>print(article.title) // PROPERTY WRAPPER</pre><p>ve artık her çağırdığınızda article’ın title’ı büyük harf’e dönmüş olacak.</p><p>Peki iyi hoş da nasıl bir sorunla karşılaştık da bizim problemimizi property wrapper çözmüş oldu? Tek derdimiz bi property’i büyük yapmak değildi. Gelin şimdi bu konuya bi göz atalım.</p><p>DTO’nuzda diyelim ki userType’ını tutacaksınız. Ve şu an 3 tipi var. Int veya string karşılıkları olarak tutabilirsiniz veya gelecek bütün karşılıklarını biliyorsanız enum bile yazabilirsiniz. Ama enum kullandığınız zaman yeni bir type eklenirse projeniz decoding error almaya başlayacak tabii eğer o enum’a custom init yazıp decoding alınca default value ataması yapmadıysanız. Biz decoding almamak için projenin her yerinde enum karşılığı olabilecek değerler için custom initlerimizi yazdık.</p><pre>enum UserType: String, Codable {<br>    case admin, user, none<br>    <br>    public init(from decoder: Decoder) throws {<br>        self = try UserType(rawValue: decoder.singleValueContainer().decode(RawValue.self)) ?? .none<br>    }<br>}</pre><p>Mesela yukarıdaki örneğe baktığınızda eğer yeni bir UserType’ı eklenirse eski client bunu decode edemeyecek. Ama sizin karşıladığınız none değerine setlenecek ve decoding error almadan hayatınıza devam edeceksiniz.</p><p>Peki decoding aldığı zaman default value setleyebilecek bir wrapper kullanmaya ne dersiniz?</p><pre>public protocol DefaultCodableInterface {<br>    associatedtype RawValue: Codable<br>    <br>    static var defaultValue: RawValue { get }<br>}</pre><pre><a href="http://twitter.com/propertyWrapper">@propertyWrapper</a><br>public struct DefaultCodable&lt;T: DefaultCodableInterface&gt;: Codable {<br>    public var wrappedValue: T.RawValue<br>    <br>    public init(wrappedValue: T.RawValue) {<br>        self.wrappedValue = wrappedValue<br>    }<br>    <br>    public init(from decoder: Decoder) throws {<br>        let container = try decoder.singleValueContainer()<br>        self.wrappedValue = (try? container.decode(T.RawValue.self)) ?? T.defaultValue<br>    }<br>    <br>    public func encode(to encoder: Encoder) throws {<br>        try wrappedValue.encode(to: encoder)<br>    }<br>}</pre><pre>extension DefaultCodable: Equatable where T.RawValue: Equatable { }<br>extension DefaultCodable: Hashable where T.RawValue: Hashable { }</pre><p>Öncelikle Property Wrapper’ımızı yaratalım. Bunun bir interface’i olsun ve bu sayede kolaylıkla işlemlerimizi generic bir yapıda yapalım. İsterseniz Default value olarak enum’ın son case’ini atayacak bir yapı yapın isterseniz de default olarak bir bool değeri null gelince false/true setleyecek bir yapı oluşturun. <br>Üstteki örnekte wrappedValue’muzun type’ı interface’den geliyor. bu sayede bunu decoder’a veriyoruz ve eğer bir değer döndüremezse elimizdeki default value’yu paslıyoruz.</p><p>Yukarıdaki UserType örneğine baktığımızda aslında default olarak last case’i vermek için bir geliştirme yapabiliriz dedik ve kolları sıvadık. Öncelikle <em>EnumDefaultValueSelectable </em>diye bi protocol yaratarak başladık. Bu protocol yapılacak aksiyonu belirleyecek. Mesela decoding aldığımızda Enum case’indeki last value’yu seçecek bir yapı yaratalım. Bunun için; <em>Codable &amp; CaseIterable &amp; RawRepresentable’ı conform eden bir protocol oluşturduk. Ve elimizdeki tüm case’leri gezerek lastCase’i return ettik.</em></p><pre>public protocol <strong>EnumDefaultValueSelectable</strong>: Codable &amp; CaseIterable &amp; RawRepresentable where RawValue: Decodable, AllCases: BidirectionalCollection { }</pre><pre>public struct <strong>LastCase</strong>&lt;T&gt;: DefaultCodableInterface where T: <strong>EnumDefaultValueSelectable</strong> {<br>    public static var defaultValue: T { T.allCases.last! }<br>}</pre><p>Yukarıdaki verdiğim UserType örneğine bir daha bakarsak eğer ne kadar temiz olduğunu fark ettiniz mi? Bi de bunu projenin her yerinden temizleyip property wrapper ile süslediğinizi düşünün. Tadından yenmez.</p><pre>enum UserType: String, EnumDefaultValueSelectable {<br>    case admin, user, none<br>}</pre><pre>struct UserResponse: Codable {<br>    @DefaultCodable&lt;LastCase&gt; var user: UserType<br>}</pre><p>Yarattığınız response’larda decoding hatası almamak için property’lerinizi optional yapıyor olabilirsiniz ama null gelen bir bool değerinin sizin için bi anlamı olmalı.</p><p>Yukarıdaki örneğe ek olarak bir de isAdmin propertymiz olsun mesela. isAdmin değeri null gelirse aslında biz buna default olarak false değerini atayabiliriz. O zaman DefaultFalse adında bir struct oluşturalım. Ve tek yapmamız gereken Interface’imizi conform eden bi struct oluşturup default value’muzu döndürmek.</p><pre>public struct DefaultFalse: DefaultCodableInterface {<br>    public static var defaultValue: Bool { return false }<br>}</pre><p>Ardından Bool tipindeki property’mizi null olduğu durumda false olacak şekilde kurgulayabiliriz.</p><pre>struct UserResponse: Codable {<br>    <a href="http://twitter.com/DefaultCodable">@DefaultCodable</a>&lt;DefaultFalse&gt; var isAdmin: Bool<br>}</pre><p>Eğer bu Property Wrapper’ı kullanmak isterseniz kolayca aşağıdaki linkten erişebilirsiniz.</p><p><a href="https://github.com/Trendyol/ios-components">Trendyol/ios-components</a></p><p>Property Wrapper’ı Production kodunda bu şekilde kullanarak bayağı bir yerde yaptığımız custom init’lerden kurtulmuş olduk. Eğer sizin de kullandığınız yapılar varsa yorum kısmında belirtebilirsiniz.</p><h3>Beğendiyseniz, alkışlarınızla daha fazla kişiye ulaşmasını sağlayabilirsiniz. 👏🏼</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*QnW6Db80O-NsfJOsal96eQ.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=9e99f47146f4" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The effect of bots on Automation]]></title>
            <link>https://medium.com/trendyol-tech/the-effect-of-bots-on-automation-fb3135908632?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/fb3135908632</guid>
            <category><![CDATA[slack]]></category>
            <category><![CDATA[bots]]></category>
            <category><![CDATA[automation]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[mobile]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Mon, 04 Jan 2021 10:20:27 GMT</pubDate>
            <atom:updated>2021-01-06T17:06:56.065Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*5ZX44THiHOuaf7SbJBTJiA.png" /></figure><p>Imagine you have an invisible robot surfing on the Internet doing certain tasks for you.</p><p>This is a bot. 🤖</p><p>They reduce frustrating repetitive tasks and save people from doing work that would take up a lot of time and energy. So what jobs can bots do? If you can explain the job step by step to a child who does not understand that job at all, i mean by extracting the algorithm, of course a bot can do it.</p><p>At Trendyol, we are trying to increase our productivity by simplifying the daily routines done by bots in the iOS team.</p><p>Why do we keep doing the things we do over and over again? Let the bots do this job. Do you have a lot of time-consuming works? There are automation tools for this. If you automate this process, you get rid of a lot of burdens. Especially if you completed these works before Covid-19 like us, you could start working remotely overnight without loss of efficiency.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*9QXjHnc3PFUnt4ItvNJPvQ.jpeg" /></figure><p>You can <a href="https://medium.com/trendyol-tech/automating-ios-development-workflow-at-trendyol-72e2fcea6e55">reach the article</a> about processes we have automated as iOS Team which is written by my teammate Ömer.</p><p>In this article, I will talk about how we trigger our automation tools and why we use them.</p><h3>Activate Slack’s superpowers by adding your own bots</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lcBKX9_ZnARlSmrm8XWdqQ.png" /></figure><p>Slack is not just a chat application where you talk to your team, it is actually an application that makes your automation processes quite easy and even contains an automation tool itself. When we see a tool that we can squeeze water from a stone as a team, we love to adapt it to our system immediately :)</p><p>We created the Command Line Tool with Swift to use our bots in Slack. Since we wrote the Trendyol app with Swift, we thought this would be the right approach for us. Because even if someone new to the team, they can easily add new features to the bot we wrote.</p><p>We actually use our bots to send requests wherever we want according to our commands. We send requests to our vapor project to get packages for our bot or to list pull requests. It makes the decisions and execute the necessary job.</p><p>In this article I will not go into how Slackbot is used on the Swift side. You can reach the <a href="https://medium.com/@pvzig/building-slack-bots-in-swift-b99e243e444c">Building Slack Bots In Swift article here</a>.</p><p>So what did we need and what did we automate?</p><h3>Package Exporting Processes</h3><p>In the works we normally do, we had to put the packages manually on the phone and go to the product managers or designers related to that task and show it. This cost us a lot of time. Think about it, you’ve finished a task, passed the code review, tested, and now it’s the last step to do the User Acceptance Test (UAT). In this process, you have to show it to the owner of the task. But after you finished the task, you already started another task and changed the branch. Now you have to leave the task at hand, return to the branch where the task is to be done, get a package from there and show it to the owner of the task. Did you realize what a waste of time it was? That’s exactly why we had to automate this stage. We obtained an Enterprise certificate and started <a href="https://developer.apple.com/videos/play/wwdc2019/304/">distributing our ipa with over the air</a>. All we have to do is tell our bot the branch (Releases/ rc-5.1.0) and schema we want. We have created a structure where we can install the application on our phone with a single click and eliminate manual processes.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/988/1*eMk6iEkGJN8bBtKbfg38pQ.gif" /></figure><p>Since we make Trendyol Yemek Application as a separate module, we can get a package just contains the Trendyol Yemek application in a shorter time.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*XMjYKWzBXE9yix_SRiciCA.png" /></figure><h3><strong>Test Coverage Reports</strong></h3><p>As the Mobile iOS team, we need to write unit test for every task we do. As <a href="https://medium.com/trendyol-tech/automating-ios-development-workflow-at-trendyol-72e2fcea6e55">Ömer mentioned</a>, our unit tests run automatically after each pull request, and as a result, Trendyol’s Test Coverage falls to our group.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0a4PE9NxVUwFYImkaQ6YQw.png" /></figure><p>But we do not have to wait for a new pull request to be able to see test coverage. We tell our bot and it calculates it and brings it to us. As Trendyol app, we can calculate the coverage of modules. Because we follow a modular approach. And we can save time by running our tests on certain test plans. You can get the information about Test Plan with <a href="https://medium.com/trendyol-tech/get-the-most-out-of-ui-tests-with-xcode-test-plans-d089a2252ba2">Get the Most Out of UI Tests With XCode Test Plans</a> article written by my teammate Atakan.</p><p>By writing the branch we want and the Test Plan, we can access the test coverage of only the modules included in that Test Plan.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*qNubnAex0O6ymsBzMctvbQ.gif" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*a2lZ5PQlOpV92HcM_EgrmA.png" /></figure><h3>Listing Open Pull Requests</h3><p>We also linked the package exporting process to Slack’s workflow. We ask Skynet to list us open pull requests. And by clicking the export package button we can export our package for the Environment with the steps of the Slack workflow.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*lhxz2pEUAhpR4NbGqLMJJQ.gif" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*eOwIcVSL_jnP5iS-7JyncQ.png" /></figure><h3>Sending Packages to the Appstore</h3><p>You can read the article written by our mobile team leader Efekan for <a href="https://medium.com/trendyol-tech/building-an-ios-distribution-pipeline-local-poc-with-command-line-tools-part-1-d9f443c7dbb5">package distribution</a>. Efekan’s automatization of this process made our processes much easier. All we have to do is give the necessary branch and update method to friday. In our team, Friday deals with the Appstore side and skynet deals with the enterprise distribution. That’s why we’re at friday in this section.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*71bW-ZokFE4xUIscXCQ6Cw.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*4yY6VYPeULLGtYLqVViHbw.png" /></figure><p>As everywhere, we made it to its current state by iterating here. We didn’t handle error cases at first, when we got an error somewhere, we have to open to the jenkins job and find the error. With <a href="https://twitter.com/strawb3rryx7">Batuhan’s</a> suggestion, we create a task to handle the error case and Batuhan quickly started adding the new feature.</p><p>Below you can see an error received during upload. One of the most common mistakes we came across in a modular structure was the following error. When we embed &amp; sign our modules in frameworks other than the host app, the following error occurs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0VT4_eJKg4_Z-nilxQKPLg.png" /></figure><h3>Skynet Check &amp; Friday Check</h3><p>As everyone knows, our generation does not like to wait, this is a fact. And we always want to be aware of the things we can manage. So there are these two commands. We want to check what Skynet and Friday are doing at the moment and get a report.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*ky9N1NTyeu_BjNpoFWPSUQ.png" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*6IVlytmq9972XpB61bBm-Q.png" /></figure><h3>Welcome</h3><p>When a new person joins our team, a warm welcome comes from skynet :) The messages with the word WORKFLOW can be easily integrated into the channels with <a href="https://slack.com/intl/en-tr/help/articles/360035692513-Guide-to-Workflow-Builder">Slack’s workflow builder tool</a>.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*GCpIZGGvXDRRn8w_ZMD5cw.png" /></figure><h3>Please feel free to comment below, if you have any questions.</h3><p>If you like this article, feel free to share it with your friends and leave me a comment. Also, click on the 👏 clap button below to show how much you like the article.</p><p>Thanks for reading! 👨🏼‍💻</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*KhJEQUmUEWZDKPZUNU15YQ.gif" /></figure><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*I5RxexvEAsuo0VCPKANJGA.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=fb3135908632" width="1" height="1" alt=""><hr><p><a href="https://medium.com/trendyol-tech/the-effect-of-bots-on-automation-fb3135908632">The effect of bots on Automation</a> was originally published in <a href="https://medium.com/trendyol-tech">Trendyol Tech</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Nearby Interaction iOS 14 WWDC20]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://aniltaskiran.medium.com/nearby-interaction-ios-14-wwdc20-e4ad9bcb3826?source=rss-1ba92a98028------2"><img src="https://cdn-images-1.medium.com/max/2000/1*0eRCTjguZMp-z5rRmH_8Sg.png" width="2000"></a></p><p class="medium-feed-snippet">Apple has announced a new feature for iOS 14 called &#x201C;Nearby Interaction&#x201D; which locate  and interact with nearby devices using distance and&#x2026;</p><p class="medium-feed-link"><a href="https://aniltaskiran.medium.com/nearby-interaction-ios-14-wwdc20-e4ad9bcb3826?source=rss-1ba92a98028------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://aniltaskiran.medium.com/nearby-interaction-ios-14-wwdc20-e4ad9bcb3826?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/e4ad9bcb3826</guid>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[wwdc]]></category>
            <category><![CDATA[ios]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Sat, 27 Jun 2020 14:07:36 GMT</pubDate>
            <atom:updated>2020-07-03T20:03:41.707Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[What’s New with Location and Bluetooth APIs on iOS 13]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://aniltaskiran.medium.com/whats-new-with-location-and-bluetooth-apis-on-ios-13-a6d8497ffa39?source=rss-1ba92a98028------2"><img src="https://cdn-images-1.medium.com/max/2500/1*8stWafUrAy0V6p8fu74vAQ.jpeg" width="2500"></a></p><p class="medium-feed-snippet">With the recently announced iOS 13, we see that Apple&#x2019;s approach to location privacy is getting more and more serious. This new update&#x2026;</p><p class="medium-feed-link"><a href="https://aniltaskiran.medium.com/whats-new-with-location-and-bluetooth-apis-on-ios-13-a6d8497ffa39?source=rss-1ba92a98028------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://aniltaskiran.medium.com/whats-new-with-location-and-bluetooth-apis-on-ios-13-a6d8497ffa39?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/a6d8497ffa39</guid>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[ios-app-development]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Tue, 28 Jan 2020 20:37:59 GMT</pubDate>
            <atom:updated>2020-01-30T10:41:48.534Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Teach Emojis to Machine on iOS with Artificial Neural Networks]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/trendyol-tech/teach-emojis-to-machine-on-ios-with-artificial-neural-networks-83acf58e3843?source=rss-1ba92a98028------2"><img src="https://cdn-images-1.medium.com/max/2000/1*0I6QYVeGd8Ycxl8FVq0yXg.png" width="2000"></a></p><p class="medium-feed-snippet">Do you want to teach your machine emojis? This is a project to demonstrate what is possible to solve applying the Artificial Neural&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/trendyol-tech/teach-emojis-to-machine-on-ios-with-artificial-neural-networks-83acf58e3843?source=rss-1ba92a98028------2">Continue reading on Trendyol Tech »</a></p></div>]]></description>
            <link>https://medium.com/trendyol-tech/teach-emojis-to-machine-on-ios-with-artificial-neural-networks-83acf58e3843?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/83acf58e3843</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <category><![CDATA[machine-learning]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[xcode]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Mon, 30 Dec 2019 21:19:46 GMT</pubDate>
            <atom:updated>2020-01-06T16:25:34.783Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Using iOS Bottom Sheet]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://aniltaskiran.medium.com/using-ios-bottom-sheet-61cfd29f905e?source=rss-1ba92a98028------2"><img src="https://cdn-images-1.medium.com/max/2000/1*sqynU2W1a9S2J1VzM9tiqg.png" width="2000"></a></p><p class="medium-feed-snippet">In March 2019, I was developing the dating app. I wanted to share with you the bottom sheet design that I came across while looking for new</p><p class="medium-feed-link"><a href="https://aniltaskiran.medium.com/using-ios-bottom-sheet-61cfd29f905e?source=rss-1ba92a98028------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://aniltaskiran.medium.com/using-ios-bottom-sheet-61cfd29f905e?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/61cfd29f905e</guid>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ux]]></category>
            <category><![CDATA[mobile-app-development]]></category>
            <category><![CDATA[swift]]></category>
            <category><![CDATA[design]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Sat, 28 Dec 2019 15:40:43 GMT</pubDate>
            <atom:updated>2021-02-12T09:45:37.377Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[iOS Bottom Sheet Kullanımı]]></title>
            <link>https://aniltaskiran.medium.com/ios-bottom-sheet-kullan%C4%B1m%C4%B1-b4875e1c2554?source=rss-1ba92a98028------2</link>
            <guid isPermaLink="false">https://medium.com/p/b4875e1c2554</guid>
            <category><![CDATA[ios-app-development]]></category>
            <category><![CDATA[mobile]]></category>
            <category><![CDATA[ux]]></category>
            <category><![CDATA[ios]]></category>
            <category><![CDATA[ux-design]]></category>
            <dc:creator><![CDATA[Anıl taşkıran]]></dc:creator>
            <pubDate>Sat, 28 Dec 2019 15:11:43 GMT</pubDate>
            <atom:updated>2019-12-28T16:02:11.377Z</atom:updated>
            <content:encoded><![CDATA[<p><a href="https://medium.com/@aniltaskiran/using-ios-bottom-sheet-61cfd29f905e">The English version is available on here</a>.</p><p>2019 Mart’ında dating app’i geliştiriyordum. Haziran ayında ikinci versiyonu için tasarım arayışındayken karşılaştığım tasarımı uygulamaya aktarışımı sizlerle paylaşmak istedim. O zamanlarBir başka yazıda oradan edindiğim deneyimleri ve nasıl ilerlediğimi anlatırım. Şu aralar üzerine çalıştığım uygulamada da aynı tasarımı kullanırken böyle bir yazı yazmaya karar verdim.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*-XSt8gn3Y2rexx1SHctuoQ.png" /></figure><p>Dribble’da <a href="https://dribbble.com/op74185">op7418</a> ‘in tasarladığı tasarım bu şekildeydi. Bunun üzerinde biraz daha çalışıp aslında profil detay sayfasından ziyade eşleştirme ekranına dönüştürmem gerekiyordu. Tasarım üzerine konuşmaktan ziyade Yukarı kaydırılabilir view üzerine konuşacağım. Aslında kolayca harici kütüphaneleri ekleyip kullanabiliceğiniz kütüphaneler mevcut. Fakat o zaman burada paylaşabileceğim bir yazı mevcut olmayacaktı. 😅</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*O5pPtilwP5C4Ot_QuE2kpQ.png" /></figure><p>Altta gözüken kaydırılabilir view aslında subview olarak eklenmiş bir child view. Burada tek yaptığım onu ana ekranda gözükecek kısmını ayarlamaktı.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*0L8NC16EAhSmJPcKrTiBkQ.png" /></figure><p>İlk olarak yaptığım Pan Gesture eklemekti. Çünkü elimizin hareketiyle hareket edecek. Tamamen açıldığında y position’ı 100&#39;e gelmesini istediğimden bunu sabitledim. 2 tane move View methodum var. Bir tanesi el hareketi tamamlandığında tetiklenen diğeri ise anlık olarak el hareketime göre view’ı hareket ettirmek için var. UIPanGestureRecognizer alan moveView methodunu incelediğimizde ekranın kısıtladığımız kısımlarında y pozisyonu değiştidiğinde onu hareket ettirecek kod parçasını göreceksiniz.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/1*lXVX6LaC4oJRSrgS_LpOAg.gif" /></figure><iframe src="" width="0" height="0" frameborder="0" scrolling="no"><a href="https://medium.com/media/c1f146dcb14b4fc61aebe1c167e57a99/href">https://medium.com/media/c1f146dcb14b4fc61aebe1c167e57a99/href</a></iframe><p>Projeyi incelemek isterseniz buradan ulaşabilirsiniz.</p><p>Şuan üzerinde çalıştığım uygulamamda ise aşağıdaki gibi kullandım.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/600/1*UvsaQ7Q8TuqdprnpSPOusg.gif" /></figure><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b4875e1c2554" width="1" height="1" alt="">]]></content:encoded>
        </item>
    </channel>
</rss>