Skip to content

Commit

Permalink
Merge branch 'SK2-clean' into develop
Browse files Browse the repository at this point in the history
* SK2-clean:
  Updated with comments
  Minor change
  Final version
  Version for release without custom timers
  Draft, pending Java and RN
  Described web part, pending SDK part
  • Loading branch information
Lutik-sun committed Nov 20, 2024
2 parents a0bc15a + 0087879 commit b48ca63
Show file tree
Hide file tree
Showing 19 changed files with 480 additions and 138 deletions.
81 changes: 81 additions & 0 deletions versioned_docs/version-3.0/android-present-paywalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -191,9 +191,90 @@ ViewCompat.setOnApplyWindowInsetsListener(paywallView, (view, insets) -> {
return insets;
});
```
</TabItem>
</Tabs>

## Use developer-defined timer

To use developer-defined timers in your mobile app, create a `timerResolver` object—a dictionary or map that pairs custom timers with the string values that will replace them when the paywall is rendered. Here's an example:

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin
import java.util.Calendar
import java.util.Date
import java.util.TimeZone

...

val customTimers = mapOf(
"CUSTOM_TIMER_NY" to Calendar.getInstance(TimeZone.getDefault()).apply { set(2025, 0, 1) }.time, // New Year 2025
)
val timerResolver = AdaptyUiTimerResolver { timerId ->
customTimers.getOrElse(timerId, { Date(System.currentTimeMillis() + 3600 * 1000L) /* in 1 hour */ } )
}
```

</TabItem>
<TabItem value="java" label="Java" default>

```JAVA
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

...

Map<String, Date> customTimers = new HashMap<>();
customTimers.put(
"CUSTOM_TIMER_NY",
new Calendar.Builder().setTimeZone(TimeZone.getDefault()).setDate(2025, 0, 1).build().getTime()
);
AdaptyUiTimerResolver timerResolver = new AdaptyUiTimerResolver() {
@NonNull
@Override
public Date timerEndAtDate(@NonNull String timerId) {
Date date = customTimers.get(timerId);
return date != null ? date : new Date(System.currentTimeMillis() + 3600 * 1000L); /* in 1 hour */
}
};
```

</TabItem>

</Tabs>

In this example, `CUSTOM_TIMER_NY` is the **Timer ID** of the developer-defined timer you set in the Adapty dashboard. The `timerResolver` ensures your app dynamically updates the timer with the correct value—like `13d 09h 03m 34s` (calculated as the timer’s end time, such as New Year’s Day, minus the current time).

## Use custom tags

To use custom tags in your mobile app, create a `tagResolver` object—a dictionary or map that pairs custom tags with the string values that will replace them when the paywall is rendered. Here's an example:

<Tabs>
<TabItem value="kotlin" label="Kotlin" default>

```kotlin
val customTags = mapOf("USERNAME" to "John")
val tagResolver = AdaptyUiTagResolver { tag -> customTags[tag] }
```

</TabItem>
<TabItem value="java" label="Java" default>

```java
Map<String, String> customTags = new HashMap<>();
customTags.put("USERNAME", "John");
AdaptyUiTagResolver tagResolver = customTags::get;
```

</TabItem>
</Tabs>

In this example, `USERNAME` is a custom tag you entered in the Adapty dashboard as `<USERNAME/>`. The `tagResolver` ensures that your app dynamically replaces this custom tag with the specified value—like `John`.

We recommend creating and populating the `tagResolver` right before presenting your paywall. Once it's ready, pass it to the AdaptyUI method you use for presenting the paywall.

## Change paywall loading indicator color

You can override the default color of the loading indicator in the following way:
Expand Down
4 changes: 2 additions & 2 deletions versioned_docs/version-3.0/fetch-paywalls-and-products.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ do {
}
```
</TabItem>
<TabItem value="Swift-Callback" label="Swift" default>
<TabItem value="Swift-Callback" label="Swift-Callback" default>

```swift
Adapty.getPaywall(placementId: "YOUR_PLACEMENT_ID", locale: "en") { result in
Expand Down Expand Up @@ -162,7 +162,7 @@ do {
}
```
</TabItem>
<TabItem value="Swift-Callback" label="Swift" default>
<TabItem value="Swift-Callback" label="Swift-Callback" default>

```swift
Adapty.getPaywallProducts(paywall: paywall) { result in
Expand Down
31 changes: 30 additions & 1 deletion versioned_docs/version-3.0/flutter-present-paywalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,33 @@ try {
} catch (e) {
// handle the error
}
```
```

## Using developer-defined timers

To use developer-defined timers in your mobile app, create a `timerResolver` object—a dictionary or map that pairs custom timers with the string values that will replace them when the paywall is rendered. Here's an example:

```typescript title="Flutter"
try {
final view = await AdaptyUI().createPaywallView(
paywall: paywall,
customTags: ...,
customTimers: {
'CUSTOM_TIMER_6H': DateTime.now().add(const Duration(seconds: 3600 * 6)),
'CUSTOM_TIMER_NY': DateTime(2025, 1, 1), // New Year 2025
},
preloadProducts: ...,
);
} on AdaptyError catch (e) {
// handle the error
} catch (e) {
// handle the error
}
```

In this example, `CUSTOM_TIMER_NY` and `CUSTOM_TIMER_6H` are the **Timer ID**s of developer-defined timers you set in the Adapty Dashboard. The `timerResolver` ensures your app dynamically updates each timer with the correct value—for example:

- `CUSTOM_TIMER_NY`: The time remaining until the timer’s end, such as New Year’s Day.
- `CUSTOM_TIMER_6H`: The time left in a 6-hour period that started when the user opened the paywall.

--->
115 changes: 89 additions & 26 deletions versioned_docs/version-3.0/get-pb-paywalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ do {
}
```
</TabItem>
<TabItem value="Swift-Callback" label="Swift" default>
<TabItem value="Swift-Callback" label="Swift-Callback" default>

```swift
Adapty.getPaywall(placementId: "YOUR_PLACEMENT_ID", locale: "en") { result in
Expand Down Expand Up @@ -181,18 +181,52 @@ guard paywall.hasViewConfiguration else {
}

do {
guard paywall.hasViewConfiguration else {
// use your custom logic
return
}

let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(forPaywall: paywall)

let paywallConfiguration = try await AdaptyUI.getPaywallConfiguration(
forPaywall: paywall,
products: products,
observerModeResolver: <AdaptyObserverModeResolver>, // only for Observer Mode
tagResolver: <AdaptyTagResolver>,
timerResolver: <AdaptyTimerResolver>
)
// use loaded configuration
} catch {
// handle the error
}
```
Parameters:

| Parameter | Presence | Description |
| :----------------------- | :------------- | :----------------------------------------------------------- |
| **paywall** | required | An `AdaptyPaywall` object to obtain a controller for the desired paywall. |
| **loadTimeout** | default: 5 sec | <p>This value limits the timeout for this method. If the timeout is reached, cached data or local fallback will be returned.</p><p></p><p>Note that in rare cases this method can timeout slightly later than specified in `loadTimeout`, since the operation may consist of different requests under the hood.</p> |
| **products** | optional | Provide an array of `AdaptyPaywallProducts` to optimize the display timing of products on the screen. If `nil` is passed, AdaptyUI will automatically fetch the necessary products. |
| **observerModeResolver** | optional | The `AdaptyObserverModeResolver` object you've implemented in the previous step |
| **tagResolver** | optional | Define a dictionary of custom tags and their resolved values. Custom tags serve as placeholders in the paywall content, dynamically replaced with specific strings for personalized content within the paywall. Refer to [Custom tags in paywall builder](custom-tags-in-paywall-builder) topic for more details. |
| **timerResolver** | optional | To use custom timers in your mobile app, create an object that follows the `AdaptyTimerResolver` protocol. This object defines how each custom timer should be rendered. If you prefer, you can use a `[String: Date]` dictionary directly, as it already conforms to this protocol. |

## Use developer-defined timers

To use custom timers in your mobile app, create an object that conforms to the `AdaptyTimerResolver` protocol. This object should provide information about how to render each custom timer. Note that the `[String: Date]` structure already conforms to this protocol, so you can simply pass a dictionary. Here’s an example:

```Swift
@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
func timerEndAtDate(for timerId: String) -> Date {
switch timerId {
case "CUSTOM_TIMER_6H":
Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
case "CUSTOM_TIMER_NY":
Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
default:
Date(timeIntervalSinceNow: 3600.0) // 1 hour
}
}
}
```

- `CUSTOM_TIMER_NY`: The time remaining until the timer’s end, such as New Year’s Day.
- `CUSTOM_TIMER_6H`: The time left in a 6-hour period that started when the user opened the paywall.

</TabItem>
<TabItem value="kotlin" label="Kotlin" default>

Expand All @@ -215,6 +249,17 @@ AdaptyUI.getViewConfiguration(paywall) { result ->
}
}
```
Parameters:

| Parameter | Presence | Description |
| :----------------------- | :------------- | :----------------------------------------------------------- |
| **paywall** | required | An `AdaptyPaywall` object to obtain a controller for the desired paywall. |
| **loadTimeout** | default: 5 sec | <p>This value limits the timeout for this method. If the timeout is reached, cached data or local fallback will be returned.</p><p></p><p>Note that in rare cases this method can timeout slightly later than specified in `loadTimeout`, since the operation may consist of different requests under the hood.</p> |
| **products** | optional | Provide an array of `AdaptyPaywallProducts` to optimize the display timing of products on the screen. If `nil` is passed, AdaptyUI will automatically fetch the necessary products. |
| **observerModeResolver** | optional | The `AdaptyObserverModeResolver` object you've implemented in the previous step |
| **tagResolver** | optional | Define a dictionary of custom tags and their resolved values. Custom tags serve as placeholders in the paywall content, dynamically replaced with specific strings for personalized content within the paywall. Refer to [Custom tags in paywall builder](custom-tags-in-paywall-builder) topic for more details. |
| **timerResolver** | optional | To use custom timers in your mobile app, create an object that follows the `AdaptyTimerResolver` protocol. This object defines how each custom timer should be rendered. If you prefer, you can use a `[String: Date]` dictionary directly, as it already conforms to this protocol. |

</TabItem>
<TabItem value="java" label="Java" default>

Expand All @@ -239,16 +284,41 @@ AdaptyUI.getViewConfiguration(paywall, result -> {
<TabItem value="Flutter" label="Flutter" default>

```javascript
import 'package:adapty_ui_flutter/adapty_ui_flutter.dart';
import 'package:adapty_flutter/adapty_flutter.dart';

try {
final view = await AdaptyUI().createPaywallView(paywall: paywall);
final view = await AdaptyUI().createPaywallView(
paywall: paywall,
customTags: {
'CUSTOM_TAG_NAME': 'John',
},
customTimers: {
'CUSTOM_TIMER_6H': DateTime.now().add(const Duration(seconds: 3600 * 6)),
'CUSTOM_TIMER_NY': DateTime(2025, 1, 1), // New Year 2025
},
preloadProducts: preloadProducts,
);
} on AdaptyError catch (e) {
// handle the error
} catch (e) {
// handle the error
}
```
Parameters:
| Parameter | Presence | Description |
| :---------------- | :------------- | :----------------------------------------------------------- |
| **paywall** | required | An `AdaptyPaywall` object to obtain a controller for the desired paywall. |
| **loadTimeout** | default: 5 sec | <p>This value limits the timeout for this method. If the timeout is reached, cached data or local fallback will be returned.</p><p></p><p>Note that in rare cases this method can timeout slightly later than specified in `loadTimeout`, since the operation may consist of different requests under the hood.</p> |
| **products** | optional | Provide an array of `AdaptyPaywallProducts` to optimize the display timing of products on the screen. If `nil` is passed, AdaptyUI will automatically fetch the necessary products. |
| **tagResolver** | optional | Define a dictionary of custom tags and their resolved values. Custom tags serve as placeholders in the paywall content, dynamically replaced with specific strings for personalized content within the paywall. Refer to [Custom tags in paywall builder](custom-tags-in-paywall-builder) topic for more details. |
| **timerResolver** | optional | To use custom timers in your mobile app, create an object that follows the `AdaptyTimerResolver` protocol. This object defines how each custom timer should be rendered. If you prefer, you can use a `[String: Date]` dictionary directly, as it already conforms to this protocol. |
In the example above, `CUSTOM_TIMER_NY` and `CUSTOM_TIMER_6H` are the **Timer ID**s of developer-defined timers you set in the Adapty Dashboard. The `timerResolver` ensures your app dynamically updates each timer with the correct value—for example:
- `CUSTOM_TIMER_NY`: The time remaining until the timer’s end, such as New Year’s Day.
- `CUSTOM_TIMER_6H`: The time left in a 6-hour period that started when the user opened the paywall.
</TabItem>
<TabItem value="React Native" label="React Native (TS)" default>
Expand All @@ -265,30 +335,23 @@ if (paywall.hasViewConfiguration) {
//use your custom logic
}
```
</TabItem>
<TabItem value="Unity" label="Unity" default>
Parameters:
| Parameter | Presence | Description |
| :---------------- | :------------- | :----------------------------------------------------------- |
| **paywall** | required | An `AdaptyPaywall` object to obtain a controller for the desired paywall. |
| **loadTimeout** | default: 5 sec | <p>This value limits the timeout for this method. If the timeout is reached, cached data or local fallback will be returned.</p><p></p><p>Note that in rare cases this method can timeout slightly later than specified in `loadTimeout`, since the operation may consist of different requests under the hood.</p> |
| **products** | optional | Provide an array of `AdaptyPaywallProducts` to optimize the display timing of products on the screen. If `nil` is passed, AdaptyUI will automatically fetch the necessary products. |
| **tagResolver** | optional | Define a dictionary of custom tags and their resolved values. Custom tags serve as placeholders in the paywall content, dynamically replaced with specific strings for personalized content within the paywall. Refer to [Custom tags in paywall builder](custom-tags-in-paywall-builder) topic for more details. |
| **timerResolver** | optional | To use custom timers in your mobile app, create an object that follows the `AdaptyTimerResolver` protocol. This object defines how each custom timer should be rendered. If you prefer, you can use a `[String: Date]` dictionary directly, as it already conforms to this protocol. |
```csharp
AdaptyUI.CreatePaywallView(paywall, preloadProducts: true, (view, error) => {
// use the view
});
```
</TabItem>
</Tabs>
:::note
If you are using multiple languages, learn how to add a [Paywall builder localization](add-paywall-locale-in-adapty-paywall-builder) and how to use locale codes correctly [here](localizations-and-locale-codes).
:::
| Parameter | Presence | Description |
| :----------------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **paywall** | required | An `AdaptyPaywall` object to obtain a controller for the desired paywall. |
| **loadTimeout** | default: 5 sec | <p>This value limits the timeout for this method. If the timeout is reached, cached data or local fallback will be returned.</p><p></p><p>Note that in rare cases this method can timeout slightly later than specified in `loadTimeout`, since the operation may consist of different requests under the hood.</p> |
| **products** | optional | Provide an array of `AdaptyPaywallProducts` to optimize the display timing of products on the screen. If `nil` is passed, AdaptyUI will automatically fetch the necessary products. |
| **observerModeResolver** | optional | The `AdaptyObserverModeResolver` object you've implemented in the previous step |
| **tagResolver** | optional | Define a dictionary of custom tags and their resolved values. Custom tags serve as placeholders in the paywall content, dynamically replaced with specific strings for personalized content within the paywall. Refer to [Custom tags in paywall builder](custom-tags-in-paywall-builder) topic for more details. |
| **timerResolver** | optional | TODO: |

Once you have successfully loaded the paywall and its paywall configuration, you can proceed to presenting the paywall in your mobile app.
Expand Down
4 changes: 2 additions & 2 deletions versioned_docs/version-3.0/identifying-users.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ do {
}
```
</TabItem>
<TabItem value="Swift-Callback" label="Swift" default>
<TabItem value="Swift-Callback" label="Swift-Callback" default>

```swift
Adapty.identify("YOUR_USER_ID") { error in
Expand Down Expand Up @@ -143,7 +143,7 @@ do {
}
```
</TabItem>
<TabItem value="Swift-Callback" label="Swift" default>
<TabItem value="Swift-Callback" label="Swift-Callback" default>

```swift
Adapty.logout { error in
Expand Down
Binary file modified versioned_docs/version-3.0/img/e83e891-timer.webp
Binary file not shown.
24 changes: 0 additions & 24 deletions versioned_docs/version-3.0/ios-present-paywalls.md
Original file line number Diff line number Diff line change
Expand Up @@ -118,27 +118,3 @@ Closure parameters:

Refer to the [iOS - Handling events](ios-handling-events) topic for other closure parameters.

## Use developer-defined timers

To use custom timers in your mobile app, create a `timerResolver` object—a dictionary or map that pairs custom timers with the string values that will replace them when the paywall is rendered. Here's an example:

```Swift
@MainActor
struct AdaptyTimerResolverImpl: AdaptyTimerResolver {
func timerEndAtDate(for timerId: String) -> Date {
switch timerId {
case "CUSTOM_TIMER_6H":
Date(timeIntervalSinceNow: 3600.0 * 6.0) // 6 hours
case "CUSTOM_TIMER_NY":
Calendar.current.date(from: DateComponents(year: 2025, month: 1, day: 1)) ?? Date(timeIntervalSinceNow: 3600.0)
default:
Date(timeIntervalSinceNow: 3600.0) // 1 hour
}
}
}
```

In this example, `CUSTOM_TIMER_NY` and `CUSTOM_TIMER_6H` are the IDs of custom timers you set in the Adapty Dashboard. The `timerResolver` ensures your app dynamically updates each timer with the correct value—for example:

- `CUSTOM_TIMER_NY`: The time remaining until the timer’s end, such as New Year’s Day.
- `CUSTOM_TIMER_6H`: The time left in a 6-hour period that started when the user opened the paywall.
Loading

0 comments on commit b48ca63

Please sign in to comment.