플러터 앱에 광고를 넣어보자
카페자리에 배너 광고를 시범 도입하기로했다.
어려운 기능은 아니었지만, 꼭 짚어야 할 부분이
있어 포스팅으로 정리해보려한다.
순서
전체적인 흐름은 다음과 같다.
진행
애드몹 홈페이지에 들어가면 물 흐르듯
자연스럽게 할 수 있을 것이다.
앱 등록된 모습
광고단위(배너) 등록된 모습
한 가지 팁은 firebase에 project를 등록해
google analytics를 사용하고 있는 경우,
앱 > 앱설정 > 연결된 서비스 관리하기
로 이동해 firebase project와 연동하는 것이다.
안드로이드는 여기,
iOS는 여기에
자세한 설명이 나와있다.
다만 우리는 플러터로 진행할 예정이니,
안드로이드의 경우에는 AndroidManifest.xml 설정까지,
iOS의 경우에는 Info.plist 설정까지만 진행하고
sdk추가는 하지 않도록 하자.
이 부분이 사실 이 포스트를 쓰게된 이유이다.
지금까지 나는 flutter 3.16 버전을 쓰고 있었는데,
이상하게 안드로이드에서 배너광고를 넣을 경우
앱이 튕기는 에러가 발생했다.
버그에 일관성이 없어서 재현도 어렵고
원인도 찾기 어려운 버그였다.
에러 로그로 구글링해본 결과 가장
비슷한 현상은 이 블로그 포스팅과 같았다.
해결 방법은 그냥 flutter를 beta버전으로
업그레이드 하는것이다..
(beta버전이 내키지 않다면 downgrade도 방법이다)
// 터미널에서 실행
$ flutter channel beta
$ flutter upgrade
애드몹 사용을 도와주는 패키지는
google_mobile_ads라는 친구이다.
여기에서 버전을 확인하고 설치해주자.
../root/pubspec.yaml
dependencies:
flutter:
sdk: flutter
.
.
# google ad
google_mobile_ads: ^4.0.0
.
.
이후 터미널에서 flutter pub get 실행 또는
IDE에서 pub get을 실행해준다.
여기까지 잘 왔다면 코드 자체는 어렵지 않다.
여러가지 구현 방법이 있겠으나,
나는 AdManager class를 만들고
모든 banner ad들을
Singleton으로 관리해보았다.
먼저 ad_manager.dart 파일을
아래와같이 작성해주자.
import 'dart:io';
import 'package:google_mobile_ads/google_mobile_ads.dart';
class AdManager {
// singleton instance
static AdManager instance = AdManager();
// 스크린 별로 사용될 AdManagerBannerAd 객체들
AdManagerBannerAd? myCafeScreenBannerAd;
AdManagerBannerAd? challengeScreenBannerAd;
AdManagerBannerAd? myPageScreenBannerAd;
AdManagerBannerAd? shopScreenBannerAd;
AdManagerBannerAd? notificationScreenBannerAd;
AdManagerBannerAd? bottomFullSheetBannerAd;
AdManager({
this.myCafeScreenBannerAd,
this.challengeScreenBannerAd,
this.myPageScreenBannerAd,
this.shopScreenBannerAd,
this.notificationScreenBannerAd,
this.bottomFullSheetBannerAd
});
// AdManager 객체 초기화
factory AdManager.init() => instance = AdManager(
myCafeScreenBannerAd: _loadBannerAd(),
challengeScreenBannerAd: _loadBannerAd(),
myPageScreenBannerAd: _loadBannerAd(),
shopScreenBannerAd: _loadBannerAd(),
notificationScreenBannerAd: _loadBannerAd(),
bottomFullSheetBannerAd: _loadBannerAd(),
);
}
// AdManagerBannerAd 객체를 로드하는 함수
AdManagerBannerAd _loadBannerAd() {
const String androidBannerAdUnitId = '/6499/example/banner';
const String iosBannerAdUnitId = '/6499/example/banner';
String adUnitId = androidBannerAdUnitId;
if(Platform.isIOS) adUnitId = iosBannerAdUnitId;
return AdManagerBannerAd(
adUnitId: adUnitId,
request: const AdManagerAdRequest(),
sizes: [AdSize.banner],
listener: AdManagerBannerAdListener(),
)..load();
}
얼핏 봤을 때 복잡해 보일 수 있지만,
뜯어보면 배너광고가 들어갈 자리가 6개라
같은 로직을 여러번 써놓았을 뿐이다.
init을 통해 6개 스크린에 들어갈
banner ad들을 모두 로드하며
Singleton instance를 만든다.
_loadBannerAd 함수를 보면,
target 기기에 따라 다른
adUnitId를 적용하는 것을 볼 수 있다.
카페자리는 안드로이드 / iOS 두 가지 기종만
서비스하므로 위와같이 두 가지 케이스만
고려했는데, 다른 기기까지 타겟팅 한다면
이부분을 적당히 고쳐 쓰면 된다.
위 androidBannerAdUnitId와 iosBannerAdUnitId는
테스트용 광고단위 id이다.
실제 서비스할때는 1번에서 만든
광고단위의 id를 가져다 넣으면 된다.
마지막으로 재사용 가능한 Widget을 만들어주자.
AdManagerBannerAd객체를 파라미터로 받고,
기기의 가로사이즈를 전부 채우는
배너 광고 위젯을 만들 것이다.
full_width_banner_ad.dart 파일을
아래와 같이 작성해주자.
import 'package:flutter/widgets.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
class FullWidthBannerAd extends StatelessWidget {
final AdManagerBannerAd? bannerAd;
final double sidePadding;
const FullWidthBannerAd({
super.key,
required this.bannerAd,
this.sidePadding = 0
});
@override
Widget build(BuildContext context) {
if(bannerAd != none) {
return SizedBox(
width: MediaQuery.of(context).size.width - sidePadding * 2,
height: bannerAd!.sizes.first.height.toDouble(),
child: AdWidget(ad: bannerAd!)
);
} else {
return const SizedBox(width: 0, height: 0);
}
}
}
파라미터로 받은 AdManagerBannerAd가 null값이면
크기가 0인 SizedBox를 return할 것이다.
또, 기본적으로 기기의 width를 배너의 width로 하되
sidePadding값을 입력해줄 경우 padding값만큼
width길이를 줄일 수 있도록 했다.
이제 준비는 끝났다.
바로 사용해보자.
../root/main.dart
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
.
.
// 광고 init
AdManager.init();
.
.
}
main에서 위처럼 AdManager instance를 init해준다.
이후에는 사용하고 싶은 곳으로 가서
다음과 같이 사용하면 된다.
@override
Widget build(BuildContext context) {
return Column(
children: [
.
.
// 패딩 적용
FullWidthBannerAd(
bannerAd: AdManager.instance.myCafeScreenBannerAd,
sidePadding: 10.0
),
.
.
]
);
}
@override
Widget build(BuildContext context) {
return Column(
children: [
.
.
// 패딩x (배너width = deviceWidth)
FullWidthBannerAd(bannerAd: AdManager.instance.shopScreenBannerAd),
.
.
]
);
}
완성!!!
![]() | ![]() | ![]() |
---|---|---|
![]() | ![]() | ![]() |
안녕하세요 개발자님 혹시 실례가 안된다면 포인트샵 기능은 어떻게 구현하신건지 여쭈어봐도 될까요..? 혹시 기프티쇼 비즈 api를 받으신걸까요?