Search code examples
swifttry-catchnsjsonserializationdo-catch

How Properly to Get the Value Outside of the Scope Do-Catch (using Try) in Swift


I am trying to parse JSON data to a dictionary, for parsing I am using the separate method, and later would like to use the results (dictionary) for other operations in another method, not just to print it out as it is given in many examples online, e. g. here.

However, I cannot return the value since I was asked to insert return statement inside guard, but after the insertion getting "Non-void function should return a value".

The code looks the following way:

 func  extractJSONDictionaryFrom(JSONData:NSData) ->NSMutableDictionary
    {
        var dict = NSMutableDictionary()
        do {
        guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:NSJSONReadingOptions(rawValue: 0)) as? NSDictionary else {
            print("Not a Dictionary")
            return
        }
            dict = NSMutableDictionary(dictionary: JSON)
        }
        catch let JSONError as NSError {
            print("\(JSONError)")
        }
        print("The JSON is \(dict)")
        return dict
    }

The approach using throw is as well hardly useful since I need to handle throws in other methods when calling "extractJSONDictionaryFrom"


Solution

  • One option, is to let your method throw errors (whether the NSJSONSerialization error because JSON parsing failed entirely or your custom error if JSON parsing worked, but it wasn't a dictionary for some reason):

    func extractJSONDictionaryFrom(JSONData: NSData) throws -> NSMutableDictionary {
        guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:[]) as? NSDictionary else {
            throw NSError(domain: NSBundle.mainBundle().bundleIdentifier!, code: -1, userInfo: [NSLocalizedDescriptionKey : "Not a dictionary"])
        }
        return NSMutableDictionary(dictionary: JSON)
    }
    

    Or, another approach is to not have it throw errors, but just return nil if the conversion failed:

    func extractJSONDictionaryFrom(JSONData: NSData) -> NSMutableDictionary? {
        do {
            guard let JSON = try NSJSONSerialization.JSONObjectWithData(JSONData, options:NSJSONReadingOptions(rawValue: 0)) as? NSDictionary else {
                print("Not a Dictionary")
                return nil
            }
            return NSMutableDictionary(dictionary: JSON)
        } catch let JSONError as NSError {
            print("\(JSONError)")
            return nil
        }
    }
    

    I'd lean towards the former, but the latter works, too.