Revises Auth flow UI

This commit is contained in:
Riley Testut
2019-09-07 15:29:19 -07:00
parent f5ea5a140a
commit ab8d51c000
11 changed files with 650 additions and 635 deletions

View File

@@ -201,15 +201,15 @@
BFE60740231AFD2A002B0E8E /* InsetGroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6073F231AFD2A002B0E8E /* InsetGroupTableViewCell.swift */; }; BFE60740231AFD2A002B0E8E /* InsetGroupTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6073F231AFD2A002B0E8E /* InsetGroupTableViewCell.swift */; };
BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */; }; BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */; };
BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFE6325922A83BEB00F30809 /* Authentication.storyboard */; }; BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFE6325922A83BEB00F30809 /* Authentication.storyboard */; };
BFE6325C22A83C0100F30809 /* AuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6325B22A83C0100F30809 /* AuthenticationViewController.swift */; };
BFE6325E22A8497000F30809 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6325D22A8497000F30809 /* SelectTeamViewController.swift */; };
BFE6326622A857C200F30809 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326522A857C100F30809 /* Team.swift */; }; BFE6326622A857C200F30809 /* Team.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326522A857C100F30809 /* Team.swift */; };
BFE6326822A858F300F30809 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326722A858F300F30809 /* Account.swift */; }; BFE6326822A858F300F30809 /* Account.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326722A858F300F30809 /* Account.swift */; };
BFE6326A22A85DAF00F30809 /* ReplaceCertificateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326922A85DAF00F30809 /* ReplaceCertificateViewController.swift */; };
BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */; }; BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */; };
BFF0B68E23219520007A79E1 /* PatreonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B68D23219520007A79E1 /* PatreonViewController.swift */; }; BFF0B68E23219520007A79E1 /* PatreonViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B68D23219520007A79E1 /* PatreonViewController.swift */; };
BFF0B69023219C6D007A79E1 /* PatreonComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */; }; BFF0B69023219C6D007A79E1 /* PatreonComponents.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */; };
BFF0B6922321A305007A79E1 /* AboutPatreonHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */; }; BFF0B6922321A305007A79E1 /* AboutPatreonHeaderView.xib in Resources */ = {isa = PBXBuildFile; fileRef = BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */; };
BFF0B6942321CB85007A79E1 /* AuthenticationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6932321CB85007A79E1 /* AuthenticationViewController.swift */; };
BFF0B6982322CAB8007A79E1 /* InstructionsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6972322CAB8007A79E1 /* InstructionsViewController.swift */; };
BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */; };
DBAC68F8EC03F4A41D62EDE1 /* Pods_AltStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1039C07E517311FC499A0B64 /* Pods_AltStore.framework */; }; DBAC68F8EC03F4A41D62EDE1 /* Pods_AltStore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1039C07E517311FC499A0B64 /* Pods_AltStore.framework */; };
/* End PBXBuildFile section */ /* End PBXBuildFile section */
@@ -479,15 +479,15 @@
BFE6073F231AFD2A002B0E8E /* InsetGroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsetGroupTableViewCell.swift; sourceTree = "<group>"; }; BFE6073F231AFD2A002B0E8E /* InsetGroupTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InsetGroupTableViewCell.swift; sourceTree = "<group>"; };
BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderFooterView.swift; sourceTree = "<group>"; }; BFE60741231B07E6002B0E8E /* SettingsHeaderFooterView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsHeaderFooterView.swift; sourceTree = "<group>"; };
BFE6325922A83BEB00F30809 /* Authentication.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Authentication.storyboard; sourceTree = "<group>"; }; BFE6325922A83BEB00F30809 /* Authentication.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = Authentication.storyboard; sourceTree = "<group>"; };
BFE6325B22A83C0100F30809 /* AuthenticationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationViewController.swift; sourceTree = "<group>"; };
BFE6325D22A8497000F30809 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = "<group>"; };
BFE6326522A857C100F30809 /* Team.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; }; BFE6326522A857C100F30809 /* Team.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Team.swift; sourceTree = "<group>"; };
BFE6326722A858F300F30809 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; }; BFE6326722A858F300F30809 /* Account.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Account.swift; sourceTree = "<group>"; };
BFE6326922A85DAF00F30809 /* ReplaceCertificateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReplaceCertificateViewController.swift; sourceTree = "<group>"; };
BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationOperation.swift; sourceTree = "<group>"; }; BFE6326B22A86FF300F30809 /* AuthenticationOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationOperation.swift; sourceTree = "<group>"; };
BFF0B68D23219520007A79E1 /* PatreonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatreonViewController.swift; sourceTree = "<group>"; }; BFF0B68D23219520007A79E1 /* PatreonViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatreonViewController.swift; sourceTree = "<group>"; };
BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatreonComponents.swift; sourceTree = "<group>"; }; BFF0B68F23219C6D007A79E1 /* PatreonComponents.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatreonComponents.swift; sourceTree = "<group>"; };
BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutPatreonHeaderView.xib; sourceTree = "<group>"; }; BFF0B6912321A305007A79E1 /* AboutPatreonHeaderView.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = AboutPatreonHeaderView.xib; sourceTree = "<group>"; };
BFF0B6932321CB85007A79E1 /* AuthenticationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthenticationViewController.swift; sourceTree = "<group>"; };
BFF0B6972322CAB8007A79E1 /* InstructionsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InstructionsViewController.swift; sourceTree = "<group>"; };
BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIScreen+CompactHeight.swift"; sourceTree = "<group>"; };
EA79A60285C6AF5848AA16E9 /* Pods-AltStore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AltStore.debug.xcconfig"; path = "Target Support Files/Pods-AltStore/Pods-AltStore.debug.xcconfig"; sourceTree = "<group>"; }; EA79A60285C6AF5848AA16E9 /* Pods-AltStore.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-AltStore.debug.xcconfig"; path = "Target Support Files/Pods-AltStore/Pods-AltStore.debug.xcconfig"; sourceTree = "<group>"; };
FC3822AB1C4CF1D4CDF7445D /* Pods_AltServer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AltServer.framework; sourceTree = BUILT_PRODUCTS_DIR; }; FC3822AB1C4CF1D4CDF7445D /* Pods_AltServer.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_AltServer.framework; sourceTree = BUILT_PRODUCTS_DIR; };
/* End PBXFileReference section */ /* End PBXFileReference section */
@@ -941,6 +941,7 @@
BF43002F22A71C960051E2BC /* UserDefaults+AltStore.swift */, BF43002F22A71C960051E2BC /* UserDefaults+AltStore.swift */,
BF9ABA4E22DD41A9008935CF /* UIColor+Hex.swift */, BF9ABA4E22DD41A9008935CF /* UIColor+Hex.swift */,
BFDB5B1522EE90D300F74113 /* Date+RelativeDate.swift */, BFDB5B1522EE90D300F74113 /* Date+RelativeDate.swift */,
BFF0B6992322D7D0007A79E1 /* UIScreen+CompactHeight.swift */,
); );
path = Extensions; path = Extensions;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1012,9 +1013,8 @@
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
BFE6325922A83BEB00F30809 /* Authentication.storyboard */, BFE6325922A83BEB00F30809 /* Authentication.storyboard */,
BFE6325B22A83C0100F30809 /* AuthenticationViewController.swift */, BFF0B6932321CB85007A79E1 /* AuthenticationViewController.swift */,
BFE6325D22A8497000F30809 /* SelectTeamViewController.swift */, BFF0B6972322CAB8007A79E1 /* InstructionsViewController.swift */,
BFE6326922A85DAF00F30809 /* ReplaceCertificateViewController.swift */,
); );
path = Authentication; path = Authentication;
sourceTree = "<group>"; sourceTree = "<group>";
@@ -1400,10 +1400,8 @@
BFDB6A0F22AB2776007EA6D6 /* SendAppOperation.swift in Sources */, BFDB6A0F22AB2776007EA6D6 /* SendAppOperation.swift in Sources */,
BFDB6A0D22AAFC1A007EA6D6 /* OperationError.swift in Sources */, BFDB6A0D22AAFC1A007EA6D6 /* OperationError.swift in Sources */,
BF3D649D22E7AC1B00E9056B /* PermissionPopoverViewController.swift in Sources */, BF3D649D22E7AC1B00E9056B /* PermissionPopoverViewController.swift in Sources */,
BFE6325E22A8497000F30809 /* SelectTeamViewController.swift in Sources */,
BFD2478F2284C8F900981D42 /* Button.swift in Sources */, BFD2478F2284C8F900981D42 /* Button.swift in Sources */,
BFD5D6F6230DDB12007955AB /* Tier.swift in Sources */, BFD5D6F6230DDB12007955AB /* Tier.swift in Sources */,
BFE6326A22A85DAF00F30809 /* ReplaceCertificateViewController.swift in Sources */,
BFB11692229322E400BB457C /* DatabaseManager.swift in Sources */, BFB11692229322E400BB457C /* DatabaseManager.swift in Sources */,
BFC1F38D22AEE3A4003AC21A /* DownloadAppOperation.swift in Sources */, BFC1F38D22AEE3A4003AC21A /* DownloadAppOperation.swift in Sources */,
BF54E8212315EF0D000AE0D8 /* ALTPatreonBenefitType.m in Sources */, BF54E8212315EF0D000AE0D8 /* ALTPatreonBenefitType.m in Sources */,
@@ -1415,6 +1413,7 @@
BFE60740231AFD2A002B0E8E /* InsetGroupTableViewCell.swift in Sources */, BFE60740231AFD2A002B0E8E /* InsetGroupTableViewCell.swift in Sources */,
BFD5D6F4230DDB0A007955AB /* Campaign.swift in Sources */, BFD5D6F4230DDB0A007955AB /* Campaign.swift in Sources */,
BFB6B21B23186D640022A802 /* NewsItem.swift in Sources */, BFB6B21B23186D640022A802 /* NewsItem.swift in Sources */,
BFF0B6982322CAB8007A79E1 /* InstructionsViewController.swift in Sources */,
BFD5D6E8230CC961007955AB /* PatreonAPI.swift in Sources */, BFD5D6E8230CC961007955AB /* PatreonAPI.swift in Sources */,
BF9ABA4522DCFF43008935CF /* BrowseViewController.swift in Sources */, BF9ABA4522DCFF43008935CF /* BrowseViewController.swift in Sources */,
BF43002E22A714AF0051E2BC /* Keychain.swift in Sources */, BF43002E22A714AF0051E2BC /* Keychain.swift in Sources */,
@@ -1434,11 +1433,11 @@
BF02419422F2156E00129732 /* RefreshAttempt.swift in Sources */, BF02419422F2156E00129732 /* RefreshAttempt.swift in Sources */,
BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */, BFE60742231B07E6002B0E8E /* SettingsHeaderFooterView.swift in Sources */,
BFE338E822F10E56002E24B9 /* LaunchViewController.swift in Sources */, BFE338E822F10E56002E24B9 /* LaunchViewController.swift in Sources */,
BFE6325C22A83C0100F30809 /* AuthenticationViewController.swift in Sources */,
BFB1169B2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift in Sources */, BFB1169B2293274D00BB457C /* JSONDecoder+ManagedObjectContext.swift in Sources */,
BF9ABA4722DD0638008935CF /* BrowseCollectionViewCell.swift in Sources */, BF9ABA4722DD0638008935CF /* BrowseCollectionViewCell.swift in Sources */,
BF3D648822E79A3700E9056B /* AppPermission.swift in Sources */, BF3D648822E79A3700E9056B /* AppPermission.swift in Sources */,
BFD6B03322DFF20800B86064 /* MyAppsComponents.swift in Sources */, BFD6B03322DFF20800B86064 /* MyAppsComponents.swift in Sources */,
BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */,
BFD5D6EE230D8A86007955AB /* Patron.swift in Sources */, BFD5D6EE230D8A86007955AB /* Patron.swift in Sources */,
BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */, BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */,
BF08858522DE7EC800DE9F1E /* UpdateCollectionViewCell.swift in Sources */, BF08858522DE7EC800DE9F1E /* UpdateCollectionViewCell.swift in Sources */,
@@ -1458,6 +1457,7 @@
BF2901312318F7A800D88A45 /* AppBannerView.swift in Sources */, BF2901312318F7A800D88A45 /* AppBannerView.swift in Sources */,
BF3D648D22E79AC800E9056B /* ALTAppPermission.m in Sources */, BF3D648D22E79AC800E9056B /* ALTAppPermission.m in Sources */,
BFD5D6F2230DD974007955AB /* Benefit.swift in Sources */, BFD5D6F2230DD974007955AB /* Benefit.swift in Sources */,
BFF0B6942321CB85007A79E1 /* AuthenticationViewController.swift in Sources */,
BF9ABA4922DD0742008935CF /* ScreenshotCollectionViewCell.swift in Sources */, BF9ABA4922DD0742008935CF /* ScreenshotCollectionViewCell.swift in Sources */,
BF9ABA4D22DD16DE008935CF /* PillButton.swift in Sources */, BF9ABA4D22DD16DE008935CF /* PillButton.swift in Sources */,
BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */, BFE6326C22A86FF300F30809 /* AuthenticationOperation.swift in Sources */,

View File

@@ -4,239 +4,440 @@
<adaptation id="fullscreen"/> <adaptation id="fullscreen"/>
</device> </device>
<dependencies> <dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="14490.49"/>
<capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
<!--Apple ID--> <!--Navigation Controller-->
<scene sceneID="3cc-cd-zDK"> <scene sceneID="lNR-II-WoW">
<objects> <objects>
<tableViewController storyboardIdentifier="authenticationViewController" id="nRn-xt-2XS" customClass="AuthenticationViewController" customModule="AltStore" customModuleProvider="target" sceneMemberID="viewController"> <navigationController storyboardIdentifier="navigationController" id="ZTo-53-dSL" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="static" style="grouped" separatorStyle="default" rowHeight="44" estimatedRowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="r38-H3-S3C"> <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" barStyle="black" largeTitles="YES" id="Aej-RF-PfV" customClass="NavigationBar" customModule="AltStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/>
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="barTintColor" name="Red"/>
<textAttributes key="titleTextAttributes">
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textAttributes>
<textAttributes key="largeTitleTextAttributes">
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</textAttributes>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="boolean" keyPath="automaticallyAdjustsItemPositions" value="NO"/>
</userDefinedRuntimeAttributes>
</navigationBar>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="9J6-jc-46k" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="-164" y="735"/>
</scene>
<!--Authentication View Controller-->
<scene sceneID="OCd-xc-Ms7">
<objects>
<viewController storyboardIdentifier="authenticationViewController" id="yO1-iT-7NP" customClass="AuthenticationViewController" customModule="AltStore" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" id="mjy-4S-hyH">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/> <subviews>
<sections> <view hidden="YES" userInteractionEnabled="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="oyW-Fd-ojD" userLabel="Sizing View">
<tableViewSection id="uDm-cx-LdY"> <rect key="frame" x="0.0" y="64" width="375" height="603"/>
<string key="footerTitle">Your email address and password are used only to sign in with Apple and is never stored. </view>
<scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" alwaysBounceVertical="YES" indicatorStyle="white" keyboardDismissMode="onDrag" translatesAutoresizingMaskIntoConstraints="NO" id="WXx-hX-AXv">
If you have two-factor authentication enabled, make sure to use an app-specific password.</string> <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<cells> <subviews>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="ER5-4r-tld"> <view contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" translatesAutoresizingMaskIntoConstraints="NO" id="2wp-qG-f0Z">
<rect key="frame" x="0.0" y="35" width="375" height="44"/> <rect key="frame" x="0.0" y="0.0" width="375" height="603"/>
<autoresizingMask key="autoresizingMask"/> <subviews>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="ER5-4r-tld" id="BnC-HI-d8z"> <stackView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" axis="vertical" spacing="50" translatesAutoresizingMaskIntoConstraints="NO" id="YmX-7v-pxh">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> <rect key="frame" x="16" y="6" width="343" height="359.5"/>
<autoresizingMask key="autoresizingMask"/> <subviews>
<subviews> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" alignment="top" spacing="6" translatesAutoresizingMaskIntoConstraints="NO" id="Yfu-hI-0B7" userLabel="Welcome">
<stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="70T-cn-6XF"> <rect key="frame" x="0.0" y="0.0" width="343" height="67.5"/>
<rect key="frame" x="16" y="0.0" width="343" height="43.5"/> <subviews>
<subviews> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Welcome to AltStore." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="EI2-V3-zQZ">
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Apple ID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="09n-b4-DRC"> <rect key="frame" x="0.0" y="0.0" width="333.5" height="41"/>
<rect key="frame" x="0.0" y="0.0" width="74" height="43.5"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="34"/>
<constraints> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraint firstAttribute="width" constant="74" id="Y87-hZ-IsD"/> <nil key="highlightedColor"/>
</constraints> </label>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Sign in with your Apple ID to get started." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="SNU-tv-8Au">
<nil key="textColor"/> <rect key="frame" x="0.0" y="47" width="308.5" height="20.5"/>
<nil key="highlightedColor"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
</label> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Email Address" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="V6B-NM-wpL"> <nil key="highlightedColor"/>
<rect key="frame" x="90" y="0.0" width="253" height="43.5"/> </label>
<nil key="textColor"/> </subviews>
<fontDescription key="fontDescription" type="system" pointSize="17"/> </stackView>
<textInputTraits key="textInputTraits" returnKeyType="next" enablesReturnKeyAutomatically="YES" textContentType="email"/> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="32" translatesAutoresizingMaskIntoConstraints="NO" id="Aqh-MD-HFf">
<connections> <rect key="frame" x="0.0" y="117.5" width="343" height="242"/>
<outlet property="delegate" destination="nRn-xt-2XS" id="5Us-OB-B4F"/> <subviews>
</connections> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="15" translatesAutoresizingMaskIntoConstraints="NO" id="Oy6-xr-cZ7">
</textField> <rect key="frame" x="0.0" y="0.0" width="343" height="159"/>
</subviews> <subviews>
</stackView> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="H95-7V-Kk8" userLabel="Apple ID">
</subviews> <rect key="frame" x="0.0" y="0.0" width="343" height="72"/>
<constraints> <subviews>
<constraint firstItem="70T-cn-6XF" firstAttribute="top" secondItem="BnC-HI-d8z" secondAttribute="top" id="Zyt-OB-o6T"/> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="KN1-Kp-M1q">
<constraint firstAttribute="trailingMargin" secondItem="70T-cn-6XF" secondAttribute="trailing" id="lYn-uy-vRk"/> <rect key="frame" x="0.0" y="0.0" width="343" height="17"/>
<constraint firstAttribute="bottom" secondItem="70T-cn-6XF" secondAttribute="bottom" id="urj-EQ-5WK"/> <subviews>
<constraint firstItem="70T-cn-6XF" firstAttribute="leading" secondItem="BnC-HI-d8z" secondAttribute="leadingMargin" id="yqr-Kr-I93"/> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="APPLE ID" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="59N-O1-6bM">
</constraints> <rect key="frame" x="14" y="0.0" width="329" height="17"/>
</tableViewCellContentView> <fontDescription key="fontDescription" type="system" pointSize="14"/>
</tableViewCell> <color key="textColor" white="1" alpha="0.75" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="none" indentationWidth="10" id="E9B-Cb-M5e"> <nil key="highlightedColor"/>
<rect key="frame" x="0.0" y="79" width="375" height="44"/> </label>
<autoresizingMask key="autoresizingMask"/> </subviews>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="E9B-Cb-M5e" id="S4n-4w-12m"> <edgeInsets key="layoutMargins" top="0.0" left="14" bottom="0.0" right="0.0"/>
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/> </stackView>
<autoresizingMask key="autoresizingMask"/> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="gNe-dC-oI1">
<subviews> <rect key="frame" x="0.0" y="21" width="343" height="51"/>
<stackView opaque="NO" contentMode="scaleToFill" spacing="16" translatesAutoresizingMaskIntoConstraints="NO" id="pON-cO-VYR"> <subviews>
<rect key="frame" x="16" y="0.0" width="343" height="43.5"/> <textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="name@email.com" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="DBu-vt-hlo">
<subviews> <rect key="frame" x="14" y="0.0" width="315" height="51"/>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Password" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vqv-cC-kya"> <color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<rect key="frame" x="0.0" y="0.0" width="74" height="43.5"/> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints> <fontDescription key="fontDescription" type="boldSystem" pointSize="19"/>
<constraint firstAttribute="width" constant="74" id="Egk-ba-Kh3"/> <textInputTraits key="textInputTraits" returnKeyType="next" textContentType="email"/>
</constraints> <connections>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <outlet property="delegate" destination="yO1-iT-7NP" id="G13-jV-DLX"/>
<nil key="textColor"/> </connections>
<nil key="highlightedColor"/> </textField>
</label> </subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="Password" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="z98-Sm-yDv"> <color key="backgroundColor" white="1" alpha="0.29999999999999999" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<rect key="frame" x="90" y="0.0" width="253" height="43.5"/> <constraints>
<nil key="textColor"/> <constraint firstAttribute="trailingMargin" secondItem="DBu-vt-hlo" secondAttribute="trailing" id="0Lf-vH-juh"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <constraint firstItem="DBu-vt-hlo" firstAttribute="centerY" secondItem="gNe-dC-oI1" secondAttribute="centerY" id="kgs-hg-ECM"/>
<textInputTraits key="textInputTraits" returnKeyType="go" enablesReturnKeyAutomatically="YES" secureTextEntry="YES" textContentType="password"/> <constraint firstItem="DBu-vt-hlo" firstAttribute="height" secondItem="gNe-dC-oI1" secondAttribute="height" id="n7y-Xg-8MP"/>
<connections> <constraint firstItem="DBu-vt-hlo" firstAttribute="leading" secondItem="gNe-dC-oI1" secondAttribute="leadingMargin" id="sat-rb-OIu"/>
<outlet property="delegate" destination="nRn-xt-2XS" id="7pH-Sf-Wmb"/> <constraint firstAttribute="height" constant="51" id="tuP-Uo-6qp"/>
</connections> </constraints>
</textField> <edgeInsets key="layoutMargins" top="0.0" left="14" bottom="0.0" right="14"/>
</subviews> </view>
</stackView> </subviews>
</subviews> </stackView>
<constraints> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="hd5-yc-rcq" userLabel="Password">
<constraint firstAttribute="trailingMargin" secondItem="pON-cO-VYR" secondAttribute="trailing" id="IPH-Og-2ch"/> <rect key="frame" x="0.0" y="87" width="343" height="72"/>
<constraint firstAttribute="bottom" secondItem="pON-cO-VYR" secondAttribute="bottom" id="j7H-Ds-pJg"/> <subviews>
<constraint firstItem="pON-cO-VYR" firstAttribute="leading" secondItem="S4n-4w-12m" secondAttribute="leadingMargin" id="uAc-4j-0pB"/> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="lvX-im-C95">
<constraint firstItem="pON-cO-VYR" firstAttribute="top" secondItem="S4n-4w-12m" secondAttribute="top" id="xZe-CS-STZ"/> <rect key="frame" x="0.0" y="0.0" width="343" height="17"/>
</constraints> <subviews>
</tableViewCellContentView> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="PASSWORD" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Ava-XY-7vs">
</tableViewCell> <rect key="frame" x="14" y="0.0" width="329" height="17"/>
</cells> <fontDescription key="fontDescription" type="system" pointSize="14"/>
</tableViewSection> <color key="textColor" white="1" alpha="0.75" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</sections> <nil key="highlightedColor"/>
<connections> </label>
<outlet property="dataSource" destination="nRn-xt-2XS" id="VWO-oe-ykv"/> </subviews>
<outlet property="delegate" destination="nRn-xt-2XS" id="CL1-Go-uiO"/> <edgeInsets key="layoutMargins" top="0.0" left="14" bottom="0.0" right="0.0"/>
</connections> </stackView>
</tableView> <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="cLc-iA-yq5">
<navigationItem key="navigationItem" title="Apple ID" id="viw-66-ZJ7"> <rect key="frame" x="0.0" y="21" width="343" height="51"/>
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="KXh-qW-MIA"> <subviews>
<textField opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="left" contentVerticalAlignment="center" placeholder="••••••••" textAlignment="natural" minimumFontSize="17" translatesAutoresizingMaskIntoConstraints="NO" id="R77-TQ-lVT">
<rect key="frame" x="14" y="0.0" width="315" height="51"/>
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="19"/>
<textInputTraits key="textInputTraits" returnKeyType="go" enablesReturnKeyAutomatically="YES" secureTextEntry="YES" textContentType="password"/>
<connections>
<outlet property="delegate" destination="yO1-iT-7NP" id="Wpg-DV-BNL"/>
</connections>
</textField>
</subviews>
<color key="backgroundColor" white="1" alpha="0.29999999999999999" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstItem="R77-TQ-lVT" firstAttribute="leading" secondItem="cLc-iA-yq5" secondAttribute="leadingMargin" id="130-RD-MwU"/>
<constraint firstAttribute="height" constant="51" id="9Jw-2V-fgf"/>
<constraint firstItem="R77-TQ-lVT" firstAttribute="height" secondItem="cLc-iA-yq5" secondAttribute="height" id="FFf-Bp-LPT"/>
<constraint firstItem="R77-TQ-lVT" firstAttribute="centerY" secondItem="cLc-iA-yq5" secondAttribute="centerY" id="agB-KM-ba3"/>
<constraint firstAttribute="trailingMargin" secondItem="R77-TQ-lVT" secondAttribute="trailing" id="jB5-Ye-cJB"/>
</constraints>
<edgeInsets key="layoutMargins" top="0.0" left="14" bottom="0.0" right="14"/>
</view>
</subviews>
</stackView>
</subviews>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="2N5-zd-fUj">
<rect key="frame" x="0.0" y="191" width="343" height="51"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="51" id="4BK-Un-5pl"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="19"/>
<state key="normal" title="Sign in">
<color key="titleColor" name="Pink"/>
</state>
<connections>
<action selector="authenticate" destination="yO1-iT-7NP" eventType="primaryActionTriggered" id="LER-a2-CbC"/>
</connections>
</button>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="4" translatesAutoresizingMaskIntoConstraints="NO" id="DBk-rT-ZE8">
<rect key="frame" x="16" y="498.5" width="343" height="96.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Why do we need this?" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="p9U-0q-Kn8">
<rect key="frame" x="0.0" y="0.0" width="343" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="on2-62-waY">
<rect key="frame" x="0.0" y="24.5" width="343" height="72"/>
<string key="text">Your Apple ID is used to configure apps so they can be installed on this device. Your credentials will be stored securely in this device's Keychain and sent only to Apple for authentication.</string>
<fontDescription key="fontDescription" type="system" pointSize="15"/>
<color key="textColor" white="1" alpha="0.75" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</view>
</subviews>
<constraints>
<constraint firstItem="2wp-qG-f0Z" firstAttribute="leading" secondItem="WXx-hX-AXv" secondAttribute="leading" id="13j-ii-X7W"/>
<constraint firstAttribute="bottom" secondItem="2wp-qG-f0Z" secondAttribute="bottom" id="Ggl-es-C4C"/>
<constraint firstAttribute="trailing" secondItem="2wp-qG-f0Z" secondAttribute="trailing" id="nl1-88-5mM"/>
<constraint firstItem="2wp-qG-f0Z" firstAttribute="top" secondItem="WXx-hX-AXv" secondAttribute="top" id="wiH-lv-L9P"/>
</constraints>
</scrollView>
</subviews>
<color key="backgroundColor" name="Red"/>
<constraints>
<constraint firstAttribute="bottom" secondItem="WXx-hX-AXv" secondAttribute="bottom" id="0jL-Ky-ju6"/>
<constraint firstAttribute="leadingMargin" secondItem="YmX-7v-pxh" secondAttribute="leading" id="2PO-lG-dmB"/>
<constraint firstItem="DBk-rT-ZE8" firstAttribute="leading" secondItem="2wp-qG-f0Z" secondAttribute="leadingMargin" id="5AT-nV-ZP9"/>
<constraint firstItem="oyW-Fd-ojD" firstAttribute="top" secondItem="zMn-DV-fpy" secondAttribute="top" id="730-db-ukB"/>
<constraint firstItem="2wp-qG-f0Z" firstAttribute="bottomMargin" secondItem="DBk-rT-ZE8" secondAttribute="bottom" id="HgY-oY-8KM"/>
<constraint firstItem="zMn-DV-fpy" firstAttribute="trailing" secondItem="oyW-Fd-ojD" secondAttribute="trailing" id="KGE-CN-SWf"/>
<constraint firstItem="WXx-hX-AXv" firstAttribute="top" secondItem="mjy-4S-hyH" secondAttribute="top" id="LPQ-bF-ic0"/>
<constraint firstItem="zMn-DV-fpy" firstAttribute="trailing" secondItem="WXx-hX-AXv" secondAttribute="trailing" id="MG7-A6-pKp"/>
<constraint firstAttribute="trailingMargin" secondItem="YmX-7v-pxh" secondAttribute="trailing" id="O4T-nu-o3e"/>
<constraint firstItem="zMn-DV-fpy" firstAttribute="bottom" secondItem="oyW-Fd-ojD" secondAttribute="bottom" id="PuX-ab-cEq"/>
<constraint firstItem="oyW-Fd-ojD" firstAttribute="leading" secondItem="zMn-DV-fpy" secondAttribute="leading" id="SzC-gC-Nvi"/>
<constraint firstItem="2wp-qG-f0Z" firstAttribute="trailingMargin" secondItem="DBk-rT-ZE8" secondAttribute="trailing" id="VCf-bW-2K4"/>
<constraint firstItem="WXx-hX-AXv" firstAttribute="leading" secondItem="zMn-DV-fpy" secondAttribute="leading" id="d08-zF-5X6"/>
<constraint firstItem="2wp-qG-f0Z" firstAttribute="height" secondItem="oyW-Fd-ojD" secondAttribute="height" id="dFN-pw-TWt"/>
<constraint firstItem="YmX-7v-pxh" firstAttribute="top" secondItem="2wp-qG-f0Z" secondAttribute="top" constant="6" id="iUr-Nd-tkt"/>
<constraint firstItem="2wp-qG-f0Z" firstAttribute="width" secondItem="oyW-Fd-ojD" secondAttribute="width" id="rYO-GN-0Lk"/>
</constraints>
<viewLayoutGuide key="safeArea" id="zMn-DV-fpy"/>
</view>
<toolbarItems/>
<navigationItem key="navigationItem" largeTitleDisplayMode="never" id="jCf-N4-xVD">
<barButtonItem key="leftBarButtonItem" title="Close" id="nDc-Zs-wnK">
<connections> <connections>
<action selector="cancel" destination="nRn-xt-2XS" id="l1X-bA-xsz"/> <action selector="cancel:" destination="yO1-iT-7NP" id="xls-in-Pre"/>
</connections>
</barButtonItem>
<barButtonItem key="rightBarButtonItem" title="Sign In" style="done" id="mkE-Q8-CxO">
<connections>
<action selector="authenticate" destination="nRn-xt-2XS" id="q60-9N-xVb"/>
</connections> </connections>
</barButtonItem> </barButtonItem>
</navigationItem> </navigationItem>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/> <simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<nil key="simulatedBottomBarMetrics"/>
<connections>
<outlet property="appleIDBackgroundView" destination="gNe-dC-oI1" id="lab-WG-pyJ"/>
<outlet property="appleIDTextField" destination="DBu-vt-hlo" id="ZMK-9K-phY"/>
<outlet property="contentStackView" destination="YmX-7v-pxh" id="ZX5-Af-cEB"/>
<outlet property="passwordBackgroundView" destination="cLc-iA-yq5" id="2JD-nS-Gf7"/>
<outlet property="passwordTextField" destination="R77-TQ-lVT" id="cLQ-Wn-MsE"/>
<outlet property="scrollView" destination="WXx-hX-AXv" id="hOb-gl-0OP"/>
<outlet property="signInButton" destination="2N5-zd-fUj" id="ul1-bh-4l4"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="U7A-Cx-Bo9" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="605.60000000000002" y="736.28185907046486"/>
</scene>
<!--How it works-->
<scene sceneID="dMt-EA-SGy">
<objects>
<viewController storyboardIdentifier="instructionsViewController" hidesBottomBarWhenPushed="YES" id="aFi-fb-W0B" customClass="InstructionsViewController" customModule="AltStore" customModuleProvider="target" sceneMemberID="viewController">
<view key="view" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" id="Otz-hn-WGS">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" axis="vertical" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="bp6-55-IG2">
<rect key="frame" x="0.0" y="64" width="375" height="544"/>
<subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="LpI-Jt-SzX">
<rect key="frame" x="16" y="35" width="343" height="95.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="1" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="0LW-eE-qHa">
<rect key="frame" x="0.0" y="0.0" width="59" height="95.5"/>
<constraints>
<constraint firstAttribute="width" constant="59" id="HzE-AA-eE5"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="black" pointSize="80"/>
<color key="textColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="dMu-eg-gIO">
<rect key="frame" x="79" y="16" width="264" height="64"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Launch AltServer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="esj-pD-D4A">
<rect key="frame" x="0.0" y="0.0" width="264" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="a.k.a. the Desktop app used to install AltStore." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="4rk-ge-FSj">
<rect key="frame" x="0.0" y="25.5" width="264" height="38.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="tfb-ja-9UC">
<rect key="frame" x="16" y="161" width="343" height="95.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="2" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="nVr-El-Csi">
<rect key="frame" x="0.0" y="0.0" width="59" height="95.5"/>
<constraints>
<constraint firstAttribute="width" constant="59" id="fRj-b4-VTe"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="black" pointSize="80"/>
<color key="textColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="z6Y-zi-teL">
<rect key="frame" x="79" y="16" width="264" height="64"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Connect to WiFi" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="JeJ-bk-UCA">
<rect key="frame" x="0.0" y="0.0" width="264" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Connect to the same WiFi as the computer running AltServer." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="M7T-9j-uyt">
<rect key="frame" x="0.0" y="25.5" width="264" height="38.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="SF8-an-Pku">
<rect key="frame" x="16" y="287.5" width="343" height="95.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="3" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="JJg-LC-FWK">
<rect key="frame" x="0.0" y="0.0" width="59" height="95.5"/>
<constraints>
<constraint firstAttribute="width" constant="59" id="XLz-ga-1gX"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="black" pointSize="80"/>
<color key="textColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="roi-ZB-E34">
<rect key="frame" x="79" y="15.5" width="264" height="64"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Download Apps" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="pKZ-nr-AYF">
<rect key="frame" x="0.0" y="0.0" width="264" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Apps will expire after a few days unless refreshed." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="dhL-Pt-4GO">
<rect key="frame" x="0.0" y="25.5" width="264" height="38.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="20" translatesAutoresizingMaskIntoConstraints="NO" id="X3r-G1-vf2">
<rect key="frame" x="16" y="413.5" width="343" height="95.5"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="4" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="i2U-NL-plG">
<rect key="frame" x="0.0" y="0.0" width="59" height="95.5"/>
<constraints>
<constraint firstAttribute="width" constant="59" id="4Qg-s9-p7s"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="black" pointSize="80"/>
<color key="textColor" white="1" alpha="0.5" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="5" translatesAutoresizingMaskIntoConstraints="NO" id="Xs6-pJ-PUz">
<rect key="frame" x="79" y="16" width="264" height="64"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Prevent Apps From Expiring" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="nvb-Aq-sYa">
<rect key="frame" x="0.0" y="0.0" width="264" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Leave AltServer running so AltStore can refresh apps in the background." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="HU5-Hv-E3d">
<rect key="frame" x="0.0" y="25.5" width="264" height="38.5"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" white="1" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</stackView>
</subviews>
</stackView>
</subviews>
<edgeInsets key="layoutMargins" top="35" left="0.0" bottom="35" right="0.0"/>
</stackView>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="qZ9-AR-2zK">
<rect key="frame" x="16" y="608" width="343" height="51"/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<constraints>
<constraint firstAttribute="height" constant="51" id="LQz-qG-ZJK"/>
</constraints>
<fontDescription key="fontDescription" type="boldSystem" pointSize="19"/>
<state key="normal" title="Got it">
<color key="titleColor" name="Pink"/>
</state>
<connections>
<action selector="dismiss" destination="aFi-fb-W0B" eventType="primaryActionTriggered" id="sBq-zj-Mln"/>
</connections>
</button>
</subviews>
<color key="backgroundColor" name="Red"/>
<constraints>
<constraint firstItem="qZ9-AR-2zK" firstAttribute="top" secondItem="bp6-55-IG2" secondAttribute="bottom" id="3yt-cr-swd"/>
<constraint firstItem="bp6-55-IG2" firstAttribute="top" secondItem="Zek-aC-HOO" secondAttribute="top" id="42S-q2-YZn"/>
<constraint firstAttribute="trailingMargin" secondItem="qZ9-AR-2zK" secondAttribute="trailing" id="8b4-iU-U7R"/>
<constraint firstItem="bp6-55-IG2" firstAttribute="leading" secondItem="Zek-aC-HOO" secondAttribute="leading" id="K1R-1r-FP3"/>
<constraint firstItem="Zek-aC-HOO" firstAttribute="trailing" secondItem="bp6-55-IG2" secondAttribute="trailing" id="aKV-sS-alh"/>
<constraint firstAttribute="bottomMargin" secondItem="qZ9-AR-2zK" secondAttribute="bottom" id="e8e-9l-Mkt"/>
<constraint firstItem="qZ9-AR-2zK" firstAttribute="leading" secondItem="Otz-hn-WGS" secondAttribute="leadingMargin" id="t2b-3e-6ld"/>
</constraints>
<viewLayoutGuide key="safeArea" id="Zek-aC-HOO"/>
</view>
<navigationItem key="navigationItem" title="How it works" largeTitleDisplayMode="always" id="bCq-Jq-gf1"/>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
<connections> <connections>
<outlet property="emailAddressTextField" destination="V6B-NM-wpL" id="N3F-eI-yhE"/> <outlet property="contentStackView" destination="bp6-55-IG2" id="k0Q-yS-Dxp"/>
<outlet property="passwordTextField" destination="z98-Sm-yDv" id="WDu-6c-oBa"/> <outlet property="dismissButton" destination="qZ9-AR-2zK" id="w5c-v6-TcC"/>
</connections> </connections>
</tableViewController> </viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="v2u-D2-stc" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="3Q4-ya-qhc" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>
<point key="canvasLocation" x="605.60000000000002" y="19.340329835082461"/> <point key="canvasLocation" x="1353" y="736"/>
</scene>
<!--Select Team-->
<scene sceneID="0Hb-4t-vQ3">
<objects>
<tableViewController storyboardIdentifier="selectTeamViewController" id="R11-Yh-Wb1" customClass="SelectTeamViewController" customModule="AltStore" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="g2d-7w-OVl">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="iCV-rW-IhB" detailTextLabel="2hi-el-KvN" style="IBUITableViewCellStyleSubtitle" id="pPa-pY-koy">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="pPa-pY-koy" id="DjO-Wt-6j2">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="iCV-rW-IhB">
<rect key="frame" x="16" y="5" width="33.5" height="20.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Detail" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="2hi-el-KvN">
<rect key="frame" x="16" y="25.5" width="33" height="14.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="12"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="R11-Yh-Wb1" id="zkX-xW-GvZ"/>
<outlet property="delegate" destination="R11-Yh-Wb1" id="vP7-NA-Y0n"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Select Team" id="ALr-U3-Ucl">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="HUE-P1-xa1">
<connections>
<action selector="cancel" destination="R11-Yh-Wb1" id="Ckg-bQ-0nv"/>
</connections>
</barButtonItem>
<barButtonItem key="rightBarButtonItem" title="Next" style="done" id="7Ou-hQ-Cr3">
<connections>
<action selector="chooseTeam:" destination="R11-Yh-Wb1" id="nin-nM-lxU"/>
</connections>
</barButtonItem>
</navigationItem>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="HxT-dJ-1Ry" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1354" y="20"/>
</scene>
<!--Replace Certificate-->
<scene sceneID="fW2-QW-a2Z">
<objects>
<tableViewController storyboardIdentifier="replaceCertificateViewController" id="LAG-dk-a0f" customClass="ReplaceCertificateViewController" customModule="AltStore" customModuleProvider="target" sceneMemberID="viewController">
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="-1" estimatedRowHeight="-1" sectionHeaderHeight="18" sectionFooterHeight="18" id="enT-LI-CNI">
<rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" reuseIdentifier="Cell" textLabel="luH-7x-QoO" style="IBUITableViewCellStyleDefault" id="i0O-XG-rRJ">
<rect key="frame" x="0.0" y="55.5" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="i0O-XG-rRJ" id="GCT-3I-GCy">
<rect key="frame" x="0.0" y="0.0" width="375" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" multipleTouchEnabled="YES" contentMode="left" insetsLayoutMarginsFromSafeArea="NO" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="luH-7x-QoO">
<rect key="frame" x="16" y="0.0" width="343" height="43.5"/>
<autoresizingMask key="autoresizingMask"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
</prototypes>
<connections>
<outlet property="dataSource" destination="LAG-dk-a0f" id="kOS-KX-Duz"/>
<outlet property="delegate" destination="LAG-dk-a0f" id="plW-kJ-BmR"/>
</connections>
</tableView>
<navigationItem key="navigationItem" title="Replace Certificate" id="BM2-Vg-AJk">
<barButtonItem key="leftBarButtonItem" systemItem="cancel" id="lPC-Dj-3Ik">
<connections>
<action selector="cancel" destination="LAG-dk-a0f" id="5C2-Hg-Les"/>
</connections>
</barButtonItem>
<barButtonItem key="rightBarButtonItem" title="Next" style="done" id="ndJ-l9-HeM">
<connections>
<action selector="replaceCertificate:" destination="LAG-dk-a0f" id="vl2-E6-qi4"/>
</connections>
</barButtonItem>
</navigationItem>
<simulatedNavigationBarMetrics key="simulatedTopBarMetrics" prompted="NO"/>
</tableViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="yxU-EG-3sE" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="2135" y="19"/>
</scene> </scene>
</scenes> </scenes>
<color key="tintColor" name="Purple"/> <resources>
<namedColor name="Pink">
<color red="0.92549019607843142" green="0.25490196078431371" blue="0.69803921568627447" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
<namedColor name="Red">
<color red="0.92156862745098034" green="0.27450980392156865" blue="0.23137254901960785" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor>
</resources>
<color key="tintColor" name="Red"/>
</document> </document>

View File

@@ -2,48 +2,57 @@
// AuthenticationViewController.swift // AuthenticationViewController.swift
// AltStore // AltStore
// //
// Created by Riley Testut on 6/5/19. // Created by Riley Testut on 9/5/19.
// Copyright © 2019 Riley Testut. All rights reserved. // Copyright © 2019 Riley Testut. All rights reserved.
// //
import UIKit import UIKit
import AltSign import AltSign
import Roxas
class AuthenticationViewController: UITableViewController class AuthenticationViewController: UIViewController
{ {
var authenticationHandler: (((ALTAccount, String)?) -> Void)? var authenticationHandler: (((ALTAccount, String)?) -> Void)?
private var _didLayoutSubviews = false private weak var toastView: ToastView?
@IBOutlet private var emailAddressTextField: UITextField! @IBOutlet private var appleIDTextField: UITextField!
@IBOutlet private var passwordTextField: UITextField! @IBOutlet private var passwordTextField: UITextField!
@IBOutlet private var signInButton: UIButton!
@IBOutlet private var appleIDBackgroundView: UIView!
@IBOutlet private var passwordBackgroundView: UIView!
@IBOutlet private var scrollView: UIScrollView!
@IBOutlet private var contentStackView: UIStackView!
override func viewDidLoad() override func viewDidLoad()
{ {
super.viewDidLoad() super.viewDidLoad()
self.update() for view in [self.appleIDBackgroundView!, self.passwordBackgroundView!, self.signInButton!]
}
override func viewDidLayoutSubviews()
{
super.viewDidLayoutSubviews()
if !_didLayoutSubviews
{ {
self.emailAddressTextField.becomeFirstResponder() view.clipsToBounds = true
view.layer.cornerRadius = 16
}
if UIScreen.main.isExtraCompactHeight
{
self.contentStackView.spacing = 20
} }
_didLayoutSubviews = true NotificationCenter.default.addObserver(self, selector: #selector(AuthenticationViewController.textFieldDidChangeText(_:)), name: UITextField.textDidChangeNotification, object: self.appleIDTextField)
NotificationCenter.default.addObserver(self, selector: #selector(AuthenticationViewController.textFieldDidChangeText(_:)), name: UITextField.textDidChangeNotification, object: self.passwordTextField)
self.update()
} }
override func viewDidDisappear(_ animated: Bool) override func viewDidDisappear(_ animated: Bool)
{ {
super.viewDidDisappear(animated) super.viewDidDisappear(animated)
self.navigationItem.rightBarButtonItem?.isIndicatingActivity = false self.signInButton.isIndicatingActivity = false
self.toastView?.dismiss()
} }
} }
@@ -53,39 +62,25 @@ private extension AuthenticationViewController
{ {
if let _ = self.validate() if let _ = self.validate()
{ {
self.navigationItem.rightBarButtonItem?.isEnabled = true self.signInButton.isEnabled = true
self.signInButton.alpha = 1.0
} }
else else
{ {
self.navigationItem.rightBarButtonItem?.isEnabled = false self.signInButton.isEnabled = false
self.signInButton.alpha = 0.6
} }
} }
func validate() -> (String, String)? func validate() -> (String, String)?
{ {
guard guard
let emailAddress = self.emailAddressTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines), !emailAddress.isEmpty, let emailAddress = self.appleIDTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines), !emailAddress.isEmpty,
let password = self.passwordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines), !password.isEmpty let password = self.passwordTextField.text?.trimmingCharacters(in: .whitespacesAndNewlines), !password.isEmpty
else { return nil } else { return nil }
return (emailAddress, password) return (emailAddress, password)
} }
func authenticate(emailAddress: String, password: String, completionHandler: @escaping (Result<(ALTAccount, [ALTTeam]), Error>) -> Void)
{
ALTAppleAPI.shared.authenticate(appleID: emailAddress, password: password) { (account, error) in
switch Result(account, error)
{
case .failure(let error): completionHandler(.failure(error))
case .success(let account):
ALTAppleAPI.shared.fetchTeams(for: account) { (teams, error) in
let result = Result(teams, error).map { (account, $0) }
completionHandler(result)
}
}
}
}
} }
private extension AuthenticationViewController private extension AuthenticationViewController
@@ -94,10 +89,10 @@ private extension AuthenticationViewController
{ {
guard let (emailAddress, password) = self.validate() else { return } guard let (emailAddress, password) = self.validate() else { return }
self.emailAddressTextField.resignFirstResponder() self.appleIDTextField.resignFirstResponder()
self.passwordTextField.resignFirstResponder() self.passwordTextField.resignFirstResponder()
self.navigationItem.rightBarButtonItem?.isIndicatingActivity = true self.signInButton.isIndicatingActivity = true
ALTAppleAPI.shared.authenticate(appleID: emailAddress, password: password) { (account, error) in ALTAppleAPI.shared.authenticate(appleID: emailAddress, password: password) { (account, error) in
do do
@@ -108,17 +103,22 @@ private extension AuthenticationViewController
catch catch
{ {
DispatchQueue.main.async { DispatchQueue.main.async {
let toastView = RSTToastView(text: NSLocalizedString("Failed to Log In", comment: ""), detailText: error.localizedDescription) let toastView = ToastView(text: NSLocalizedString("Failed to Log In", comment: ""), detailText: error.localizedDescription)
toastView.tintColor = .altPurple toastView.tintColor = .altGreen
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2.0) toastView.show(in: self.navigationController?.view ?? self.view)
self.toastView = toastView
self.navigationItem.rightBarButtonItem?.isIndicatingActivity = false self.signInButton.isIndicatingActivity = false
} }
} }
DispatchQueue.main.async {
self.scrollView.setContentOffset(CGPoint(x: 0, y: -self.view.safeAreaInsets.top), animated: true)
}
} }
} }
@IBAction func cancel() @IBAction func cancel(_ sender: UIBarButtonItem)
{ {
self.authenticationHandler?(nil) self.authenticationHandler?(nil)
} }
@@ -130,7 +130,7 @@ extension AuthenticationViewController: UITextFieldDelegate
{ {
switch textField switch textField
{ {
case self.emailAddressTextField: self.passwordTextField.becomeFirstResponder() case self.appleIDTextField: self.passwordTextField.becomeFirstResponder()
case self.passwordTextField: self.authenticate() case self.passwordTextField: self.authenticate()
default: break default: break
} }
@@ -140,12 +140,21 @@ extension AuthenticationViewController: UITextFieldDelegate
return false return false
} }
func textField(_ textField: UITextField, shouldChangeCharactersIn range: NSRange, replacementString string: String) -> Bool func textFieldDidBeginEditing(_ textField: UITextField)
{ {
DispatchQueue.main.async { guard UIScreen.main.isExtraCompactHeight else { return }
self.update()
}
return true // Position all the controls within visible frame.
var contentOffset = self.scrollView.contentOffset
contentOffset.y = 44
self.scrollView.setContentOffset(contentOffset, animated: true)
}
}
extension AuthenticationViewController
{
@objc func textFieldDidChangeText(_ notification: Notification)
{
self.update()
} }
} }

View File

@@ -0,0 +1,50 @@
//
// InstructionsViewController.swift
// AltStore
//
// Created by Riley Testut on 9/6/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import UIKit
class InstructionsViewController: UIViewController
{
var completionHandler: (() -> Void)?
var showsBottomButton: Bool = false
@IBOutlet private var contentStackView: UIStackView!
@IBOutlet private var dismissButton: UIButton!
override func viewDidLoad()
{
super.viewDidLoad()
if UIScreen.main.isExtraCompactHeight
{
self.contentStackView.layoutMargins.top = 0
self.contentStackView.layoutMargins.bottom = self.contentStackView.layoutMargins.left
}
self.dismissButton.clipsToBounds = true
self.dismissButton.layer.cornerRadius = 16
if self.showsBottomButton
{
self.navigationItem.hidesBackButton = true
}
else
{
self.dismissButton.isHidden = true
}
}
}
private extension InstructionsViewController
{
@IBAction func dismiss()
{
self.completionHandler?()
}
}

View File

@@ -1,156 +0,0 @@
//
// ReplaceCertificateViewController.swift
// AltStore
//
// Created by Riley Testut on 6/5/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import UIKit
import AltSign
import Roxas
extension ReplaceCertificateViewController
{
private enum Error: LocalizedError
{
case missingPrivateKey
case missingCertificate
var errorDescription: String? {
switch self
{
case .missingPrivateKey: return NSLocalizedString("The certificate's private key could not be found.", comment: "")
case .missingCertificate: return NSLocalizedString("The certificate could not be found.", comment: "")
}
}
}
}
class ReplaceCertificateViewController: UITableViewController
{
var replacementHandler: ((ALTCertificate?) -> Void)?
var team: ALTTeam!
var certificates: [ALTCertificate] {
get {
return self.dataSource.items
}
set {
self.dataSource.items = newValue
}
}
private var selectedCertificate: ALTCertificate? {
didSet {
self.update()
}
}
private lazy var dataSource = self.makeDataSource()
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.dataSource = self.dataSource
self.update()
}
}
private extension ReplaceCertificateViewController
{
func makeDataSource() -> RSTArrayTableViewDataSource<ALTCertificate>
{
let dataSource = RSTArrayTableViewDataSource<ALTCertificate>(items: [])
dataSource.proxy = self
dataSource.cellConfigurationHandler = { [weak self] (cell, certificate, indexPath) in
cell.textLabel?.text = certificate.name
cell.accessoryType = (self?.selectedCertificate == certificate) ? .checkmark : .none
}
let placeholderView = RSTPlaceholderView(frame: .zero)
placeholderView.textLabel.text = NSLocalizedString("No Certificates", comment: "")
placeholderView.detailTextLabel.text = NSLocalizedString("There are no certificates associated with this team.", comment: "")
dataSource.placeholderView = placeholderView
return dataSource
}
func update()
{
self.navigationItem.rightBarButtonItem?.isEnabled = (self.selectedCertificate != nil)
if self.isViewLoaded
{
self.tableView.reloadData()
}
}
}
private extension ReplaceCertificateViewController
{
@IBAction func replaceCertificate(_ sender: UIBarButtonItem)
{
guard let certificate = self.selectedCertificate else { return }
func replace()
{
sender.isIndicatingActivity = true
ALTAppleAPI.shared.revoke(certificate, for: self.team) { (success, error) in
let result = Result(success, error).map { certificate }
do
{
let certificate = try result.get()
self.replacementHandler?(certificate)
}
catch
{
DispatchQueue.main.async {
let toastView = RSTToastView(text: NSLocalizedString("Error Replacing Certificate", comment: ""), detailText: error.localizedDescription)
toastView.tintColor = .altPurple
toastView.show(in: self.navigationController?.view ?? self.view, duration: 2.0)
sender.isIndicatingActivity = false
}
}
}
}
let localizedTitle = String(format: NSLocalizedString("Are you sure you want to replace %@?", comment: ""), certificate.name)
let localizedMessage = NSLocalizedString("Any AltStore apps currently installed with this certificate will need to be refreshed.", comment: "")
let localizedReplaceActionTitle = String(format: NSLocalizedString("Replace %@", comment: ""), certificate.name)
let alertController = UIAlertController(title: localizedTitle, message: localizedMessage, preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: localizedReplaceActionTitle, style: .destructive) { (action) in
replace()
})
alertController.addAction(.cancel)
self.present(alertController, animated: true, completion: nil)
}
@IBAction func cancel()
{
self.replacementHandler?(nil)
}
}
extension ReplaceCertificateViewController
{
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?
{
return NSLocalizedString("You have reached the maximum number of development certificates. Please select a certificate to replace.", comment: "")
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let certificate = self.dataSource.item(at: indexPath)
self.selectedCertificate = certificate
}
}

View File

@@ -1,141 +0,0 @@
//
// SelectTeamViewController.swift
// AltStore
//
// Created by Riley Testut on 6/5/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import UIKit
import AltSign
import Roxas
class SelectTeamViewController: UITableViewController
{
var selectionHandler: ((ALTTeam?) -> Void)?
var teams: [ALTTeam] {
get {
return self.dataSource.items
}
set {
self.dataSource.items = newValue
}
}
private var selectedTeam: ALTTeam? {
didSet {
self.update()
}
}
private lazy var dataSource = self.makeDataSource()
override func viewDidLoad()
{
super.viewDidLoad()
self.tableView.dataSource = self.dataSource
self.update()
}
override func viewWillDisappear(_ animated: Bool)
{
super.viewDidDisappear(animated)
self.navigationItem.rightBarButtonItem?.isIndicatingActivity = false
}
}
private extension SelectTeamViewController
{
func makeDataSource() -> RSTArrayTableViewDataSource<ALTTeam>
{
let dataSource = RSTArrayTableViewDataSource<ALTTeam>(items: [])
dataSource.proxy = self
dataSource.cellConfigurationHandler = { [weak self] (cell, team, indexPath) in
cell.textLabel?.text = team.name
cell.detailTextLabel?.text = team.type.localizedDescription
cell.accessoryType = (self?.selectedTeam == team) ? .checkmark : .none
}
let placeholderView = RSTPlaceholderView(frame: .zero)
placeholderView.textLabel.text = NSLocalizedString("No Teams", comment: "")
placeholderView.detailTextLabel.text = NSLocalizedString("You are not a member of any development teams.", comment: "")
dataSource.placeholderView = placeholderView
return dataSource
}
func update()
{
self.navigationItem.rightBarButtonItem?.isEnabled = (self.selectedTeam != nil)
if self.isViewLoaded
{
self.tableView.reloadData()
}
}
func fetchCertificates(for team: ALTTeam, completionHandler: @escaping (Result<[ALTCertificate], Error>) -> Void)
{
ALTAppleAPI.shared.fetchCertificates(for: team) { (certificate, error) in
let result = Result(certificate, error)
completionHandler(result)
}
}
}
private extension SelectTeamViewController
{
@IBAction func chooseTeam(_ sender: UIBarButtonItem)
{
guard let team = self.selectedTeam else { return }
func choose()
{
sender.isIndicatingActivity = true
self.selectionHandler?(team)
}
if team.type == .organization
{
let localizedActionTitle = String(format: NSLocalizedString("Use %@?", comment: ""), team.name)
let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to use an Organization team?", comment: ""),
message: NSLocalizedString("Doing so may affect other members of this team.", comment: ""), preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: localizedActionTitle, style: .destructive, handler: { (action) in
choose()
}))
alertController.addAction(.cancel)
self.present(alertController, animated: true, completion: nil)
}
else
{
choose()
}
}
@IBAction func cancel()
{
self.selectionHandler?(nil)
}
}
extension SelectTeamViewController
{
override func tableView(_ tableView: UITableView, titleForFooterInSection section: Int) -> String?
{
return NSLocalizedString("Select the team you would like to use to install apps.", comment: "")
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath)
{
let team = self.dataSource.item(at: indexPath)
self.selectedTeam = team
}
}

View File

@@ -12,6 +12,8 @@ extension UIColor
{ {
static let altPurple = UIColor(named: "Purple")! static let altPurple = UIColor(named: "Purple")!
static let altGreen = UIColor(named: "Green")! static let altGreen = UIColor(named: "Green")!
static let altRed = UIColor(named: "Red")!
static let altPink = UIColor(named: "Pink")!
static let refreshRed = UIColor(named: "RefreshRed")! static let refreshRed = UIColor(named: "RefreshRed")!
static let refreshOrange = UIColor(named: "RefreshOrange")! static let refreshOrange = UIColor(named: "RefreshOrange")!

View File

@@ -0,0 +1,16 @@
//
// UIScreen+CompactHeight.swift
// AltStore
//
// Created by Riley Testut on 9/6/19.
// Copyright © 2019 Riley Testut. All rights reserved.
//
import UIKit
extension UIScreen
{
var isExtraCompactHeight: Bool {
return self.fixedCoordinateSpace.bounds.height < 600
}
}

View File

@@ -34,17 +34,22 @@ class AuthenticationOperation: ResultOperation<ALTSigner>
{ {
private weak var presentingViewController: UIViewController? private weak var presentingViewController: UIViewController?
private lazy var navigationController = UINavigationController() private lazy var navigationController: UINavigationController = {
let navigationController = self.storyboard.instantiateViewController(withIdentifier: "navigationController") as! UINavigationController
return navigationController
}()
private lazy var storyboard = UIStoryboard(name: "Authentication", bundle: nil) private lazy var storyboard = UIStoryboard(name: "Authentication", bundle: nil)
private var appleIDPassword: String? private var appleIDPassword: String?
private var shouldShowInstructions = false
init(presentingViewController: UIViewController?) init(presentingViewController: UIViewController?)
{ {
self.presentingViewController = presentingViewController self.presentingViewController = presentingViewController
super.init() super.init()
self.progress.totalUnitCount = 3 self.progress.totalUnitCount = 3
} }
@@ -82,8 +87,10 @@ class AuthenticationOperation: ResultOperation<ALTSigner>
case .success(let certificate): case .success(let certificate):
self.progress.completedUnitCount += 1 self.progress.completedUnitCount += 1
let signer = ALTSigner(team: team, certificate: certificate) self.showInstructionsIfNecessary() { (didShowInstructions) in
self.finish(.success(signer)) let signer = ALTSigner(team: team, certificate: certificate)
self.finish(.success(signer))
}
} }
} }
} }
@@ -161,7 +168,7 @@ private extension AuthenticationOperation
{ {
guard let presentingViewController = self.presentingViewController else { return false } guard let presentingViewController = self.presentingViewController else { return false }
self.navigationController.view.tintColor = .altPurple self.navigationController.view.tintColor = .white
if self.navigationController.viewControllers.isEmpty if self.navigationController.viewControllers.isEmpty
{ {
@@ -191,8 +198,11 @@ private extension AuthenticationOperation
authenticationViewController.authenticationHandler = { (result) in authenticationViewController.authenticationHandler = { (result) in
if let (account, password) = result if let (account, password) = result
{ {
self.appleIDPassword = password // We presented the Auth UI and the user signed in.
// In this case, we'll assume we should show the instructions again.
self.shouldShowInstructions = true
self.appleIDPassword = password
completionHandler(.success(account)) completionHandler(.success(account))
} }
else else
@@ -242,38 +252,29 @@ private extension AuthenticationOperation
{ {
func selectTeam(from teams: [ALTTeam]) func selectTeam(from teams: [ALTTeam])
{ {
if let team = teams.first, teams.count == 1 if let team = teams.first(where: { $0.type == .free })
{ {
return completionHandler(.success(team)) return completionHandler(.success(team))
} }
else if let team = teams.first(where: { $0.type == .individual })
DispatchQueue.main.async { {
let selectTeamViewController = self.storyboard.instantiateViewController(withIdentifier: "selectTeamViewController") as! SelectTeamViewController return completionHandler(.success(team))
selectTeamViewController.teams = teams }
selectTeamViewController.selectionHandler = { (team) in else if let team = teams.first
if let team = team {
{ return completionHandler(.success(team))
completionHandler(.success(team)) }
} else
else {
{ return completionHandler(.failure(AuthenticationError.noTeam))
completionHandler(.failure(OperationError.cancelled))
}
}
if !self.present(selectTeamViewController)
{
completionHandler(.failure(AuthenticationError.noTeam))
}
} }
} }
ALTAppleAPI.shared.fetchTeams(for: account) { (teams, error) in ALTAppleAPI.shared.fetchTeams(for: account) { (teams, error) in
switch Result(teams, error) switch Result(teams, error)
{ {
case .failure(let error): completionHandler(.failure(error)) case .failure(let error): completionHandler(.failure(error))
case .success(let teams): case .success(let teams):
DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in
if let activeTeam = DatabaseManager.shared.activeTeam(in: context), let altTeam = teams.first(where: { $0.identifier == activeTeam.identifier }) if let activeTeam = DatabaseManager.shared.activeTeam(in: context), let altTeam = teams.first(where: { $0.identifier == activeTeam.identifier })
{ {
@@ -326,40 +327,16 @@ private extension AuthenticationOperation
func replaceCertificate(from certificates: [ALTCertificate]) func replaceCertificate(from certificates: [ALTCertificate])
{ {
if let certificate = certificates.first, certificates.count == 1 guard let certificate = certificates.first else { return completionHandler(.failure(AuthenticationError.noCertificate)) }
{
ALTAppleAPI.shared.revoke(certificate, for: team) { (success, error) in
if let error = error, !success
{
completionHandler(.failure(error))
}
else
{
requestCertificate()
}
}
return
}
DispatchQueue.main.async { ALTAppleAPI.shared.revoke(certificate, for: team) { (success, error) in
let replaceCertificateViewController = self.storyboard.instantiateViewController(withIdentifier: "replaceCertificateViewController") as! ReplaceCertificateViewController if let error = error, !success
replaceCertificateViewController.team = team
replaceCertificateViewController.certificates = certificates
replaceCertificateViewController.replacementHandler = { (certificate) in
if certificate != nil
{
requestCertificate()
}
else
{
completionHandler(.failure(OperationError.cancelled))
}
}
if !self.present(replaceCertificateViewController)
{ {
completionHandler(.failure(AuthenticationError.noCertificate)) completionHandler(.failure(error))
}
else
{
requestCertificate()
} }
} }
} }
@@ -393,4 +370,21 @@ private extension AuthenticationOperation
} }
} }
func showInstructionsIfNecessary(completionHandler: @escaping (Bool) -> Void)
{
guard self.shouldShowInstructions else { return completionHandler(false) }
DispatchQueue.main.async {
let instructionsViewController = self.storyboard.instantiateViewController(withIdentifier: "instructionsViewController") as! InstructionsViewController
instructionsViewController.showsBottomButton = true
instructionsViewController.completionHandler = {
completionHandler(true)
}
if !self.present(instructionsViewController)
{
completionHandler(false)
}
}
}
} }

View File

@@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "236",
"alpha" : "1.000",
"blue" : "178",
"green" : "65"
}
}
}
]
}

View File

@@ -0,0 +1,20 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
},
"colors" : [
{
"idiom" : "universal",
"color" : {
"color-space" : "srgb",
"components" : {
"red" : "235",
"alpha" : "1.000",
"blue" : "59",
"green" : "70"
}
}
}
]
}