Skip to content

Instantly share code, notes, and snippets.

@mnort9
Forked from coreyjv/NullEmptyStringDemo.java
Last active November 19, 2015 04:10
Show Gist options
  • Save mnort9/e250c11984d1c78a4ccb to your computer and use it in GitHub Desktop.
Save mnort9/e250c11984d1c78a4ccb 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)
//
// OPTION 3: Apiclient with empty check & generic error handler
//
public class ErrorHandler {
enum CustomErrorType {
case EmptyResponse
}
class func handleError(errorType: CustomErrorType) {
if errorType == CustomErrorType.EmptyResponse {
print("Safely handle error")
// Throw here, if somethong MUST be thrown to mimic Java api
}
}
}
public class ApiClientWithoutThrows {
// A trimmed down version of the getItemAsync method from ApiClient
public func getItemAsync(id: String, userId: String /* Other params */) {
if id.isEmpty || userId.isEmpty {
// Safely handle error
ErrorHandler.handleError(ErrorHandler.CustomErrorType.EmptyResponse)
return
}
print("Users/\(id)/Items/\(userId)")
}
}
public class Caller {
let apiClient = ApiClientWithoutThrows()
public func callApiClient(id: String, userId: String) {
apiClient.getItemAsync(id, userId: userId)
print("Other code")
}
}
let caller = Caller()
caller.callApiClient("", userId: "")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment