Skip to content

Commit 5789efe

Browse files
authored
Merge branch 'SideStore:develop' into LiveContainerSupport
2 parents 75e7698 + 669d331 commit 5789efe

7 files changed

Lines changed: 55 additions & 44 deletions

File tree

AltStore/My Apps/MyAppsViewController.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ class MyAppsViewController: UICollectionViewController, PeekPopPreviewing
170170
var minimuxerStatus: Bool {
171171
// added isMinimuxerStatusCheckEnabled to forcefully ignore minimuxer status if status check is disabled in settings
172172
guard !UserDefaults.standard.isMinimuxerStatusCheckEnabled || minimuxer.ready() else {
173-
ToastView(error: (OperationError.noWiFi as NSError).withLocalizedTitle("No WiFi or VPN!")).show(in: self)
173+
ToastView(error: (OperationError.noWiFi as NSError).withLocalizedTitle("No Wi-Fi or VPN!")).show(in: self)
174174
return false
175175
}
176176
return true

AltStore/Operations/Errors/OperationError.swift

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -220,16 +220,16 @@ struct OperationError: ALTLocalizedError {
220220
case .openAppFailed:
221221
let appName = self.appName ?? NSLocalizedString("The app", comment: "")
222222
return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), appName)
223-
case .noWiFi: return NSLocalizedString("You do not appear to be connected to WiFi and/or StosVPN!\nSideStore will never be able to install or refresh applications without WiFi and the StosVPN.", comment: "")
224-
case .tooNewError: return NSLocalizedString("iOS 17 has changed how JIT is enabled therefore SideStore cannot enable it without SideJITServer at this time, sorry for any inconvenience.\nWe will let everyone know once we have a solution!", comment: "")
225-
case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer Please check that you are on the Same Wi-Fi and your Firewall has been set correctly", comment: "")
226-
case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice Please make sure you have paired your Device by doing 'SideJITServer -y' or try Refreshing SideJITServer from Settings", comment: "")
227-
case .wrongSideJITIP: return NSLocalizedString("Incorrect SideJITServer IP Please make sure that you are on the Samw Wifi as SideJITServer", comment: "")
228-
case .refreshsidejit: return NSLocalizedString("Unable to find App Please try Refreshing SideJITServer from Settings", comment: "")
229-
case .anisetteV1Error: return NSLocalizedString("An error occurred when getting anisette data from a V1 server: %@. Try using another anisette server.", comment: "")
230-
case .provisioningError: return NSLocalizedString("An error occurred when provisioning: %@ %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: "")
231-
case .anisetteV3Error: return NSLocalizedString("An error occurred when getting anisette data from a V3 server: %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: "")
232-
case .cacheClearError: return NSLocalizedString("An error occurred while clearing cache: %@", comment: "")
223+
case .noWiFi: return NSLocalizedString("You do not appear to be connected to Wi-Fi and/or StosVPN!\nSideStore will never be able to install or refresh applications without Wi-Fi and StosVPN.", comment: "")
224+
case .tooNewError: return NSLocalizedString("iOS 17 has changed how JIT is enabled, therefore, SideStore cannot enable JIT without SideJITServer, StikDebug, or SideStore-nightly at this time, sorry for any inconvenience.", comment: "")
225+
case .unableToConnectSideJIT: return NSLocalizedString("Unable to connect to SideJITServer. Please check that you are on the same Wi-Fi of and your Firewall has been set correctly on your server", comment: "")
226+
case .unableToRespondSideJITDevice: return NSLocalizedString("SideJITServer is unable to connect to your iDevice. Please make sure you have paired your Device by running 'SideJITServer -y', or try refreshing SideJITServer from Settings", comment: "")
227+
case .wrongSideJITIP: return NSLocalizedString("Incorrect SideJITServer IP. Please make sure that you are on the same Wi-Fi as SideJITServer", comment: "")
228+
case .refreshsidejit: return NSLocalizedString("Unable to find app; Please try refreshing SideJITServer from Settings", comment: "")
229+
case .anisetteV1Error: return NSLocalizedString("An error occurred while getting anisette data from a V1 server: %@. Try using another anisette server.", comment: "")
230+
case .provisioningError: return NSLocalizedString("An error occurred while provisioning: %@ %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: "")
231+
case .anisetteV3Error: return NSLocalizedString("An error occurred while getting anisette data from a V3 server: %@. Please try again. If the issue persists, report it on GitHub Issues!", comment: "")
232+
case .cacheClearError: return NSLocalizedString("An error occurred while clearing the cache: %@", comment: "")
233233
case .SideJITIssue: return NSLocalizedString("An error occurred while using SideJIT: %@", comment: "")
234234

235235
case .refreshAppFailed:
@@ -260,7 +260,7 @@ struct OperationError: ALTLocalizedError {
260260
var recoverySuggestion: String? {
261261
switch self.code
262262
{
263-
case .noWiFi: return NSLocalizedString("Make sure the VPN is toggled on and you are connected to any WiFi network!", comment: "")
263+
case .noWiFi: return NSLocalizedString("Make sure StosVPN is toggled on and you are connected to any Wi-Fi network!", comment: "")
264264
case .serverNotFound: return NSLocalizedString("Make sure you're on the same Wi-Fi network as a computer running AltServer, or try connecting this device to your computer via USB.", comment: "")
265265
case .maximumAppIDLimitReached:
266266
let baseMessage = NSLocalizedString("Delete sideloaded apps to free up App ID slots.", comment: "")
@@ -308,7 +308,7 @@ extension MinimuxerError: LocalizedError {
308308
case .NoDevice:
309309
return NSLocalizedString("Cannot fetch the device from the muxer", comment: "")
310310
case .NoConnection:
311-
return NSLocalizedString("Unable to connect to the device, make sure StosVPN is enabled and you're connected to WiFi. This could mean an invalid pairing.", comment: "")
311+
return NSLocalizedString("Unable to connect to the device, make sure StosVPN is enabled and you're connected to Wi-Fi. This could mean an invalid pairing.", comment: "")
312312
case .PairingFile:
313313
return NSLocalizedString("Invalid pairing file. Your pairing file either didn't have a UDID, or it wasn't a valid plist. Please use idevice_pair to regenerate it", comment: "")
314314

AltStore/Settings/Error Log/ErrorLogViewController.swift

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -380,13 +380,8 @@ private extension ErrorLogViewController
380380

381381
func searchFAQ(for loggedError: LoggedError)
382382
{
383-
let baseURL = URL(string: "https://faq.altstore.io/getting-started/error-codes")!
384-
var components = URLComponents(url: baseURL, resolvingAgainstBaseURL: false)!
385-
386-
let query = [loggedError.domain, "\(loggedError.error.displayCode)"].joined(separator: "+")
387-
components.queryItems = [URLQueryItem(name: "q", value: query)]
388-
389-
let safariViewController = SFSafariViewController(url: components.url ?? baseURL)
383+
let staticURL = URL(string: "https://docs.sidestore.io/docs/troubleshooting/error-codes")!
384+
let safariViewController = SFSafariViewController(url: staticURL)
390385
safariViewController.preferredControlTintColor = .altPrimary
391386
self.present(safariViewController, animated: true)
392387
}

AltStore/Settings/PatreonComponents.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ final class AboutPatreonHeaderView: UICollectionReusableView
8282
imageView.layer.cornerRadius = imageView.bounds.midY
8383
}
8484

85-
for button in [self.supportButton, self.accountButton].compactMap({$0})
85+
for button in [self.supportButton, self.accountButton, self.twitterButton, self.instagramButton].compactMap({$0})
8686
{
8787
button.clipsToBounds = true
8888
button.layer.cornerRadius = 16

Build.xcconfig

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
// Configuration settings file format documentation can be found at:
22
// https://help.apple.com/xcode/#/dev745c5c974
33

4-
MARKETING_VERSION = 0.6.2
5-
CURRENT_PROJECT_VERSION = 0602
4+
MARKETING_VERSION = 0.6.3
5+
CURRENT_PROJECT_VERSION = 0603
66

77
// Vars to be overwritten by `CodeSigning.xcconfig` if exists
88
DEVELOPMENT_TEAM = S32Z3HMYVQ

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,10 @@ Why iOS 15? Targeting such a recent version of iOS allows us to accelerate devel
2828
SideStore is a just regular, sandboxed iOS application. The AltStore app target contains the vast majority of SideStore's functionality, including all the logic for downloading and updating apps through SideStore. SideStore makes heavy use of standard iOS frameworks and technologies most iOS developers are familiar with.
2929

3030
### EM Proxy
31-
[SideServer mobile](https://github.com/jkcoxson/em_proxy) powers the defining feature of SideStore: untethered app installation. By leveraging an App Store app with additional entitlements (WireGuard or StosVPN) to create the VPN tunnel for us, it allows SideStore to take advantage of [Jitterbug](https://github.com/osy/Jitterbug)'s loopback method without requiring a paid developer account.
31+
[SideServer mobile](https://github.com/jkcoxson/em_proxy) powers the defining feature of SideStore: untethered app installation. By leveraging a custom-built App Store app with additional entitlements (StosVPN) to create the VPN tunnel for us, it allows SideStore to take advantage of [Jitterbug](https://github.com/osy/Jitterbug)'s loopback method without requiring a paid developer account.
3232

3333
### Minimuxer
34-
[Minimuxer](https://github.com/jkcoxson/minimuxer) is a lockdown muxer that can run inside iOS’s sandbox. It replicates Apple’s usbmuxd protocol on MacOS to “discover” devices to interface with wireguard On-Device.
34+
[Minimuxer](https://github.com/jkcoxson/minimuxer) is a lockdown muxer that can run inside iOS’s sandbox. It replicates Apple’s usbmuxd protocol on MacOS to “discover” devices to interface with StosVPN On-Device.
3535

3636
### Roxas
3737
[Roxas](https://github.com/rileytestut/roxas) is Riley Testut's internal framework from AltStore used across many of their iOS projects, developed to simplify a variety of common tasks used in iOS development.

SideStore/Utils/iostreams/ConsoleLogger.swift

Lines changed: 35 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -59,48 +59,64 @@ public class AbstractConsoleLogger<T: OutputStream>: ConsoleLogger{
5959
originalStdout = dup(STDOUT_FILENO)
6060
originalStderr = dup(STDERR_FILENO)
6161

62+
let redirectedOutStream = self.outPipe?.fileHandleForWriting.fileDescriptor ?? -1
63+
let redirectedErrStream = self.errPipe?.fileHandleForWriting.fileDescriptor ?? -1
64+
6265
// Redirect stdout and stderr to our pipes
63-
dup2(self.outPipe?.fileHandleForWriting.fileDescriptor ?? -1, STDOUT_FILENO)
64-
dup2(self.errPipe?.fileHandleForWriting.fileDescriptor ?? -1, STDERR_FILENO)
66+
dup2(redirectedOutStream, STDOUT_FILENO)
67+
dup2(redirectedErrStream, STDERR_FILENO)
6568

69+
// Disable libc-level buffering
70+
// (libc by default uses bufferring except its own console/TTYs such as for pipes)
71+
// we do have our own buffering so we disable stdlib io level bufferring
72+
setvbuf(stdout, nil, _IONBF, 0) // disable buffering for stdout
73+
setvbuf(stderr, nil, _IONBF, 0) // disable buffering for stderr
74+
6675
// Setup readability handlers for raw data
6776
setupReadabilityHandler(for: outputHandle, isError: false)
6877
setupReadabilityHandler(for: errorHandle, isError: true)
6978
}
7079

80+
let shutdownLock = NSLock()
81+
7182
private func setupReadabilityHandler(for handle: FileHandle?, isError: Bool) {
72-
handle?.readabilityHandler = { [weak self] handle in
73-
let data = handle.availableData
74-
if !data.isEmpty {
75-
self?.writeQueue.async {
76-
try? self?.writeData(data)
77-
}
78-
79-
// Forward to original std stream
80-
if let originalFD = isError ? self?.originalStderr : self?.originalStdout {
81-
data.withUnsafeBytes { (bufferPointer) -> Void in
82-
if let baseAddress = bufferPointer.baseAddress, bufferPointer.count > 0 {
83-
write(originalFD, baseAddress, bufferPointer.count)
84-
}
85-
}
86-
}
83+
handle?.readabilityHandler = readHandler(for: handle, isError: isError)
84+
}
85+
86+
private func readHandler(for handle: FileHandle?, isError: Bool) -> (FileHandle) -> Void {
87+
return { [weak self] _ in
88+
guard let self, let data = handle?.availableData else { return }
89+
90+
shutdownLock.lock()
91+
defer { shutdownLock.unlock() }
92+
93+
writeQueue.async {
94+
try? self.writeData(data)
95+
}
96+
97+
if let fd = isError ? self.originalStderr : self.originalStdout {
98+
data.withUnsafeBytes { _ = write(fd, $0.baseAddress, $0.count) }
8799
}
88100
}
89101
}
102+
90103

91104
func writeData(_ data: Data) throws {
92105
throw AbstractClassError.abstractMethodInvoked
93106
}
94107

95108
func stopCapturing() {
109+
shutdownLock.lock()
110+
defer { shutdownLock.unlock() }
111+
96112
ostream.close()
97113

98114
// Restore original stdout and stderr
99-
if let stdout = originalStdout {
115+
if let stdout = originalStdout, stdout != STDOUT_FILENO {
100116
dup2(stdout, STDOUT_FILENO)
101117
close(stdout)
102118
}
103-
if let stderr = originalStderr {
119+
if let stderr = originalStderr, stderr != STDERR_FILENO {
104120
dup2(stderr, STDERR_FILENO)
105121
close(stderr)
106122
}

0 commit comments

Comments
 (0)