Merge branch 'main' into main
6
.github/workflows/appcast.yml
vendored
|
|
@ -15,15 +15,15 @@ jobs:
|
|||
persist-credentials: false
|
||||
|
||||
- name: Cache 📦
|
||||
uses: actions/cache@v3.0.11
|
||||
uses: actions/cache@v3.3.1
|
||||
with:
|
||||
path: AppCast/vendor/bundle
|
||||
key: ${{ runner.os }}-gems-v1.0-${{ hashFiles('AppCast/Gemfile') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gems-
|
||||
|
||||
- name: Ruby ♦️
|
||||
uses: actions/setup-ruby@v1.1.3
|
||||
- name: Setup Ruby, JRuby and TruffleRuby
|
||||
uses: ruby/setup-ruby@v1.149.0
|
||||
with:
|
||||
ruby-version: '2.7'
|
||||
|
||||
|
|
|
|||
46
README.md
|
|
@ -2,13 +2,17 @@
|
|||
|
||||
The easiest way to install and switch between multiple versions of Xcode.
|
||||
|
||||
_If you're looking for a command-line version of Xcodes.app, try [`xcodes`](https://github.com/RobotsAndPencils/xcodes)._
|
||||
_If you're looking for a command-line version of Xcodes.app, try [`xcodes`](https://github.com/XcodesOrg/xcodes)._
|
||||
|
||||

|
||||

|
||||
|
||||

|
||||

|
||||
|
||||
### :tada: Announcment
|
||||
|
||||
XcodesApp is now part of the `XcodesOrg` - [read more here](nextstep.md)
|
||||
|
||||
## Features
|
||||
|
||||
- List all available Xcode versions from [Xcode Releases'](https://xcodereleases.com) data or the Apple Developer website.
|
||||
|
|
@ -21,14 +25,14 @@ _If you're looking for a command-line version of Xcodes.app, try [`xcodes`](http
|
|||
|
||||
## Experiments
|
||||
|
||||
- Thanks to the wonderful work of [https://github.com/saagarjha/unxip](https://github.com/saagarjha/unxip), turn on the experiment to increase your unxipping time by up to 70%! More can be found on his repo, but bugs, high memory may occur if used.
|
||||
- Thanks to the wonderful work of [https://github.com/saagarjha/unxip](https://github.com/saagarjha/unxip), turn on the experiment to increase your unxipping time by up to 70%! More can be found on his repo, but bugs, high memory may occur if used.
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
## Localization
|
||||
|
||||
Xcodes supports localization in several languages.
|
||||
Xcodes supports localization in several languages.
|
||||
|
||||
The following languages are supported because of the following community users!
|
||||
|
||||
|
|
@ -36,37 +40,36 @@ The following languages are supported because of the following community users!
|
|||
|-|-|-|-|
|
||||
|French 🇫🇷 |[@dompepin](https://github.com/dompepin)|Italian 🇮🇹 |[gualtierofrigerio](https://github.com/gualtierofrigerio)|
|
||||
|Spanish 🇪🇸🇲 |[@cesartru88](https://github.com/cesartru88)|Korean 🇰🇷 |[@ryan-son](https://github.com/ryan-son)|
|
||||
|Russian 🇷🇺 |[@alexmazlov](https://github.com/alexmazlov)|Turkish 🇹🇷 |[@egrimo](https://github.com/egrimo)|
|
||||
|Russian 🇷🇺 |[@alexmazlov](https://github.com/alexmazlov)|Turkish 🇹🇷 |[@egesucu](https://github.com/egesucu)|
|
||||
|Hindi 🇮🇳 |[@KGurpreet](https://github.com/KGurpreet)|Chinese-Simplified 🇨🇳|[@megabitsenmzq](https://github.com/megabitsenmzq)|
|
||||
|Finnish 🇫🇮 |[@marcusziade](https://github.com/marcusziade)|Chinese-Traditional 🇹🇼|[@itszero](https://github.com/itszero)|
|
||||
|Ukranian 🇺🇦 |[@gelosi](https://github.com/gelosi)|Japanese 🇯🇵|[@tatsuz0u](https://github.com/tatsuz0u)|
|
||||
|German 🇩🇪|[@drct](https://github.com/drct)|Dutch 🇳🇱|[@jfversluis](https://github/com/jfversluis)|
|
||||
|Brazilian Portuguese 🇧🇷|[@brunomunizaf](https://github.com/brunomunizaf)|Catalan|[@ferranabello](https://github.com/ferranabello)||
|
||||
|Brazilian Portuguese 🇧🇷|[@brunomunizaf](https://github.com/brunomunizaf)|Polish 🇵🇱|[@jakex7](https://github.com/jakex7)|
|
||||
|Catalan|[@ferranabello](https://github.com/ferranabello)|
|
||||
|
||||
Want to add more languages? Simply create a PR with the updated strings file.
|
||||
Want to add more languages? Simply create a PR with the updated strings file.
|
||||
## Installation
|
||||
|
||||
Xcodes.app runs on macOS Big Sur 11.0 or later.
|
||||
|
||||
### Homebrew Cask
|
||||
### Install with Homebrew
|
||||
|
||||
Developer ID-signed and notarized release builds are available on Homebrew. These don't require Xcode to already be installed in order to use.
|
||||
|
||||
```sh
|
||||
brew install --cask xcodes
|
||||
|
||||
# These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.
|
||||
```
|
||||
|
||||
### Download a release
|
||||
### Manually install
|
||||
|
||||
1. Download the latest version [here](https://github.com/RobotsAndPencils/XcodesApp/releases/latest) using the **Xcodes.zip** asset. These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.
|
||||
1. Download the latest version [here](https://github.com/XcodesOrg/XcodesApp/releases/latest) using the **Xcodes.zip** asset. These are Developer ID-signed and notarized release builds and don't require Xcode to already be installed in order to use.
|
||||
2. Move the unzipped `Xcodes.app` to your `/Applications` directory
|
||||
|
||||
## Development
|
||||
|
||||
You'll need macOS 12 Big Sur and Xcode 13 in order to build and run Xcodes.app.
|
||||
|
||||
If you aren't a Robots and Pencils employee you'll need to change the CODE_SIGNING_SUBJECT_ORGANIZATIONAL_UNIT build setting to your Apple Developer team ID in order for code signing validation to succeed between the main app and the privileged helper.
|
||||
|
||||
`Unxip` and `aria2` must be compiled as a universal binary
|
||||
```
|
||||
# compile for Intel
|
||||
|
|
@ -77,7 +80,7 @@ If you aren't a Robots and Pencils employee you'll need to change the CODE_SIGNI
|
|||
# combine for universal binary
|
||||
lipo -create -output unxip unxip_intel unxip_m1
|
||||
# check it
|
||||
lipo -archs unxip
|
||||
lipo -archs unxip
|
||||
```
|
||||
|
||||
Notable design decisions are recorded in [DECISIONS.md](./DECISIONS.md). The Apple authentication flow is described in [Apple.paw](./Apple.paw), which will allow you to play with the API endpoints that are involved using the [Paw](https://paw.cloud) app.
|
||||
|
|
@ -133,7 +136,7 @@ pushd Product
|
|||
../scripts/sign_update Xcodes.zip
|
||||
popd
|
||||
|
||||
# Go to https://github.com/RobotsAndPencils/XcodesApp/releases
|
||||
# Go to https://github.com/XcodesOrg/XcodesApp/releases
|
||||
# If there are uncategorized PRs, add the appropriate label and run the Release Drafter action manually
|
||||
# Edit the latest draft release
|
||||
# Set its tag to the tag you just pushed
|
||||
|
|
@ -152,9 +155,4 @@ popd
|
|||
|
||||
[Matt Kiazyk](https://github.com/mattkiazyk) - [Twitter](https://www.twitter.com/mattkiazyk)
|
||||
|
||||
|
||||
<a href="http://www.robotsandpencils.com"><img src="R&PLogo.png" width="153" height="74" /></a>
|
||||
|
||||
Made with ❤️ by [Robots & Pencils](http://www.robotsandpencils.com)
|
||||
|
||||
[Twitter](https://twitter.com/xcodesApp) | [GitHub](https://github.com/robotsandpencils)
|
||||
[Twitter](https://twitter.com/xcodesApp) | [GitHub](https://github.com/xcodesOrg)
|
||||
|
|
|
|||
|
|
@ -172,6 +172,7 @@
|
|||
|
||||
/* Begin PBXFileReference section */
|
||||
15FAD1652811D15600B63259 /* hi */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = hi; path = hi.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
23703D6E29EBF63500DFA346 /* pl */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = pl; path = pl.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
25E2FA26284769A00014A318 /* it */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = it; path = it.lproj/Localizable.strings; sourceTree = "<group>"; };
|
||||
327DF109286ABE6B00D694D5 /* pt-BR */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "pt-BR"; path = "pt-BR.lproj/Localizable.strings"; sourceTree = "<group>"; };
|
||||
36741BFC291E4FDB00A85AAE /* DownloadPreferencePane.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DownloadPreferencePane.swift; sourceTree = "<group>"; };
|
||||
|
|
@ -736,6 +737,7 @@
|
|||
ca,
|
||||
"pt-BR",
|
||||
nl,
|
||||
pl,
|
||||
);
|
||||
mainGroup = CAD2E7952449574E00113D76;
|
||||
packageReferences = (
|
||||
|
|
@ -955,6 +957,7 @@
|
|||
5C3927ED28E4B486007B5119 /* ca */,
|
||||
327DF109286ABE6B00D694D5 /* pt-BR */,
|
||||
E2AFDCCA28F024D000864ADD /* nl */,
|
||||
23703D6E29EBF63500DFA346 /* pl */,
|
||||
);
|
||||
name = Localizable.strings;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -1033,7 +1036,7 @@
|
|||
CODE_SIGN_IDENTITY = "-";
|
||||
CODE_SIGN_STYLE = Manual;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Xcodes/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = "";
|
||||
ENABLE_HARDENED_RUNTIME = NO;
|
||||
|
|
@ -1043,7 +1046,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesApp;
|
||||
PRODUCT_NAME = Xcodes;
|
||||
PROVISIONING_PROFILE_SPECIFIER = "";
|
||||
|
|
@ -1274,7 +1277,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Xcodes/Resources/Xcodes.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Xcodes/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = PBH8V487HB;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
|
@ -1284,7 +1287,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesApp;
|
||||
PRODUCT_NAME = Xcodes;
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
|
@ -1298,7 +1301,7 @@
|
|||
CODE_SIGN_ENTITLEMENTS = Xcodes/Resources/Xcodes.entitlements;
|
||||
CODE_SIGN_STYLE = Automatic;
|
||||
COMBINE_HIDPI_IMAGES = YES;
|
||||
CURRENT_PROJECT_VERSION = 17;
|
||||
CURRENT_PROJECT_VERSION = 18;
|
||||
DEVELOPMENT_ASSET_PATHS = "\"Xcodes/Preview Content\"";
|
||||
DEVELOPMENT_TEAM = PBH8V487HB;
|
||||
ENABLE_HARDENED_RUNTIME = YES;
|
||||
|
|
@ -1308,7 +1311,7 @@
|
|||
"$(inherited)",
|
||||
"@executable_path/../Frameworks",
|
||||
);
|
||||
MARKETING_VERSION = 1.9.0;
|
||||
MARKETING_VERSION = 1.10.0;
|
||||
PRODUCT_BUNDLE_IDENTIFIER = com.robotsandpencils.XcodesApp;
|
||||
PRODUCT_NAME = Xcodes;
|
||||
SWIFT_VERSION = 5.0;
|
||||
|
|
|
|||
|
|
@ -14,12 +14,22 @@ public class Client {
|
|||
return Current.network.dataTask(with: URLRequest.itcServiceKey)
|
||||
.map(\.data)
|
||||
.decode(type: ServiceKeyResponse.self, decoder: JSONDecoder())
|
||||
.flatMap { serviceKeyResponse -> AnyPublisher<URLSession.DataTaskPublisher.Output, Swift.Error> in
|
||||
.flatMap { serviceKeyResponse -> AnyPublisher<(String, String), Swift.Error> in
|
||||
serviceKey = serviceKeyResponse.authServiceKey
|
||||
return Current.network.dataTask(with: URLRequest.signIn(serviceKey: serviceKey, accountName: accountName, password: password))
|
||||
.mapError { $0 as Swift.Error }
|
||||
|
||||
// Fixes issue https://github.com/RobotsAndPencils/XcodesApp/issues/360
|
||||
// On 2023-02-23, Apple added a custom implementation of hashcash to their auth flow
|
||||
// Without this addition, Apple ID's would get set to locked
|
||||
return self.loadHashcash(accountName: accountName, serviceKey: serviceKey)
|
||||
.map { return (serviceKey, $0)}
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
.flatMap { (serviceKey, hashcash) -> AnyPublisher<URLSession.DataTaskPublisher.Output, Swift.Error> in
|
||||
|
||||
return Current.network.dataTask(with: URLRequest.signIn(serviceKey: serviceKey, accountName: accountName, password: password, hashcash: hashcash))
|
||||
.mapError { $0 as Swift.Error }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
.flatMap { result -> AnyPublisher<AuthenticationState, Swift.Error> in
|
||||
let (data, response) = result
|
||||
return Just(data)
|
||||
|
|
@ -56,6 +66,44 @@ public class Client {
|
|||
.mapError { $0 as Swift.Error }
|
||||
.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
func loadHashcash(accountName: String, serviceKey: String) -> AnyPublisher<String, Swift.Error> {
|
||||
|
||||
Result {
|
||||
try URLRequest.federate(account: accountName, serviceKey: serviceKey)
|
||||
}
|
||||
.publisher
|
||||
.flatMap { request in
|
||||
Current.network.dataTask(with: request)
|
||||
.mapError { $0 as Error }
|
||||
.tryMap { (data, response) throws -> (String) in
|
||||
guard let urlResponse = response as? HTTPURLResponse else {
|
||||
throw AuthenticationError.invalidSession
|
||||
}
|
||||
switch urlResponse.statusCode {
|
||||
case 200..<300:
|
||||
|
||||
let httpResponse = response as! HTTPURLResponse
|
||||
guard let bitsString = httpResponse.allHeaderFields["X-Apple-HC-Bits"] as? String, let bits = UInt(bitsString) else {
|
||||
throw AuthenticationError.invalidHashcash
|
||||
}
|
||||
guard let challenge = httpResponse.allHeaderFields["X-Apple-HC-Challenge"] as? String else {
|
||||
throw AuthenticationError.invalidHashcash
|
||||
}
|
||||
guard let hashcash = Hashcash().mint(resource: challenge, bits: bits) else {
|
||||
throw AuthenticationError.invalidHashcash
|
||||
}
|
||||
return (hashcash)
|
||||
case 400, 401:
|
||||
throw AuthenticationError.invalidHashcash
|
||||
case let code:
|
||||
throw AuthenticationError.badStatusCode(statusCode: code, data: data, response: urlResponse)
|
||||
}
|
||||
}
|
||||
}
|
||||
.eraseToAnyPublisher()
|
||||
|
||||
}
|
||||
|
||||
func handleTwoStepOrFactor(data: Data, response: URLResponse, serviceKey: String) -> AnyPublisher<AuthenticationState, Swift.Error> {
|
||||
let httpResponse = response as! HTTPURLResponse
|
||||
|
|
@ -190,6 +238,7 @@ public enum AuthenticationState: Equatable {
|
|||
|
||||
public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
||||
case invalidSession
|
||||
case invalidHashcash
|
||||
case invalidUsernameOrPassword(username: String)
|
||||
case incorrectSecurityCode
|
||||
case unexpectedSignInResponse(statusCode: Int, message: String?)
|
||||
|
|
@ -206,6 +255,8 @@ public enum AuthenticationError: Swift.Error, LocalizedError, Equatable {
|
|||
switch self {
|
||||
case .invalidSession:
|
||||
return "Your authentication session is invalid. Try signing in again."
|
||||
case .invalidHashcash:
|
||||
return "Could not create a hashcash for the session."
|
||||
case .invalidUsernameOrPassword:
|
||||
return "Invalid username and password combination."
|
||||
case .incorrectSecurityCode:
|
||||
|
|
|
|||
96
Xcodes/AppleAPI/Sources/AppleAPI/Hashcash.swift
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
//
|
||||
// Hashcash.swift
|
||||
//
|
||||
//
|
||||
// Created by Matt Kiazyk on 2023-02-23.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CryptoKit
|
||||
import CommonCrypto
|
||||
|
||||
/*
|
||||
# This App Store Connect hashcash spec was generously donated by...
|
||||
#
|
||||
# __ _
|
||||
# __ _ _ __ _ __ / _|(_) __ _ _ _ _ __ ___ ___
|
||||
# / _` || '_ \ | '_ \ | |_ | | / _` || | | || '__|/ _ \/ __|
|
||||
# | (_| || |_) || |_) || _|| || (_| || |_| || | | __/\__ \
|
||||
# \__,_|| .__/ | .__/ |_| |_| \__, | \__,_||_| \___||___/
|
||||
# |_| |_| |___/
|
||||
#
|
||||
#
|
||||
*/
|
||||
public struct Hashcash {
|
||||
/// A function to returned a minted hash, using a bit and resource string
|
||||
///
|
||||
/**
|
||||
X-APPLE-HC: 1:11:20230223170600:4d74fb15eb23f465f1f6fcbf534e5877::6373
|
||||
^ ^ ^ ^ ^
|
||||
| | | | +-- Counter
|
||||
| | | +-- Resource
|
||||
| | +-- Date YYMMDD[hhmm[ss]]
|
||||
| +-- Bits (number of leading zeros)
|
||||
+-- Version
|
||||
|
||||
We can't use an off-the-shelf Hashcash because Apple's implementation is not quite the same as the spec/convention.
|
||||
1. The spec calls for a nonce called "Rand" to be inserted between the Ext and Counter. They don't do that at all.
|
||||
2. The Counter conventionally encoded as base-64 but Apple just uses the decimal number's string representation.
|
||||
|
||||
Iterate from Counter=0 to Counter=N finding an N that makes the SHA1(X-APPLE-HC) lead with Bits leading zero bits
|
||||
We get the "Resource" from the X-Apple-HC-Challenge header and Bits from X-Apple-HC-Bits
|
||||
*/
|
||||
/// - Parameters:
|
||||
/// - resource: a string to be used for minting
|
||||
/// - bits: grabbed from `X-Apple-HC-Bits` header
|
||||
/// - date: Default uses Date() otherwise used for testing to check.
|
||||
/// - Returns: A String hash to use in `X-Apple-HC` header on /signin
|
||||
public func mint(resource: String,
|
||||
bits: UInt = 10,
|
||||
date: String? = nil) -> String? {
|
||||
|
||||
let ver = "1"
|
||||
|
||||
var ts: String
|
||||
if let date = date {
|
||||
ts = date
|
||||
} else {
|
||||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "yyMMddHHmmss"
|
||||
ts = formatter.string(from: Date())
|
||||
}
|
||||
|
||||
let challenge = "\(ver):\(bits):\(ts):\(resource):"
|
||||
|
||||
var counter = 0
|
||||
|
||||
while true {
|
||||
guard let digest = ("\(challenge):\(counter)").sha1 else {
|
||||
print("ERROR: Can't generate SHA1 digest")
|
||||
return nil
|
||||
}
|
||||
|
||||
if digest == bits {
|
||||
return "\(challenge):\(counter)"
|
||||
}
|
||||
counter += 1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
extension String {
|
||||
var sha1: Int? {
|
||||
|
||||
let data = Data(self.utf8)
|
||||
var digest = [UInt8](repeating: 0, count:Int(CC_SHA1_DIGEST_LENGTH))
|
||||
data.withUnsafeBytes {
|
||||
_ = CC_SHA1($0.baseAddress, CC_LONG(data.count), &digest)
|
||||
}
|
||||
let bigEndianValue = digest.withUnsafeBufferPointer {
|
||||
($0.baseAddress!.withMemoryRebound(to: UInt32.self, capacity: 1) { $0 })
|
||||
}.pointee
|
||||
let value = UInt32(bigEndian: bigEndianValue)
|
||||
return value.leadingZeroBitCount
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7,6 +7,7 @@ public extension URL {
|
|||
static let requestSecurityCode = URL(string: "https://idmsa.apple.com/appleauth/auth/verify/phone")!
|
||||
static func submitSecurityCode(_ code: SecurityCode) -> URL { URL(string: "https://idmsa.apple.com/appleauth/auth/verify/\(code.urlPathComponent)/securitycode")! }
|
||||
static let trust = URL(string: "https://idmsa.apple.com/appleauth/auth/2sv/trust")!
|
||||
static let federate = URL(string: "https://idmsa.apple.com/appleauth/auth/federate")!
|
||||
static let olympusSession = URL(string: "https://appstoreconnect.apple.com/olympus/v1/session")!
|
||||
}
|
||||
|
||||
|
|
@ -15,7 +16,7 @@ public extension URLRequest {
|
|||
return URLRequest(url: .itcServiceKey)
|
||||
}
|
||||
|
||||
static func signIn(serviceKey: String, accountName: String, password: String) -> URLRequest {
|
||||
static func signIn(serviceKey: String, accountName: String, password: String, hashcash: String) -> URLRequest {
|
||||
struct Body: Encodable {
|
||||
let accountName: String
|
||||
let password: String
|
||||
|
|
@ -27,6 +28,7 @@ public extension URLRequest {
|
|||
request.allHTTPHeaderFields?["Content-Type"] = "application/json"
|
||||
request.allHTTPHeaderFields?["X-Requested-With"] = "XMLHttpRequest"
|
||||
request.allHTTPHeaderFields?["X-Apple-Widget-Key"] = serviceKey
|
||||
request.allHTTPHeaderFields?["X-Apple-HC"] = hashcash
|
||||
request.allHTTPHeaderFields?["Accept"] = "application/json, text/javascript"
|
||||
request.httpMethod = "POST"
|
||||
request.httpBody = try! JSONEncoder().encode(Body(accountName: accountName, password: password))
|
||||
|
|
@ -117,4 +119,21 @@ public extension URLRequest {
|
|||
static var olympusSession: URLRequest {
|
||||
return URLRequest(url: .olympusSession)
|
||||
}
|
||||
|
||||
static func federate(account: String, serviceKey: String) throws -> URLRequest {
|
||||
struct FederateRequest: Encodable {
|
||||
let accountName: String
|
||||
let rememberMe: Bool
|
||||
}
|
||||
var request = URLRequest(url: .signIn)
|
||||
request.allHTTPHeaderFields?["Accept"] = "application/json"
|
||||
request.allHTTPHeaderFields?["Content-Type"] = "application/json"
|
||||
request.httpMethod = "GET"
|
||||
|
||||
// let encoder = JSONEncoder()
|
||||
// encoder.outputFormatting = .withoutEscapingSlashes
|
||||
// request.httpBody = try encoder.encode(FederateRequest(accountName: account, rememberMe: true))
|
||||
|
||||
return request
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,14 +2,26 @@ import XCTest
|
|||
@testable import AppleAPI
|
||||
|
||||
final class AppleAPITests: XCTestCase {
|
||||
func testExample() {
|
||||
// This is an example of a functional test case.
|
||||
// Use XCTAssert and related functions to verify your tests produce the correct
|
||||
// results.
|
||||
XCTAssertEqual(AppleAPI().text, "Hello, World!")
|
||||
|
||||
func testValidHashCashMint() {
|
||||
let bits: UInt = 11
|
||||
let resource = "4d74fb15eb23f465f1f6fcbf534e5877"
|
||||
let testDate = "20230223170600"
|
||||
|
||||
let stamp = Hashcash().mint(resource: resource, bits: bits, date: testDate)
|
||||
XCTAssertEqual(stamp, "1:11:20230223170600:4d74fb15eb23f465f1f6fcbf534e5877::6373")
|
||||
}
|
||||
func testValidHashCashMint2() {
|
||||
let bits: UInt = 10
|
||||
let resource = "bb63edf88d2f9c39f23eb4d6f0281158"
|
||||
let testDate = "20230224001754"
|
||||
|
||||
let stamp = Hashcash().mint(resource: resource, bits: bits, date: testDate)
|
||||
XCTAssertEqual(stamp, "1:10:20230224001754:bb63edf88d2f9c39f23eb4d6f0281158::866")
|
||||
}
|
||||
|
||||
static var allTests = [
|
||||
("testExample", testExample),
|
||||
("testValidHashCashMint", testValidHashCashMint),
|
||||
("testValidHashCashMint2", testValidHashCashMint2),
|
||||
]
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ extension DateFormatter {
|
|||
let formatter = DateFormatter()
|
||||
formatter.dateFormat = "MM/dd/yy HH:mm"
|
||||
formatter.locale = Locale(identifier: "en_US_POSIX")
|
||||
formatter.calendar = .init(identifier: .iso8601)
|
||||
return formatter
|
||||
}()
|
||||
|
||||
|
|
|
|||
|
|
@ -117,8 +117,8 @@ class ObservableUpdater: ObservableObject {
|
|||
}
|
||||
|
||||
extension URL {
|
||||
static let appcast = URL(string: "https://robotsandpencils.github.io/XcodesApp/appcast.xml")!
|
||||
static let prereleaseAppcast = URL(string: "https://robotsandpencils.github.io/XcodesApp/appcast_pre.xml")!
|
||||
static let appcast = URL(string: "https://www.xcodes.app/appcast.xml")!
|
||||
static let prereleaseAppcast = URL(string: "https://www.xcodes.app/appcast_pre.xml")!
|
||||
}
|
||||
|
||||
struct UpdatesPreferencePane_Previews: PreviewProvider {
|
||||
|
|
|
|||
|
|
@ -9,27 +9,27 @@
|
|||
import Foundation
|
||||
import SwiftUI
|
||||
|
||||
|
||||
struct BottomStatusModifier: ViewModifier {
|
||||
@EnvironmentObject var appState: AppState
|
||||
|
||||
func body(content: Content) -> some View {
|
||||
content
|
||||
VStack(spacing: 0) {
|
||||
Divider()
|
||||
HStack {
|
||||
Text(appState.bottomStatusBarMessage)
|
||||
.font(.subheadline)
|
||||
Spacer()
|
||||
Text(Bundle.main.shortVersion!)
|
||||
.font(.subheadline)
|
||||
content
|
||||
VStack(spacing: 0) {
|
||||
Divider()
|
||||
HStack {
|
||||
Text(appState.bottomStatusBarMessage)
|
||||
.font(.subheadline)
|
||||
Spacer()
|
||||
Text(Bundle.main.shortVersion!)
|
||||
.font(.subheadline)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
|
||||
.padding([.leading, .trailing], 10)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
|
||||
.padding([.leading, .trailing], 10)
|
||||
}
|
||||
.frame(maxWidth: .infinity, maxHeight: 30, alignment: .leading)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extension View {
|
||||
|
|
|
|||
|
|
@ -13,12 +13,12 @@ struct MainToolbarModifier: ViewModifier {
|
|||
}
|
||||
|
||||
private var toolbar: some ToolbarContent {
|
||||
ToolbarItemGroup(placement: .status) {
|
||||
ToolbarItemGroup {
|
||||
Button(action: { appState.presentedSheet = .signIn }, label: {
|
||||
Label("Login", systemImage: "person.circle")
|
||||
})
|
||||
.help("LoginDescription")
|
||||
|
||||
|
||||
ProgressButton(
|
||||
isInProgress: appState.isUpdating,
|
||||
action: appState.update
|
||||
|
|
@ -85,7 +85,7 @@ struct MainToolbarModifier: ViewModifier {
|
|||
}
|
||||
.keyboardShortcut(KeyboardShortcut("i", modifiers: [.command, .option]))
|
||||
.help("InfoDescription")
|
||||
|
||||
|
||||
Button(action: {
|
||||
if #available(macOS 13, *) {
|
||||
NSApp.sendAction(Selector(("showSettingsWindow:")), to: nil, from: nil)
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2022 Robots and Pencils.</string>
|
||||
<string>Copyright © 2023 Robots and Pencils.</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
<key>NSSupportsAutomaticTermination</key>
|
||||
|
|
@ -38,7 +38,7 @@
|
|||
<string>identifier "com.robotsandpencils.XcodesApp.Helper" and info [CFBundleShortVersionString] >= "1.0.0" and anchor apple generic and certificate leaf[subject.OU] = "$(CODE_SIGNING_SUBJECT_ORGANIZATIONAL_UNIT)"</string>
|
||||
</dict>
|
||||
<key>SUFeedURL</key>
|
||||
<string>https://robotsandpencils.github.io/XcodesApp/appcast.xml</string>
|
||||
<string>https://www.xcodes.app/appcast.xml</string>
|
||||
<key>SUPublicEDKey</key>
|
||||
<string>SEcz0vgUSeBTOoAXYe+64zea95G6lIf5NgzFs3InYJQ=</string>
|
||||
</dict>
|
||||
|
|
|
|||
|
|
@ -86,14 +86,25 @@
|
|||
"LocalCachePathDescription" = "Xcodesは、利用可能なXcodeのバージョンをキャッシュし、新しいバージョンをディレクトリに一時的にダウンロードします。";
|
||||
"Change" = "変更";
|
||||
"Active/Select" = "アクティブ";
|
||||
"InstallDirectory" = "インストール先";
|
||||
"InstallPathDescription" = "Xcodesは1つのディレクトリを検索し、そこにインストールします。デフォルト (推奨) は /Applications です。Xcodeの格納場所を変更すると、他のアプリケーションやサービスが動作しなくなる可能性があります。";
|
||||
|
||||
"OnSelectDoNothing" = "名前をXcode-X.X.X.appのまま維持する";
|
||||
"OnSelectDoNothingDescription" = "選択時、バージョン付きの名前を維持します。例) Xcode-13.4.1.app";
|
||||
"AutomaticallyCreateSymbolicLink" = "Xcode.appへのシンボリックリンクの自動生成";
|
||||
"AutomaticallyCreateSymbolicLinkDescription" = "Xcodeのバージョンをアクティブにする時、インストール先でXcode.appのシンボリックリンクの作成を試みます。";
|
||||
"OnSelectRenameXcode" = "名前を常にXcode.appに変更する";
|
||||
"OnSelectRenameXcodeDescription" = "選択時、自動的にアクティブなXcodeをXcode.appに、以前のXcode.appをバージョン付きの名前に変更します。";
|
||||
|
||||
"PrivilegedHelper" = "権限のあるヘルパー";
|
||||
"PrivilegedHelperDescription" = "Xcodesは、rootとしてタスクを実行するために、別の権限のあるヘルパーを使用します。インストール後の手順や xcode-select による Xcode のバージョン切り替えなど、コマンドラインで sudo を必要とするものです。\n\nインストールには、macOS アカウントのパスワードの入力が必要です。";
|
||||
"HelperInstalled" = "インストール済み";
|
||||
"HelperNotInstalled" = "未インストール";
|
||||
"InstallHelper" = "ヘルパーのインストール";
|
||||
|
||||
"ShowOpenInRosetta" = "Rosettaで開くオプションを表示する";
|
||||
"ShowOpenInRosettaDescription" = "Rosettaで開くオプションは \"開く\" 機能が利用できる場所に表示されます。注意: これはApple Siliconマシンにのみ表示されます。";
|
||||
|
||||
// Experiment Preference Pane
|
||||
"Experiments" = "試験的な機能";
|
||||
"FasterUnxip" = "高速な Unxip";
|
||||
|
|
@ -152,6 +163,7 @@
|
|||
"Alert.Uninstall.Title" = "Xcode %@ をアンインストールしてもよろしいですか?";
|
||||
"Alert.Uninstall.Message" = "ゴミ箱に移動されますが、ゴミ箱を自動的に空にすることはありません。";
|
||||
"Alert.Uninstall.Error.Title" = "Xcode をアンインストールできませんでした";
|
||||
"Alert.Uninstall.Error.Message.FileNotFound" = "ファイル \"%@\" が見つかりませんでした。";
|
||||
|
||||
// Cancel Install
|
||||
"Alert.CancelInstall.Title" = "Xcode %@ のインストールを中止してもよろしいですか?";
|
||||
|
|
@ -221,3 +233,6 @@
|
|||
// Notifications
|
||||
"Notification.NewXcodeVersion.Title" = "新しいXcodeのバージョン";
|
||||
"Notification.NewXcodeVersion.Body" = "新しいバージョンがダウンロードできます。";
|
||||
|
||||
// WWDC
|
||||
"WWDC.Message" = "👨🏻💻👩🏼💻 Happy WWDC %@! 👨🏽💻🧑🏻💻";
|
||||
|
|
|
|||
239
Xcodes/Resources/pl.lproj/Localizable.strings
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
// Menu
|
||||
"Menu.About" = "O Xcodes";
|
||||
"Menu.CheckForUpdates" = "Sprawdź aktualizacje...";
|
||||
"Menu.Acknowledgements" = "Podziękowania Xcodes";
|
||||
"Menu.GitHubRepo" = "Repozytorium Xcodes na GitHubie";
|
||||
"Menu.ReportABug" = "Zgłoś błąd";
|
||||
"Menu.RequestNewFeature" = "Poproś o nową funkcję";
|
||||
|
||||
// Common
|
||||
"Install" = "Zainstaluj";
|
||||
"InstallDescription" = "Zainstaluj tę wersję";
|
||||
"RevealInFinder" = "Pokaż w Finderze";
|
||||
"Active" = "Aktywny";
|
||||
"MakeActive" = "Ustaw jako aktywny";
|
||||
"Open" = "Otwórz";
|
||||
"OpenDescription" = "Otwórz tę wersję";
|
||||
"CopyPath" = "Kopiuj ścieżkę";
|
||||
"CreateSymLink" = "Utwórz Symlink jako Xcode.app";
|
||||
"CreateSymLinkBeta" = "Utwórz Symlink jako Xcode-Beta.app";
|
||||
"Uninstall" = "Odinstaluj";
|
||||
"Selected" = "Wybrany";
|
||||
"Select" = "Wybierz";
|
||||
"Cancel" = "Anuluj";
|
||||
"Next" = "Dalej";
|
||||
"Continue" = "Kontynuuj";
|
||||
"Close" = "Zamknij";
|
||||
"OK" = "OK";
|
||||
|
||||
// Info Pane
|
||||
"IdenticalBuilds" = "Takie same wersje";
|
||||
"IdenticalBuilds.help" = "Czasami wersja przedpremierowa i wydana są dokładnie takie same. Xcodes automatycznie wyświetla te wersje razem.";
|
||||
|
||||
"ReleaseDate" = "Data wydania";
|
||||
"ReleaseNotes" = "Notatki wydania";
|
||||
"ReleaseNotes.help" = "Wyświetl notatki wydania";
|
||||
"CopyReleaseNoteURL" = "Kopiuj adres URL";
|
||||
"Compatibility" = "Kompatybilność";
|
||||
"MacOSRequirement" = "Wymaga systemu macOS %@ lub nowszego";
|
||||
"SDKs" = "SDK";
|
||||
"Compilers" = "Kompilatory";
|
||||
"DownloadSize" = "Wielkość pobierania";
|
||||
"NoXcodeSelected" = "Nie wybrano Xcode";
|
||||
|
||||
// Installation Steps
|
||||
// When localizing. Items will be replaced in order. ie "Step 1 of 6: Downloading"
|
||||
// So if changing order, make sure the positional specficier is retained. ex: "%3$@: Step %1$d of %2$d"
|
||||
"InstallationStepDescription" = "Krok %1$d z %2$d: %3$@";
|
||||
"DownloadingPercentDescription" = "Pobieranie: %d%% ukończone";
|
||||
"StopInstallation" = "Przerwij instalację";
|
||||
"DownloadingError" = "Nie znaleziono informacji o pobieraniu";
|
||||
|
||||
// About
|
||||
"VersionWithBuild" = "Wersja %@ (%@)";
|
||||
"GithubRepo" = "Repozytorium GitHub";
|
||||
"Acknowledgements" = "Podziękowania";
|
||||
"UnxipExperiment" = "Eksperyment Unxip";
|
||||
"License" = "Licencja";
|
||||
|
||||
// General Preference Pane
|
||||
"General" = "Ogólne";
|
||||
"AppleID" = "Apple ID";
|
||||
"SignIn" = "Zaloguj się";
|
||||
"Notifications" = "Powiadomienia";
|
||||
|
||||
// Updates Preference Pane
|
||||
"Updates" = "Aktualizacje";
|
||||
"Versions" = "Wersje";
|
||||
"AutomaticInstallNewVersion" = "Automatycznie instaluj nowe wersje Xcode";
|
||||
"IncludePreRelease" = "Dołącz wersje beta/wstępne";
|
||||
"AppUpdates" = "Aktualizacje Xcodes.app";
|
||||
"CheckForAppUpdates" = "Automatycznie sprawdzaj aktualizacje aplikacji";
|
||||
"CheckNow" = "Sprawdź teraz";
|
||||
"LastChecked" = "Ostatnio sprawdzono: %@";
|
||||
"Never" = "Nigdy";
|
||||
|
||||
// Download Preference Pane
|
||||
"Downloads" = "Pobieranie";
|
||||
"DataSource" = "Źródło danych";
|
||||
"DataSourceDescription" = "Źródło danych Apple przeszukuje stronę internetową Apple Developer. Zawsze wyświetla najnowsze dostępne wydania, ale jest bardziej podatne na problemy.\n\nXcode Releases to nieoficjalna lista wydań Xcode. Udostępnia ona dobrze sformatowane dane, zawiera dodatkowe informacje, które nie są łatwo dostępne w Apple, i jest mniej podatna na problemy, gdy Apple zmienia swoją stronę dla deweloperów.";
|
||||
"Downloader" = "Pobieranie";
|
||||
"DownloaderDescription" = "aria2 używa do pobierania do 16 połączeń, co pozwala na pobieranie Xcode 3-5x szybciej niż URLSession. Jest on dostarczany jako plik wykonywalny wraz ze swoim kodem źródłowym w ramach Xcodes w celu przestrzegania jego licencji GPLv2.\n\nURLSession to domyślne API Apple do tworzenia żądań URL.";
|
||||
|
||||
// Advanced Preference Pane
|
||||
"Advanced" = "Zaawansowane";
|
||||
"LocalCachePath" = "Katalog cache";
|
||||
"LocalCachePathDescription" = "Xcodes przechowuje w cache dostępne wersje Xcode oraz tymczasowo pobiera nowe pliki do tego katalogu.";
|
||||
"Change" = "Zmień";
|
||||
"Active/Select" = "Aktywny/wybrany";
|
||||
"InstallDirectory" = "Katalog instalacji";
|
||||
"InstallPathDescription" = "Xcodes wyszukuje i instaluje w jednym katalogu. Domyślnie (i zalecane) jest to /Applications. Wszelkie zmiany w miejscu przechowywania Xcode mogą spowodować, że inne aplikacje/usługi przestaną działać.";
|
||||
|
||||
"OnSelectDoNothing" = "Zachowaj nazwę jako Xcode-X.X.X.app";
|
||||
"OnSelectDoNothingDescription" = "Po wybraniu, nazwa pozostanie w formacie z numerem wersji, np. Xcode-13.4.1.app";
|
||||
"AutomaticallyCreateSymbolicLink" = "Automatycznie twórz symboliczne połączenie do Xcode.app";
|
||||
"AutomaticallyCreateSymbolicLinkDescription" = "Przy ustawianiu Xcode jako aktywny/wybrany, próbuj automatycznie stworzyć symboliczne połączenie o nazwie Xcode.app w katalogu instalacji.";
|
||||
"OnSelectRenameXcode" = "Zawsze zmieniaj nazwę na Xcode.app";
|
||||
"OnSelectRenameXcodeDescription" = "Po wybraniu, automatycznie zmienia aktywną wersję Xcode na Xcode.app, a poprzednie Xcode.app zostanie zmienione na nazwę wersji.";
|
||||
|
||||
"PrivilegedHelper" = "Helper z uprawnieniami";
|
||||
"PrivilegedHelperDescription" = "Xcodes używa oddzielnego helpera z uprawnieniami do wykonywania zadań jako root. Są to rzeczy, które wymagałyby użycia komendy sudo w wierszu poleceń, w tym kroki po instalacji oraz przełączanie wersji Xcode za pomocą xcode-select.\n\nZostaniesz poproszony o podanie hasła do swojego konta macOS, aby go zainstalować.";
|
||||
"HelperInstalled" = "Helper jest zainstalowany";
|
||||
"HelperNotInstalled" = "Helper nie jest zainstalowany";
|
||||
"InstallHelper" = "Zainstaluj helpera";
|
||||
|
||||
"ShowOpenInRosetta" = "Pokaż opcję Otwórz w Rosetta";
|
||||
"ShowOpenInRosettaDescription" = "Opcja Otwórz w Rosetta będzie wyświetlana, gdy dostępne są inne funkcje \"Otwórz\". Uwaga: Będzie to działać tylko na urządzeniach z Apple Silicon.";
|
||||
|
||||
// Experiment Preference Pane
|
||||
"Experiments" = "Eksperymenty";
|
||||
"FasterUnxip" = "Szybsze Unxip";
|
||||
"UseUnxipExperiment" = "Podczas rozpakowywania, użyj wersji eksperymentalnej";
|
||||
"FasterUnxipDescription" = "Dzięki @_saagarjha, wersja eksperymentalna może zwiększyć prędkość rozpakowywania o nawet 70% dla niektórych systemów.\n\nWięcej informacji na temat tego, jak to jest osiągane, można znaleźć w repozytorium unxip - https://github.com/saagarjha/unxip";
|
||||
|
||||
// Notifications
|
||||
"AccessGranted" = "Dostęp przyznany. Będziesz otrzymywać powiadomienia z Xcodes.";
|
||||
"AccessDenied" = "⚠️ Dostęp zabroniony ⚠️\n\nOtwórz ustawienia powiadomień i wybierz Xcodes, jeśli chcesz zezwolić na dostęp.";
|
||||
"NotificationSettings" = "Ustawienia powiadomień";
|
||||
"EnableNotifications" = "Włącz powiadomienia";
|
||||
|
||||
// SignIn
|
||||
"SignInWithApple" = "Zaloguj się przy użyciu Apple ID.";
|
||||
"AppleID" = "AppleID:";
|
||||
"Password" = "Hasło:";
|
||||
"Required" = "Wymagane";
|
||||
"SignOut" = "Wyloguj się";
|
||||
|
||||
// SMS/2FA
|
||||
"DigitCodeDescription" = "Wprowadź %d-cyfrowy kod z jednego ze swoich zaufanych urządzeń:";
|
||||
"SendSMS" = "Wyślij SMS";
|
||||
"EnterDigitCodeDescription" = "Wprowadź %d-cyfrowy kod wysłany do %@: ";
|
||||
"SelectTrustedPhone" = "Wybierz zaufany numer telefonu, aby otrzymać %d-cyfrowy kod przez SMS:";
|
||||
"NoTrustedPhones" = "Twoje konto nie ma żadnych zaufanych numerów telefonów, ale są one wymagane do autoryzacji dwuskładnikowej.\n\nZobacz https://support.apple.com/HT204915.";
|
||||
|
||||
// MainWindow
|
||||
"UpdatedAt" = "Zaktualizowano o";
|
||||
|
||||
// ToolBar
|
||||
"Login" = "Zaloguj się";
|
||||
"LoginDescription" = "Otwórz okno logowania";
|
||||
"Refresh" = "Odśwież";
|
||||
"RefreshDescription" = "Odśwież listę Xcode";
|
||||
"All" = "Wszystkie";
|
||||
"Release" = "Stabilne";
|
||||
"ReleaseOnly" = "Tylko stabilne";
|
||||
"Beta" = "Beta";
|
||||
"BetaOnly" = "Tylko beta";
|
||||
"Filter" = "Filtr";
|
||||
"FilterAvailableDescription" = "Filtruj dostępne wersje";
|
||||
"FilterInstalledDescription" = "Filtruj zainstalowane wersje";
|
||||
"Info" = "Informacje";
|
||||
"InfoDescription" = "Pokaż lub ukryj okno informacji";
|
||||
"Preferences" = "Ustawienia";
|
||||
"PreferencesDescription" = "Otwórz ustawienia";
|
||||
"Search" = "Szukaj...";
|
||||
"SearchDescription" = "Przeszukaj listę";
|
||||
|
||||
// List
|
||||
"ActiveVersionDescription" = "To jest aktywna wersja";
|
||||
"MakeActiveVersionDescription" = "Ustaw jako aktywną wersję";
|
||||
|
||||
// Alerts
|
||||
// Uninstall
|
||||
"Alert.Uninstall.Title" = "Odinstalować Xcode %@?";
|
||||
"Alert.Uninstall.Message" = "Zostanie przeniesiony do kosza, ale nie zostanie opróżniony.";
|
||||
"Alert.Uninstall.Error.Title" = "Nie można odinstalować Xcode";
|
||||
"Alert.Uninstall.Error.Message.FileNotFound" = "Nie znaleziono pliku \"%@\".";
|
||||
|
||||
// Cancel Install
|
||||
"Alert.CancelInstall.Title" = "Czy na pewno chcesz przerwać instalację Xcode %@?";
|
||||
"Alert.CancelInstall.Message" = "Postęp zostanie utracony.";
|
||||
"Alert.CancelInstall.PrimaryButton" = "Przerwij instalację";
|
||||
|
||||
// Privileged Helper
|
||||
"Alert.PrivilegedHelper.Title" = "Helper z uprawnieniami";
|
||||
"Alert.PrivilegedHelper.Message" = "Xcodes używa oddzielnego helpera z uprawnieniami, aby wykonywać zadania jako root. Są to rzeczy, które wymagałyby sudo w wierszu poleceń, w tym kroki po instalacji i przełączanie wersji Xcode z xcode-select.\n\nBędziesz proszony o podanie hasła do konta macOS, aby go zainstalować.";
|
||||
"Alert.PrivilegedHelper.Error.Title" = "Nie można zainstalować helpera";
|
||||
|
||||
// Min MacOS Supported
|
||||
"Alert.MinSupported.Title" = "Niezgodność z minimalnymi wymaganiami";
|
||||
"Alert.MinSupported.Message" = "Xcode %@ wymaga macOS %@, a ty masz macOS %@. Czy nadal chcesz go zainstalować?";
|
||||
|
||||
// Install
|
||||
"Alert.Install.Error.Title" = "Nie można zainstalować Xcode";
|
||||
"Alert.InstallArchive.Error.Title" = "Nie można zainstalować zarchiwizowanego Xcode";
|
||||
|
||||
// Update
|
||||
"Alert.Update.Error.Title" = "Nie można zaktualizować wybranej wersji Xcode";
|
||||
|
||||
// Active/Select
|
||||
"Alert.Select.Error.Title" = "Nie można wybrać Xcode";
|
||||
|
||||
// Symbolic Links
|
||||
"Alert.SymLink.Title" = "Nie można utworzyć linku symbolicznego";
|
||||
"Alert.SymLink.Message" = "Xcode.app istnieje i nie jest linkiem symbolicznym";
|
||||
|
||||
// Post install
|
||||
"Alert.PostInstall.Title" = "Nie można wykonać czynności po-instalacyjnych";
|
||||
|
||||
// InstallationErrors
|
||||
"InstallationError.DamagedXIP" = "Archiwum \"%@\" jest uszkodzone i nie może zostać rozpakowane.";
|
||||
"InstallationError.NotEnoughFreeSpaceToExpandArchive" = "Nie można rozpakować archiwum \"%@\", ponieważ wolumin nie ma wystarczającej ilości wolnego miejsca.\n\nZrób więcej miejsca, aby rozpakować archiwum, a następnie zainstaluj ponownie Xcode %@, aby kontynuować instalację od miejsca, w którym została wstrzymana.";
|
||||
"InstallationError.FailedToMoveXcodeToApplications" = "Nie udało się przenieść Xcode do katalogu %@.";
|
||||
"InstallationError.FailedSecurityAssessment" = "Xcode %@ nie przeszedł testu bezpieczeństwa z następującym wynikiem:\n%@\nPozostaje zainstalowany w %@, jeśli mimo to chcesz go używać.";
|
||||
"InstallationError.CodesignVerifyFailed" = "Pobrany Xcode nie przeszedł weryfikacji sygnatury kodu z wynikiem:\n%@";
|
||||
"InstallationError.UnexpectedCodeSigningIdentity" = "Pobrany Xcode nie ma oczekiwanej sygnatury kodu.\nOtrzymano:\n%@\n%@\nOczekiwano:\n%@\n%@";
|
||||
"InstallationError.UnsupportedFileFormat" = "Xcodes nie obsługuje (jeszcze) instalowania Xcode z formatu %@.";
|
||||
|
||||
"InstallationError.MissingSudoerPassword" = "Brak hasła. Spróbuj ponownie.";
|
||||
"InstallationError.UnavailableVersion" = "Nie można znaleźć wersji %@.";
|
||||
"InstallationError.NoNonPrereleaseVersionAvailable" = "Brak wersji nie-przedpremierowych.";
|
||||
"InstallationError.NoPrereleaseVersionAvailable" = "Brak wersji przedpremierowych.";
|
||||
"InstallationError.MissingUsernameOrPassword" = "Brak nazwy użytkownika lub hasła. Spróbuj ponownie.";
|
||||
"InstallationError.VersionAlreadyInstalled" = "%@ jest już zainstalowany w %@.";
|
||||
"InstallationError.InvalidVersion" = "%@ nie jest prawidłowym numerem wersji.";
|
||||
"InstallationError.VersionNotInstalled" = "%@ nie jest zainstalowany.";
|
||||
"InstallationError.PostInstallStepsNotPerformed.Installed" = "Instalacja została zakończona, ale niektóre kroki po instalacji nie zostały wykonane automatycznie. Zostaną one wykonane przy pierwszym uruchomieniu Xcode %@.";
|
||||
"InstallationError.PostInstallStepsNotPerformed.NotInstalled" = "Instalacja została zakończona, ale niektóre kroki po instalacji nie zostały wykonane automatycznie. Xcodes wykonuje te kroki z pomocą helpera z uprawnieniami, który nie jest zainstalowany. Możesz go zainstalować w Ustawienia > Zaawansowane.\n\nTe kroki zostaną wykonane przy pierwszym uruchomieniu Xcode %@.";
|
||||
|
||||
// Installation Steps
|
||||
"Downloading" = "Pobieranie";
|
||||
"Unarchiving" = "Rozpakowywanie (To może chwilę potrwać)";
|
||||
"Moving" = "Przenoszenie do %@";
|
||||
"TrashingArchive" = "Przenoszenie archiwum do kosza";
|
||||
"CheckingSecurity" = "Weryfikacja zabezpieczeń";
|
||||
"Finishing" = "Kończenie";
|
||||
|
||||
// Notifications
|
||||
"Notification.NewVersionAvailable" = "Dostępna jest nowa wersja";
|
||||
"Notification.FinishedInstalling" = "Zakończono instalację";
|
||||
|
||||
|
||||
"HelperClient.error" = "Nie można komunikować się z helperem z uprawnieniami.";
|
||||
///++
|
||||
// Notifications
|
||||
"Notification.NewXcodeVersion.Title" = "Nowe wersje Xcode";
|
||||
"Notification.NewXcodeVersion.Body" = "Dostępne są nowe wersje Xcode do pobrania.";
|
||||
|
||||
// WWDC
|
||||
"WWDC.Message" = "👨🏻💻👩🏼💻 Wesołego WWDC %@! 👨🏽💻🧑🏻💻";
|
||||
|
|
@ -81,7 +81,7 @@
|
|||
"AutomaticallyCreateSymbolicLink" = "Criar link simbólico para o Xcode.app automaticamente";
|
||||
"AutomaticallyCreateSymbolicLinkDescription" = "Quando ativar/selecionar uma versão do Xcode, tentar criar um link simbólico chamado Xcode.app no diretório de instalação";
|
||||
"DataSource" = "Fonte de dados";
|
||||
"DataSourceDescription" = "A fonte de dados da Apple copia o site Apple Developer. Sempre mostrará os lançamentos mais recentes que estão disponíveis, porém é mais frágil.\n\nLançamentos do Xcode é uma lista de lançamentos do Xcode não-oficial. É provido como dado formatado, contem informação extra que não está prontamente disponível pela Apple, e é menos provável que quebre se a Apple redesenhar o seu site de desenvolvedores.";
|
||||
"DataSourceDescription" = "A fonte de dados da Apple copia o site Apple Developer. Sempre mostrará os lançamentos mais recentes que estão disponíveis, porém é mais frágil.\n\nLançamentos do Xcode (Xcode Releases) é uma lista de lançamentos do Xcode não-oficial. É provido como dado formatado, contem informação extra que não está prontamente disponível pela Apple, e é menos provável que quebre se a Apple redesenhar o seu site de desenvolvedores.";
|
||||
"Downloader" = "Baixador";
|
||||
"DownloaderDescription" = "aria2 usa até 16 conexões para baixar o Xcode 3-5x mais rápido que URLSession. Está empacotado como um executável junto com o seu código fonte dentro do Xcodes para conformar com a licensa GPLv2.\n\nURLSession é a API padrão da Apple para performar requisições URL.";
|
||||
"PrivilegedHelper" = "Ajudante privilegiado";
|
||||
|
|
@ -89,6 +89,11 @@
|
|||
"HelperInstalled" = "Ajudante está instalado";
|
||||
"HelperNotInstalled" = "Ajudante não está instalado";
|
||||
"InstallHelper" = "Instalar ajudante";
|
||||
"OnSelectDoNothing" = "Manter nome como Xcode-X.X.X.app";
|
||||
"OnSelectRenameXcode" = "Sempre renomear para Xcode.app";
|
||||
"OnSelectRenameXcodeDescription" = "Ao selecionar, tentar renomear o Xcode ativo para Xcode.app, renomeando o Xcode.app anterior para um nome com a versão.";
|
||||
"ShowOpenInRosetta" = "Mostrar opçao abrir com Rosetta";
|
||||
"ShowOpenInRosettaDescription" = "Opção de abrir com o Rosetta será mostrar onde outras opções \"Abrir\" estão disponíveis. Nota: Isso só será mostrado pra máquinas Apple Silicon.";
|
||||
|
||||
// Experiment Preference Pane
|
||||
"Experiments" = "Experiments";
|
||||
|
|
|
|||
|
|
@ -95,12 +95,16 @@
|
|||
"AutomaticallyCreateSymbolicLinkDescription" = "Bir Xcode sürümünü Aktif/Seç yaparken Xcode.app ismindeki uygulamanın sembolik linkini yükleme klasörüne otomatik oluşturmayı dene";
|
||||
"OnSelectRenameXcode" = "Her zaman Xcode.app şeklinde ismi değiştir";
|
||||
"OnSelectRenameXcodeDescription" = "Seçildiğinde, aktif olan Xcode'u Xcode.app olarak isimlendirmeye çalışır ve eski Xcode ismine sürüm ismi ekler.";
|
||||
|
||||
"PrivilegedHelper" = "Ayrıcalıklı Yardımcı";
|
||||
"PrivilegedHelperDescription" ="Xcodes, root görevlerini yerine getirmek için bir Ayrıcalıklı yardımcı aracı kullanır. Bunlar komut satırındaki sudo gerektiren, yükleme sonrası adımlarını sağlayan ve Xcode sürümü değiştiren xcode-select gibi komutlardan ibarettir.\n\nBunu yüklemek için macOS hesap şifrenizi girmeniz istenecektir.";
|
||||
"HelperInstalled" = "Yardımcı yüklendi";
|
||||
"HelperNotInstalled" = "Yardımcı yüklenmedi";
|
||||
"InstallHelper" = "Yardımcıyı yükle";
|
||||
|
||||
"ShowOpenInRosetta" = "Rosetta ile açma seçeneğini göster";
|
||||
"ShowOpenInRosettaDescription" = "Rosetta ile açma opsiyonu diğer uygun \"Açma\" fonksiyonlarını gösterecektir. Not: Bu sadece Apple Silikon makinelerinde gözükecektir.";
|
||||
|
||||
// Experiment Preference Pane
|
||||
"Experiments" = "Deneyler";
|
||||
"FasterUnxip" = "Daha Hızlı Unxip";
|
||||
|
|
@ -159,6 +163,7 @@
|
|||
"Alert.Uninstall.Title" = "Xcode %@ sürümünü Kaldır?";
|
||||
"Alert.Uninstall.Message" = "Uygulama Çöp Kutusuna taşınacaktır, fakat silinmeyecektir.";
|
||||
"Alert.Uninstall.Error.Title" = "Xcode Kaldırılamadı";
|
||||
"Alert.Uninstall.Error.Message.FileNotFound" = "\"%@\" dosyası bulunamadı.";
|
||||
|
||||
// Cancel Install
|
||||
"Alert.CancelInstall.Title" = "Xcode %@ sürümünün yüklenmesini durdurmak istediğinize emin misiniz?";
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@
|
|||
"InstallPathDescription" = "Xcodes会在一个目录中检索及安装。默认(推荐)保持/Applications。任何对Xcode存储位置的变更都可能会导致其他App或服务停止工作。";
|
||||
|
||||
"OnSelectDoNothing" = "保持名称为Xcode-X.X.X.app";
|
||||
"OnSelectDoNothingDescription" = "选中时,将会将会保持各版本的名称。例如Xcode-13.4.1.app。";
|
||||
"OnSelectDoNothingDescription" = "选中时,将会保持各版本的名称。例如Xcode-13.4.1.app。";
|
||||
"AutomaticallyCreateSymbolicLink" = "自动创建名为Xcode.app的软连接";
|
||||
"AutomaticallyCreateSymbolicLinkDescription" = "当激活/选定某个Xcode版本时,尝试在安装目录创建一个名为Xcode.app的软链接。";
|
||||
"OnSelectRenameXcode" = "总是重命名为Xcode.app";
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 75 KiB |
BIN
experiment_dark.png
Normal file
|
After Width: | Height: | Size: 223 KiB |
|
Before Width: | Height: | Size: 80 KiB |
BIN
experiment_light.png
Normal file
|
After Width: | Height: | Size: 211 KiB |
15
nextstep.md
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
## The next step
|
||||
|
||||
As Xcodes continues to grow beyond a small little utility used by Apple Developers all over the world to make their lives easier when it comes to downloading, managing and saving their sanity with Xcode, it was time to move the repo away from Robots and Pencils and into it's own managed org.
|
||||
|
||||
Starting April 21, 2023, all Xcodes repos are now contained under the `XcodesOrg` organization. https://github.com/XcodesOrg
|
||||
|
||||
This change will have no effect on the tools at all, but allows the utilites to grow to the next level. I'm (Matt Kiazyk) still the owner and current sole maintainer, and have no plans to stop.
|
||||
|
||||
Xcodes would not be where it is without contributors over the years. It would also not be where it is without each and every one of you sharing the tool.
|
||||
|
||||
So from myself - thank you!
|
||||
|
||||
Matt Kiazyk - maintainer
|
||||
@XcodesApp
|
||||
@mattkiazyk
|
||||
|
Before Width: | Height: | Size: 379 KiB After Width: | Height: | Size: 325 KiB |
|
Before Width: | Height: | Size: 316 KiB After Width: | Height: | Size: 308 KiB |