Appelium is a platform and a set of tools for improving the quality of mobile apps.
With just a simple shake, your users or beta testers can report bugs or send app feedback and the SDK will automatically capture an environment snapshot of your user's device including all console logs, network requests and even a video prior the bug happened which should provide you with enough details for debugging and fixing bugs faster.
Appelium also provides you with tools for capturing your Automated UI Tests executions in a separate SDK: AppeliumTests. This SDK automatically records videos of all of your UI Tests and supplements them with full console logs of your app and the tests runner.
For more info, visit Appelium.com.
To integrate AppeliumFeedback SDK into your Xcode project using Carthage, add this to your Cartfile:
binary "https://api.appelium.com/v1/sdkArchives/AppeliumFeedbackKit.json"
Then run:
carthage update --platform iOS --use-xcframeworksOnce it finishes, drag the AppeliumFeedbackKit.xcframework into your Xcode project.
Already using CocoaLumberjack for logging? Great! Appelium provides an extension which allows you to simply route all logging calls to it without changing a lot of code. Take a look at AppeliumCocoaLumberjack for integration instructions.
-
import AppeliumFeedbackKit framework header in your app delegate
import AppeliumFeedbackKit -
Add the following to your app delegate's
application:didFinishLaunchingWithOptions:method.AppeliumFeedback.start(apiKey: <#app token#>)
You can create an
app tokenor find an existing one here.
Appelium supports rich network log capturing. This include structured request and response information like:
- Headers
- Payload
- Duration
- Status codes
By default, this is enabled for all network requests which use URLSessionConfiguration .default and URLSessionConfiguration.ephemeral configuration.
If you wish to enable network logging for any other/custom session configuration you can simply call:
let urlSessionConfiguration = ... // Reference to your custom URLSessionConfiguration
AppeliumFeedback.enableLogging(for: urlSessionConfiguration)If you are already printing network requests information to the console using
NSLogor
You can enable custom request filters or implement full obfuscation.
AppeliumFeedback.networkRequestObfuscationHandler = self
And then implement NetworkRequestObfuscationHandler:
func obfuscateNetworkRequest(_ originalRequest: NetworkRequest) -> NetworkRequest? {
return NetworkRequest(
url: originalRequest.url, // Additionally you can remove query params, path, port etc
httpMethod: originalRequest.httpMethod, // You can modify it as well
headerFields: nil, // Remove all headers, or pass an `[HTTPHeaderField]` to keep/modify them
body: nil // Remove the body or modify it
)
}
func obfuscateNetworkResponse(_ originalResponse: NetworkResponse) -> NetworkResponse? {
return NetworkResponse(
url: originalResponse.url, // Additionally you can remove query params, path, port etc
statusCode: originalResponse.statusCode, // You can modify it as well
headerFields: nil, // Remove all headers, or pass an `[HTTPHeaderField]` to keep/modify them
body: nil, // Remove the body or modify it
error: originalResponse.error
)
}Appelium logs are similar to NSLog() and print(), but they have the added benefit of having different verbosity levels and can have associated domains. This lets you filter logs better when analyzing them in the Appelium dashboard.
Use Appelium logs through the following methods:
AppeliumFeedback.logVerbose("Verbose statement")
AppeliumFeedback.logInfo("Info statement")
AppeliumFeedback.logWarning("Warning statement")
AppeliumFeedback.logDebug("Debug statement")
AppeliumFeedback.logError("Error statement")all the logging levels allow you to pass an optional domain for even better granularity:
AppeliumFeedback.logError("Transaction failed", domain: "Payment")If you wish to upload additional files which will be attached to each bug report, you can do that by setting:
AppeliumFeedback.bugReportingDelegate = self
And then implement BugReportingDelegate:
func additionalBugReportAttachments() -> [BugReportAttachment] {
return [
.init(fileName: "db_dump.sqlite", data: FileManager().contents(atPath: "db/main.sqlite")!),
.init(fileName: "logs.txt", data: FileManager().contents(atPath: "logs/additional.txt")!),
]
}
You can upload up to 3 files with each bug report.