Incorporação de GIFs em mensagens no app
Saiba como incorporar GIFs em mensagens no app para o Braze SDK.
About GIFs
Braze offers the ability to use a custom image library to display animated GIFs. Although the example below uses Glide, any image library that supports GIFs is compatible.
Integrating a custom image library
Step 1: Creating the image loader delegate
The Image Loader delegate must implement the following methods:
getInAppMessageBitmapFromUrl()
getPushBitmapFromUrl()
renderUrlIntoCardView()
renderUrlIntoInAppMessageView()
setOffline()
The integration example below is taken from the Glide integration sample app included with the Braze Android SDK.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
public class GlideBrazeImageLoader implements IBrazeImageLoader {
private static final String TAG = GlideBrazeImageLoader.class.getName();
private RequestOptions mRequestOptions = new RequestOptions();
@Override
public void renderUrlIntoCardView(Context context, Card card, String imageUrl, ImageView imageView, BrazeViewBounds viewBounds) {
renderUrlIntoView(context, imageUrl, imageView, viewBounds);
}
@Override
public void renderUrlIntoInAppMessageView(Context context, IInAppMessage inAppMessage, String imageUrl, ImageView imageView, BrazeViewBounds viewBounds) {
renderUrlIntoView(context, imageUrl, imageView, viewBounds);
}
@Override
public Bitmap getPushBitmapFromUrl(Context context, Bundle extras, String imageUrl, BrazeViewBounds viewBounds) {
return getBitmapFromUrl(context, imageUrl, viewBounds);
}
@Override
public Bitmap getInAppMessageBitmapFromUrl(Context context, IInAppMessage inAppMessage, String imageUrl, BrazeViewBounds viewBounds) {
return getBitmapFromUrl(context, imageUrl, viewBounds);
}
private void renderUrlIntoView(Context context, String imageUrl, ImageView imageView, BrazeViewBounds viewBounds) {
Glide.with(context)
.load(imageUrl)
.apply(mRequestOptions)
.into(imageView);
}
private Bitmap getBitmapFromUrl(Context context, String imageUrl, BrazeViewBounds viewBounds) {
try {
return Glide.with(context)
.asBitmap()
.apply(mRequestOptions)
.load(imageUrl).submit().get();
} catch (Exception e) {
Log.e(TAG, "Failed to retrieve bitmap at url: " + imageUrl, e);
}
return null;
}
@Override
public void setOffline(boolean isOffline) {
// If the loader is offline, then we should only be retrieving from the cache
mRequestOptions = mRequestOptions.onlyRetrieveFromCache(isOffline);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class GlideBrazeImageLoader : IBrazeImageLoader {
companion object {
private val TAG = GlideBrazeImageLoader::class.qualifiedName
}
private var mRequestOptions = RequestOptions()
override fun renderUrlIntoCardView(context: Context, card: Card, imageUrl: String, imageView: ImageView, viewBounds: BrazeViewBounds) {
renderUrlIntoView(context, imageUrl, imageView, viewBounds)
}
override fun renderUrlIntoInAppMessageView(context: Context, inAppMessage: IInAppMessage, imageUrl: String, imageView: ImageView, viewBounds: BrazeViewBounds) {
renderUrlIntoView(context, imageUrl, imageView, viewBounds)
}
override fun getPushBitmapFromUrl(context: Context, extras: Bundle, imageUrl: String, viewBounds: BrazeViewBounds): Bitmap? {
return getBitmapFromUrl(context, imageUrl, viewBounds)
}
override fun getInAppMessageBitmapFromUrl(context: Context, inAppMessage: IInAppMessage, imageUrl: String, viewBounds: BrazeViewBounds): Bitmap? {
return getBitmapFromUrl(context, imageUrl, viewBounds)
}
private fun renderUrlIntoView(context: Context, imageUrl: String, imageView: ImageView, viewBounds: BrazeViewBounds) {
Glide.with(context)
.load(imageUrl)
.apply(mRequestOptions)
.into(imageView)
}
private fun getBitmapFromUrl(context: Context, imageUrl: String, viewBounds: BrazeViewBounds): Bitmap? {
try {
return Glide.with(context)
.asBitmap()
.apply(mRequestOptions)
.load(imageUrl).submit().get()
} catch (e: Exception) {
Log.e(TAG, "Failed to retrieve bitmap at url: $imageUrl", e)
}
return null
}
override fun setOffline(isOffline: Boolean) {
// If the loader is offline, then we should only be retrieving from the cache
mRequestOptions = mRequestOptions.onlyRetrieveFromCache(isOffline)
}
}
Step 2: Setting the image loader delegate
The Braze SDK will use any custom image loader set with IBrazeImageLoader
. We recommend setting the custom image loader in a custom application subclass:
1
2
3
4
5
6
7
public class GlideIntegrationApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
Braze.getInstance(context).setImageLoader(new GlideBrazeImageLoader());
}
}
1
2
3
4
5
6
class GlideIntegrationApplication : Application() {
override fun onCreate() {
super.onCreate()
Braze.getInstance(context).imageLoader = GlideBrazeImageLoader()
}
}
Custom Image Loading with Jetpack Compose
To override image loading with Jetpack Compose, you can pass in a value to imageComposable
. This function will take a Card
and render the image and the modifiers needed. Alternatively, you can use customCardComposer
of ContentCardsList
to render the entire card.
In the following example, Glide’s Compose library is used for the cards listed in the imageComposable
function:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
ContentCardsList(
cardStyle = ContentCardStyling(
imageComposable = { card ->
when (card.cardType) {
CardType.CAPTIONED_IMAGE -> {
val captionedImageCard = card as CaptionedImageCard
GlideImage(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.run {
if (captionedImageCard.aspectRatio > 0) {
aspectRatio(captionedImageCard.aspectRatio)
} else {
this
}
},
contentScale = ContentScale.Crop,
model = captionedImageCard.url,
loading = placeholder(R.drawable.pushpin),
contentDescription = ""
)
}
CardType.IMAGE -> {
val imageOnlyCard = card as ImageOnlyCard
GlideImage(
modifier = Modifier
.fillMaxWidth()
.run {
if (imageOnlyCard.aspectRatio > 0) {
aspectRatio(imageOnlyCard.aspectRatio)
} else {
this
}
},
contentScale = ContentScale.Crop,
model = imageOnlyCard.url,
loading = placeholder(R.drawable.pushpin),
contentDescription = ""
)
}
CardType.SHORT_NEWS -> {
val shortNews = card as ShortNewsCard
GlideImage(
modifier = Modifier
.width(100.dp)
.height(100.dp),
model = shortNews.url,
loading = placeholder(R.drawable.pushpin),
contentDescription = ""
)
}
else -> Unit
}
}
)
)
Pré-requisitos
Antes de usar este recurso, você precisará integrar o SDK Swift Braze.
Integração de uma biblioteca de imagens personalizada
Etapa 1: Integrar SDWebImage
Integre o repositório SDWebImage em seu projeto Xcode.
Etapa 2: Criar um novo arquivo Swift
Em seu projeto Xcode, crie um novo arquivo chamado SDWebImageGIFViewProvider.swift
e importe o seguinte:
1
2
3
import UIKit
import BrazeUI
import SDWebImage
Etapa 3: Adicionar GIFViewProvider
Em seguida, adicione nossa amostra de SDWebImage GIFViewProvider
. Seu arquivo deve ser semelhante ao seguinte:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import UIKit
import BrazeUI
import SDWebImage
extension GIFViewProvider {
/// A GIF view provider using [SDWebImage](https://github.com/SDWebImage/SDWebImage) as a
/// rendering library.
public static let sdWebImage = Self(
view: { SDAnimatedImageView(image: image(for: $0)) },
updateView: { ($0 as? SDAnimatedImageView)?.image = image(for: $1) }
)
private static func image(for url: URL?) -> UIImage? {
guard let url else { return nil }
return url.pathExtension == "gif"
? SDAnimatedImage(contentsOfFile: url.path)
: UIImage(contentsOfFile: url.path)
}
}
Etapa 4: Modifique seu AppDelegate.swift
No site AppDelegate.swift
de seu projeto, adicione suporte a GIF aos componentes BrazeUI
usando GIFViewProvider
. Seu arquivo deve ser semelhante ao seguinte:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
import UIKit
import BrazeKit
import BrazeUI
@main
class AppDelegate: UIResponder, UIApplicationDelegate {
static var braze: Braze? = nil
func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
/* ... */
GIFViewProvider.shared = .sdWebImage
return true
}
}