├── .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 | 
3 | 
4 | 
5 | 
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 | [](https://www.buymeacoffee.com/fatihdurmaz)
537 |
--------------------------------------------------------------------------------
/README.tr-TR.md:
--------------------------------------------------------------------------------
1 | # SwiftUI Admob Rehberi
2 | 
3 | 
4 | 
5 | 
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 |
--------------------------------------------------------------------------------