mirror of
https://github.com/SideStore/SideStore.git
synced 2026-02-09 06:43:25 +01:00
Revises Auth flow UI
This commit is contained in:
@@ -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 */,
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
50
AltStore/Authentication/InstructionsViewController.swift
Normal file
50
AltStore/Authentication/InstructionsViewController.swift
Normal 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?()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -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")!
|
||||||
|
|||||||
16
AltStore/Extensions/UIScreen+CompactHeight.swift
Normal file
16
AltStore/Extensions/UIScreen+CompactHeight.swift
Normal 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
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
@@ -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"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user