C# & Swift Network

Building a Generic Network Handling Layer: Swift vs. C#

Navigating the world of software development, it’s intriguing to see how different programming languages handle similar tasks. I work day to day with Javascript, C#, Swift, Kotlin and SQL. Today, we’ll dissect the construction of a generic network handling layer using two of these: Swift and C# . We’ll focus on a simple HTTP GET request as our example. It’s a pickle!

1. System Architecture Differences:

Swift (iOS):

  • MVC Architecture: Swift in iOS predominantly uses the Model-View-Controller (MVC) pattern. The network layer often resides separately from these components to ensure reusability and separation of concerns.
  • Asynchronous Handling: Swift uses Grand Central Dispatch (GCD) or async/await (introduced in Swift 5.5) to handle asynchronous tasks, including network calls.

C# (.NET):

  • MVVM or MVC: Depending on whether you’re developing a WPF or an ASP.NET application, you might be using Model-View-ViewModel (MVVM) or MVC, respectively. The network handling layer often integrates within services or repositories.
  • Asynchronous Handling: C# uses the async and await keywords, leveraging the Task class for managing asynchronous operations.

2. Code Requirements and Implementation:

Swift:

Firstly, you’d want to integrate Apple’s Foundation framework.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
import Foundation

class NetworkHandler {
func get<T: Decodable>(url: String, completion: @escaping (Result<T, Error>) -> Void) {
guard let url = URL(string: url) else {
completion(.failure(NSError(domain: "", code: 400, userInfo: nil)))
return
}

URLSession.shared.dataTask(with: url) { data, _, error in
if let error = error {
completion(.failure(error))
return
}

if let data = data {
do {
let object = try JSONDecoder().decode(T.self, from: data)
completion(.success(object))
} catch {
completion(.failure(error))
}
}
}.resume()
}
}

C#:

For .NET applications, the HttpClient class within the System.Net.Http namespace is a boon.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
using System;
using System.Net.Http;
using System.Threading.Tasks;

public class NetworkHandler {
private readonly HttpClient _client = new HttpClient();

public async Task<T> Get<T>(string url) where T : class {
try {
var response = await _client.GetAsync(url);
response.EnsureSuccessStatusCode();

var responseBody = await response.Content.ReadAsStringAsync();
return JsonSerializer.Deserialize<T>(responseBody);
}
catch (HttpRequestException e) {
Console.WriteLine($"Request error: {e.Message}");
return null;
}
}
}

3. Highlighted Differences:

  • Dependency Management: Swift relies on URLSession, a part of the Foundation framework, while C# uses HttpClient from the System.Net.Http namespace.
  • Error Handling: Swift leverages the Result type for cleaner callback structures, whereas C# typically employs exceptions, which can be caught and managed.
  • Serialization: Swift’s JSONDecoder class is used for decoding, while C# has JsonSerializer for the same purpose.

While Swift and C# have distinct system architectures and handle asynchronous tasks slightly differently, the foundational logic for creating a network handling layer remains consistent: issue a request, await a response, handle errors, and parse the returned data. Understanding these nuances aids in smoother cross-platform development and better knowledge transfer across different tech stacks.