アプリ内メッセージにGIFを埋め込む
Braze SDK のアプリ内メッセージにGIF を埋め込む方法について説明します。
GIFについて
Braze はカスタム画像ライブラリーを使用してアニメーション GIF を表示する機能を提供しています。以下の例では Glide を使用していますが、GIF をサポートする画像ライブラリーであればどれでも互換性があります。
カスタム画像ライブラリーの統合
ステップ 1: 画像ローダーデリゲートの作成
画像ローダーデリゲートは、以下のメソッドを実装する必要があります。
getInAppMessageBitmapFromUrl()getPushBitmapFromUrl()renderUrlIntoCardView()renderUrlIntoInAppMessageView()setOffline()
以下の統合例は、Braze Android SDK に含まれる Glide 統合サンプルアプリから取得したものです。
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
58
import com.braze.support.BrazeLogger;
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);
}
@Override
public void renderUrlIntoInAppMessageView(Context context, IInAppMessage inAppMessage, String imageUrl, ImageView imageView, BrazeViewBounds viewBounds) {
renderUrlIntoView(context, imageUrl, imageView);
}
@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) {
imageView.post(() -> {
try {
Glide.with(context)
.load(imageUrl)
.apply(mRequestOptions)
.into(imageView);
} catch (Exception e) {
BrazeLogger.e(TAG, "Failed to render URL into view: " + imageUrl, e);
}
});
}
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
49
50
51
52
53
54
55
56
import com.braze.support.BrazeLogger
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)
}
override fun renderUrlIntoInAppMessageView(context: Context, inAppMessage: IInAppMessage, imageUrl: String, imageView: ImageView, viewBounds: BrazeViewBounds) {
renderUrlIntoView(context, imageUrl, imageView)
}
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) {
imageView.post {
try {
Glide.with(context)
.load(imageUrl)
.apply(mRequestOptions)
.into(imageView)
} catch (e: Exception) {
BrazeLogger.e(TAG, "Failed to render URL into view: $imageUrl", e)
}
}
}
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)
}
}
ステップ 2: 画像ローダーデリゲートの設定
Braze SDK は、IBrazeImageLoader で設定されたカスタム画像ローダーを使用します。カスタムアプリケーションサブクラスでカスタム画像ローダーを設定することをお勧めします。
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()
}
}
Jetpack Compose によるカスタム画像の読み込み
Jetpack Compose で画像の読み込みをオーバーライドするには、imageComposable に値を渡します。この関数は Card を受け取り、必要な画像とモディファイアをレンダリングします。または、ContentCardsList の customCardComposer を使用してカード全体をレンダリングすることもできます。
次の例では、imageComposable 関数にリストされているカードに Glide の Compose ライブラリーが使用されています。
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
}
}
)
)
前提条件
この機能を使う前に、Swift Braze SDKを統合する必要がある。
カスタムイメージライブラリの統合
ステップ 1: SDOAImageの統合
SDOBImageリポジトリをXコードプロジェクトに統合します。
ステップ 2:新しいSwift ファイルを作成する
Xコードプロジェクトで、SDWebImageGIFViewProvider.swiftという名前の新しいファイルを作成し、以下をインポートします。
1
2
3
import UIKit
import BrazeUI
import SDWebImage
ステップ 3:GIFViewProvider を追加する
次に、サンプルSDOAImage GIFViewProvider を追加します。ファイルは次のようになります。
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)
}
}
ステップ 4: 変更する AppDelegate.swift
プロジェクトのAppDelegate.swift で、BrazeUI コンポーネントにGIFViewProvider を使用してGIF サポートを追加します。ファイルは次のようになります。
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
}
}
GitHub でこのページを編集