<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: complexityclass</title>
    <description>The latest articles on DEV Community by complexityclass (@complexityclass).</description>
    <link>https://dev.to/complexityclass</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F301169%2F70a6494c-08d0-4444-a6cb-70b693c54d36.JPG</url>
      <title>DEV Community: complexityclass</title>
      <link>https://dev.to/complexityclass</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/complexityclass"/>
    <language>en</language>
    <item>
      <title>Rustling Up Cross-Platform Development</title>
      <dc:creator>complexityclass</dc:creator>
      <pubDate>Sun, 12 Mar 2023 21:26:11 +0000</pubDate>
      <link>https://dev.to/complexityclass/rustling-up-cross-platform-development-5en</link>
      <guid>https://dev.to/complexityclass/rustling-up-cross-platform-development-5en</guid>
      <description>&lt;p&gt;&lt;em&gt;My experience with cross-platform mobile development lacks some important elements, such as Flutter or Xamarin. Therefore, this article is not a comprehensive analysis of tools in this space.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Over the years, I've tried a few different tools for cross-platform development, including PhoneGap (which, in hindsight, I probably should have avoided), React Native, Qt, and a bit of Kotlin Native. Generally speaking, I firmly believe that the UI should be native, and that tools like PhoneGap just don't cut it for anything more than a simple app. While React Native has its pros and cons, it hasn't won me over as a developer. Instead, I prefer the idea of having a cross-platform core and native UI. As someone who switched from Android to iOS around the time of KitKat (4.4? 🤔), As I'm naturally more inclined towards llvm based languages, C++ was my first choice for a cross-platform code. On iOS it's relatively easy to bridge C++ and Objective-C through a mix of both called Objective-C++. I've worked on some big projects that were heavily based on this idea, and I can attest that it's a working solution. However, Objective-C is becoming less popular every day, and Objective-C++ is an even scarier beast to work with. I can't say that I found writing it enjoyable. Furthermore, I can't see any compelling reason to write application-level code in C++. Perhaps for OS-level code, but that's a topic for another discussion. After a few attempts with C++, I tried Kotlin Native (KN), which had much better tooling and IDE support, even in the earliest versions. Kotlin is a fun language to read and write, and with the "Native" part, we can even rid ourselves of the JVM. So if you're already immersed in the Android ecosystem, love Kotlin, and enjoy working in Android Studio, then KN should be a good choice for you. However, in this article, I'd like to explore a more "rusty" perspective. Let's dive in.&lt;/p&gt;

&lt;p&gt;I've dabbled with Rust on iOS a few times, and it seemed a lot like C++. You build a static library, use C headers as glue, and end up struggling with debugging. This approach is straightforward when you're only extracting a small piece of logic into a shared library and interacting with it through a thin interface. But what if you want to put most of the app logic into the shared lib? That's when things get tricky.&lt;/p&gt;

&lt;p&gt;Recently, I stumbled upon a project at the Rust London conference that caught my eye. It's called &lt;a href="https://github.com/redbadger/crux" rel="noopener noreferrer"&gt;Crux&lt;/a&gt;, and it's a library that helps you implement a functional core and imperative shell paradigm. In other words, it allows you to separate your app logic from your UI code, and share it between platforms.&lt;/p&gt;

&lt;p&gt;Although the idea of a functional core and imperative shell might sound straightforward, the actual implementation can be tricky. As you start working on it, you'll inevitably run into obstacles and challenges, especially when it comes to separating the core logic from the user interface.&lt;/p&gt;

&lt;p&gt;Second biggest challenges after "variable naming" is finding the appropriate architecture to use. Traditional MVC/MVP architectures may not always be the best fit, and I found it difficult to keep track of all the data flows in applications I used to work with. Additionally, real-world user interfaces can be complex and dynamic, which adds even more states and interactions to the UI layer.&lt;/p&gt;

&lt;p&gt;This is where functional concept of free from side-effects Core comes in. Crux helps to build foundation. For me, it's been really helpful in figuring out how to structure my code and how to isolate the core logic in a way that's both ergonomic and easy to read. In a few hours I created a small app that interacts with the DALL-E APIs (pretty obvious, right?) and works on 3 platforms (actually 2.5 as I haven't finished web 😅). In the following section, I'll share my initial impressions.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setup
&lt;/h3&gt;

&lt;p&gt;Since the project is in its very early stages, setting it up isn't quite as seamless as with React Native. However, it's not a big deal to contribute to the tooling in-house if you decide to go with this stack for a real project. In fact, most big projects, even single-platform ones, contain a zoo of different bash scripts and make files anyway. The &lt;a href="https://redbadger.github.io/crux/overview.html" rel="noopener noreferrer"&gt;book&lt;/a&gt; has a really good explanation of how it works and even provides example apps.&lt;/p&gt;

&lt;p&gt;Personally, I found it better to set up the project from scratch using the book. That way, I was able to see all the places to look if something went wrong. It took me less than an hour to set up the core and iOS project, and the process was straightforward. Luckily, the core configuration is in .rs and toml files, which are very easy to follow.&lt;/p&gt;

&lt;p&gt;For iOS, you need some bash scripts (oh, I hate writing bash). But in my case, copy-pasting was enough, and ChatGPT made life bearable even if some customisation in bash is needed. Long story short, you need to compile the core as a static library, generate UI languages bindings using the &lt;a href="https://crates.io/crates/uniffi" rel="noopener noreferrer"&gt;uniffi&lt;/a&gt; crate, and add these steps to the Xcode project so you don't need to rebuild and relink the core manually. The uniffi requires to write an IDL Interface Definition Language file describing the methods and data structures available to the targeted languages. I generated Swift/ Kotlin and TS for iOS/Android and Web respectively.&lt;/p&gt;

&lt;p&gt;UDL looks like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace core {
  sequence&amp;lt;u8&amp;gt; handle_event([ByRef] sequence&amp;lt;u8&amp;gt; msg);
  sequence&amp;lt;u8&amp;gt; view();
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;At the end, the project structure looks like this (no Android and web on the screenshot):&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F99blm6gwbnc9rldwhzl3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F99blm6gwbnc9rldwhzl3.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Development
&lt;/h3&gt;

&lt;p&gt;When it comes to development, you'll probably be splitting your time between Xcode/Android Studio and whatever you prefer for Rust and web development. I've seen some brave souls trying to do mobile development in Emacs, but at the end of the day, they were significantly slower than their teammates.&lt;/p&gt;

&lt;p&gt;The good news is that it's quite convenient to work on the core first, crafting the interface and writing tests, and then switching to Xcode/Studio to polish bits of the Core in parallel. Personally, I use CLion for Rust and I don't dare to open more than 2 out of the 3 (CLion/Xcode/Android Studio) at once. Rust compiles quite slowly, which isn't a problem for me since my Swift/ObjC project at work took around 50 minutes for a clean build on a top configuration MacPro(not a MacBook 🐌). However, for web developers, this might be a bit of a drag. But proper project modularization can help with this.&lt;/p&gt;

&lt;p&gt;Writing code in Rust can be a bit challenging at first, but I found that a lot of the ideas are similar to Swift, so it's not like a completely different experience. Enums like in Swift, isn't it? 😁&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#[derive(Serialize, Deserialize)]
pub enum Event {
    Reset,
    Ask(String),
    Gen(String),
    #[serde(skip)]
    Set(Result&amp;lt;Response&amp;lt;gpt::ChatCompletion&amp;gt;&amp;gt;),
    #[serde(skip)]
    SetImage(Result&amp;lt;Response&amp;lt;gpt::PictureMetadata&amp;gt;&amp;gt;),
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When it comes to debugging, you can use breakpoints through the &lt;strong&gt;lldb "breakpoint set"&lt;/strong&gt; command to debug both the Swift and Rust code in your linked static library. It's not as convenient as debugging a pure Kotlin project in Android Studio, but it still gets the job done.&lt;/p&gt;

&lt;p&gt;E.g missing .env variable error easily identifiable even from within Xcode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86nja6fb04cdhs1gcqp8.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F86nja6fb04cdhs1gcqp8.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Exact line in the logs:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu0uhsicafc6ujuht9ld.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvu0uhsicafc6ujuht9ld.png" alt="Image description"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, I couldn't see any issues with debugging the core and shell separately. In fact, it can be quite helpful to be able to debug each component independently, as it can make it easier to pinpoint the source of any bugs or issues.&lt;/p&gt;

&lt;p&gt;What about interop... I'm not going to lie, it's not ideal. In particular, interop between Rust and Swift isn't as seamless as it is between Swift/Objective-C and Kotlin/Java. For example, &lt;strong&gt;f64&lt;/strong&gt; can't be passed as is through the boundary ( &lt;em&gt;which is logical, but still&lt;/em&gt;). However, there are some cheat sheets available to help make sense of the interop rules. For Swift, the following rules apply:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Primitives map to their obvious Swift counterpart (e.g. &lt;strong&gt;&lt;code&gt;u32&lt;/code&gt;&lt;/strong&gt; becomes &lt;strong&gt;&lt;code&gt;UInt32&lt;/code&gt;&lt;/strong&gt;, &lt;strong&gt;&lt;code&gt;string&lt;/code&gt;&lt;/strong&gt; becomes &lt;strong&gt;&lt;code&gt;String&lt;/code&gt;&lt;/strong&gt;, etc.).&lt;/li&gt;
&lt;li&gt;An object interface declared as &lt;strong&gt;&lt;code&gt;interface T&lt;/code&gt;&lt;/strong&gt; is represented as a Swift protocol &lt;strong&gt;&lt;code&gt;TProtocol&lt;/code&gt;&lt;/strong&gt; and a concrete Swift class &lt;strong&gt;&lt;code&gt;T&lt;/code&gt;&lt;/strong&gt; that conforms to it.&lt;/li&gt;
&lt;li&gt;An enum declared &lt;strong&gt;&lt;code&gt;enum T&lt;/code&gt;&lt;/strong&gt; or &lt;strong&gt;&lt;code&gt;[Enum] interface T&lt;/code&gt;&lt;/strong&gt; is represented as a Swift enum &lt;strong&gt;&lt;code&gt;T&lt;/code&gt;&lt;/strong&gt; with appropriate variants.&lt;/li&gt;
&lt;li&gt;Optional types are represented using Swift's built-in optional type syntax &lt;strong&gt;&lt;code&gt;T?&lt;/code&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Sequences are represented as Swift arrays, and maps as Swift dictionaries.&lt;/li&gt;
&lt;li&gt;Errors are represented as Swift enums that conform to the &lt;strong&gt;&lt;code&gt;Error&lt;/code&gt;&lt;/strong&gt; protocol.&lt;/li&gt;
&lt;li&gt;Function calls that have an associated error type are marked with &lt;strong&gt;&lt;code&gt;throws&lt;/code&gt;&lt;/strong&gt; in Swift.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I remember similar rules for Kotlin Native. Actually, the interface between the core and shell should be laconic. I don't think these limitations are good, but they don't hurt too much either.&lt;/p&gt;

&lt;h3&gt;
  
  
  Architecture
&lt;/h3&gt;

&lt;p&gt;Talking about architectural patterns. &lt;em&gt;Have you seen mobile Eng who are not talking about patterns?&lt;/em&gt; Crux is inspired by Elm, there is quite good page in the &lt;a href="https://redbadger.github.io/crux/guide/elm_architecture.html" rel="noopener noreferrer"&gt;book&lt;/a&gt; and also &lt;a href="https://guide.elm-lang.org/architecture/" rel="noopener noreferrer"&gt;Elm docs&lt;/a&gt; worth reading, so let’s skip the description. In general I see movement to unidirectional and message passing architectures. They are clean and quite strict, which makes it easier to update code and not introduce inconsistency when one text field has three different states across layers. True that UIKit or Vanila android libraries are not the best fit (though still possible to reuse some ideas), but SwiftUI and Jetpack Compose fit quite nice. If you write gesture interaction and animation heavy UIs - this would be challenging. Like if you do some gesture driven transition, should you keep current state in UI or pass it to the core? Or UITableView (iOS) and RecyclerView (Android) have a bit different lifecycle for cells, hence for cell models, how core will be dealing with it. A bit challenging, but still possible, no silver bullets as always.&lt;/p&gt;

&lt;p&gt;The part that I liked the most, though, was the capabilities feature. Capabilities provide a nice and clear way to deal with side effects, such as networking, databases, and system frameworks. Sure, you could write a single HTTP library in C and use it everywhere, and maybe you could even standardize persistence to use only SQLite. But there are so many different things to consider, such as audio/video, file systems, notifications, biometrics, or even peripherals like the Apple Pencil. And your system already has good libraries to deal with these things, which might even be optimized ( quality of service or URLSession configuration on iOS) to be more effective. That's where capabilities come in - they allow you to declare what you need, while keeping the implementation specifics for the platform code. It's a great way to keep your code modular and maintainable. &lt;/p&gt;

&lt;p&gt;When core handles event that need to make an HTTP call, it's actually instructing Shell to do the call.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;fn update(&amp;amp;self, event: Self::Event, model: &amp;amp;mut Self::Model, caps: &amp;amp;Self::Capabilities) {
        match event {
            Event::Ask(question) =&amp;gt; {
                model.questions_number += 1;
                gpt::API::new().make_request(&amp;amp;question, &amp;amp;caps.http).send(Event::Set);
            },
...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And shell is sending request&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;switch req.effect {
            ...
            case .http(let hr):
                // create and start URLSession task
            }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The same logic can be applied to databases (just separate KV-storages and relational), biometric, whatever else.&lt;/p&gt;

&lt;h3&gt;
  
  
  Final Thoughts
&lt;/h3&gt;

&lt;p&gt;Despite the fact that I'm new to Crux and not yet fluent in Rust, I was able to build a simple app that works on iOS, Android, and Web (almost) in less time than it would have taken to build all three from scratch.&lt;/p&gt;

&lt;p&gt;Crux is still in its early stages, e.g. at the time of my note, the HTTP capability didn't support headers and body. But I have high hopes that this project will continue to grow and attract more contributors, as the idea behind it is really cool.&lt;/p&gt;

&lt;p&gt;Even if you don't want to use Rust for cross platform development, I think it's worth taking a look at this project to see how you might be able to reuse some of the ideas in your favourite stack. At the end of the day, anything that helps us write better, more modular, and more maintainable code is a win.&lt;/p&gt;

</description>
      <category>rust</category>
      <category>ios</category>
      <category>crossplatform</category>
    </item>
    <item>
      <title>Unveiling the Power of Proxies for Mobile Clients</title>
      <dc:creator>complexityclass</dc:creator>
      <pubDate>Sun, 26 Feb 2023 21:17:21 +0000</pubDate>
      <link>https://dev.to/complexityclass/unveiling-the-power-of-proxies-for-mobile-clients-1c3l</link>
      <guid>https://dev.to/complexityclass/unveiling-the-power-of-proxies-for-mobile-clients-1c3l</guid>
      <description>&lt;p&gt;It's pretty common for mobile applications to participate in client-server communication. As a mobile developer, you may build apps that communicate with your own trusted server. However, there might be cases when you need to communicate with third-party servers. In such situations, you may not want to expose the IP address of your mobile client. To solve this issue, using a proxy server appears to be an obvious choice. So in this article, I'm going to show you one way you can use a proxy in your systems to improve privacy. And, based on my experience, there are a few things that mobile engineers might find helpful to navigate this topic further.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy 101
&lt;/h2&gt;

&lt;p&gt;Proxy servers are quite helpful for a variety of reasons, such as content filtering or caching, but their main purpose is to provide privacy and security. While SSL and TLS already do a great job of securing communication, a proxy server can add an extra layer of protection.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6c381rqjty6dyip96to6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F6c381rqjty6dyip96to6.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;Client-server with a proxy
  &lt;/p&gt;

&lt;p&gt;In a typical HTTPS connection between a client and a server without a proxy in the middle, the traffic is secured with the Transport Layer Security (TLS) protocol. When a client sends a request to the server, the TLS protocol ensures that the data is encrypted before it is transmitted over the network. Once the server receives the encrypted data, it decrypts it using a private key that only the server has access to.&lt;/p&gt;

&lt;p&gt;However, even though the traffic is encrypted, the server can still see the IP address of the client, which may reveal sensitive information about the client's location or network configuration. This is where a proxy server or other techniques come into play to provide additional privacy and security.&lt;/p&gt;

&lt;h2&gt;
  
  
  Proxy or VPN?
&lt;/h2&gt;

&lt;p&gt;When you want to keep your IP address hidden, you have two popular options: a proxy server and a virtual private network (VPN). Here's how they work:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A proxy server acts as an intermediary between the client and the server. This means that it forwards requests from the client to the server and then returns the server's response back to the client. The server sees the IP address of the proxy server instead of the client's, which provides an additional layer of privacy.&lt;/li&gt;
&lt;li&gt;A VPN creates a secure, encrypted connection between the client and a remote server. All traffic is routed through the remote server, which masks the client's IP address and provides an added layer of security. However, setting up a VPN can be more complex than using a proxy server. It may also conflict with the VPN proxy, block traffic that is not routed through the VPN tunnel, and require additional resources.&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;To set up a VPN proxy with the &lt;a href="https://developer.apple.com/documentation/networkextension" rel="noopener noreferrer"&gt;Network Extensions&lt;/a&gt; framework, you'll need to create a new Network Extension target in your Xcode project and implement a few delegate methods. You will also need to configure the tunnel provider with the details of your proxy server, such as its hostname and port number.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  The Many Shades of Proxies
&lt;/h2&gt;

&lt;p&gt;Proxy servers have a long history. There are actually a bunch of different protocols you can use with them, like SMTP, SOCKS, and FTP. But for now, let's focus on HTTP(s).&lt;/p&gt;

&lt;p&gt;The main thing to know about HTTP vs HTTPS proxies is that HTTPS uses SSL/TLS encryption to keep your data safe. That means when you use an HTTPS proxy, your data is encrypted from the moment it leaves your device until it reaches the server, which makes it a lot more secure.&lt;/p&gt;

&lt;p&gt;On the other hand, HTTP proxies don't encrypt your data, so it's visible to anyone who might be snooping around. While they can be helpful for caching and filtering web traffic, they're not great for sending sensitive information. So if you're doing something like online shopping or sending private messages, it's definitely a good idea to use an HTTPS proxy.&lt;/p&gt;

&lt;p&gt;It's worth mentioning that proxies come in all shapes and sizes, not just protocols. Did you know that even http(s) can have different types? The most common ones are forward and reverse proxies. A forward proxy acts as a middleman between a client and a server, while a reverse proxy acts as a middleman between a server and the internet.&lt;/p&gt;

&lt;h4&gt;
  
  
  Forward proxy
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;  
  &lt;tr&gt;
    &lt;td&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fguuko3a9fygaki1w50c4.png" alt="Alt Text"&gt;&lt;/td&gt;
    &lt;td&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;small&gt;Acts as an intermediary between a client and a server&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Client initiates the request&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Used to provide anonymity or bypass firewalls&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Commonly used for content caching and filtering&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Usually deployed in client networks&lt;/small&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h4&gt;
  
  
  Reverse proxy
&lt;/h4&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fje8bewlzb2ss7hyptag8.png" alt="Alt Text"&gt;&lt;/td&gt;
    &lt;td&gt;
      &lt;ul&gt;
        &lt;li&gt;&lt;small&gt;Acts as an intermediary between a server and the internet&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Server initiates the request&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Used for load balancing, content caching, and enhancing security&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Commonly used to distribute traffic across multiple servers&lt;/small&gt;&lt;/li&gt;
        &lt;li&gt;&lt;small&gt;Usually deployed in server networks&lt;/small&gt;&lt;/li&gt;
      &lt;/ul&gt;
    &lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Ensuring a well-distributed infrastructure and protecting client anonymity are crucial. To maintain anonymity, a significant number of clients should be hidden behind the proxy address. In practice, a combination of reverse-proxy and forward-proxy is often used. For simplicity, the examples below will only use one forward proxy.&lt;/p&gt;

&lt;h2&gt;
  
  
  HTTP: Connecting &lt;del&gt;people&lt;/del&gt; packets
&lt;/h2&gt;

&lt;p&gt;Okay, so proxy servers are pretty popular these days. In fact, the HTTP protocol has a whole method just for them called &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT" rel="noopener noreferrer"&gt;HTTP CONNECT&lt;/a&gt;. This method helps you create a safe tunnel through an unsafe network, like the internet. When you're using HTTP Connect to connect to a server, you send an HTTP CONNECT request to the proxy server, and you just need to let the proxy server know the hostname and port number of the server you want to reach.&lt;/p&gt;

&lt;p&gt;The proxy server then establishes a two-way communication channel with the destination server and passes data between the client and server, allowing the client to communicate with the server securely. This method is commonly used to establish SSL/TLS encrypted connections between a client and server. It can be used for a variety of purposes, such as bypassing firewalls, establishing secure communication channels, and enabling remote access to internal networks.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwu53jwx62mo36wzgzsi.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fjwu53jwx62mo36wzgzsi.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;HTTP CONNECT setup
  &lt;/p&gt;

&lt;p&gt;If you're a mobile developer, you probably use methods like GET, POST, and PUT all the time. But have you ever used CONNECT? Let’s explore how to get &lt;a href="https://developer.apple.com/documentation/foundation/nsurlsession" rel="noopener noreferrer"&gt;URLSession&lt;/a&gt; to use it, or whether you should go with a more hardcore library.&lt;/p&gt;

&lt;p&gt;So check it, the first thing - you can totally set up a proxy address in the session configuration. No big deal, just wanted to give you the heads up.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a session configuration object&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;URLSessionConfiguration&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;default&lt;/span&gt;

&lt;span class="c1"&gt;// Create a proxy object with your desired host and port&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;kCFNetworkProxiesHTTPSEnable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="nx"&gt;kCFNetworkProxiesHTTPSProxy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your.https.proxy.host&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
             &lt;span class="nx"&gt;kCFNetworkProxiesHTTPSPort&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;String&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Any&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;// Set the proxy on the session configuration&lt;/span&gt;
&lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;connectionProxyDictionary&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt;

&lt;span class="c1"&gt;// Create an NSURLSession with the configuration&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;URLSession&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;config&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One way to understand what's happening under the hood is by intercepting the traffic using Wireshark or any other tool you prefer. Alrighty, just fire off a GET request to your fave endpoint with this session and we're good to roll. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6f945ta48ys26m0580l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fl6f945ta48ys26m0580l.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;Tcp dump from the wireshark
  &lt;/p&gt;

&lt;p&gt;So get this, tcp dump shows that the client is actually sending a CONNECT for us behind the scenes. Pretty good!&lt;/p&gt;

&lt;p&gt;Setting up Android is just as easy and you'll still get the same results.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Create a URL object for the destination server&lt;/span&gt;
&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;URL&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.example.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;// Create a Proxy object with your desired host and port&lt;/span&gt;
&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="nx"&gt;proxy&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Proxy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nc"&gt;InetSocketAddress&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;your.https.proxy.host&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;8080&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;

&lt;span class="c1"&gt;// Open a connection to the URL with the proxy&lt;/span&gt;
&lt;span class="nx"&gt;val&lt;/span&gt; &lt;span class="nx"&gt;connection&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;openConnection&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;proxy&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HttpURLConnection&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Houston, We Have a Problem (Again)
&lt;/h2&gt;

&lt;p&gt;Alright, so is the case all wrapped up? Or is there still more to it? Actually, on top of the VPN, iOS/Android has a nifty feature that lets you use a system-level proxy setting for a specific Wi-Fi network. This is mainly used by big-shot companies that have their own devices to manage. But this led us to a new issue with changing the system proxy configuration: when you set a new proxy config through session configuration, it overwrites the user's current settings for any requests handled by those sessions.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Note that by overriding, we only mean session-level requests (i.e., requests served during your app session) rather than app or device-level requests, which will not be affected.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;You might decide to override the default settings, but this could have the following consequences:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;No connectivity, as the ISP/network can require all traffic to go through the proxy.&lt;/li&gt;
&lt;li&gt;Loss of privacy for the user, as they may be using the proxy for additional privacy.&lt;/li&gt;
&lt;li&gt;Malfunction of some features (e.g. payment due to geo-blocking).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Okay, so let's say we want to keep both proxies, right? No worries, because the cool thing about network protocols is that you can layer them on top of one another, which makes them really powerful. One way to do this is by nesting one tunnel inside another. For example, you can open one connect tunnel through the system proxy and then nest it inside a second tunnel that goes through a forward proxy.&lt;/p&gt;

&lt;p&gt;The diagram from before will be updated in the following manner&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foij1p463znxvswwvh608.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Foij1p463znxvswwvh608.png" alt="Alt Text"&gt;&lt;/a&gt;&lt;br&gt;Double HTTP CONNECT setup
  &lt;/p&gt;

&lt;p&gt;So, the diagram might seem a bit more complicated, but it's actually just duplicating the same mechanism for two proxies. The only issue is that the default iOS/Android libraries don't support this out of the box, so we'll need to put in some extra work. To get around this, we can go one level down and use &lt;a href="https://developer.apple.com/documentation/network" rel="noopener noreferrer"&gt;Network.framework&lt;/a&gt; on iOS, subclass NWConnection, and handle it manually.&lt;/p&gt;

&lt;h2&gt;
  
  
  So Much to Proxy, So Little Time
&lt;/h2&gt;

&lt;p&gt;Alright, let's wrap up this article so it doesn't drag on. We've gone over how using proxies on mobile clients can improve  security and privacy for our users. We also talked about the differences between VPNs and proxy servers, and delved into the two most common types of proxies: forward and reverse proxies. Lastly, we checked out client libraries and how they can help with proxies, as well as their limitations.&lt;/p&gt;

&lt;p&gt;Keep an eye on the next article where we'll try to mix and match proxies. We'll be using NWConnection and might even do some byte juggling. Stay tuned!&lt;/p&gt;

</description>
      <category>ios</category>
      <category>networking</category>
      <category>architecture</category>
    </item>
  </channel>
</rss>
