Compare commits

..

5 Commits

Author SHA1 Message Date
naturecodevoid
8a8c5167c6 Switch to apps.sidestore.io 2023-11-27 14:28:29 -08:00
naturecodevoid
96f0d41986 Trusted Sources: Add stable and beta 2023-11-27 14:28:29 -08:00
naturecodevoid
f2b555beae News: fix duplicate news items from multiple SideStore release channel sources 2023-11-27 14:28:29 -08:00
naturecodevoid
d853791ad2 My Apps: Fix incorrect app name on first launch 2023-11-27 14:28:29 -08:00
naturecodevoid
8f5b56f717 Release channel support
- Show SideStore in Browse if it's not from the current SideStore source
- Change SideStore source URL and source ID based on if beta and nightly are in the version string
- Use StoreApp name for InstalledApp name to allow for source-specified name to show up in My Apps
2023-11-27 14:28:29 -08:00
21 changed files with 139 additions and 127 deletions

View File

@@ -2,7 +2,8 @@ name: Bug Report
description: Report a bug description: Report a bug
title: "[BUG] " title: "[BUG] "
labels: ["bug"] labels: ["bug"]
assignees: [] assignees:
- naturecodevoid
body: body:
- type: markdown - type: markdown
attributes: attributes:

View File

@@ -2,7 +2,8 @@ name: Feature Request
description: Suggest a feature description: Suggest a feature
title: "[FEATURE REQUEST] " title: "[FEATURE REQUEST] "
labels: ["enhancement"] labels: ["enhancement"]
assignees: [] assignees:
- naturecodevoid
body: body:
- type: markdown - type: markdown
attributes: attributes:

View File

@@ -3,6 +3,7 @@ on:
push: push:
tags: tags:
- '[0-9]+.[0-9]+.[0-9]+' # example: 1.0.0 - '[0-9]+.[0-9]+.[0-9]+' # example: 1.0.0
workflow_dispatch:
jobs: jobs:
build: build:

View File

@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="32700.99.1234" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="wKh-xq-NuP"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="21223" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES" initialViewController="wKh-xq-NuP">
<device id="retina4_7" orientation="portrait" appearance="light"/> <device id="retina4_7" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="22684"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21204"/>
<capability name="Named colors" minToolsVersion="9.0"/> <capability name="Named colors" minToolsVersion="9.0"/>
<capability name="Safe area layout guides" minToolsVersion="9.0"/> <capability name="Safe area layout guides" minToolsVersion="9.0"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/> <capability name="System colors in document resources" minToolsVersion="11.0"/>
@@ -356,8 +356,8 @@
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="ewH-gi-pyW"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" translatesAutoresizingMaskIntoConstraints="NO" id="ewH-gi-pyW">
<rect key="frame" x="0.0" y="30.5" width="335" height="17"/> <rect key="frame" x="0.0" y="30.5" width="335" height="17"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Version 0.5.6" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7E0-TV-G4l"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" verticalCompressionResistancePriority="751" text="Version 4.4.2" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="7E0-TV-G4l">
<rect key="frame" x="0.0" y="0.0" width="84" height="17"/> <rect key="frame" x="0.0" y="0.0" width="84.5" height="17"/>
<fontDescription key="fontDescription" type="system" pointSize="14"/> <fontDescription key="fontDescription" type="system" pointSize="14"/>
<color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="0.66666666666666663" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@@ -596,7 +596,7 @@ World</string>
<tabBarItem key="tabBarItem" title="Browse" image="Browse" id="Uwh-Bg-Ymq"/> <tabBarItem key="tabBarItem" title="Browse" image="Browse" id="Uwh-Bg-Ymq"/>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="dIv-qd-9L5" customClass="NavigationBar" customModule="SideStore" customModuleProvider="target"> <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="dIv-qd-9L5" customClass="NavigationBar" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="375" height="96"/> <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<color key="tintColor" name="Primary"/> <color key="tintColor" name="Primary"/>
</navigationBar> </navigationBar>
@@ -626,7 +626,7 @@ World</string>
</tabBarItem> </tabBarItem>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="CzO-Kt-BlZ" customClass="NavigationBar" customModule="SideStore" customModuleProvider="target"> <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="CzO-Kt-BlZ" customClass="NavigationBar" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="375" height="96"/> <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</navigationBar> </navigationBar>
<nil name="viewControllers"/> <nil name="viewControllers"/>
@@ -883,7 +883,7 @@ World</string>
<navigationItem key="navigationItem" title="App IDs" id="3Co-uv-Fhb"> <navigationItem key="navigationItem" title="App IDs" id="3Co-uv-Fhb">
<barButtonItem key="leftBarButtonItem" style="plain" id="Aqs-QK-Ups"> <barButtonItem key="leftBarButtonItem" style="plain" id="Aqs-QK-Ups">
<view key="customView" contentMode="scaleToFill" id="p0q-Fg-3Ba"> <view key="customView" contentMode="scaleToFill" id="p0q-Fg-3Ba">
<rect key="frame" x="16" y="7" width="83" height="42"/> <rect key="frame" x="16" y="1" width="83" height="42"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
</view> </view>
</barButtonItem> </barButtonItem>
@@ -909,7 +909,7 @@ World</string>
<tabBarItem key="tabBarItem" title="News" image="News" id="fVN-ed-uO1"/> <tabBarItem key="tabBarItem" title="News" image="News" id="fVN-ed-uO1"/>
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="525-jF-uDK" customClass="NavigationBar" customModule="SideStore" customModuleProvider="target"> <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="525-jF-uDK" customClass="NavigationBar" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="20" width="375" height="96"/> <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<edgeInsets key="layoutMargins" top="8" left="20" bottom="8" right="8"/> <edgeInsets key="layoutMargins" top="8" left="20" bottom="8" right="8"/>
</navigationBar> </navigationBar>
@@ -928,7 +928,7 @@ World</string>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="IXk-qg-mFJ" sceneMemberID="viewController"> <navigationController automaticallyAdjustsScrollViewInsets="NO" id="IXk-qg-mFJ" sceneMemberID="viewController">
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="9sB-f3-Fnk"> <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="9sB-f3-Fnk">
<rect key="frame" x="0.0" y="0.0" width="375" height="108"/> <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</navigationBar> </navigationBar>
<nil name="viewControllers"/> <nil name="viewControllers"/>
@@ -1070,7 +1070,7 @@ World</string>
<navigationController automaticallyAdjustsScrollViewInsets="NO" id="Qo4-72-Hmr" sceneMemberID="viewController"> <navigationController automaticallyAdjustsScrollViewInsets="NO" id="Qo4-72-Hmr" sceneMemberID="viewController">
<toolbarItems/> <toolbarItems/>
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="mcx-oR-qPe"> <navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" largeTitles="YES" id="mcx-oR-qPe">
<rect key="frame" x="0.0" y="0.0" width="375" height="108"/> <rect key="frame" x="0.0" y="0.0" width="375" height="96"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
</navigationBar> </navigationBar>
<nil name="viewControllers"/> <nil name="viewControllers"/>
@@ -1095,13 +1095,13 @@ World</string>
<image name="News" width="19" height="20"/> <image name="News" width="19" height="20"/>
<image name="Settings" width="20" height="20"/> <image name="Settings" width="20" height="20"/>
<namedColor name="Background"> <namedColor name="Background">
<color red="0.45098039215686275" green="0.015686274509803921" blue="0.68627450980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.6431" green="0.0196" blue="0.9804" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor> </namedColor>
<namedColor name="BlurTint"> <namedColor name="BlurTint">
<color red="1" green="1" blue="1" alpha="0.30000001192092896" colorSpace="custom" customColorSpace="sRGB"/> <color red="1" green="1" blue="1" alpha="0.3" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor> </namedColor>
<namedColor name="Primary"> <namedColor name="Primary">
<color red="0.64313725490196083" green="0.019607843137254902" blue="0.98039215686274506" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.6431" green="0.0196" blue="0.9804" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor> </namedColor>
<systemColor name="systemBackgroundColor"> <systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

View File

@@ -78,7 +78,7 @@ private extension BrowseViewController
NSSortDescriptor(keyPath: \StoreApp.name, ascending: true), NSSortDescriptor(keyPath: \StoreApp.name, ascending: true),
NSSortDescriptor(keyPath: \StoreApp.bundleIdentifier, ascending: true)] NSSortDescriptor(keyPath: \StoreApp.bundleIdentifier, ascending: true)]
fetchRequest.returnsObjectsAsFaults = false fetchRequest.returnsObjectsAsFaults = false
fetchRequest.predicate = NSPredicate(format: "%K != %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID) fetchRequest.predicate = NSPredicate(format: "%K != %@", #keyPath(StoreApp.sourceIdentifier), Source.altStoreIdentifier)
let dataSource = RSTFetchedResultsCollectionViewPrefetchingDataSource<StoreApp, UIImage>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext) let dataSource = RSTFetchedResultsCollectionViewPrefetchingDataSource<StoreApp, UIImage>(fetchRequest: fetchRequest, managedObjectContext: DatabaseManager.shared.viewContext)
dataSource.cellConfigurationHandler = { (cell, app, indexPath) in dataSource.cellConfigurationHandler = { (cell, app, indexPath) in

View File

@@ -2,8 +2,6 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>ALTAnisetteURL</key>
<string>https://ani.sidestore.io</string>
<key>ALTAppGroups</key> <key>ALTAppGroups</key>
<array> <array>
<string>group.$(APP_GROUP_IDENTIFIER)</string> <string>group.$(APP_GROUP_IDENTIFIER)</string>
@@ -11,10 +9,12 @@
</array> </array>
<key>ALTDeviceID</key> <key>ALTDeviceID</key>
<string>00008101-000129D63698001E</string> <string>00008101-000129D63698001E</string>
<key>ALTPairingFile</key>
<string>&lt;insert pairing file here&gt;</string>
<key>ALTServerID</key> <key>ALTServerID</key>
<string>1F7D5B55-79CE-4546-A029-D4DDC4AF3B6D</string> <string>1F7D5B55-79CE-4546-A029-D4DDC4AF3B6D</string>
<key>ALTPairingFile</key>
<string>&lt;insert pairing file here&gt;</string>
<key>ALTAnisetteURL</key>
<string>https://ani.sidestore.io</string>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDocumentTypes</key> <key>CFBundleDocumentTypes</key>
@@ -44,6 +44,8 @@
<string>$(PRODUCT_NAME)</string> <string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>$(MARKETING_VERSION)</string> <string>$(MARKETING_VERSION)</string>
<key>CFBundleURLTypes</key> <key>CFBundleURLTypes</key>
@@ -91,13 +93,6 @@
</array> </array>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>NSBonjourServices</key> <key>NSBonjourServices</key>
<array> <array>
<string>_altserver._tcp</string> <string>_altserver._tcp</string>
@@ -136,10 +131,13 @@
<string>fetch</string> <string>fetch</string>
<string>remote-notification</string> <string>remote-notification</string>
</array> </array>
<key>UIFileSharingEnabled</key>
<true/>
<key>UILaunchStoryboardName</key> <key>UILaunchStoryboardName</key>
<string>LaunchScreen</string> <string>LaunchScreen</string>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIMainStoryboardFile</key> <key>UIMainStoryboardFile</key>
<string>Main</string> <string>Main</string>
<key>UIRequiredDeviceCapabilities</key> <key>UIRequiredDeviceCapabilities</key>
@@ -206,5 +204,7 @@
</dict> </dict>
</dict> </dict>
</array> </array>
<key>UIFileSharingEnabled</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@@ -72,11 +72,10 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
fm.fileExists(atPath: appResourcePath.path), fm.fileExists(atPath: appResourcePath.path),
let data = fm.contents(atPath: appResourcePath.path), let data = fm.contents(atPath: appResourcePath.path),
let contents = String(data: data, encoding: .utf8), let contents = String(data: data, encoding: .utf8),
!contents.isEmpty, !contents.isEmpty {
!UserDefaults.standard.isPairingReset {
print("Loaded ALTPairingFile from \(appResourcePath.path)") print("Loaded ALTPairingFile from \(appResourcePath.path)")
return contents return contents
} else if let plistString = Bundle.main.object(forInfoDictionaryKey: "ALTPairingFile") as? String, !plistString.isEmpty, !plistString.contains("insert pairing file here"), !UserDefaults.standard.isPairingReset{ } else if let plistString = Bundle.main.object(forInfoDictionaryKey: "ALTPairingFile") as? String, !plistString.isEmpty, !plistString.contains("insert pairing file here"){
print("Loaded ALTPairingFile from Info.plist") print("Loaded ALTPairingFile from Info.plist")
return plistString return plistString
} else { } else {
@@ -94,7 +93,6 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
documentPickerController.shouldShowFileExtensions = true documentPickerController.shouldShowFileExtensions = true
documentPickerController.delegate = self documentPickerController.delegate = self
self.present(documentPickerController, animated: true, completion: nil) self.present(documentPickerController, animated: true, completion: nil)
UserDefaults.standard.isPairingReset = false
}) })
//Add OK button to a dialog message //Add OK button to a dialog message
@@ -103,13 +101,6 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
// Present Alert to // Present Alert to
self.present(dialogMessage, animated: true, completion: nil) self.present(dialogMessage, animated: true, completion: nil)
let dialogMessage2 = UIAlertController(title: "Analytics", message: "This app contains anonymous analytics for research and project development. By continuing to use this app, you are consenting to this data collection", preferredStyle: .alert)
let ok2 = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in})
dialogMessage2.addAction(ok2)
self.present(dialogMessage2, animated: true, completion: nil)
return nil return nil
} }
} }

View File

@@ -116,9 +116,7 @@ private extension ResignAppOperation
infoDictionary[kCFBundleIdentifierKey as String] = profile.bundleIdentifier infoDictionary[kCFBundleIdentifierKey as String] = profile.bundleIdentifier
infoDictionary[Bundle.Info.altBundleID] = identifier infoDictionary[Bundle.Info.altBundleID] = identifier
infoDictionary[Bundle.Info.devicePairingString] = "<insert pairing file here>" infoDictionary[Bundle.Info.devicePairingString] = Bundle.main.object(forInfoDictionaryKey: "ALTPairingFile") as? String
infoDictionary.removeValue(forKey: "DTXcode")
infoDictionary.removeValue(forKey: "DTXcodeBuild")
for (key, value) in additionalInfoDictionaryValues for (key, value) in additionalInfoDictionaryValues
{ {
@@ -186,7 +184,7 @@ private extension ResignAppOperation
{ {
guard let udid = fetch_udid()?.toString() as? String else { throw OperationError.unknownUDID } guard let udid = fetch_udid()?.toString() as? String else { throw OperationError.unknownUDID }
guard let pairingFileString = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.devicePairingString) as? String else { throw OperationError.unknownUDID } guard let pairingFileString = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.devicePairingString) as? String else { throw OperationError.unknownUDID }
additionalValues[Bundle.Info.devicePairingString] = "<insert pairing file here>" additionalValues[Bundle.Info.devicePairingString] = pairingFileString
additionalValues[Bundle.Info.deviceID] = udid additionalValues[Bundle.Info.deviceID] = udid
additionalValues[Bundle.Info.serverID] = UserDefaults.standard.preferredServerID additionalValues[Bundle.Info.serverID] = UserDefaults.standard.preferredServerID

View File

@@ -20,20 +20,24 @@
<key>Titles</key> <key>Titles</key>
<array> <array>
<string>SideStore</string> <string>SideStore</string>
<string>SideStore (.zip)</string>
<string>SideStore (.xyz)</string>
<string>Macley (US)</string> <string>Macley (US)</string>
<string>Macley (DE)</string>
<string>DrPudding</string>
<string>Sideloadly</string>
<string>Nick</string>
<string>Jawshoeadan</string> <string>Jawshoeadan</string>
<string>WesleyBryie</string> <string>crystall1nedev</string>
</array> </array>
<key>Values</key> <key>Values</key>
<array> <array>
<string>https://ani.sidestore.io</string> <string>https://ani.sidestore.io</string>
<string>https://ani.sidestore.zip</string>
<string>https://ani.846969.xyz</string>
<string>http://5.249.163.88:6969/</string> <string>http://5.249.163.88:6969/</string>
<string>http://45.132.246.138:6969/</string>
<string>https://sign.rheaa.xyz</string>
<string>https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx</string>
<string>http://45.33.29.114</string>
<string>https://anisette.jawshoeadan.me</string> <string>https://anisette.jawshoeadan.me</string>
<string>https://ani.wesbryie.com</string> <string>https://anisette.crystall1ne.software/</string>
</array> </array>
</dict> </dict>
<dict> <dict>

View File

@@ -279,7 +279,7 @@
<rect key="frame" x="0.0" y="0.0" width="375" height="51"/> <rect key="frame" x="0.0" y="0.0" width="375" height="51"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Allow Siri To Refresh Apps…" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c6K-fI-CVr"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Add to Siri…" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="c6K-fI-CVr">
<rect key="frame" x="30" y="15.5" width="100.5" height="20.5"/> <rect key="frame" x="30" y="15.5" width="100.5" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/> <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>

View File

@@ -106,33 +106,16 @@ final class SettingsViewController: UITableViewController
debugModeGestureRecognizer.numberOfTouchesRequired = 3 debugModeGestureRecognizer.numberOfTouchesRequired = 3
self.tableView.addGestureRecognizer(debugModeGestureRecognizer) self.tableView.addGestureRecognizer(debugModeGestureRecognizer)
print(Bundle.main.infoDictionary)
var versionString: String = ""
if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String if let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String
{ {
versionString += "SideStore \(version)" self.versionLabel.text = NSLocalizedString(String(format: "SideStore %@", version), comment: "SideStore Version")
if let xcode = Bundle.main.object(forInfoDictionaryKey: "DTXcode") as? String {
print(xcode)
versionString += " - Xcode \(xcode) - "
if let build = Bundle.main.object(forInfoDictionaryKey: "DTXcodeBuild") as? String {
print(build)
versionString += "\(build)"
}
}
if let pairing = Bundle.main.object(forInfoDictionaryKey: "ALTPairingFile") as? String {
let pair_test = pairing == "<insert pairing file here>"
if !pair_test {
versionString += " - \(!pair_test)"
}
}
} }
else else
{ {
versionString += "SideStore\t" self.versionLabel.text = NSLocalizedString("SideStore", comment: "")
} }
self.versionLabel.text = NSLocalizedString(versionString, comment: "SideStore Version")
self.tableView.contentInset.bottom = 20
self.tableView.contentInset.bottom = 40
self.update() self.update()
@@ -169,7 +152,6 @@ private extension SettingsViewController
} }
self.backgroundRefreshSwitch.isOn = UserDefaults.standard.isBackgroundRefreshEnabled self.backgroundRefreshSwitch.isOn = UserDefaults.standard.isBackgroundRefreshEnabled
self.noIdleTimeoutSwitch.isOn = UserDefaults.standard.isIdleTimeoutDisableEnabled
if self.isViewLoaded if self.isViewLoaded
{ {
@@ -221,7 +203,7 @@ private extension SettingsViewController
} }
else else
{ {
settingsHeaderFooterView.secondaryLabel.text = NSLocalizedString("Enable Background Refresh to automatically refresh apps in the background when connected to Wi-Fi. \n\nDisable the Idle Timeout toggle to allow SideStore to not let your device go to sleep during a refresh or install of any apps.", comment: "") settingsHeaderFooterView.secondaryLabel.text = NSLocalizedString("Enable Background Refresh to automatically refresh apps in the background when connected to Wi-Fi.", comment: "")
} }
case .instructions: case .instructions:
@@ -594,12 +576,11 @@ extension SettingsViewController
alertController.addAction(UIAlertAction(title: NSLocalizedString("Delete and Reset", comment: ""), style: .destructive){ _ in alertController.addAction(UIAlertAction(title: NSLocalizedString("Delete and Reset", comment: ""), style: .destructive){ _ in
if fm.fileExists(atPath: documentsPath.path), let contents = try? String(contentsOf: documentsPath), !contents.isEmpty { if fm.fileExists(atPath: documentsPath.path), let contents = try? String(contentsOf: documentsPath), !contents.isEmpty {
UserDefaults.standard.isPairingReset = true
try? fm.removeItem(atPath: documentsPath.path) try? fm.removeItem(atPath: documentsPath.path)
NSLog("Pairing File Reseted") NSLog("Pairing File Reseted")
} }
self.tableView.deselectRow(at: indexPath, animated: true) self.tableView.deselectRow(at: indexPath, animated: true)
let dialogMessage = UIAlertController(title: NSLocalizedString("Pairing File Reset", comment: ""), message: NSLocalizedString("Please restart SideStore", comment: ""), preferredStyle: .alert) let dialogMessage = UIAlertController(title: NSLocalizedString("Pairing File Reseted", comment: ""), message: NSLocalizedString("Please restart SideStore", comment: ""), preferredStyle: .alert)
self.present(dialogMessage, animated: true, completion: nil) self.present(dialogMessage, animated: true, completion: nil)
}) })
alertController.addAction(.cancel) alertController.addAction(.cancel)

View File

@@ -197,7 +197,7 @@ private extension SourcesViewController
{ {
let alertController = UIAlertController(title: NSLocalizedString("Add Source", comment: ""), message: nil, preferredStyle: .alert) let alertController = UIAlertController(title: NSLocalizedString("Add Source", comment: ""), message: nil, preferredStyle: .alert)
alertController.addTextField { (textField) in alertController.addTextField { (textField) in
textField.placeholder = "https://apps.sidestore.io" textField.placeholder = "https://apps.altstore.io"
textField.textContentType = .URL textField.textContentType = .URL
} }
alertController.addAction(.cancel) alertController.addAction(.cancel)
@@ -545,19 +545,19 @@ extension SourcesViewController: UICollectionViewDelegateFlowLayout
footerView.textView.delegate = self footerView.textView.delegate = self
let attributedText = NSMutableAttributedString( let attributedText = NSMutableAttributedString(
string: NSLocalizedString("SideStore has reviewed these sources to make sure they meet our safety standards.", comment: ""), string: NSLocalizedString("SideStore has reviewed these sources to make sure they meet our safety standards.\n\nSupport for untrusted sources is currently in beta, but you can help test them out by", comment: ""),
attributes: [.font: font, .foregroundColor: UIColor.gray] attributes: [.font: font, .foregroundColor: UIColor.gray]
) )
//attributedText.mutableString.append(" ") attributedText.mutableString.append(" ")
//let boldedFont = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold)!, size: font.pointSize) let boldedFont = UIFont(descriptor: font.fontDescriptor.withSymbolicTraits(.traitBold)!, size: font.pointSize)
//let openPatreonURL = URL(string: "https://SideStore.io/")! let openPatreonURL = URL(string: "https://SideStore.io/patreon")!
// let joinPatreonText = NSAttributedString( let joinPatreonText = NSAttributedString(
// string: NSLocalizedString("", comment: ""), string: NSLocalizedString("joining our Patreon.", comment: ""),
// attributes: [.font: boldedFont, .link: openPatreonURL, .underlineColor: UIColor.clear] attributes: [.font: boldedFont, .link: openPatreonURL, .underlineColor: UIColor.clear]
//) )
//attributedText.append(joinPatreonText) attributedText.append(joinPatreonText)
footerView.textView.attributedText = attributedText footerView.textView.attributedText = attributedText
footerView.textView.textAlignment = .natural footerView.textView.textAlignment = .natural

View File

@@ -28,7 +28,6 @@ public extension UserDefaults
@NSManaged var isBackgroundRefreshEnabled: Bool @NSManaged var isBackgroundRefreshEnabled: Bool
@NSManaged var isIdleTimeoutDisableEnabled: Bool @NSManaged var isIdleTimeoutDisableEnabled: Bool
@NSManaged var isPairingReset: Bool
@NSManaged var isDebugModeEnabled: Bool @NSManaged var isDebugModeEnabled: Bool
@NSManaged var presentedLaunchReminderNotification: Bool @NSManaged var presentedLaunchReminderNotification: Bool
@@ -75,7 +74,6 @@ public extension UserDefaults
let defaults = [ let defaults = [
#keyPath(UserDefaults.isBackgroundRefreshEnabled): true, #keyPath(UserDefaults.isBackgroundRefreshEnabled): true,
#keyPath(UserDefaults.isIdleTimeoutDisableEnabled): true, #keyPath(UserDefaults.isIdleTimeoutDisableEnabled): true,
#keyPath(UserDefaults.isPairingReset): true,
#keyPath(UserDefaults.isLegacyDeactivationSupported): isLegacyDeactivationSupported, #keyPath(UserDefaults.isLegacyDeactivationSupported): isLegacyDeactivationSupported,
#keyPath(UserDefaults.activeAppLimitIncludesExtensions): activeAppLimitIncludesExtensions, #keyPath(UserDefaults.activeAppLimitIncludesExtensions): activeAppLimitIncludesExtensions,
#keyPath(UserDefaults.localServerSupportsRefreshing): localServerSupportsRefreshing, #keyPath(UserDefaults.localServerSupportsRefreshing): localServerSupportsRefreshing,

View File

@@ -103,6 +103,7 @@
<attribute name="externalURL" optional="YES" attributeType="URI"/> <attribute name="externalURL" optional="YES" attributeType="URI"/>
<attribute name="identifier" attributeType="String"/> <attribute name="identifier" attributeType="String"/>
<attribute name="imageURL" optional="YES" attributeType="URI"/> <attribute name="imageURL" optional="YES" attributeType="URI"/>
<attribute name="isDuplicate" optional="YES" attributeType="Boolean" usesScalarValueType="YES"/>
<attribute name="isSilent" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/> <attribute name="isSilent" attributeType="Boolean" defaultValueString="YES" usesScalarValueType="YES"/>
<attribute name="sortIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/> <attribute name="sortIndex" attributeType="Integer 32" defaultValueString="0" usesScalarValueType="YES"/>
<attribute name="sourceIdentifier" optional="YES" attributeType="String"/> <attribute name="sourceIdentifier" optional="YES" attributeType="String"/>

View File

@@ -222,7 +222,7 @@ private extension DatabaseManager
let storeApp: StoreApp let storeApp: StoreApp
if let app = StoreApp.first(satisfying: NSPredicate(format: "%K == %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID), in: context) if let app = StoreApp.first(satisfying: NSPredicate(format: "%K == %@ AND %K == %@", #keyPath(StoreApp.bundleIdentifier), StoreApp.altstoreAppID, #keyPath(StoreApp.sourceIdentifier), Source.altStoreIdentifier), in: context)
{ {
storeApp = app storeApp = app
} }

View File

@@ -108,6 +108,10 @@ public class InstalledApp: NSManagedObject, InstalledAppProtocol
public func update(resignedApp: ALTApplication, certificateSerialNumber: String?) public func update(resignedApp: ALTApplication, certificateSerialNumber: String?)
{ {
self.name = resignedApp.name self.name = resignedApp.name
if storeApp != nil {
// This might break things; maybe only do this if the bundle ID is SideStore's?
self.name = storeApp!.name // If we don't do this, the name will always be SideStore in My Apps, even when using beta/nightly
}
self.resignedBundleIdentifier = resignedApp.bundleIdentifier self.resignedBundleIdentifier = resignedApp.bundleIdentifier
self.version = resignedApp.version self.version = resignedApp.version
@@ -178,7 +182,7 @@ public extension InstalledApp
class func fetchAltStore(in context: NSManagedObjectContext) -> InstalledApp? class func fetchAltStore(in context: NSManagedObjectContext) -> InstalledApp?
{ {
let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.bundleIdentifier), StoreApp.altstoreAppID) let predicate = NSPredicate(format: "%K == %@ AND %K != nil AND %K == %@", #keyPath(InstalledApp.bundleIdentifier), StoreApp.altstoreAppID, #keyPath(InstalledApp.storeApp), #keyPath(InstalledApp.storeApp.sourceIdentifier), Source.altStoreIdentifier)
print("Fetch 'AltStore' Predicate: \(String(describing: predicate))") print("Fetch 'AltStore' Predicate: \(String(describing: predicate))")
let altStore = InstalledApp.first(satisfying: predicate, in: context) let altStore = InstalledApp.first(satisfying: predicate, in: context)
return altStore return altStore

View File

@@ -32,6 +32,15 @@ public class NewsItem: NSManagedObject, Decodable, Fetchable
@NSManaged public var storeApp: StoreApp? @NSManaged public var storeApp: StoreApp?
@NSManaged public var source: Source? @NSManaged public var source: Source?
@objc public var isDuplicate: Bool {
if self.source == nil { return false }
// Hide news from sources that begin with the SideStore identifier, and aren't from the same source as the current SideStore source
if self.source!.identifier.starts(with: Bundle.Info.appbundleIdentifier) && self.source!.identifier != Source.altStoreIdentifier { return true }
return false
}
private enum CodingKeys: String, CodingKey private enum CodingKeys: String, CodingKey
{ {
case identifier case identifier
@@ -86,6 +95,9 @@ public extension NewsItem
{ {
@nonobjc class func fetchRequest() -> NSFetchRequest<NewsItem> @nonobjc class func fetchRequest() -> NSFetchRequest<NewsItem>
{ {
return NSFetchRequest<NewsItem>(entityName: "NewsItem") let fetchRequest = NSFetchRequest<NewsItem>(entityName: "NewsItem")
fetchRequest.predicate = NSPredicate(format: "%K == NO",
#keyPath(NewsItem.isDuplicate))
return fetchRequest
} }
} }

View File

@@ -11,29 +11,37 @@ import UIKit
public extension Source public extension Source
{ {
#if ALPHA static var altStoreIdentifier: String {
static let altStoreIdentifier = Bundle.Info.appbundleIdentifier let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
#else
static let altStoreIdentifier = Bundle.Info.appbundleIdentifier if appVersion != nil {
#endif if appVersion!.contains("beta") {
return Bundle.Info.appbundleIdentifier + ".Beta"
}
if appVersion!.contains("nightly") {
return Bundle.Info.appbundleIdentifier + ".Nightly"
}
}
return Bundle.Info.appbundleIdentifier
}
#if STAGING static let altStoreSourceBaseURL = "https://apps.sidestore.io/"
#if ALPHA static var altStoreSourceURL: URL {
static let altStoreSourceURL = URL(string: "https://apps.sidestore.io/")! let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
#else
static let altStoreSourceURL = URL(string: "https://apps.sidestore.io/")! if appVersion != nil {
#endif if appVersion!.contains("beta") {
return URL(string: altStoreSourceBaseURL + "beta")!
#else }
if appVersion!.contains("nightly") {
#if ALPHA return URL(string: altStoreSourceBaseURL + "nightly")!
static let altStoreSourceURL = URL(string: "https://apps.sidestore.io/")! }
#else }
static let altStoreSourceURL = URL(string: "https://apps.sidestore.io/")!
#endif return URL(string: altStoreSourceBaseURL)!
}
#endif
} }
public struct AppPermissionFeed: Codable { public struct AppPermissionFeed: Codable {

View File

@@ -343,16 +343,28 @@ public extension StoreApp
{ {
let app = StoreApp(context: context) let app = StoreApp(context: context)
app.name = "SideStore" app.name = "SideStore"
let currentAppVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
if currentAppVersion != nil {
if currentAppVersion!.contains("beta") {
app.name += " (Beta)"
}
if currentAppVersion!.contains("nightly") {
app.name += " (Nightly)"
}
}
app.bundleIdentifier = StoreApp.altstoreAppID app.bundleIdentifier = StoreApp.altstoreAppID
app.developerName = "Side Team" app.developerName = "SideStore Team"
app.localizedDescription = "SideStore is an alternative App Store." app.localizedDescription = "SideStore is an alternative app store for non-jailbroken devices.\n\nSideStore allows you to sideload other .ipa files and apps from the Files app or via the SideStore Library."
app.iconURL = URL(string: "https://user-images.githubusercontent.com/705880/63392210-540c5980-c37b-11e9-968c-8742fc68ab2e.png")! app.iconURL = URL(string: "https://sidestore.io/assets/icon.png")!
app.screenshotURLs = [] app.screenshotURLs = []
app.sourceIdentifier = Source.altStoreIdentifier app.sourceIdentifier = Source.altStoreIdentifier
let appVersion = AppVersion.makeAppVersion(version: "0.3.0", let appVersion = AppVersion.makeAppVersion(version: "0.0.0", // this is set to the current app version later
date: Date(), date: Date(),
downloadURL: URL(string: "http://rileytestut.com")!, downloadURL: URL(string: "https://sidestore.io")!,
size: 0, size: 0,
appBundleID: app.bundleIdentifier, appBundleID: app.bundleIdentifier,
sourceID: Source.altStoreIdentifier, sourceID: Source.altStoreIdentifier,
@@ -361,10 +373,6 @@ public extension StoreApp
print("makeAltStoreApp StoreApp: \(String(describing: app))") print("makeAltStoreApp StoreApp: \(String(describing: app))")
#if BETA
app.isBeta = true
#endif
return app return app
} }
} }

View File

@@ -1,8 +1,8 @@
// Configuration settings file format documentation can be found at: // Configuration settings file format documentation can be found at:
// https://help.apple.com/xcode/#/dev745c5c974 // https://help.apple.com/xcode/#/dev745c5c974
MARKETING_VERSION = 0.5.6 MARKETING_VERSION = 0.5.5
CURRENT_PROJECT_VERSION = 5060 CURRENT_PROJECT_VERSION = 5050
// Vars to be overwritten by `CodeSigning.xcconfig` if exists // Vars to be overwritten by `CodeSigning.xcconfig` if exists
DEVELOPMENT_TEAM = S32Z3HMYVQ DEVELOPMENT_TEAM = S32Z3HMYVQ

View File

@@ -4,6 +4,14 @@
{ {
"identifier": "io.sidestore.example" "identifier": "io.sidestore.example"
}, },
{
"identifier": "com.SideStore.SideStore",
"sourceURL": "https://apps.sidestore.io/"
},
{
"identifier": "com.SideStore.SideStore.Beta",
"sourceURL": "https://apps.sidestore.io/beta"
},
{ {
"identifier": "com.sidestoreapps.community", "identifier": "com.sidestoreapps.community",
"sourceURL": "https://community-apps.sidestore.io/sidecommunity.json" "sourceURL": "https://community-apps.sidestore.io/sidecommunity.json"
@@ -43,10 +51,6 @@
{ {
"identifier": "com.litritt.litsource", "identifier": "com.litritt.litsource",
"sourceURL": "https://altstore.ignitedemulator.com/" "sourceURL": "https://altstore.ignitedemulator.com/"
},
{
"identifier": "thatstel.la.altsource",
"sourceURL": "https://alt.thatstel.la/"
} }
] ]
} }