Miscellaneous

Error Handling


ApiError is a superclass for the standard iOS class for error handling - NSError.

It’s designed to help you handle errors within your application. It provides details about failures in communication with the Synerise API.

This error is normally returned from the SDK methods that communicate with the Synerise API.

Type

You can check this by calling the getType() method that returns ApiErrorType.

SNRApiErrorType.Unknown

Returned when an unknown error occurs (for example, no response from server when expected).

SNRApiErrorTypeHttp

Returned when a request is executed, but something else goes wrong and an error code is returned (for example, 403).

SNRApiErrorTypeNetwork

Returned when a request fails to execute (for example, due to no Internet connection).

SNRApiErrorTypeUnauthorizedSession

Returned when a session is invalid for a given request.

HTTP code

You can check this by calling the getHttpCode() method.

The method returns the HTTP status code. If a request failed to execute (for example, due to no Internet connection), this value is -1.

Body

You can check this by calling the getBody() method.

Returns a description parsed from the response’s error cause list.

Note: May be null if the error type is different than ApiErrorTypeHttp.

Errors

You can check this by getting the errors property.

Returns a list of Error objects that describe failure causes from the Synerise API.

Custom attributes provided in the userInfo property:

Attribute Customer Info key Description
CODE code Code corresponding to the error that occurred from the Synerise API
FIELD field Name of the argument that didn’t pass validation
PATH path Path of the argument that didn’t pass validation
MESSAGE message Description of the error
REJECTED VALUE rejectedValue Value that was rejected

Example

When you receive an error from the SDK method, you can check if the error is an ApiError instance and then you can work with the properties described above.

func presentAlert(title: String, message: String) {
	let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert)
	let okAction = UIAlertAction(title: "OK", style: .default, handler: nil)
	alertController.addAction(okAction)
	self.present(alertController, animated: true, completion: nil)
}
func showErrorInfo(_ error: NSError, title: String = "Error", debug: Bool = true) {
	if let apiError = error as? SNRApiError {
		var apiErrorDebugInfo: String = String()
		let apiErrorType: SNRApiErrorType = apiError.getType()
		switch (apiErrorType) {
		case .network: apiErrorDebugInfo.append("NETWORK ERROR")
		case .unauthorizedSession: apiErrorDebugInfo.append("UNAUTHORIZED SESSION ERROR")
		case .http: apiErrorDebugInfo.append("HTTP ERROR: \(apiError.getHttpCode())")
		case .unknown: apiErrorDebugInfo.append("UNKNOWN ERROR")
		}
		apiErrorDebugInfo.append("\n\n")
		apiErrorDebugInfo.append("\(apiError.localizedDescription)")
		// first approach
		if let apiErrorCauses = apiError.errors, !apiErrorCauses.isEmpty {
			apiErrorDebugInfo.append("\n\n")
			apiErrorCauses.forEach({ (error) in
				let apiErrorCause: NSError = error as NSError
				var apiErrorCauseString: String = String()
				apiErrorCauseString.append("CODE: \(apiErrorCause.code)")
				apiErrorCauseString.append("\n")
				apiErrorCauseString.append("MESSAGE: \(apiErrorCause.localizedDescription)")
				apiErrorDebugInfo.append(apiErrorCauseString)
				apiErrorDebugInfo.append("\n\n")
			})
		}
		// second approach
		// apiErrorDebugInfo.append("\n\n")
		//
		// let apiErrorCauseString: String = apiError.getBody() ?? ""
		// apiErrorDebugInfo.append(apiErrorCauseString)
		self.presentAlert(title: "Debug SNRApiError", message: apiErrorDebugInfo)
		if debug {
			DebugUtils.print("\(title) \(apiError.code) \(apiError.localizedDescription)")
		}
		return
	}
	if debug {
		DebugUtils.print("\(title) \(error.code) \(error.localizedDescription)")
	}
}
func signIn(email: String, password: String) {
	Client.signIn(email: email, password: password, deviceId: nil, success: { (success) in
		//...
	}, failure: { (error) in
		self.showErrorInfo(error as NSError)
	})
}

Crash Handling


Crash handler allows you to find customers whose mobile applications crashed and to see information about that in their customer cards in Profiles as events.

You can enable crash handling for Synerise SDK by using the Synerise.setCrashHandlingEnabled(_:) method.

Synerise.setCrashHandlingEnabled(true)

When it is enabled, SyneriseSDK passes info about customer application crashes as dedicated events to the backend (client.applicationCrashed is the action parameter of those events).

Cache Manager


CacheManager provides you with an easy-to-use option to retrieve cached data (if available) if communication problems with the backend occur.

If a request fails, you can obtain the cached data by using the get(_:) method.

Currently, our CacheManager supports the caching of the ClientAccountInformation model after a successful Client.getAccount(success:failure:) method response.

let clientAccountInformation: ClientAccountInformation? = CacheManager.get(ClientAccountInformation.self) as? ClientAccountInformation

if clientAccountInformation != nil {
	// cached data is available
}

SDK Commands


Get Location

Any time you send the below frame from app.synerise.com, the SDK can send the AppearedInLocationEvent event automatically.

"data": {
    "issuer": "Synerise",
    "message-type": "dynamic-content",
    "content-type": "silent-sdk-command",
    "content": {
        "class_name": "com.synerise.sdk.injector.Injector",
        "method_name": "GET_LOCATION",
        "method_parameters": []
    }
}

To enable this functionality, your application needs permission to use localization services.

Check Apple Developer - CoreLocation for details.

You also need to configure the following settings:

Synerise.settings.tracker.locationAutomatic = true

Custom Implementation

You can specify additional custom actions or send a suitable event by yourself. You need to implement the optional method from TrackerDelegate.

//MARK: - TrackerDelegate

extension ApplicationController: TrackerDelegate {
	func snr_locationUpdateRequired() -> Void {
		// your custom code for Silent Localization Command
        // get your coordinates
        let latitude: CLLocationDegrees = CLLocationDegrees(0.0)
        let longitude: CLLocationDegrees = CLLocationDegrees(0.0)
        let location: CLLocation = CLLocation(latitude: latitude, longitude: longitude)

        let event: AppearedInLocationEvent = AppearedInLocationEvent(label: "LABEL", location: location)

        Tracker.send(event)
	}
}
Note: If you want to manage location command by yourself only - set Synerise.settings.tracker.locationAutomatic to false. Then, after a silent command is received, only your custom implementation is invoked.

Sign Out

Any time you send the below frame from app.synerise.com, the SDK signs out the customer.

"data": {
    "issuer": "Synerise",
    "message-type": "dynamic-content",
    "content-type": "silent-sdk-command",
    "content": {
        "class_name": "com.synerise.sdk.injector.Injector",
        "method_name": "SIGN_OUT",
        "method_parameters": []
    }
}

😕

We are sorry to hear that

Thank you for helping improve out documentation. If you need help or have any questions, please consider contacting support.

😉

Awesome!

Thank you for helping improve out documentation. If you need help or have any questions, please consider contacting support.

Close modal icon Placeholder alt for modal to satisfy link checker