Implementierung App iOS
1 Über diese Anleitung
Die vorliegende Anleitung dient dazu, alle notwendigen Informationen für die technische Integration und Nutzung der ÖWA-Library in Apps mit dem Betriebsystem iOS zur Verfügung zu stellen. Die unterstützte App-Platform ist hier iOS ab Version 10.0.
2 ÖWA-Library (iOS)
Die ÖWA-Library für iOS bereitgestellt durch INFOnline (im Folgenden auch „IOLib“ genannt) ist eine Software-Bibliothek, welche die Nutzung von iOS Apps erfasst, speichert und zum Zwecke der Vailidierung und Kontrolle an das Mess-System sendet.
2.1 Bereitstellung
Die IOLib wird von der ÖWA zum Download zur Verfügung gestellt. Im Download befinden sich:
- die Release Notes als Textdatei
- das Change Log als Textdatei
- ein Verzeichnis INFOnlineLibrary: Die IOLib wird als „Framework“ bereitgestellt und kann somit leicht in bereits existierende iOS-Projekte integriert werden. Zu diesem Zweck kann das beiliegende Copy-Framework Script eingesetzt werden.
- ein Verzeichnis ObjCSample: Ein Beispiel-Projekt mit integrierter IOLib auf Objective-C Basis
- ein Verzeichnis Swift Sample: Ein Beispiel-Projket mit integrierter IOLib auf Swift 4.2 Basis
2.2 Anforderungen
Die IOLib unterstützt ausschließlich die Integration über die Entwicklungsumgebung Xcode unter macOS.
2.2.1 Entwicklungsumgebung
Um die Integration der IOLib durchzuführen, sind folgende Voraussetzungen notwendig:
- macOS 10.14 (Mojave) und höher
- iOS SDK 13 und höher
- Xcode 11.0 und höher
- Objective-C oder Swift
iOS APPs, welche die IOLib benutzen, müssen mind. mit iOS SDK 13 kompiliert werden.
Deployment Target muss mind. auf 10.0 eingestellt werden.
2.2.2 Betriebssystem/Plattform
Die IOLib unterstützt den Betrieb unter 32-Bit und 64-Bit Architekturen.
Die IOLib setzt für den Betrieb iOS 10.0 oder höher voraus.
2.2.3 Kompatibilität
Eine neue Version von Xcode bzw. des iOS-Betriebssystems macht evtl. ein Update der
IOLib notwendig. Eine vollständige Aufwärtskompatibilität kann u.U. nicht gewährleistet werden.
2.3 Funktionsweise
2.3.1 Wann muss die ÖWA-Library aufgerufen werden?
Der Aufruf der Funktionen der IOLib innerhalb der App ist an bestimmte Events gebunden. Hierzu werden für die App-Anbieter seitens der ÖWA Vorgaben bzw. Empfehlungen formuliert, an welchen Stellen der App bzw. bei welchen Nutzer-Aktionen die ÖWA-Library aufgerufen werden soll und welche Informationen zu übermitteln sind.
Die Vorgaben zum Aufruf der IOLib innerhalb der App werden in Kapitel 4 (Vorgaben zum Aufruf der ÖWA-Library) beschrieben.
2.3.2 Übertragung der Messdaten
Der Versand der Daten findet asynchron statt. Dadurch wird die Interaktion des Benutzers mit der App nicht verzögert oder blockiert.
3 Integration der ÖWA-Library iOS
Dieses Kapitel beschreibt die technische Integration der ÖWA-Library in eine iOS-Projektstruktur.
3.1 Thread-safe
Die IOLib ist Thread-safe.
3.2 IOLib Dateien
Die ÖWA-Library für iOS umfasst folgende Dateien
- RELEASE_NOTES.txt
Diese Datei enthält Informationen zum Release der IOLib. - CHANGE_LOG.txt
Diese Datei enthält Informationen zur Änderungshistorie der IOLib. - INFOnlineLibrary
Enthält die IOLib (INFOnlineLibrary.framework) zur Erfassung der Nutzungsdaten einer App, sowie das copy-framework Script zur automatischen Integration des Frameworks in ein Projekt. - ObjCSample
Ein Beispiel-Projekt, welches den Einsatz der IOLib demonstriert.
Die Interaktion mit der IOLib ist mit Objective-C implementiert.
Das Projekt beinhaltet eine TodayExtension. - SwiftSample
Ein Beispiel-Projekt, welches den Einsatz der IOLib demonstriert.
Die Interaktion mit der IOLib ist mit Swift 4.2 implementiert.
Das Projekt beinhaltet eine TodayExtension.
3.3 Integration des IOLib Frameworks
Die Integration erfolgt in wenigen einfachen Schritten.
1. Im Finder:
Den Ordner „INFOnlineLibrary“ in den Projekt-Ordner kopieren (oder per Drag’n’Drop ziehen)
2. In Xcode: Build Settings
Den Pfad zum „INFOnlineLibrary“ Ordner zu den Framework Search Paths in den Build Settings hinzufügen.
In unserem Sample:
$(PROJECT_DIR)/../INFOnlineLibrary/$(PLATFORM_NAME)/
Bei den Other Linker Flags in den Build Settings muss die INFOnlineLibrary wie folgt angegeben werden:
-framework INFOnlineLibrary
3. In Xcode: Run Script Build Phase
Eine Run Script Phase zu den Build Phases hinzufügen:
In unserem Sample:
${PROJECT_DIR}/../INFOnlineLibrary/copy-framework.sh
4. In Xcode:
Linking des Frameworks AdSupport
Um eine korrekte und vollständige Messung für die ÖWA-Messung zu gewährleisten, muss das o.g. Framework eingebunden werden.Wenn Sie das Framework nicht einbinden, kann der für die ÖWA-Messung erforderliche Identifier (Advertising Identifier / IDFA) nicht übermittelt werden – eine Teilnahme an der ÖWA-Messung ist somit nicht möglich.
5. In Xcode:
Objective-C:
Import der IOLib Header im ApplicationDelegate und in den ViewControllern (alternativ im Prefix Header)
import <INFOnlineLibrary/INFOnlineLibrary.h>
Es sollte immer der Umbrella Header benutzt werden und niemals einzelne Header aus dem Framework!
Swift:
Import des IOLib Frameworks im ApplicationDelegate und in den ViewControllern
import INFOnlineLibrary
6. In Xcode: Initialisierung und Start einer Session der IOLib beim Application-Start:
Objective-C:
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions: (NSDictionary*) launchOptions {
[self startSession];
// Other code
return YES;
}
- (void)startSession {
// Initialisierung der IOLib; Session-Start
// privacySetting LIN = Berechtigtes Interesse ist gegeben
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA]
startSessionWithOfferIdentifier:@„" privacyType:IOLPrivacyTypeLIN];
}
// AddDelegate.m
// ObjCSample
//
// Copyright (c) 2017 RockAByte GmbH. All rights reserved
//
#import "AddDelegate.h"
#import
NS_ASSUME_NONNULL_BEGIN
@implementation AppDelegate
-(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary * _Nullable)launchOptions{
[self startSession];
return YES;
}
#pragma mark - Helper
-(void)startSession{
[IOLLogging setDebugLevel:IOLDebugLevelVerbose];
BOOL isOptOut = [[NUserDefaults standardUserDefaults] boolForKey:@"IOLSOptOutKey"];
if(!isOptOut) {
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] startSessionWithOfferIdentifier:@"oewaOfferID"
privacyType:IOLPrivacyTypeLIN];
}
}
@end
NS_ASSUME_NONNULL_END
Swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
self.startSession()
// Other code
return true
}
func startSession() {
// Initialisierung der IOLib; Session-Start
// privacySetting LIN = Berechtigtes Interesse ist gegeben
IOLSession.defaultSession(for: .OEWA).start(withOfferIdentifier:@„", privacyType: .LIN)
}
// AddDelegate.swift
// SwiftSample
//
// Copyright (c) 2017 RockAByte GmbH. All rights reserved
//
import UIKit
import INFOnlineLibrary
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFishinLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
startSession()
return true
}
//MARK: - Helper
private func startSession() {
IOLLogging.setDebugLogLevel(.verbose)
let isOptOut = UserDefaults.standard.bool(forKey: "IOLSOptOutKey")
guard !isOptOut else { return }
IOLSession.defaultSession(for: .OEWA).start(withOfferIdentifier: "oewaOfferID", privacyType: .LIN)
}
}
7. In Xcode:
Events können in den View Controllern der App geloggt werden, z.B. der Aufruf eines Views:
Objective-C:
// Tracking View Appeared
IOLViewEvent *event = [[IOLViewEvent alloc] initWithType:IOLViewEventTypeAppeared category:@"TestCategory" comment:nil];
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] logEvent:event];
- (void)viewDidAppear:(BOOL)animated{
[super viewDidAppear:animated];
IOLViewEvent *event = [[IOLViewEvent alloc] initWithType:IOLViewEventTypeAppeared category:@"TestCategory" comment:nil];
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] logEvent: event];
}
Swift:
// Tracking View Appeared
let event = IOLViewEvent(type: .appeared, category: "TestCategory", comment: nil)
IOLSession.defaultSession(for: .OEWA).logEvent(event)
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let event = IOLViewEvent(type: .appeared, category: "TestCategory", comment: nil)
IOLSession.defaultSession(for: .OEWA).logEvent(event)
}
3.4 Parallel-Messung ÖWA und INFOnline (IVW, AGOF)
Die IOLib iOS unterstützt den parallelen Betrieb von Sessions unterschiedlicher Mess-Systeme. Im folgenden soll gezeigt werden, wie beide Messungen gleichzeitig betrieben werden können.
Voraussetzung ist eine Integration der IOLib iOS gemäß Kapitel 3.3 Punkte 1-5.
1. In Xcode: Initialisierung und Start beider Sessions beim Application-Start:
Objective-C:
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
[self startSessions];
// Other code
return YES;
}
- (void)startSessions {
// Initialisierung der IOLib; Session-Start
// privacySetting LIN
[[IOLSession defaultSessionFor:IOLSessionTypeSZM]
startSessionWithOfferIdentifier:@„"
privacyType:IOLPrivacyTypeLIN];
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA]
startSessionWithOfferIdentifier:@„"
privacyType:IOLPrivacyTypeLIN];
}
//
// AppDelegate.m
// ObjCSample
//
// Copyright (c) 2017 RockAByte GmbH. All rights reserved.
//
#import "AppDelegate.h"
#import
NS_ASSUME_NONNULL_BEGIN
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary* _Nullable)launchOptions {
[self startSessions];
return YES;
}
#pragma mark - Helper
- (void) startSessions{
[IOLLogging setDebugLevel: IOLDebugLevelVerbose];
BOOL isOptOut =[[NSUserDefaults standardUserDefaults]
boolForKey:@"IOLSOptOutKey"];
if (!isOptOut) {
[[IOLSession defaultSessionFor:IOLSessionTypeSZM]
startSessionWithOfferIdentifier:@"szmOfferID"
privacyType: IOLPrivacyTypeLIN];
[[IOLSession defaultSessionFor:IOLSessionTypeSZM]
startSessionWithOfferIdentifier:@"oewaOfferID"
privacyType: IOLPrivacyTypeLIN];
}
}
@end
NS_ASSUME_NONNULL_END
Swift:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey : Any]? = nil) -> Bool {
self.startSessions()
// Other code
return true
}
func startSessions() {
// Initialisierung der IOLib; Session-Start
// privacySetting LIN = Berechtigtes Interesse ist gegeben
IOLSession.defaultSession(for: .SZM).start(
withOfferIdentifier:„“, privacyType: .LIN)
IOLSession.defaultSession(for: .OEWA).start(
withOfferIdentifier:„“, privacyType: .LIN)
}
//
// AppDelegate.swift
// SwiftSample
//
// Copyright (c) 2017 RockAByte GmbH. All rights reserved.
//
#import UIKit
#import INFOnlineLibrary
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool{
startSessions()
return true
}
//MARK: - Helper
private func startSessions() {
IOLLogging.setDebugLevel(.verbose)
let istOptOut = UserDefaults.standard.bool(forKey: "IOLSOptOutKey")
guard !istOptOut else { return }
IOLSession.defaultSession(for: .SZM).start(withOfferIdentifier: "szmOfferID",
privacyType: .LIN)
IOLSession.defaultSession(for: .OEWA).start(withOfferIdentifier: "oewaOfferID",
privacyType: .LIN)
}
}
2. Messen eines Events
Events können in den View Controllern der App geloggt werden, z.B. der Aufruf eines Views:
Objective-C:
// Tracking View Appeared
IOLViewEvent *event = [[IOLViewEvent alloc] initWithType:IOLViewEventTypeAppeared
category:@"TestCategory" comment:nil];
[[IOLSession defaultSessionFor:IOLSessionTypeSZM] logEvent:event];
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] logEvent:event];
-(void) viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
IOLViewEvent *event = [[IOLViewEvent alloc] initWIthType:IOLViewEventTypeAppeared
category: "TestCategory", comment: nil)];
[[IOLSession defaultSessionFor:IOLSessionTypeSZM] logEvent: event]
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] logEvent: event]
}
Swift:
// Tracking View Appeared
let event = IOLViewEvent(type: .appeared, category: "TestCategory", comment: nil)
IOLSession.defaultSession(for: .SZM).logEvent(event)
IOLSession.defaultSession(for: .OEWA).logEvent(event)
override func viewDidAppear(_ animated: Bool){
super.viewDidAppear(animated)
let event = IOLViewEvent(type: .appeared, category: "TestCategory", comment: nil)
IOLSession.defaultSession(for: .SZM).logEvent(event)
IOLSession.defaultSession(for: .OEWA).logEvent(event)
}
3.5 IOLib Funktionen
Die IOLib bietet die im Folgenden beschriebenen Funktionen:
3.5.1 Aufruf der Default Session
Alle im Folgenden beschriebenen Funktionen der IOLib müssen auf dem Default Session Objekt aufgerufen werden. Dabei muss der SessionType als Parameter übergeben werden.
Parameter:
- IOLSessionType (mandatory)
Der Typ der zu verwendenden Session. Für die ÖWA-Messung muss IOLSessionTypeOEWA verwendet werden!
Beispiel:
Objective-C:
+(IOLSession*)defaultSessionFor:(IOLSessionType)sessionType;
Für die ÖWA-Messung muss als sessionType IOLSessionTypeOEWA übergeben werden.
IOLSession *session = [IOLSession defaultSessionFor:IOLSessionTypeOEWA];
Swift:
class func defaultSession(for sessionType: IOLSessionType) -> IOLSession
Für die ÖWA-Messung muss als sessionType .OEWA übergeben werden.
let session = IOLSession.defaultSession(for: .OEWA)
3.5.2 Start einer Session
Die IOLib muss vor der Erfassung der Events gestartet werden. Dabei müssen die Angebotskennung der App sowie die Datenschutz-Einstellung als Parameter übergeben werden.
Parameter:
- Angebotskennung (mandatory)
Eine eindeutige Kennung des Angebots der jeweiligen App. Die Angebotskennung wird von ÖWA pro App und pro Betriebssystem eindeutig vergeben. - Datenschutz-Einstellung (mandatory)
Angabe, auf welcher Rechtsgrundlage gemessen wird. Im Fall der ÖWA ist hier LIN zu verwenden.
Beispiel (hier ist die Angebotskennung “iamtest” und die Datenschutz Einstellung „LIN“):
Objective-C:
– (void)startSessionWithOfferIdentifier:(NSString*)offerID privacyType:(IOLPrivacyType)privacyType;
[session startSessionWithOfferIdentifier:@„iamtest“ privacyType:IOLPrivacyTypeLIN];
// AddDelegate.m
// ObjCSample
//
// Copyright (c) 2017 RockAByte GmbH. All rights reserved
//
#import "AddDelegate.h"
#import
NS_ASSUME_NONNULL_BEGIN
@implementation AppDelegate
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(NSDictionary*)launchOptions{
[self startSession];
return YES;
}
#pragma mark - Helper
-(void)startSession{
[IOLLogging setDebugLevel:IOLDebugLevelVerbose];
BOOL isOptOut = [[NUserDefaults standardUserDefaults] boolForKey:@"IOLSOptOutKey"];
if(!isOptOut) {
[IOLSession defaultSessionFor:IOLSessionTypeOEWA] startSessionWithOfferIdentifier:@"oewaOfferID"
privacyType:IOLPrivacyTypeLIN];
}
}
@end
NS_ASSUME_NONNULL_END
Swift:
func start(withOfferIdentifier offerIdentifier: String, privacyType: IOLPrivacyType)
session.start(withOfferIdentifier: „iamtest“, privacyType: .LIN)
// AddDelegate.swift
// SwiftSample
//
// Copyright (c) 2017 RockAByte GmbH. All rights reserved
//
import UIKit
import INFOnlineLibrary
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]? = nil) -> Bool {
startSession()
return true
}
//MARK: - Helper
private func startSession() {
IOLLogging.setDebugLogLevel(.verbose)
let isOptOut = UserDefaults.standard.bool(forKey: "IOLSOptOutKey")
guard !isOptOut else { return }
IOLSession.defaultSession(for: .OEWA).start(withOfferIdentifier: "oewaOfferID", privacyType: .LIN)
}
}
3.5.3 Logging eines Events
Die Messdaten werden mittels des Aufrufs logEvent erfasst. Dabei muss ein zuvor initialisiertes Event übergeben werden.
Objective-C:
- (void)logEvent:(IOLEvent*)event;
Swift:
func logEvent(_ event: IOLEvent)
Um ein Event zu erzeugen, muss ein Initializer der entsprechenden IOLEvent-Subklasse aufgerufen werden. Dabei können bis zu vier Parameter übergeben werden, drei davon sind optional.
Objective-C:
- (IOL_xy_Event*)initWithType:(IOL_xy_EventType)type;
- (IOL_xy_Event*)initWithType:(IOL_xy_EventType)type category:(nullable NSString*)category comment:(nullable NSString*)comment;
- (IOL_xy_Event*)initWithType:(IOL_xy_EventType)type category:(nullable NSString*)category comment:(nullable NSString*)comment parameter:(nullable NSDictionary*)parameter;
Swift:
public init(type: IOL_xy_EventType) -> IOL_xy_Event
public init(type: IOL_xy_EventType, category: String?, comment: String?) -> IOL_xy_Event
public init(type: IOL_xy_EventType, category: String?, comment: String?, parameter: [String: String]?) -> IOL_xy_Event
Die ersten beiden Aufrufe sind Convenience-Funktionen, welche intern die Letztgenannte aufrufen.
Die fehlenden Werte werden dann um nil bzw. Default-Werte ergänzt.
Parameter:
- EventType (mandatory)
Die einzelnen Events können verschiedene Zustände einnehmen. So kann ein Download z.B. gestartet, durch den User abgebrochen, erfolgreich durchgeführt oder fehlerhaft beendet worden sein.
Bei einigen Events entfällt der type Parameter, da für diese Events nur ein gültiger Type definiert ist. Beim IOLCustomEvent wird statt eines type der frei definierbare String Parameter name benötigt. - Category (mandatory): Contentpath
Der Contentpath wird im Parameter “category“ übermittelt. Dieser Code wird vom Anbieter selbst festgelegt. Die syntaktischen Vorgaben sind Kapitel 4.2 (Richtlinien zur Vergabe der Codes) zu entnehmen. Der Code dient zur inhaltlichen Kennzeichnung des angezeigten Content.
Der Anbieter entscheidet anhand der im Kapitel 4 (Vorgaben zum Aufruf der ÖWA-Library) beschriebenen Richtlinien, ob ein Event eine gültige PI im Sinne der ÖWA-Richtlinien darstellt. Wenn ein Event unter die Definition einer gültigen PI fällt, ist zwingend ein Contentpath mitzugeben. Stellt ein Event keine gültige PI dar, soll nil übergeben werden. Die Länge dieses Feldes ist auf 255 Zeichen beschränkt. - Kommentar (optional)
Kommentarfeld. Die Länge dieses Feldes ist nicht beschränkt. Übergabe dieses Wertes ist optional, ist er nicht definiert, soll nil übergeben werden. - Parameter (optional)
Ein Dictionary mit frei bestimmbaren Zusatzinformationen zu dem Event. Key und Value müssen vom Typ String sein, die maximale Länge ist jeweils auf 255 Zeichen beschränkt.
Übergabe dieses Wertes ist optional, ist er nicht definiert, soll nil übergeben werden.
Verfügbare Events
Die IOLib stellt folgende von „IOLEvent“ abgeleitete Event-Klassen mit den zugehörigen Types zur Verfügung:
- IOLViewEvent
- IOLViewEventTypeAppeared
Beispiele:
IOLViewEvent/IOLViewEventTypeAppeared
Objective-C:
@implementation ViewController
- (void)viewDidAppear:(BOOL)animated {
[super viewDidAppear:animated];
IOLEvent *event = [IOLViewEvent initWithState:IOLViewEventTypeAppeared
category:@”Home”
comment:nil];
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] logEvent:event];
// Other Code ..
}
Swift:
class ViewController: UIViewController {
override func viewDidAppear(_ animated: Bool) {
super.viewDidAppear(animated)
let event = IOLViewEvent(type: .appeared,
category: "Home"
comment: nil)
IOLSession.defaultSession(for: .OEWA).logEvent(event)
// Other Code ..
}
}
3.5.4 Versand der Messdaten
-(void)sendLoggedEvents;
Die IOLib steuert den Versand der Messdaten selbständig und völlig transparent für den Enduser. Um den Versand der Daten zu forcieren, kann sendLoggedEvents aufgerufen werden. Die IOLib versucht dann, die Messdaten sofort bzw. alternativ nochmals zu versenden, sobald eine Datenverbindung aufgebaut wurde.
Beispiele:
Objective-C:
@implementation ViewController
- (IBAction)send:(id)sender {
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] sendLoggedEvents];
}
Swift:
class ViewController: UIViewController {
@IBAction func send(sender: AnyObject) {
IOLSession.defaultSession(for: .OEWA).sendLoggedEvents()
}
}
3.5.5 Session beenden
– (void)terminateSession;
Die aktive Session der IOLib kann explizit beendet werden. Dies ermöglicht ein Opt-out während der App-Laufzeit. Die bis dahin erfassten Daten werden nicht mehr versendet.
Nur bei Opt-out durch den Nutzer verwenden!
Beispiele:
Objective-C:
@implementation ViewController
- (void)disableIOLSession {
[[IOLSession defaultSessionFor:IOLSessionTypeOEWA] terminateSession];
}
Swift:
class ViewController: UIViewController {
func disableIOLSession() {
IOLSession.defaultSession(for: .OEWA).terminateSession()
}
}
Die IOLib Session muss anschließend neu gestartet werden! Das Vorgehen ist in Kapitel 3.4.2 (Start einer Session) beschrieben.
3.5.6 Einbindung Opt-out-Funktion
Die Implementierung obliegt dem Entwickler der jeweiligen App und sollte bei Aktivierung durch den Benutzer dazu führen, dass die ÖWA-Library entweder gar nicht initialisiert wird oder die laufende Session explizit beendet wird. Das Vorgehen ist in Kapitel 3.4.5 (Session beenden) beschrieben.
Nach Einbindung der Funktion können die Nutzer der App das Opt-out aktivieren und deaktivieren. Sofern Opt-out aktiviert wird, wird kein Zählimpuls ausgelöst.
Wird die laufende Session explizit beendet, dann werden alle bis dahin erfassten, aber noch nicht versandten Messdaten verworfen.
Wird das Opt-out revidiert, dann sollte die MessLib wieder gestartet werden. Das Vorgehen ist in Kapitel 3.5.2 (Start einer Session) beschrieben.
3.6 Debug-Informationen
Zum Zweck der allgemeinen Fehleranalyse und insb. des Versands der Messdaten kann die ÖWA-Library in einen Debug-Modus versetzt werden. In diesem Debug-Modus erzeugt die ÖWA-Library Ausgaben im Logstrom (Konsole). Um die IOLib in den DebugModus zu versetzen, wir die Methode setDebugModeEnabled aufgerufen:
IOLSession.setDebugModeEnabled(true);
Per default ist der Debug-Modus deaktiviert, es sei denn, der Debug-Modus wurde bei der Initialisierung explizit aktiviert.
Objective-C:
- (void)applicationDidFinishLaunching:(UIApplication*)application {
[IOLLogging setDebugLogLevel:IOLDebugLevelInfo];
}
Swift:
func applicationDidFinishLaunching(application: UIApplication) {
IOLLogging.setDebugLogLevel(.info)
}
Art und Umfang der Logausgaben können über einen DebugLevel bestimmt werden.
Folgende Debug-Level sind definiert:
- IOLDebugLevelOff
➢ Logausgabe: Deaktiviert(Default) - IOLDebugLevelError
➢ Logausgabe: nur Fehler - IOLDebugLevelWarning
➢ Logausgabe: Fehler und Warnungen - IOLDebugLevelInfo
➢ Logausgabe: Fehler, Warnungen und Infos - IOLDebugLevelTrace
➢ Logausgabe: Fehler, Warnungen, Infos, Events, Requests und Responses
Requests und Responses werden im Documents Folder gespeichert. Zu Debugging-Zwecken kann in iTunes Filesharing eingeschaltet werden und die entsprechenden Dateien einfach über iTunes kopiert werden.
3.7 App Tracking Transparency Framework (ab iOS14)
Mit Einführung von iOS14 wird der bisherige LAT (Limit Ad Tracking) Mechanismus durch das neue Framework „App Tracking Transparency“ (ATT) abgelöst. Die IOLib unterstützt ATT ab Version 2.2.0 und respektiert die über die App einzuholende Einwilligung resp. Ablehnung der Nutzer ebenso wie die Einstellungen/Restriktionen im jeweiligen Endgerät.
Zur Erhebung des für die ÖWA-Messung erforderlichen Identifier (Advertising Identifier / IDFA) müssen Apps, welche das iOS14 SDK oder höher nutzen, die notwendigen Schritte gemäß Apple iOS Developer Dokumentation auszuführen.
Im Wesentlichen sind dies die folgenden 2 Schritte:
1. In Xcode: Neuen Key in Info.plist einfügen
In der Information Property List des Projekts muss ein neuer Key „NSUserTrackingUsageDescription“ angelegt werden:
Dieser enthält einen Text (String) zur Erläuterung der Begründung für die Abfrage zum Tracking der Werbe-ID (IDFA) durch die jeweilige App.
2. In Xcode:
Direkt nach Start der App sollte die Authorisierungsanfrage ausgelöst werden, indem die Methode „requestTrackingAuthorization“ aufgerufen wird.
Objective-C:
#import
...
- (BOOL)application:(UIApplication*)application didFinishLaunchingWithOptions:(nullable NSDictionary*)launchOptions {
[self requestIDFA];
// start IOLSession
return YES;
}
- (void)requestIDFA {
[ATTrackingManager requestTrackingAuthorizationWithCompletionHandler:
^(ATTrackingManagerAuthorizationStatus status) {
//Tracking authorization completed
}];
}
Swift:
import AppTrackingTransparency
...
func application(_ application: UIApplication, didfinishlaunchingWithOptions
launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
requestIDFA()
// start IOLSession
return true
}
private func requestIDFA() {
ATTrackingManager.requestTrackingAuthorization(completionHandler: { status in
// Tracking authorization completed
})
}
Wird diese Anfrage zum ersten Mal gestellt, erscheint folgender Alert (Beispiel aus IOLibSample):
Der Text innerhalb des roten Rahmens entspricht exakt dem String, welcher in Schritt 1 in der Info.plist unter „NSUserTrackingUsageDescription“ definiert wurde.
Das iOS System persistiert die Wahl des Nutzer, daher erscheint dieser Alert exakt einmal. Wurde die Erlaubnis zur Abfrage in den System-Einstellungen des Gerätes global deaktiviert, dann wird der Alert nicht angezeigt.
Es ist ratsam, den App Nutzern vor Aufruf der ATT-Authorisierungsabfrage die Hintergründe dieser Abfrage ausführlicher zu erläutern. Dies könnte die Opt-in Quote deutlich erhöhen.
Da Apple die Pflicht des Einbaus der Abfrage des Advertising Identifiers auf April 2021 verschoben hat, kann eine App noch mit dem SDK13 kompiliert werden. So erscheint in der App keine ATT-Authorisierungsabfrage. Der AuthorizationStatus bleibt auf „NotDetermined“ und somit wird weiterhin der Advertising Identifier geliefert.
3.8 Hinweise zum Apple Store
Wir möchten Sie erinnern, dass seit dem 8. Dezember 2020 für den Apple App Store Datenschutzangaben verpflichtend sind. Dies gilt sowohl für neue Apps und App-Updates. Im Folgenden finden Sie sämtliche Informationen, welche in diesem Zusammenhang bereits für Sie zur Verfügung stehen.
Welche Informationen müssen für die IOLib angegeben werden?
Folgen Sie der Anleitung zum Update der App Privacy Details. Diese finden Sie unter folgendem Link:
https://help.apple.com/app-store-connect/#/dev1b4647c5b
3.8.1 Layer Datenerfassung
Frage:
Erfassen Sie oder Ihre Drittanbieter Daten von dieser App?
Auszuwählende Antwort:
Ja, wir erfassen Daten von dieser App
Auswahl Punkt Kennungen:
Geräte-ID
Auswahl Punkt :
Produktinteraktion
Werbedaten
3.8.2 Layer Geräte-ID
Frage:
Werden die von dieser App erfassten Geräte-IDs mit der Identität des Benutzers verknüpft?
Auszuwählende Antwort:
Nein, die von dieser App erfassten Geräte-IDs werden nicht mit der Identität des Benutzers verknüpft.
Frage:
Verwenden Sie oder Ihre Drittanbieter Geräte-IDs für Tracking-Zwecke?
Auszuwählende Antwort:
Ja, wir verwenden Geräte-IDs für Tracking-Zwecke
3.8.3 Layer Produktinteraktion
Frage:
Werden die von dieser App erfassten Daten zur Produktinteraktion mit der Identität des Benutzers verknüpft?
Auszuwählende Antwort:
Nein, die von dieser App erfassten Produktinteraktion werden nicht mit der Identität des Benutzers verknüpft.
Frage:
Verwenden Sie oder Drittpartner Daten zur Produktinteraktion für Tracking-Zwecke?
Auszuwählende Antwort:
Ja, wir verwenden Produktinteraktion für Tracking-Zwecke
3.8.4 Layer Werbedaten
Frage:
Werden die von dieser App erfassten Werbedaten mit der Identität des Benutzers verknüpft?
Auszuwählende Antwort:
Nein, die von dieser App erfassten Werbedaten werden nicht mit der Identität des Benutzers verknüpft.
Frage:
Verwenden Sie oder Ihre Drittpartner Werbedaten für Tracking-Zwecke?
Auszuwählende Antwort:
Ja, wir verwenden Werbedaten für Tracking-Zwecke
3.8.5 Layer Gesamtübersicht
In diesem Layer sehen Sie nochmal den Überblick Ihrer Eingaben.
4 Vorgaben zum Aufruf der ÖWA-Library
4.1 Allgemeines
Die Erfassung der App-Nutzung durch den Benutzer erfolgt, indem die App die ÖWA-Library bei definierten Ereignissen, welche eine Nutzer-Interaktion kennzeichnen, aufruft.
Die Nutzer-Interaktion wird als Event bezeichnet.
Die ÖWA-Library muss von der App bei Eintreten des Events explizit aufgerufen werden.
4.1.1 Interpretation von Events als gültige PI
Die nachfolgend aufgeführten Vorgaben definieren, wie die ÖWA-Library im Kontext der
ÖWA App Messung zu verwenden ist.
PI-Events
Bei den PI-Events wird der Event dazu benutzt, analog zur Web-Messung, eine Page Impression zu erzeugen. Diesem Event muss ein Contentpath (in der Folge einfach als „CP“ bezeichnet) zugeordnet werden. Dieser CP kann anschließend den unterschiedlichen Kategorien zugeordnet werden und dient als Grundlage für die Bildung von Belegungseinheiten. Bei den PI-Events sind die Vorgaben zur Page Impression der ÖWA zu beachten.
4.2 Richtlinien zur Vergabe des Contentpath
Bei den PI-Events ist der CP als eindeutige Kennzeichnung des angezeigten Inhalts mitzugeben. Der CP wird vom App-Anbieter spezifiziert.
Bei der Spezifikation des Contentpaths sind die CP-Richtlinien der ÖWA zu beachten:
– Länge: Ein CP darf maximal 255 Zeichen enthalten
– Anzahl: Es dürfen maximal 15.000 CPs verwendet werden
– Erlaubte Zeichen: a-z, A-Z, 0-9; Komma „,“; Bindestrich „-“; Unterstrich „_“; Slash „/“
Eine ausführliche Liste gültiger ÖWA-Kategorien (Contentpath) finden Sie unter: