Skip to content

Instantly share code, notes, and snippets.

@coreyjv
Created November 19, 2015 01:21
Show Gist options
  • Save coreyjv/525e59c0332b31838b3d to your computer and use it in GitHub Desktop.
Save coreyjv/525e59c0332b31838b3d to your computer and use it in GitHub Desktop.
Handling empty and nil Strings in Swift compared to Java
public class NullEmptyStringDemo {
public static void main(String[] args) {
ApiClient apiClient = new ApiClient();
// throws IllegalArgumentException, but note that we don't have to catch it
apiClient.getItemAsync("", "");
}
public static class ApiClient {
// Simulate a similar call in ApiClient
public void getItemAsync(String id, String userId /* other parameters */) {
if ( id == null || id.isEmpty() ) {
throw new IllegalArgumentException("id");
}
if ( userId == null || userId.isEmpty() ) {
throw new IllegalArgumentException("userId");
}
// Do stuff
}
}
}
//: Playground - noun: a place where people can play
// An example error type that could be used when we need to throw an error an empty string
enum StringError: ErrorType {
case EmptyString(variableName: String)
}
//
// OPTION 1: ApiClient with guard statements
//
public class ApiClientWithThrows {
// A trimmed down version of the getItemAsync method from ApiClient
public func getItemAsync(id: String, userId: String /* Other params */) throws {
guard !id.isEmpty else {
throw StringError.EmptyString(variableName: "id")
}
guard !userId.isEmpty else {
throw StringError.EmptyString(variableName: "userId")
}
print("Users/\(id)/Items/\(userId)")
}
}
//
// OPTION 1: Simulate caller
//
public class Caller {
let apiClient = ApiClientWithThrows()
public func callApiClient(id: String, userId: String) {
do {
try apiClient.getItemAsync(id, userId: userId)
} catch StringError.EmptyString(let variableName) {
print("found empty string for \(variableName)")
} catch {
// This catch is needed if we do not want to declare 'callApiClient' with throws
print("Exhaust all options")
}
print("Other code")
}
}
let caller = Caller()
caller.callApiClient("", userId: "")
// Prints: found empty string for id
// Prints: Other code
//
// OPTION 2: ApiClient without guard statements, assuming Strings created with extension
//
public class ApiClientWithoutThrows {
// A trimmed down version of the getItemAsync method from ApiClient
public func getItemAsync(id: String, userId: String /* Other params */) {
print("Users/\(id)/Items/\(userId)")
}
}
//
// OPTION 2: Simulate caller using String extension with failable
//
extension String {
init!(nonEmptyString: String) {
if nonEmptyString.isEmpty { return nil }
self.init(nonEmptyString)
}
}
public class CallerWithString {
let apiClient = ApiClientWithoutThrows()
public func callApiClient(id: String, userId: String) {
apiClient.getItemAsync(id, userId: userId)
print("Other code")
}
}
let callerWithString = CallerWithString()
let id = String(nonEmptyString: "")
let userId = String(nonEmptyString: "dd")
// call fails with fatal error: unexpectedly found nil while unwrapping an Optional value
callerWithString.callApiClient(id, userId: userId)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment