Created
November 19, 2015 01:21
-
-
Save coreyjv/525e59c0332b31838b3d to your computer and use it in GitHub Desktop.
Handling empty and nil Strings in Swift compared to Java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 | |
| } | |
| } | |
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //: 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