Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: Cio client interface #25

Merged
merged 6 commits into from
Oct 7, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,9 @@ dependencies {
implementation Dependencies.androidxCoreKtx
implementation Dependencies.materialComponents

implementation Dependencies.coroutinesCore
implementation Dependencies.coroutinesAndroid

androidTestImplementation Dependencies.junit4
testImplementation Dependencies.junit4
testImplementation Dependencies.androidxTestJunit
Expand Down
14 changes: 10 additions & 4 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.customer.example">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:name=".MainApplication"
android:allowBackup="true"
android:usesCleartextTraffic="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:name=".MainApplication"
android:theme="@style/Theme.App">
<activity android:name="io.customer.example.MainActivity"
android:exported="false">
android:theme="@style/Theme.App"
tools:targetApi="m">
<activity
android:name="io.customer.example.MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />

Expand Down
38 changes: 37 additions & 1 deletion app/src/main/java/io/customer/example/MainActivity.kt
Original file line number Diff line number Diff line change
@@ -1,13 +1,49 @@
package io.customer.example

import android.os.Bundle
import android.util.Log
import androidx.appcompat.app.AppCompatActivity
import io.customer.base.data.ErrorResult
import io.customer.base.data.Success
import io.customer.sdk.CustomerIo
import io.customer.sdk.data.model.IdentityAttributeValue
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch

class MainActivity : AppCompatActivity() {

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)

setContentView(R.layout.activity_main)
// there are two ways to identify customer

// 1st way
makeSynchronousRequest()

// 2nd way
makeAsynchronousRequest()
}

private fun makeAsynchronousRequest() {
CustomerIo.instance()
.identify(
"identifier",
attributes = mapOf("email" to IdentityAttributeValue.StringAttribute("sample@email.com"))
).enqueue {
when (it) {
is ErrorResult -> Log.v("ErrorResult", it.error.cause.toString())
is Success -> Log.v("Success", "Success")
}
}
}

private fun makeSynchronousRequest() {
CoroutineScope(Dispatchers.IO).launch {
when (val result = CustomerIo.instance().identify("testcoo@email.com").execute()) {
is ErrorResult -> Log.v("ErrorResult", result.error.cause.toString())
is Success -> Log.v("Success", "Success")
}
}
}
}
13 changes: 12 additions & 1 deletion app/src/main/java/io/customer/example/MainApplication.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
package io.customer.example

import android.app.Application
import io.customer.sdk.CustomerIo

class MainApplication : Application()
class MainApplication : Application() {

override fun onCreate() {
super.onCreate()
CustomerIo.Builder(
siteId = "YOUR-SITE-ID",
apiKey = "YOUR-API-KEY",
appContext = this
).build()
}
}
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package io.customer.base.comunication

import androidx.annotation.WorkerThread
import io.customer.base.data.Result

/**
*
* [Call] can be used either by following ways:
* [execute]: Calls may be executed synchronously or asynchronously with [enqueue]
* [Action] can be used by following ways:
* [execute]: Action may be executed synchronously or asynchronously with [enqueue]
*
*/
public interface Call<T : Any> {
interface Action<T : Any> {
/**
* Synchronously send the request and return its response. Only call this from a background thread.
*/
Expand All @@ -18,25 +19,25 @@ public interface Call<T : Any> {
/**
* Asynchronously send the request and notify callback of its response.
*/
public fun enqueue(callback: Callback<T>)
fun enqueue(callback: Callback<T>)

/**
* Executes the call asynchronously, on a background thread. Safe to call from the main
* thread.
*
* To get notified of the result and handle errors, use enqueue(callback) instead.
*/
public fun enqueue(): Unit = enqueue {}
fun enqueue(): Unit = enqueue {}

/**
* Cancels the execution of the call, if cancellation is supported for the operation.
*
* Note that calls can not be cancelled when running them with [execute].
*/
public fun cancel()
fun cancel()

public fun interface Callback<T : Any> {
public fun onResult(result: Result<T>)
fun interface Callback<T : Any> {
fun onResult(result: Result<T>)
}
}

2 changes: 1 addition & 1 deletion base/src/main/java/io/customer/base/data/Result.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ sealed class Result<T> {
}
}

data class Success<T>(val data: T, val responseModified: Boolean = true) : Result<T>() {
data class Success<T>(val data: T) : Result<T>() {
override fun get(): T = data
}

Expand Down
7 changes: 4 additions & 3 deletions base/src/main/java/io/customer/base/error/ErrorDetail.kt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package io.customer.base.error

public open class ErrorDetail(
public val message: String? = null,
public val cause: Throwable = Throwable()
open class ErrorDetail(
val message: String? = null,
val statusCode: StatusCode = StatusCode.Unknown,
val cause: Throwable = Throwable()
)
78 changes: 78 additions & 0 deletions base/src/main/java/io/customer/base/error/StatusCode.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
package io.customer.base.error

enum class StatusCode(val code: Int) {
Continue(100),
SwitchingProtocols(101),
Processing(102),

OK(200),
Created(201),
Accepted(202),
NonAuthoritativeInformation(203),
NoContent(204),
ResetContent(205),
PartialContent(206),
MultiStatus(207),
AlreadyReported(208),
IMUsed(226),

MultipleChoices(300),
MovedPermanently(301),
Found(302),
SeeOther(303),
NotModified(304),
UseProxy(305),
TemporaryRedirect(307),
PermanentRedirect(308),

BadRequest(400),
Unauthorized(401),
PaymentRequired(402),
Forbidden(403),
NotFound(404),
MethodNotAllowed(405),
NotAcceptable(406),
ProxyAuthenticationRequired(407),
RequestTimeout(408),
Conflict(409),
Gone(410),
LengthRequired(411),
PreconditionFailed(412),
PayloadTooLarge(413),
URITooLong(414),
UnsupportedMediaType(415),
RangeNotSatisfiable(416),
ExpectationFailed(417),
IAmATeapot(418),
MisdirectedRequest(421),
UnprocessableEntity(422),
Locked(423),
FailedDependency(424),
UpgradeRequired(426),
PreconditionRequired(428),
TooManyRequests(429),
RequestHeaderFieldsTooLarge(431),
UnavailableForLegalReasons(451),

InternalServerError(500),
NotImplemented(501),
BadGateway(502),
ServiceUnavailable(503),
GatewayTimeout(504),
HTTPVersionNotSupported(505),
VariantAlsoNegotiates(506),
InsufficientStorage(507),
LoopDetected(508),
NotExtended(510),
NetworkAuthenticationRequired(511),

Unknown(0);

// Custom description for the Error to describe the error that happened.
fun getMessage(): String {
return when (this) {
Unauthorized -> "HTTP request responded with 401. Configure the SDK with valid credentials."
else -> this.name
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ object Dependencies {
const val timber = "com.jakewharton.timber:timber:${Versions.TIMBER}"
const val robolectric = "org.robolectric:robolectric:${Versions.ROBOLECTRIC}"
const val retrofit = "com.squareup.retrofit2:retrofit:${Versions.RETROFIT}"
const val retrofitMoshiConverter = "com.squareup.retrofit2:converter-moshi:${Versions.RETROFIT}"
const val okhttp = "com.squareup.okhttp3:okhttp:${Versions.OKHTTP}"
const val okhttpLoggingInterceptor = "com.squareup.okhttp3:logging-interceptor:${Versions.OKHTTP}"

Expand Down
1 change: 1 addition & 0 deletions buildSrc/src/main/kotlin/io.customer/android/Versions.kt
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,5 @@ object Versions {
internal const val ROBOLECTRIC = "4.6.1"
internal const val OKHTTP = "4.9.1"
internal const val RETROFIT = "2.9.0"

}
1 change: 1 addition & 0 deletions sdk/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ dependencies {
implementation Dependencies.coroutinesCore
implementation Dependencies.coroutinesAndroid
implementation Dependencies.retrofit
implementation Dependencies.retrofitMoshiConverter
implementation Dependencies.okhttpLoggingInterceptor

testImplementation Dependencies.androidxTestJunit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package io.customer.sdk

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.*
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

Expand Down
7 changes: 7 additions & 0 deletions sdk/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="io.customer.sdk">

<uses-permission android:name="android.permission.INTERNET" />

<application
android:hardwareAccelerated="true"
android:networkSecurityConfig="@xml/network_security_config"
tools:targetApi="n" />
</manifest>
Loading