iOS: improve consent dialog

master
MoNTE48 2022-01-19 21:34:11 +01:00
parent 7fea51579d
commit 91b4202e56
4 changed files with 186 additions and 123 deletions

View File

@ -43,9 +43,9 @@
84A4380425535BA5002571D4 /* soft_oal.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84A4380325535BA5002571D4 /* soft_oal.framework */; };
84A4380525535BA5002571D4 /* soft_oal.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 84A4380325535BA5002571D4 /* soft_oal.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
84A608A425F0A02900D79FCD /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 84A608A325F0A02900D79FCD /* Sentry */; };
84B1647F27988B92002A670A /* Bundle+AppIcon.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B1647E27988B92002A670A /* Bundle+AppIcon.swift */; };
84B9C11724A4D82400016BCE /* ConsentAlertViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84B9C11524A4D82400016BCE /* ConsentAlertViewController.swift */; };
84B9C11824A4D82400016BCE /* ConsentAlertViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 84B9C11624A4D82400016BCE /* ConsentAlertViewController.xib */; };
84C32A3724AF7A4500445E92 /* Nantes in Frameworks */ = {isa = PBXBuildFile; productRef = 84C32A3624AF7A4500445E92 /* Nantes */; };
84C32A3924AF7DDE00445E92 /* UITextViewPlaceholder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84C32A3824AF7DDE00445E92 /* UITextViewPlaceholder.swift */; };
84C67B1E25D5E06B002E2735 /* AppTrackingTransparency.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 84C67B1D25D5E06B002E2735 /* AppTrackingTransparency.framework */; };
84CD4A64248782720019B81D /* MainWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 84CD4A59248782720019B81D /* MainWindow.swift */; };
@ -323,6 +323,7 @@
8473ED8325C0562C0053293B /* unidata.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = unidata.h; path = ../../../../lib/luautf8/unidata.h; sourceTree = "<group>"; };
849C4F85209656D2005EB041 /* ru.lproj */ = {isa = PBXFileReference; lastKnownFileType = folder; path = ru.lproj; sourceTree = "<group>"; };
84A4380325535BA5002571D4 /* soft_oal.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = soft_oal.framework; path = ../deps/soft_oal.framework; sourceTree = "<group>"; };
84B1647E27988B92002A670A /* Bundle+AppIcon.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Bundle+AppIcon.swift"; sourceTree = "<group>"; };
84B9C11524A4D82400016BCE /* ConsentAlertViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConsentAlertViewController.swift; sourceTree = "<group>"; };
84B9C11624A4D82400016BCE /* ConsentAlertViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ConsentAlertViewController.xib; sourceTree = "<group>"; };
84C32A3824AF7DDE00445E92 /* UITextViewPlaceholder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextViewPlaceholder.swift; sourceTree = "<group>"; };
@ -748,7 +749,6 @@
F8E6C7D51DCA476800F64426 /* libIrrlicht.a in Frameworks */,
84A608A425F0A02900D79FCD /* Sentry in Frameworks */,
843F4C3126617D0D005277FA /* ZipArchive in Frameworks */,
84C32A3724AF7A4500445E92 /* Nantes in Frameworks */,
F8E6C7C91DCA430300F64426 /* OpenGLES.framework in Frameworks */,
8E0FFE3234B35EC9603EC82A /* Pods_MultiCraft.framework in Frameworks */,
F8E6C7C51DCA42F300F64426 /* QuartzCore.framework in Frameworks */,
@ -800,6 +800,22 @@
name = irrlicht_changes;
sourceTree = "<group>";
};
84B1647C27988B92002A670A /* Extensions */ = {
isa = PBXGroup;
children = (
84B1647D27988B92002A670A /* Bundle */,
);
path = Extensions;
sourceTree = "<group>";
};
84B1647D27988B92002A670A /* Bundle */ = {
isa = PBXGroup;
children = (
84B1647E27988B92002A670A /* Bundle+AppIcon.swift */,
);
path = Bundle;
sourceTree = "<group>";
};
84CD4A56248782720019B81D /* Main */ = {
isa = PBXGroup;
children = (
@ -882,6 +898,7 @@
F8E6C4DC1DCA3B7900F64426 /* Supporting Files */ = {
isa = PBXGroup;
children = (
84B1647C27988B92002A670A /* Extensions */,
84CD4A56248782720019B81D /* Main */,
84CD4A5A248782720019B81D /* UI */,
84CD4A55248781420019B81D /* Bridge-Header.h */,
@ -1451,7 +1468,6 @@
);
name = MultiCraft;
packageProductDependencies = (
84C32A3624AF7A4500445E92 /* Nantes */,
84A608A325F0A02900D79FCD /* Sentry */,
843F4C3026617D0D005277FA /* ZipArchive */,
);
@ -1491,7 +1507,6 @@
);
mainGroup = F8E6C4D01DCA3B7900F64426;
packageReferences = (
84C32A3524AF7A4500445E92 /* XCRemoteSwiftPackageReference "Nantes" */,
84A608A225F0A02900D79FCD /* XCRemoteSwiftPackageReference "sentry-cocoa" */,
843F4C2F26617D0D005277FA /* XCRemoteSwiftPackageReference "ZipArchive" */,
);
@ -1663,6 +1678,7 @@
F8E6C6F61DCA41DB00F64426 /* c_content.cpp in Sources */,
4B35A9EA1EEE010D00274961 /* l_metadata.cpp in Sources */,
F8E6C6551DCA3F9900F64426 /* shader.cpp in Sources */,
84B1647F27988B92002A670A /* Bundle+AppIcon.swift in Sources */,
F8E6C7491DCA420A00F64426 /* l_env.cpp in Sources */,
F8E6C6381DCA3F9900F64426 /* mapsector.cpp in Sources */,
F8E6C7B81DCA428800F64426 /* auth.cpp in Sources */,
@ -2073,14 +2089,6 @@
minimumVersion = 7.5.0;
};
};
84C32A3524AF7A4500445E92 /* XCRemoteSwiftPackageReference "Nantes" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/instacart/Nantes";
requirement = {
kind = upToNextMinorVersion;
minimumVersion = 0.1.2;
};
};
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
@ -2094,11 +2102,6 @@
package = 84A608A225F0A02900D79FCD /* XCRemoteSwiftPackageReference "sentry-cocoa" */;
productName = Sentry;
};
84C32A3624AF7A4500445E92 /* Nantes */ = {
isa = XCSwiftPackageProductDependency;
package = 84C32A3524AF7A4500445E92 /* XCRemoteSwiftPackageReference "Nantes" */;
productName = Nantes;
};
/* End XCSwiftPackageProductDependency section */
};
rootObject = F8E6C4D11DCA3B7900F64426 /* Project object */;

View File

@ -0,0 +1,14 @@
import UIKit
extension Bundle {
var appIcon: UIImage? {
if let icons = infoDictionary?["CFBundleIcons"] as? [String: Any],
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
let lastIcon = iconFiles.last {
return UIImage(named: lastIcon)
}
return nil
}
}

View File

@ -1,16 +1,15 @@
import UIKit
import Nantes
private enum Constants {
static let oldInfoStatusKey = "personalized_ad_status"
static let newInfoStatusKey = "new_personalized_ad_status"
}
final class ConsentAlertViewController: BasePresentViewController, NantesLabelDelegate {
final class ConsentAlertViewController: BasePresentViewController {
@IBOutlet private weak var buttonRelevant: UIButton!
@IBOutlet private weak var buttonAllow: UIButton!
@IBOutlet private weak var viewContainer: UIView!
@IBOutlet private weak var labelPrivacy: NantesLabel!
@IBOutlet private weak var privacyTextView: UITextView!
@IBOutlet private weak var viewFirst: UIView!
@IBOutlet private weak var viewSecond: UIView!
@IBOutlet private weak var buttonAgree: UIButton!
@ -26,6 +25,8 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
var finishTapped: (() -> Void)?
let screenWidth = UIScreen.main.bounds.size.width
private enum Status: String, Codable {
case unknown
case personalized
@ -50,8 +51,13 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
override func viewWillLayoutSubviews() {
super.viewWillLayoutSubviews()
imageAppIcon.layer.cornerRadius = imageAppIcon.frame.size.height * 0.22
setupContentHeight()
if (isShowFirstPage && screenWidth <= 568.0) {
buttonAllow.titleLabel?.font = .boldSystemFont(ofSize: 15)
buttonRelevant.titleLabel?.font = .boldSystemFont(ofSize: 15)
}
}
private func setupContentHeight() {
@ -60,12 +66,16 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
}
private func setupUI() {
if UIScreen.main.bounds.size.width <= 667 {
leftPadding.constant = 30
rightPadding.constant = 30
var widthMultiplierValue: CGFloat = 0.7
if screenWidth <= 568.0 {
widthMultiplierValue = 0.95
} else if screenWidth <= 667.0 {
widthMultiplierValue = 0.91
}
imageAppIcon.image = Bundle.main.icon
viewContainer.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: widthMultiplierValue).isActive = true
imageAppIcon.image = Bundle.main.appIcon
buttonAgree.layer.cornerRadius = 6
buttonBack.layer.borderWidth = 1
@ -75,12 +85,10 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
buttonAllow.layer.cornerRadius = 8
buttonAllow.layer.borderWidth = 3
buttonAllow.layer.borderColor = UIColor(220, 220, 220).cgColor
buttonAllow.titleLabel?.numberOfLines = 2
buttonRelevant.layer.cornerRadius = 8
buttonRelevant.layer.borderWidth = 3
buttonRelevant.layer.borderColor = UIColor(220, 220, 220).cgColor
buttonRelevant.titleLabel?.numberOfLines = 2
viewContainer.layer.shadowColor = UIColor.black.cgColor
viewContainer.layer.shadowRadius = 6
@ -88,20 +96,27 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
viewContainer.layer.shadowOffset = .init(width: 0, height: 3)
viewContainer.layer.cornerRadius = 8
labelPrivacy.delegate = self
let text = "Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on Privacy Policy."
labelPrivacy.text = text
setupTextView()
}
labelPrivacy.linkAttributes = [NSAttributedString.Key.underlineColor: NSUnderlineStyle.single.rawValue,
NSAttributedString.Key.foregroundColor: UIColor(0, 98, 232)]
private func setupTextView() {
privacyTextView.delegate = self
privacyTextView.backgroundColor = .clear
privacyTextView.textContainerInset = UIEdgeInsets(top: 0.0, left: privacyTextView.textContainerInset.left, bottom: 0.0, right: privacyTextView.textContainerInset.right)
privacyTextView.textContainer.lineFragmentPadding = 0
let paragraphStyle = NSMutableParagraphStyle()
paragraphStyle.alignment = .center
privacyTextView.linkTextAttributes = [NSAttributedString.Key.foregroundColor : UIColor.blue]
labelPrivacy.activeLinkAttributes = [NSAttributedString.Key.backgroundColor: UIColor(white: 0.5, alpha: 0.5),
NSAttributedString.Key.underlineColor: NSUnderlineStyle.single.rawValue]
let attributedString = NSMutableAttributedString(string: "Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on ", attributes: [NSAttributedString.Key.paragraphStyle : paragraphStyle, NSAttributedString.Key.foregroundColor : UIColor.darkGray])
labelPrivacy.lineSpacing = 3
labelPrivacy.textColor = .lightGray
labelPrivacy.addLink(to: privacyURL, withRange: (text as NSString).range(of: "Privacy Policy"))
let linkAttrString = NSMutableAttributedString(string: "Privacy Policy", attributes: [NSAttributedString.Key.link : privacyURL.absoluteString])
attributedString.append(linkAttrString)
attributedString.append(NSMutableAttributedString(string: "."))
privacyTextView.attributedText = attributedString
}
@IBAction private func showMulticraftUses(_ sender: Any) {
@ -120,12 +135,6 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
}
}
@IBAction private func showPrivacy(_ sender: Any) {
if UIApplication.shared.canOpenURL(privacyURL) {
UIApplication.shared.open(privacyURL)
}
}
@IBAction private func allowTapped(_ sender: Any) {
Self.setPersonalizedConsentStatus(.personalized)
finishTapped?()
@ -147,12 +156,6 @@ final class ConsentAlertViewController: BasePresentViewController, NantesLabelDe
self.view.layoutIfNeeded()
}
}
func attributedLabel(_ label: NantesLabel, didSelectLink link: URL) {
if UIApplication.shared.canOpenURL(link) {
UIApplication.shared.open(link)
}
}
}
extension ConsentAlertViewController {
@ -215,14 +218,8 @@ extension ConsentAlertViewController {
}
}
extension Bundle {
var icon: UIImage? {
if let icons = infoDictionary?["CFBundleIcons"] as? [String: Any],
let primaryIcon = icons["CFBundlePrimaryIcon"] as? [String: Any],
let iconFiles = primaryIcon["CFBundleIconFiles"] as? [String],
let lastIcon = iconFiles.last {
return UIImage(named: lastIcon)
}
return nil
extension ConsentAlertViewController: UITextViewDelegate {
func textViewDidChangeSelection(_ textView: UITextView) {
textView.selectedTextRange = nil
}
}

View File

@ -1,8 +1,11 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="16097" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="19529" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_5" orientation="landscape" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16087"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="19519"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<objects>
@ -14,9 +17,7 @@
<outlet property="buttonRelevant" destination="Rxj-Jo-vAL" id="fSr-Od-uZN"/>
<outlet property="containerHeight" destination="mdm-AS-So4" id="dVy-Df-6N4"/>
<outlet property="imageAppIcon" destination="ju7-3g-6gQ" id="AW9-2J-l6P"/>
<outlet property="labelPrivacy" destination="qle-ba-Sha" id="Q17-98-lxH"/>
<outlet property="leftPadding" destination="Ryb-ju-2gI" id="YfH-nI-hcr"/>
<outlet property="rightPadding" destination="ima-Vy-JsH" id="KoJ-yU-zSl"/>
<outlet property="privacyTextView" destination="UIS-L6-1Hk" id="goB-1D-Upq"/>
<outlet property="view" destination="i5M-Pr-FkT" id="sfx-zR-JGt"/>
<outlet property="viewContainer" destination="jN6-lz-Z5i" id="b4F-U0-QNA"/>
<outlet property="viewFirst" destination="no2-jY-28I" id="a62-Vq-hlY"/>
@ -29,146 +30,191 @@
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jN6-lz-Z5i">
<rect key="frame" x="80" y="67" width="736" height="280"/>
<rect key="frame" x="89.666666666666686" y="72" width="716.66666666666652" height="270"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bbD-X9-thg">
<rect key="frame" x="300.5" y="10" width="135.5" height="50"/>
<rect key="frame" x="287.33333333333331" y="10" width="142.33333333333331" height="40"/>
<subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" translatesAutoresizingMaskIntoConstraints="NO" id="ju7-3g-6gQ">
<rect key="frame" x="0.0" y="5" width="40" height="40"/>
<rect key="frame" x="0.0" y="0.0" width="40" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="MF5-dK-QZm"/>
<constraint firstAttribute="width" constant="40" id="gyE-ko-6qD"/>
<constraint firstAttribute="width" constant="40" id="gyE-ko-6qD">
<variation key="heightClass=regular-widthClass=regular" constant="60"/>
</constraint>
<constraint firstAttribute="width" secondItem="ju7-3g-6gQ" secondAttribute="height" multiplier="1:1" id="omA-jD-JXD"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="MultiCraft" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="VL7-9o-er1">
<rect key="frame" x="55" y="14.5" width="80.5" height="21.5"/>
<fontDescription key="fontDescription" type="system" pointSize="18"/>
<rect key="frame" x="54.999999999999993" y="9.3333333333333304" width="87.333333333333314" height="21.666666666666671"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="boldSystem" pointSize="25"/>
</variation>
</label>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="ju7-3g-6gQ" firstAttribute="centerY" secondItem="bbD-X9-thg" secondAttribute="centerY" id="9BN-kH-3SV"/>
<constraint firstItem="VL7-9o-er1" firstAttribute="centerY" secondItem="bbD-X9-thg" secondAttribute="centerY" id="LRC-gB-qkY"/>
<constraint firstAttribute="height" constant="50" id="Ox3-ju-Z6g"/>
<constraint firstItem="VL7-9o-er1" firstAttribute="leading" secondItem="ju7-3g-6gQ" secondAttribute="trailing" constant="15" id="PvL-dV-kaL"/>
<constraint firstItem="ju7-3g-6gQ" firstAttribute="top" secondItem="bbD-X9-thg" secondAttribute="top" id="hH8-J1-ABV"/>
<constraint firstItem="ju7-3g-6gQ" firstAttribute="leading" secondItem="bbD-X9-thg" secondAttribute="leading" id="iPB-7V-PH7"/>
<constraint firstAttribute="bottom" secondItem="ju7-3g-6gQ" secondAttribute="bottom" id="m0q-dQ-YcL"/>
<constraint firstAttribute="trailing" secondItem="VL7-9o-er1" secondAttribute="trailing" id="pco-lS-gvm"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="FVI-kf-H4t">
<rect key="frame" x="0.0" y="70" width="736" height="200"/>
<rect key="frame" x="0.0" y="60" width="716.66666666666663" height="200"/>
<subviews>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="no2-jY-28I" userLabel="first">
<rect key="frame" x="0.0" y="9.5" width="736" height="181"/>
<rect key="frame" x="0.0" y="2" width="716.66666666666663" height="196"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="We care about your privacy and data security. We keep this app free by showing ads." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="reR-NS-ZXk">
<rect key="frame" x="50" y="0.0" width="636" height="38.5"/>
<rect key="frame" x="50" y="0.0" width="616.66666666666663" height="38.333333333333336"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="16"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="21"/>
</variation>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Can we continue to use your data to tailor ads for you?" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Rbf-k7-ND1">
<rect key="frame" x="30" y="53.5" width="676" height="20.5"/>
<rect key="frame" x="30" y="53.333333333333343" width="656.66666666666663" height="20.333333333333329"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
<color key="textColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="22"/>
</variation>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="qle-ba-Sha" customClass="NantesLabel" customModule="Nantes">
<rect key="frame" x="20" y="89" width="696" height="27"/>
<string key="text">Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on Privacy Policy</string>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" bouncesZoom="NO" editable="NO" textAlignment="center" translatesAutoresizingMaskIntoConstraints="NO" id="UIS-L6-1Hk">
<rect key="frame" x="20" y="88.666666666666657" width="676.66666666666663" height="42.333333333333343"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<string key="text">Our partners will collect data and use a unique identifier on your device to show you ads. By agreeing, you confirm that you are 16 years old. You can learn how we and our partners collect and use data on </string>
<color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rxj-Jo-vAL">
<rect key="frame" x="375.5" y="131" width="345.5" height="50"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="No, see ads that are less releant"/>
<connections>
<action selector="relevantTapped:" destination="-1" eventType="touchUpInside" id="g2V-dM-M7Y"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qsc-Xi-g92">
<rect key="frame" x="15" y="131" width="345.5" height="50"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="16"/>
</variation>
</textView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="fillEqually" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="hAu-gU-FOo">
<rect key="frame" x="15" y="146" width="686.66666666666663" height="50"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qsc-Xi-g92">
<rect key="frame" x="0.0" y="0.0" width="336" height="50"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="Yes, I allow to use my data">
<color key="titleColor" red="0.0" green="0.50196078431372548" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="22"/>
</variation>
<connections>
<action selector="allowTapped:" destination="-1" eventType="touchUpInside" id="Dj8-nb-viX"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Rxj-Jo-vAL">
<rect key="frame" x="351" y="0.0" width="335.66666666666674" height="50"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="No, see ads that are less releant">
<color key="titleColor" red="1" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</state>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="22"/>
</variation>
<connections>
<action selector="relevantTapped:" destination="-1" eventType="touchUpInside" id="g2V-dM-M7Y"/>
</connections>
</button>
</subviews>
<constraints>
<constraint firstAttribute="height" constant="50" id="UQv-WK-cC3"/>
<constraint firstAttribute="height" constant="50" id="fME-oB-mgo">
<variation key="heightClass=regular-widthClass=regular" constant="70"/>
</constraint>
</constraints>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<state key="normal" title="Yes, I allow to use my data"/>
<connections>
<action selector="allowTapped:" destination="-1" eventType="touchUpInside" id="Dj8-nb-viX"/>
</connections>
</button>
</stackView>
</subviews>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="Rbf-k7-ND1" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="30" id="2Br-ef-GGz"/>
<constraint firstAttribute="bottom" secondItem="qsc-Xi-g92" secondAttribute="bottom" id="2Mx-zx-h7L"/>
<constraint firstItem="qsc-Xi-g92" firstAttribute="width" secondItem="Rxj-Jo-vAL" secondAttribute="width" id="2Ue-Yh-2qf"/>
<constraint firstAttribute="trailing" secondItem="Rbf-k7-ND1" secondAttribute="trailing" constant="30" id="2l2-ee-69m"/>
<constraint firstAttribute="trailing" secondItem="Rxj-Jo-vAL" secondAttribute="trailing" constant="15" id="59i-dn-8ok"/>
<constraint firstItem="Rxj-Jo-vAL" firstAttribute="leading" secondItem="qsc-Xi-g92" secondAttribute="trailing" constant="15" id="5xv-IS-Bs3"/>
<constraint firstAttribute="trailing" secondItem="reR-NS-ZXk" secondAttribute="trailing" constant="50" id="8Nh-tt-z0k"/>
<constraint firstItem="qsc-Xi-g92" firstAttribute="top" secondItem="qle-ba-Sha" secondAttribute="bottom" constant="15" id="DoF-Us-qDK"/>
<constraint firstItem="Rxj-Jo-vAL" firstAttribute="height" secondItem="qsc-Xi-g92" secondAttribute="height" id="HVP-2W-nY0"/>
<constraint firstItem="hAu-gU-FOo" firstAttribute="top" secondItem="UIS-L6-1Hk" secondAttribute="bottom" constant="15" id="N9p-41-frs"/>
<constraint firstItem="hAu-gU-FOo" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="15" id="SAj-br-Qgz"/>
<constraint firstItem="Rbf-k7-ND1" firstAttribute="top" secondItem="reR-NS-ZXk" secondAttribute="bottom" constant="15" id="Twf-aC-yrB"/>
<constraint firstAttribute="trailing" secondItem="qle-ba-Sha" secondAttribute="trailing" constant="20" id="VYy-4Q-DpO"/>
<constraint firstItem="reR-NS-ZXk" firstAttribute="top" secondItem="no2-jY-28I" secondAttribute="top" id="YPQ-2N-HjD"/>
<constraint firstItem="Rxj-Jo-vAL" firstAttribute="top" secondItem="qsc-Xi-g92" secondAttribute="top" id="a91-QX-7fT"/>
<constraint firstItem="qsc-Xi-g92" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="15" id="cyc-yq-fD7"/>
<constraint firstAttribute="bottom" secondItem="hAu-gU-FOo" secondAttribute="bottom" id="b9P-Ld-nZA"/>
<constraint firstAttribute="trailing" secondItem="hAu-gU-FOo" secondAttribute="trailing" constant="15" id="cgs-UN-bn9"/>
<constraint firstItem="UIS-L6-1Hk" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="20" id="ds9-ho-fos"/>
<constraint firstItem="reR-NS-ZXk" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="50" id="j30-js-cgR"/>
<constraint firstItem="qle-ba-Sha" firstAttribute="leading" secondItem="no2-jY-28I" secondAttribute="leading" constant="20" id="jyb-F3-agL"/>
<constraint firstItem="qle-ba-Sha" firstAttribute="top" secondItem="Rbf-k7-ND1" secondAttribute="bottom" constant="15" id="njl-xJ-UHL"/>
<constraint firstAttribute="trailing" secondItem="UIS-L6-1Hk" secondAttribute="trailing" constant="20" id="lPE-Yd-wYR"/>
<constraint firstItem="UIS-L6-1Hk" firstAttribute="top" secondItem="Rbf-k7-ND1" secondAttribute="bottom" constant="15" id="ylc-Ol-Zoc"/>
</constraints>
</view>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="b0v-eJ-u4n" userLabel="second">
<rect key="frame" x="0.0" y="36" width="736" height="128.5"/>
<rect key="frame" x="0.0" y="36" width="716.66666666666663" height="128.33333333333334"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Well partner with Appodeal and use a unique identifier on your device to respect your data usage choice." textAlignment="center" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lKc-3Y-oYd">
<rect key="frame" x="40" y="0.0" width="656" height="38.5"/>
<rect key="frame" x="40" y="0.0" width="636.66666666666663" height="38.333333333333336"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="0.33333333329999998" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="21"/>
</variation>
</label>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FtZ-2K-YYB">
<rect key="frame" x="264" y="43.5" width="208" height="40"/>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="FtZ-2K-YYB">
<rect key="frame" x="254.33333333333331" y="43.333333333333343" width="208" height="40"/>
<constraints>
<constraint firstAttribute="height" constant="40" id="6eW-eW-3sn"/>
</constraints>
<state key="normal" title="How MultiCraft uses your data"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="20"/>
</variation>
<connections>
<action selector="showMulticraftUses:" destination="-1" eventType="touchUpInside" id="LCL-n2-viJ"/>
</connections>
</button>
<view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="kok-zY-LLa">
<rect key="frame" x="268" y="88.5" width="200" height="40"/>
<rect key="frame" x="258.33333333333331" y="88.333333333333314" width="200" height="40"/>
<subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fHL-HQ-Ax8">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="fHL-HQ-Ax8">
<rect key="frame" x="120" y="0.0" width="80" height="40"/>
<color key="backgroundColor" red="0.0" green="0.38431372549019605" blue="0.90980392156862744" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstAttribute="width" constant="80" id="IA1-gD-Usp"/>
<constraint firstAttribute="width" constant="80" id="IA1-gD-Usp">
<variation key="heightClass=regular-widthClass=regular" constant="120"/>
</constraint>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="14"/>
<state key="normal" title="Agree">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="18"/>
</variation>
<connections>
<action selector="agreeTapped:" destination="-1" eventType="touchUpInside" id="L3x-I7-rA9"/>
</connections>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1nL-wW-oAr">
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="1nL-wW-oAr">
<rect key="frame" x="0.0" y="0.0" width="100" height="40"/>
<constraints>
<constraint firstAttribute="width" constant="100" id="Npb-sR-MK2"/>
<constraint firstAttribute="width" constant="100" id="Npb-sR-MK2">
<variation key="heightClass=regular-widthClass=regular" constant="140"/>
</constraint>
</constraints>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<inset key="titleEdgeInsets" minX="10" minY="0.0" maxX="0.0" maxY="0.0"/>
<inset key="imageEdgeInsets" minX="-10" minY="0.0" maxX="0.0" maxY="0.0"/>
<state key="normal" title="Back" image="icon_back"/>
<variation key="heightClass=regular-widthClass=regular">
<fontDescription key="fontDescription" type="system" pointSize="21"/>
</variation>
<connections>
<action selector="backTapped:" destination="-1" eventType="touchUpInside" id="Bnq-48-ydl"/>
</connections>
@ -177,12 +223,12 @@
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="1nL-wW-oAr" secondAttribute="bottom" id="1yD-Ct-4mA"/>
<constraint firstItem="fHL-HQ-Ax8" firstAttribute="leading" secondItem="1nL-wW-oAr" secondAttribute="trailing" constant="20" id="EM0-lY-QWh"/>
<constraint firstItem="fHL-HQ-Ax8" firstAttribute="top" secondItem="kok-zY-LLa" secondAttribute="top" id="J02-9n-GkM"/>
<constraint firstAttribute="trailing" secondItem="fHL-HQ-Ax8" secondAttribute="trailing" id="Jh5-HG-QGM"/>
<constraint firstAttribute="height" constant="40" id="cgR-IG-iWU"/>
<constraint firstItem="1nL-wW-oAr" firstAttribute="top" secondItem="kok-zY-LLa" secondAttribute="top" id="cvK-7Q-DcV"/>
<constraint firstAttribute="bottom" secondItem="fHL-HQ-Ax8" secondAttribute="bottom" id="gYN-KQ-Eh0"/>
<constraint firstAttribute="width" constant="200" id="gZr-LH-Jho"/>
<constraint firstItem="1nL-wW-oAr" firstAttribute="leading" secondItem="kok-zY-LLa" secondAttribute="leading" id="kmj-ly-5MP"/>
</constraints>
</view>
@ -223,17 +269,20 @@
</constraints>
</view>
</subviews>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<color key="backgroundColor" white="0.0" alpha="0.20000000000000001" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="width" secondItem="i5M-Pr-FkT" secondAttribute="width" multiplier="0.8" placeholder="YES" id="6oa-4n-J1R"/>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="centerY" secondItem="i5M-Pr-FkT" secondAttribute="centerY" id="79d-ga-FPU"/>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="leading" secondItem="i5M-Pr-FkT" secondAttribute="leading" constant="80" id="Ryb-ju-2gI"/>
<constraint firstAttribute="trailing" secondItem="jN6-lz-Z5i" secondAttribute="trailing" constant="80" id="ima-Vy-JsH"/>
<constraint firstItem="jN6-lz-Z5i" firstAttribute="centerX" secondItem="fnl-2z-Ty3" secondAttribute="centerX" id="XBL-cD-ih3"/>
</constraints>
<viewLayoutGuide key="safeArea" id="fnl-2z-Ty3"/>
<point key="canvasLocation" x="48.883928571428569" y="34.782608695652179"/>
<point key="canvasLocation" x="48.755490483162518" y="34.5703125"/>
</view>
</objects>
<resources>
<image name="icon_back" width="10" height="18"/>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>