├── .github └── FUNDING.yml ├── LICENSE ├── README.md └── README.tr-TR.md /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | custom: ["buymeacoffee.com/fatihdurmaz"] 4 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2024 Fatih Durmaz 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SwiftUI Admob Guide 2 | ![Swift](https://img.shields.io/badge/Swift-5.9-orange.svg) 3 | ![Platform](https://img.shields.io/badge/Platform-iOS17%20-red.svg) 4 | ![Platform](https://img.shields.io/badge/SwiftUI-4-green.svg) 5 | ![License](https://img.shields.io/badge/License-MIT-blue.svg) 6 | 7 | [](https://durmaz.notion.site/SwiftUI-Admob-Rehberi-0b531e7be21f4d83a37214c62d2cc637 "SwiftUI Admob Guide") 8 | 9 | 1. **Admob SDK Installation** 10 | 1. Xcode with SPM → Add Package Dependencies 11 | 12 | ```swift 13 | https://github.com/googleads/swift-package-manager-google-mobile-ads.git 14 | ``` 15 | 16 | 2. Adding Application Identifier and SKAdNetworkIdentifier to Info.plist file 17 | 18 | ```swift 19 | 20 | 21 | 22 | 23 | GADApplicationIdentifier 24 | admob-app-identifier //start with ca-app-pub 25 | SKAdNetworkItems 26 | 27 | 28 | SKAdNetworkIdentifier 29 | cstr6suwn9.skadnetwork 30 | 31 | 32 | SKAdNetworkIdentifier 33 | 4fzdc2evr5.skadnetwork 34 | 35 | 36 | SKAdNetworkIdentifier 37 | 4pfyvq9l8r.skadnetwork 38 | 39 | 40 | SKAdNetworkIdentifier 41 | 2fnua5tdw4.skadnetwork 42 | 43 | 44 | SKAdNetworkIdentifier 45 | ydx93a7ass.skadnetwork 46 | 47 | 48 | SKAdNetworkIdentifier 49 | 5a6flpkh64.skadnetwork 50 | 51 | 52 | SKAdNetworkIdentifier 53 | p78axxw29g.skadnetwork 54 | 55 | 56 | SKAdNetworkIdentifier 57 | v72qych5uu.skadnetwork 58 | 59 | 60 | SKAdNetworkIdentifier 61 | ludvb6z3bs.skadnetwork 62 | 63 | 64 | SKAdNetworkIdentifier 65 | cp8zw746q7.skadnetwork 66 | 67 | 68 | SKAdNetworkIdentifier 69 | 3sh42y64q3.skadnetwork 70 | 71 | 72 | SKAdNetworkIdentifier 73 | c6k4g5qg8m.skadnetwork 74 | 75 | 76 | SKAdNetworkIdentifier 77 | s39g8k73mm.skadnetwork 78 | 79 | 80 | SKAdNetworkIdentifier 81 | 3qy4746246.skadnetwork 82 | 83 | 84 | SKAdNetworkIdentifier 85 | f38h382jlk.skadnetwork 86 | 87 | 88 | SKAdNetworkIdentifier 89 | hs6bdukanm.skadnetwork 90 | 91 | 92 | SKAdNetworkIdentifier 93 | v4nxqhlyqp.skadnetwork 94 | 95 | 96 | SKAdNetworkIdentifier 97 | wzmmz9fp6w.skadnetwork 98 | 99 | 100 | SKAdNetworkIdentifier 101 | yclnxrl5pm.skadnetwork 102 | 103 | 104 | SKAdNetworkIdentifier 105 | t38b2kh725.skadnetwork 106 | 107 | 108 | SKAdNetworkIdentifier 109 | 7ug5zh24hu.skadnetwork 110 | 111 | 112 | SKAdNetworkIdentifier 113 | gta9lk7p23.skadnetwork 114 | 115 | 116 | SKAdNetworkIdentifier 117 | vutu7akeur.skadnetwork 118 | 119 | 120 | SKAdNetworkIdentifier 121 | y5ghdn5j9k.skadnetwork 122 | 123 | 124 | SKAdNetworkIdentifier 125 | n6fk4nfna4.skadnetwork 126 | 127 | 128 | SKAdNetworkIdentifier 129 | v9wttpbfk9.skadnetwork 130 | 131 | 132 | SKAdNetworkIdentifier 133 | n38lu8286q.skadnetwork 134 | 135 | 136 | SKAdNetworkIdentifier 137 | 47vhws6wlr.skadnetwork 138 | 139 | 140 | SKAdNetworkIdentifier 141 | kbd757ywx3.skadnetwork 142 | 143 | 144 | SKAdNetworkIdentifier 145 | 9t245vhmpl.skadnetwork 146 | 147 | 148 | SKAdNetworkIdentifier 149 | eh6m2bh4zr.skadnetwork 150 | 151 | 152 | SKAdNetworkIdentifier 153 | a2p9lx4jpn.skadnetwork 154 | 155 | 156 | SKAdNetworkIdentifier 157 | 22mmun2rn5.skadnetwork 158 | 159 | 160 | SKAdNetworkIdentifier 161 | 4468km3ulz.skadnetwork 162 | 163 | 164 | SKAdNetworkIdentifier 165 | 2u9pt9hc89.skadnetwork 166 | 167 | 168 | SKAdNetworkIdentifier 169 | 8s468mfl3y.skadnetwork 170 | 171 | 172 | SKAdNetworkIdentifier 173 | klf5c3l5u5.skadnetwork 174 | 175 | 176 | SKAdNetworkIdentifier 177 | ppxm28t8ap.skadnetwork 178 | 179 | 180 | SKAdNetworkIdentifier 181 | ecpz2srf59.skadnetwork 182 | 183 | 184 | SKAdNetworkIdentifier 185 | uw77j35x4d.skadnetwork 186 | 187 | 188 | SKAdNetworkIdentifier 189 | pwa73g5rt2.skadnetwork 190 | 191 | 192 | SKAdNetworkIdentifier 193 | mlmmfzh3r3.skadnetwork 194 | 195 | 196 | SKAdNetworkIdentifier 197 | 578prtvx9j.skadnetwork 198 | 199 | 200 | SKAdNetworkIdentifier 201 | 4dzt52r2t5.skadnetwork 202 | 203 | 204 | SKAdNetworkIdentifier 205 | e5fvkxwrpn.skadnetwork 206 | 207 | 208 | SKAdNetworkIdentifier 209 | 8c4e2ghe7u.skadnetwork 210 | 211 | 212 | SKAdNetworkIdentifier 213 | zq492l623r.skadnetwork 214 | 215 | 216 | SKAdNetworkIdentifier 217 | 3rd42ekr43.skadnetwork 218 | 219 | 220 | SKAdNetworkIdentifier 221 | 3qcr597p9d.skadnetwork 222 | 223 | 224 | 225 | 226 | ``` 227 | 228 | 3. Calling the Admob SDK in the startup file of the SwiftUI application 229 | 230 | ```swift 231 | import SwiftUI 232 | import GoogleMobileAds 233 | 234 | @main 235 | struct KPSS_Puan_HesaplamaApp: App { 236 | 237 | init() { 238 | // Admob SDK 239 | GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [ "c458ae01182d2fad3701091c1e7991e0" ] 240 | GADMobileAds.sharedInstance().start(completionHandler: nil) 241 | // If you are going to use a test device, you must call it before the start method. 242 | } 243 | 244 | var body: some Scene { 245 | WindowGroup { 246 | ContentView() 247 | } 248 | } 249 | } 250 | ``` 251 | 252 | 2. **Banner ADS:** 253 | 254 | ```swift 255 | import Foundation 256 | import UIKit 257 | 258 | protocol BannerViewControllerWidthDelegate: AnyObject { 259 | func bannerViewController(_ bannerViewController: BannerViewController, didUpdate width: CGFloat) 260 | } 261 | 262 | class BannerViewController: UIViewController { 263 | weak var delegate: BannerViewControllerWidthDelegate? 264 | 265 | override func viewDidAppear(_ animated: Bool) { 266 | super.viewDidAppear(animated) 267 | 268 | // Tell the delegate the initial ad width. 269 | delegate?.bannerViewController( 270 | self, didUpdate: view.frame.inset(by: view.safeAreaInsets).size.width) 271 | } 272 | 273 | override func viewWillTransition( 274 | to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator 275 | ) { 276 | coordinator.animate { _ in 277 | // do nothing 278 | } completion: { _ in 279 | // Notify the delegate of ad width changes. 280 | self.delegate?.bannerViewController( 281 | self, didUpdate: self.view.frame.inset(by: self.view.safeAreaInsets).size.width) 282 | } 283 | } 284 | } 285 | ``` 286 | 287 | ```swift 288 | import SwiftUI 289 | import GoogleMobileAds 290 | 291 | struct BannerView: UIViewControllerRepresentable { 292 | @State private var viewWidth: CGFloat = .zero 293 | private let bannerView = GADBannerView() 294 | private let adUnitID = "ca-app-pub-xxxxxx" // Reklam Birimi Identifier 295 | 296 | func makeUIViewController(context: Context) -> some UIViewController { 297 | let bannerViewController = BannerViewController() 298 | bannerView.adUnitID = adUnitID 299 | bannerView.rootViewController = bannerViewController 300 | bannerView.delegate = context.coordinator 301 | bannerView.translatesAutoresizingMaskIntoConstraints = false 302 | bannerViewController.view.addSubview(bannerView) 303 | // Constrain GADBannerView to the bottom of the view. 304 | NSLayoutConstraint.activate([ 305 | bannerView.bottomAnchor.constraint( 306 | equalTo: bannerViewController.view.safeAreaLayoutGuide.bottomAnchor), 307 | bannerView.centerXAnchor.constraint(equalTo: bannerViewController.view.centerXAnchor), 308 | ]) 309 | bannerViewController.delegate = context.coordinator 310 | 311 | return bannerViewController 312 | } 313 | 314 | func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { 315 | guard viewWidth != .zero else { return } 316 | 317 | let request = GADRequest() 318 | // iPad'lerde adaptif reklam boyutları için 319 | request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene 320 | bannerView.load(request) 321 | } 322 | 323 | func makeCoordinator() -> Coordinator { 324 | Coordinator(self) 325 | } 326 | 327 | internal class Coordinator: NSObject, BannerViewControllerWidthDelegate, GADBannerViewDelegate 328 | { 329 | let parent: BannerView 330 | 331 | init(_ parent: BannerView) { 332 | self.parent = parent 333 | } 334 | 335 | // MARK: - BannerViewControllerWidthDelegate methods 336 | 337 | func bannerViewController( 338 | _ bannerViewController: BannerViewController, didUpdate width: CGFloat 339 | ) { 340 | parent.viewWidth = width 341 | } 342 | 343 | // MARK: - GADBannerViewDelegate methods 344 | 345 | func bannerViewDidReceiveAd(_ bannerView: GADBannerView) { 346 | print("\(#function) called") 347 | } 348 | 349 | func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) { 350 | print("\(#function) called") 351 | } 352 | 353 | func bannerViewDidRecordImpression(_ bannerView: GADBannerView) { 354 | print("\(#function) called") 355 | } 356 | 357 | func bannerViewWillPresentScreen(_ bannerView: GADBannerView) { 358 | print("\(#function) called") 359 | } 360 | 361 | func bannerViewWillDismissScreen(_ bannerView: GADBannerView) { 362 | print("\(#function) called") 363 | } 364 | 365 | func bannerViewDidDismissScreen(_ bannerView: GADBannerView) { 366 | print("\(#function) called") 367 | } 368 | } 369 | } 370 | ``` 371 | 372 | Contains methods within a class in the AdMob iOS SDK that implements the **`GADBannerViewDelegate`** protocol. These methods are used to receive notifications about the status and interaction of the Google AdMob advertising banner: 373 | 374 | 1. **`bannerViewDidReceiveAd(_ bannerView: GADBannerView)`**: Called when a banner ad is received and displayed. 375 | 2. **`bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error)`**: Called when a banner ad fails to load and specifies the error. 376 | 3. **`bannerViewDidRecordImpression(_ bannerView: GADBannerView)`**: Called when an impression is recorded for a banner ad. 377 | 4. **`bannerViewWillPresentScreen(_ bannerView: GADBannerView)`**: Called when a banner ad is about to cover the screen after being clicked. 378 | 5. **`bannerViewWillDismissScreen(_ bannerView: GADBannerView)`**: Called before a banner ad's full-screen content is dismissed. 379 | 6. **`bannerViewDidDismissScreen(_ bannerView: GADBannerView)`**: Called after a banner ad's full-screen content is dismissed. 380 | 381 | 4. **Interstitial ADS:** 382 | 383 | ```swift 384 | import Foundation 385 | import GoogleMobileAds 386 | 387 | class AdCoordinator: NSObject,GADFullScreenContentDelegate { 388 | private var ad: GADInterstitialAd? 389 | 390 | override init() { 391 | super.init() 392 | loadAd() 393 | } 394 | 395 | func loadAd() { 396 | let request = GADRequest() 397 | request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene 398 | 399 | GADInterstitialAd.load( 400 | withAdUnitID: "ca-app-pub-xxxx", request: request 401 | ) { ad, error in 402 | if let error = error { 403 | return print("Failed to load ad with error: \(error.localizedDescription)") 404 | } 405 | 406 | self.ad = ad 407 | self.ad?.fullScreenContentDelegate = self 408 | 409 | } 410 | } 411 | 412 | func presentAd() { 413 | guard let fullScreenAd = ad else { 414 | return print("Ad wasn't ready") 415 | } 416 | 417 | // View controller is an optional parameter. Pass in nil. 418 | fullScreenAd.present(fromRootViewController: nil) 419 | } 420 | 421 | // MARK: - GADFullScreenContentDelegate methods 422 | 423 | func adDidRecordImpression(_ ad: GADFullScreenPresentingAd) { 424 | print("\(#function) called") 425 | } 426 | 427 | func adDidRecordClick(_ ad: GADFullScreenPresentingAd) { 428 | print("\(#function) called") 429 | } 430 | 431 | func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { 432 | print("\(#function) called") 433 | } 434 | 435 | func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) { 436 | print("\(#function) called") 437 | } 438 | 439 | func adWillDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) { 440 | print("\(#function) called") 441 | } 442 | 443 | func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) { 444 | print("\(#function) called") 445 | loadAd() 446 | } 447 | 448 | ``` 449 | 450 | The **`GADFullScreenContentDelegate`** methods in the AdMob iOS SDK are used to track events related to the delivery of full-screen content by the ad publisher and user interaction. Its functions are as follows: 451 | 452 | 1. **`adDidRecordImpression(_ ad: GADFullScreenPresentingAd)`**: Called when an impression is recorded for an interstitial ad. 453 | 2. **`adDidRecordClick(_ ad: GADFullScreenPresentingAd)`**: Called when a click is recorded for an interstitial ad. 454 | 3. **`ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error)`**: Called when an interstitial ad fails to present its full-screen content and specifies the error. 455 | 4. **`adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd)`**: Called before an interstitial ad's full-screen content is presented. 456 | 5. **`adWillDismissFullScreenContent(_ ad: GADFullScreenPresentingAd)`**: Called before an interstitial ad's full-screen content is dismissed. 457 | 6. **`adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd)`**: Called after an interstitial ad's full-screen content is dismissed. 458 | 459 | These methods allow for better control of full-screen ads by the publisher and tracking of user interactions. In this way, the performance of ads and user experience can be optimized. 460 | 461 | 6. **App Tracking Transparency (tracking permission for Personalized Ads)** 462 | 463 | AppTrackingTransparency is an API introduced in iOS 14 and later that requires users to explicitly accept the tracking purpose of apps. This API imposes a consent requirement for apps that track users' devices for advertising and analytics purposes. 464 | Apps must ask the user for permission using the AppTrackingTransparency API before serving user tracking requests. The user is given an option to accept or decline the app from sharing their personal data with other companies for advertising or data analysis purposes. 465 | This API ensures that users are informed about tracking and their consent is obtained, providing better control over privacy. This allows users to feel more privacy and security. 466 | 467 | 1. The following Key and Value are defined in the Info.plist file. 468 | > Privacy - Tracking Usage Description : Would you allow us to make ads more personalized for you? 469 | 470 | 2. Permission is requested from the user with the following onReceive modifier in any view or main file of the application. 471 | 472 | ```swift 473 | import SwiftUI 474 | import AppTrackingTransparency 475 | 476 | struct ContentView: View { 477 | var body: some View { 478 | VStack{ 479 | Text("Hello ADMOB!") 480 | } 481 | .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in 482 | ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in }) 483 | } 484 | } 485 | } 486 | 487 | ``` 488 | 489 | 490 | 491 | ### **Examples:** 492 | 493 | 1. **Banner** 494 | 495 | ```swift 496 | import SwiftUI 497 | import GoogleMobileAds 498 | 499 | struct ContentView: View { 500 | var width: CGFloat = UIScreen.main.bounds.width 501 | 502 | var size: CGSize { 503 | return GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(width).size 504 | } // adaptif reklam boyutları için (iPad uyumluluğu için) 505 | 506 | var body: some View { 507 | VStack{ 508 | Text("Hello ADMOB!") 509 | BannerView() 510 | .frame(height: size.height) 511 | } 512 | } 513 | } 514 | ``` 515 | 516 | 2. **Interstitial** 517 | 518 | ```swift 519 | import SwiftUI 520 | import GoogleMobileAds 521 | 522 | struct ContentView: View { 523 | private let adCoordinator = AdCoordinator() 524 | 525 | var body: some View { 526 | VStack{ 527 | Text("Hello ADMOB!") 528 | Button("Show Interstitial"){ 529 | adCoordinator.presentAd() 530 | } 531 | } 532 | } 533 | } 534 | ``` 535 | 536 | [!["Buy Me A Coffee"](https://www.buymeacoffee.com/assets/img/custom_images/orange_img.png)](https://www.buymeacoffee.com/fatihdurmaz) 537 | -------------------------------------------------------------------------------- /README.tr-TR.md: -------------------------------------------------------------------------------- 1 | # SwiftUI Admob Rehberi 2 | ![Swift](https://img.shields.io/badge/Swift-5.9-orange.svg) 3 | ![Platform](https://img.shields.io/badge/Platform-iOS17%20-red.svg) 4 | ![Platform](https://img.shields.io/badge/SwiftUI-4-green.svg) 5 | ![License](https://img.shields.io/badge/License-MIT-blue.svg) 6 | 7 | [](https://durmaz.notion.site/SwiftUI-Admob-Rehberi-0b531e7be21f4d83a37214c62d2cc637 "SwiftUI Admob Guide") 8 | 9 | 1. **Admob SDK Kurulumu** 10 | 1. SPM ile Xcode → Add Package Dependencies 11 | 12 | ```swift 13 | https://github.com/googleads/swift-package-manager-google-mobile-ads.git 14 | ``` 15 | 16 | 2. Info.plist dosyasına Uygulama Identifier ve SKAdNetworkIdentifier ekleme 17 | 18 | ```swift 19 | 20 | 21 | 22 | 23 | GADApplicationIdentifier 24 | admob-uygulama-identifier //ca-app-pub ile başlayan 25 | SKAdNetworkItems 26 | 27 | 28 | SKAdNetworkIdentifier 29 | cstr6suwn9.skadnetwork 30 | 31 | 32 | SKAdNetworkIdentifier 33 | 4fzdc2evr5.skadnetwork 34 | 35 | 36 | SKAdNetworkIdentifier 37 | 4pfyvq9l8r.skadnetwork 38 | 39 | 40 | SKAdNetworkIdentifier 41 | 2fnua5tdw4.skadnetwork 42 | 43 | 44 | SKAdNetworkIdentifier 45 | ydx93a7ass.skadnetwork 46 | 47 | 48 | SKAdNetworkIdentifier 49 | 5a6flpkh64.skadnetwork 50 | 51 | 52 | SKAdNetworkIdentifier 53 | p78axxw29g.skadnetwork 54 | 55 | 56 | SKAdNetworkIdentifier 57 | v72qych5uu.skadnetwork 58 | 59 | 60 | SKAdNetworkIdentifier 61 | ludvb6z3bs.skadnetwork 62 | 63 | 64 | SKAdNetworkIdentifier 65 | cp8zw746q7.skadnetwork 66 | 67 | 68 | SKAdNetworkIdentifier 69 | 3sh42y64q3.skadnetwork 70 | 71 | 72 | SKAdNetworkIdentifier 73 | c6k4g5qg8m.skadnetwork 74 | 75 | 76 | SKAdNetworkIdentifier 77 | s39g8k73mm.skadnetwork 78 | 79 | 80 | SKAdNetworkIdentifier 81 | 3qy4746246.skadnetwork 82 | 83 | 84 | SKAdNetworkIdentifier 85 | f38h382jlk.skadnetwork 86 | 87 | 88 | SKAdNetworkIdentifier 89 | hs6bdukanm.skadnetwork 90 | 91 | 92 | SKAdNetworkIdentifier 93 | v4nxqhlyqp.skadnetwork 94 | 95 | 96 | SKAdNetworkIdentifier 97 | wzmmz9fp6w.skadnetwork 98 | 99 | 100 | SKAdNetworkIdentifier 101 | yclnxrl5pm.skadnetwork 102 | 103 | 104 | SKAdNetworkIdentifier 105 | t38b2kh725.skadnetwork 106 | 107 | 108 | SKAdNetworkIdentifier 109 | 7ug5zh24hu.skadnetwork 110 | 111 | 112 | SKAdNetworkIdentifier 113 | gta9lk7p23.skadnetwork 114 | 115 | 116 | SKAdNetworkIdentifier 117 | vutu7akeur.skadnetwork 118 | 119 | 120 | SKAdNetworkIdentifier 121 | y5ghdn5j9k.skadnetwork 122 | 123 | 124 | SKAdNetworkIdentifier 125 | n6fk4nfna4.skadnetwork 126 | 127 | 128 | SKAdNetworkIdentifier 129 | v9wttpbfk9.skadnetwork 130 | 131 | 132 | SKAdNetworkIdentifier 133 | n38lu8286q.skadnetwork 134 | 135 | 136 | SKAdNetworkIdentifier 137 | 47vhws6wlr.skadnetwork 138 | 139 | 140 | SKAdNetworkIdentifier 141 | kbd757ywx3.skadnetwork 142 | 143 | 144 | SKAdNetworkIdentifier 145 | 9t245vhmpl.skadnetwork 146 | 147 | 148 | SKAdNetworkIdentifier 149 | eh6m2bh4zr.skadnetwork 150 | 151 | 152 | SKAdNetworkIdentifier 153 | a2p9lx4jpn.skadnetwork 154 | 155 | 156 | SKAdNetworkIdentifier 157 | 22mmun2rn5.skadnetwork 158 | 159 | 160 | SKAdNetworkIdentifier 161 | 4468km3ulz.skadnetwork 162 | 163 | 164 | SKAdNetworkIdentifier 165 | 2u9pt9hc89.skadnetwork 166 | 167 | 168 | SKAdNetworkIdentifier 169 | 8s468mfl3y.skadnetwork 170 | 171 | 172 | SKAdNetworkIdentifier 173 | klf5c3l5u5.skadnetwork 174 | 175 | 176 | SKAdNetworkIdentifier 177 | ppxm28t8ap.skadnetwork 178 | 179 | 180 | SKAdNetworkIdentifier 181 | ecpz2srf59.skadnetwork 182 | 183 | 184 | SKAdNetworkIdentifier 185 | uw77j35x4d.skadnetwork 186 | 187 | 188 | SKAdNetworkIdentifier 189 | pwa73g5rt2.skadnetwork 190 | 191 | 192 | SKAdNetworkIdentifier 193 | mlmmfzh3r3.skadnetwork 194 | 195 | 196 | SKAdNetworkIdentifier 197 | 578prtvx9j.skadnetwork 198 | 199 | 200 | SKAdNetworkIdentifier 201 | 4dzt52r2t5.skadnetwork 202 | 203 | 204 | SKAdNetworkIdentifier 205 | e5fvkxwrpn.skadnetwork 206 | 207 | 208 | SKAdNetworkIdentifier 209 | 8c4e2ghe7u.skadnetwork 210 | 211 | 212 | SKAdNetworkIdentifier 213 | zq492l623r.skadnetwork 214 | 215 | 216 | SKAdNetworkIdentifier 217 | 3rd42ekr43.skadnetwork 218 | 219 | 220 | SKAdNetworkIdentifier 221 | 3qcr597p9d.skadnetwork 222 | 223 | 224 | 225 | 226 | ``` 227 | 228 | 3. SwiftUI uygulamasının başlangıç dosyasında Admob SDK’inin çağrılması 229 | 230 | ```swift 231 | import SwiftUI 232 | import GoogleMobileAds 233 | 234 | @main 235 | struct KPSS_Puan_HesaplamaApp: App { 236 | 237 | init() { 238 | // Admob SDK 239 | GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [ "c458ae01182d2fad3701091c1e7991e0" ] 240 | GADMobileAds.sharedInstance().start(completionHandler: nil) 241 | // Test cihazı kullanacaksanız start metodundan önce çağırmalısınız. 242 | } 243 | 244 | var body: some Scene { 245 | WindowGroup { 246 | ContentView() 247 | } 248 | } 249 | } 250 | ``` 251 | 252 | 2. **Banner Reklamı:** 253 | 254 | ```swift 255 | import Foundation 256 | import UIKit 257 | 258 | protocol BannerViewControllerWidthDelegate: AnyObject { 259 | func bannerViewController(_ bannerViewController: BannerViewController, didUpdate width: CGFloat) 260 | } 261 | 262 | class BannerViewController: UIViewController { 263 | weak var delegate: BannerViewControllerWidthDelegate? 264 | 265 | override func viewDidAppear(_ animated: Bool) { 266 | super.viewDidAppear(animated) 267 | 268 | // Tell the delegate the initial ad width. 269 | delegate?.bannerViewController( 270 | self, didUpdate: view.frame.inset(by: view.safeAreaInsets).size.width) 271 | } 272 | 273 | override func viewWillTransition( 274 | to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator 275 | ) { 276 | coordinator.animate { _ in 277 | // do nothing 278 | } completion: { _ in 279 | // Notify the delegate of ad width changes. 280 | self.delegate?.bannerViewController( 281 | self, didUpdate: self.view.frame.inset(by: self.view.safeAreaInsets).size.width) 282 | } 283 | } 284 | } 285 | ``` 286 | 287 | ```swift 288 | import SwiftUI 289 | import GoogleMobileAds 290 | 291 | struct BannerView: UIViewControllerRepresentable { 292 | @State private var viewWidth: CGFloat = .zero 293 | private let bannerView = GADBannerView() 294 | private let adUnitID = "ca-app-pub-xxxxxx" // Reklam Birimi Identifier 295 | 296 | func makeUIViewController(context: Context) -> some UIViewController { 297 | let bannerViewController = BannerViewController() 298 | bannerView.adUnitID = adUnitID 299 | bannerView.rootViewController = bannerViewController 300 | bannerView.delegate = context.coordinator 301 | bannerView.translatesAutoresizingMaskIntoConstraints = false 302 | bannerViewController.view.addSubview(bannerView) 303 | // Constrain GADBannerView to the bottom of the view. 304 | NSLayoutConstraint.activate([ 305 | bannerView.bottomAnchor.constraint( 306 | equalTo: bannerViewController.view.safeAreaLayoutGuide.bottomAnchor), 307 | bannerView.centerXAnchor.constraint(equalTo: bannerViewController.view.centerXAnchor), 308 | ]) 309 | bannerViewController.delegate = context.coordinator 310 | 311 | return bannerViewController 312 | } 313 | 314 | func updateUIViewController(_ uiViewController: UIViewControllerType, context: Context) { 315 | guard viewWidth != .zero else { return } 316 | 317 | let request = GADRequest() 318 | // iPad'lerde adaptif reklam boyutları için 319 | request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene 320 | bannerView.load(request) 321 | } 322 | 323 | func makeCoordinator() -> Coordinator { 324 | Coordinator(self) 325 | } 326 | 327 | internal class Coordinator: NSObject, BannerViewControllerWidthDelegate, GADBannerViewDelegate 328 | { 329 | let parent: BannerView 330 | 331 | init(_ parent: BannerView) { 332 | self.parent = parent 333 | } 334 | 335 | // MARK: - BannerViewControllerWidthDelegate methods 336 | 337 | func bannerViewController( 338 | _ bannerViewController: BannerViewController, didUpdate width: CGFloat 339 | ) { 340 | parent.viewWidth = width 341 | } 342 | 343 | // MARK: - GADBannerViewDelegate methods 344 | 345 | func bannerViewDidReceiveAd(_ bannerView: GADBannerView) { 346 | print("\(#function) called") 347 | } 348 | 349 | func bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error) { 350 | print("\(#function) called") 351 | } 352 | 353 | func bannerViewDidRecordImpression(_ bannerView: GADBannerView) { 354 | print("\(#function) called") 355 | } 356 | 357 | func bannerViewWillPresentScreen(_ bannerView: GADBannerView) { 358 | print("\(#function) called") 359 | } 360 | 361 | func bannerViewWillDismissScreen(_ bannerView: GADBannerView) { 362 | print("\(#function) called") 363 | } 364 | 365 | func bannerViewDidDismissScreen(_ bannerView: GADBannerView) { 366 | print("\(#function) called") 367 | } 368 | } 369 | } 370 | ``` 371 | 372 | AdMob iOS SDK içindeki, **`GADBannerViewDelegate`** protokolünü uygulayan bir sınıf içindeki yöntemleri içerir. Bu yöntemler, Google AdMob reklam bannerinin durumu ve etkileşimi hakkında bildirim almak için kullanılır: 373 | 374 | 1. **`bannerViewDidReceiveAd(_ bannerView: GADBannerView)`**: Banner reklamın başarıyla alındığı ve görüntülendiği zaman bu metot çağrılır. 375 | 2. **`bannerView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: Error)`**: Banner reklamın yüklenme işlemi başarısız olduğunda bu metot çağrılır. Bir hata nesnesi, hata hakkında daha fazla bilgi sağlar. 376 | 3. **`bannerViewDidRecordImpression(_ bannerView: GADBannerView)`**: Banner reklamın bir izlenim kaydedildiğinde bu metot çağrılır. Banner reklamın görüntülendiği her bir defa bu metot tetiklenir. 377 | 4. **`bannerViewWillPresentScreen(_ bannerView: GADBannerView)`**: Banner reklamın tam ekran bir sayfa veya ekranın bir bölümüyle örtüştüğü bir ekranın sunulması öncesinde bu metot çağrılır. Örneğin, bir kullanıcı reklama tıkladığında ve uygulama bir tarayıcı ekranı veya başka bir uygulama ekranı açtığında bu metot tetiklenir. 378 | 5. **`bannerViewWillDismissScreen(_ bannerView: GADBannerView)`**: Banner reklamın tam ekran bir sayfa veya ekranın örtüştüğü ekranın kapatılması öncesinde bu metot çağrılır. 379 | 6. **`bannerViewDidDismissScreen(_ bannerView: GADBannerView)`**: Banner reklamın tam ekran bir sayfa veya ekranın örtüştüğü ekranın kapatılması sonrasında bu metot çağrılır. Bu metot, reklam ekranının kapatılması işleminin tamamlandığını belirtir. 380 | 381 | 3. **Interstitial Reklamı:** 382 | 383 | ```swift 384 | import Foundation 385 | import GoogleMobileAds 386 | 387 | class AdCoordinator: NSObject,GADFullScreenContentDelegate { 388 | private var ad: GADInterstitialAd? 389 | 390 | override init() { 391 | super.init() 392 | loadAd() 393 | } 394 | 395 | func loadAd() { 396 | let request = GADRequest() 397 | request.scene = UIApplication.shared.connectedScenes.first as? UIWindowScene 398 | 399 | GADInterstitialAd.load( 400 | withAdUnitID: "ca-app-pub-xxxx", request: request 401 | ) { ad, error in 402 | if let error = error { 403 | return print("Failed to load ad with error: \(error.localizedDescription)") 404 | } 405 | 406 | self.ad = ad 407 | self.ad?.fullScreenContentDelegate = self 408 | 409 | } 410 | } 411 | 412 | func presentAd() { 413 | guard let fullScreenAd = ad else { 414 | return print("Ad wasn't ready") 415 | } 416 | 417 | // View controller is an optional parameter. Pass in nil. 418 | fullScreenAd.present(fromRootViewController: nil) 419 | } 420 | 421 | // MARK: - GADFullScreenContentDelegate methods 422 | 423 | func adDidRecordImpression(_ ad: GADFullScreenPresentingAd) { 424 | print("\(#function) called") 425 | } 426 | 427 | func adDidRecordClick(_ ad: GADFullScreenPresentingAd) { 428 | print("\(#function) called") 429 | } 430 | 431 | func ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error) { 432 | print("\(#function) called") 433 | } 434 | 435 | func adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd) { 436 | print("\(#function) called") 437 | } 438 | 439 | func adWillDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) { 440 | print("\(#function) called") 441 | } 442 | 443 | func adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd) { 444 | print("\(#function) called") 445 | loadAd() 446 | } 447 | 448 | ``` 449 | 450 | AdMob iOS SDK içindeki **`GADFullScreenContentDelegate`** yöntemleri, tam ekran içeriğin reklam yayıncısı tarafından sunulması ve kullanıcının etkileşimiyle ilgili olayları izlemek için kullanılır. İşlevleri şu şekildedir: 451 | 452 | 1. **`adDidRecordImpression(_ ad: GADFullScreenPresentingAd)`**: Reklam gösterim olayının kaydedildiği zaman bu metot çağrılır. Bir reklamın izlenme sayısı gibi metriklerin takibi için kullanılabilir. 453 | 2. **`adDidRecordClick(_ ad: GADFullScreenPresentingAd)`**: Kullanıcının reklama tıkladığı zaman bu metot çağrılır. Kullanıcıların reklamla etkileşimlerinin takibi için kullanılabilir. 454 | 3. **`ad(_ ad: GADFullScreenPresentingAd, didFailToPresentFullScreenContentWithError error: Error)`**: Tam ekran içeriğin sunulamadığı bir hata oluştuğunda bu metot çağrılır. Örneğin, reklam yüklenirken bir ağ hatası oluşabilir. 455 | 4. **`adWillPresentFullScreenContent(_ ad: GADFullScreenPresentingAd)`**: Tam ekran içeriğin gösterilmeye başlanmadan önce bu metot çağrılır. Uygulamanın gerektiği gibi durumunu ayarlamak için kullanılabilir. 456 | 5. **`adWillDismissFullScreenContent(_ ad: GADFullScreenPresentingAd)`**: Tam ekran içeriğin kullanıcı tarafından kapatılmadan önce bu metot çağrılır. Kullanıcı reklamı kapatmaya karar verirse, bu olay tetiklenir. 457 | 6. **`adDidDismissFullScreenContent(_ ad: GADFullScreenPresentingAd)`**: Tam ekran içeriğin kullanıcı tarafından kapatıldıktan sonra bu metot çağrılır. Reklamı kapatma işlemi tamamlandığında kullanılabilir. 458 | 459 | Bu yöntemler, tam ekran reklamların yayıncı tarafından daha iyi kontrol edilmesini ve kullanıcı etkileşimlerinin izlenmesini sağlar. Bu şekilde, reklamların performansı ve kullanıcı deneyimi optimize edilebilir. 460 | 461 | 4. **App Tracking Transparency (Kişiselleştirilmiş Reklamlar için takip izni)** 462 | 463 | AppTrackingTransparency, iOS 14 ve sonraki sürümlerde tanıtılan bir API'dir ve kullanıcıların uygulamaların takip etme amacını açıkça kabul etmelerini gerektirir. Bu API, reklamcılık ve analitik amaçlarla kullanıcıların cihazlarını takip eden uygulamalar için bir onay gerekliliği getirir. 464 | 465 | Uygulamalar, kullanıcı izleme isteklerini sunmadan önce AppTrackingTransparency API'sini kullanarak kullanıcıdan izin istemelidir. Kullanıcı, uygulamanın kişisel verilerini reklam veya veri analizi amacıyla başka şirketlere paylaşmasını kabul etmek veya reddetmek için bir seçenek sunulur. 466 | 467 | Bu API, gizlilik açısından daha iyi bir kontrol sağlayarak kullanıcıların izleme hakkında bilgilendirilmesini ve rızalarının alınmasını sağlar. Bu da kullanıcıların daha fazla gizlilik ve güvenlik hissetmelerini sağlar. 468 | 469 | 1. Info.plist dosyasına aşağıdaki Key ve Value olacak şekilde tanımlama yapılır. 470 | 471 | > Privacy - Tracking Usage Description : Reklamları sizin için daha kişiselleştirilir hale getirebilmemize izin verir misiniz? 472 | > 473 | 2. Uygulamanın herhangi bir view ya da main dosyasında aşağıdaki onReceive modifier ile kullanıcıdan izin talep edilir. 474 | 475 | ```swift 476 | import SwiftUI 477 | import AppTrackingTransparency 478 | 479 | struct ContentView: View { 480 | var body: some View { 481 | VStack{ 482 | Text("Merhaba ADMOB!") 483 | } 484 | .onReceive(NotificationCenter.default.publisher(for: UIApplication.didBecomeActiveNotification)) { _ in 485 | ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in }) 486 | } 487 | } 488 | } 489 | 490 | ``` 491 | 492 | 493 | 494 | ### **Kullanım Örnekleri:** 495 | 496 | 1. **Banner** 497 | 498 | ```swift 499 | import SwiftUI 500 | import GoogleMobileAds 501 | 502 | struct ContentView: View { 503 | var width: CGFloat = UIScreen.main.bounds.width 504 | 505 | var size: CGSize { 506 | return GADCurrentOrientationAnchoredAdaptiveBannerAdSizeWithWidth(width).size 507 | } // adaptif reklam boyutları için (iPad uyumluluğu için) 508 | 509 | var body: some View { 510 | VStack{ 511 | Text("Merhaba ADMOB!") 512 | BannerView() 513 | .frame(height: size.height) 514 | } 515 | } 516 | } 517 | ``` 518 | 519 | 2. **Interstitial** 520 | 521 | ```swift 522 | import SwiftUI 523 | import GoogleMobileAds 524 | 525 | struct ContentView: View { 526 | private let adCoordinator = AdCoordinator() 527 | 528 | var body: some View { 529 | VStack{ 530 | Text("Merhaba ADMOB!") 531 | Button("Reklam Göster"){ 532 | adCoordinator.presentAd() 533 | } 534 | } 535 | } 536 | } 537 | ``` 538 | --------------------------------------------------------------------------------