Compare commits

...

99 Commits
0.4.0 ... 0.5.3

Author SHA1 Message Date
nythepegasus
502b89d890 [skip ci] Add other project maintainers to CODEOWNERS
Signed-off-by: nythepegasus <nythepegasus84@gmail.com>
2023-11-27 09:37:25 -05:00
junepark678
5f0015fad0 chore(Clear Cache): do proper error handling 2023-11-27 09:31:36 -05:00
June Park
c81236957b bugfix(settings): fix rounding issues on clear cache button (#536) 2023-11-27 09:31:36 -05:00
Spidy123222
970ab38b27 move debug row 2023-11-27 09:31:36 -05:00
Spidy123222
8a5c31b81d make button function again 2023-11-27 09:31:36 -05:00
Spidy123222
8508fe79b5 change order of settings debug section 2023-11-27 09:31:36 -05:00
Spidy123222
3859e98801 Add button to storyboard 🙄 2023-11-27 09:31:36 -05:00
Spidy123222
a759c7be9e please fix to show button 2023-11-27 09:31:36 -05:00
Spidy123222
12fc6cf6e2 attempt fix settings 2023-11-27 09:31:36 -05:00
Spidy123222
580db6530e fix the mighty error 2023-11-27 09:31:36 -05:00
Spidy123222
9c67c237ee get rest of batcherror 2023-11-27 09:31:36 -05:00
Spidy123222
357d85a72e please o riley build 2023-11-27 09:31:36 -05:00
Spidy123222
88ad828ce0 hopefully fix error code build error 2023-11-27 09:31:36 -05:00
Riley Testut
a95625a34a Adds “Clear Cache” description to Techy Things section footer
(cherry picked from commit 913db5131b)
2023-11-27 09:31:36 -05:00
Riley Testut
95e00d81f5 Adds “Clear Cache” button to remove temporary files and uninstalled app backups
(cherry picked from commit 3adfc9db6d)
2023-11-27 09:31:36 -05:00
junepark678
c2e386a5c5 chore(App IDs, My Apps): change back to full 2023-11-27 09:22:19 -05:00
junepark678
a76aade4ff chore(App IDs, My Apps): change to use DateComponentsFormatter.UnitsStyle.abbreviated 2023-11-27 09:22:19 -05:00
junepark678
65c9986103 bugfix(App IDs, My Apps): fix date display 2023-11-27 09:22:19 -05:00
junepark678
9e2b9b6639 bugfix(App IDs, My Apps): display only necessary information 2023-11-27 09:22:19 -05:00
junepark678
cf373634d7 bugfix(App IDs, My Apps): calculate in correct direction in time (we aren't time travelers) 2023-11-27 09:22:19 -05:00
junepark678
b3d5d976b4 feat(My Apps): make expiration dates more specific 2023-11-27 09:22:19 -05:00
junepark678
c3c31995ce chore(App IDs): localize Unknown string 2023-11-27 09:22:19 -05:00
junepark678
7e92e17429 feat(App IDs): make expiration dates more specific 2023-11-27 09:22:19 -05:00
junepark678
88ab8fa8d7 feat: remove reliance on Info.plist for getting udid 2023-11-27 09:21:54 -05:00
nythepegasus
2e613e6d15 [skip ci] Update Ignited source URL 2023-11-06 09:02:49 -05:00
Spidy123222
35ee92db12 Change pairing file link with new wiki link
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-10-23 13:12:23 -07:00
nythepegasus
04d9f760ad Fix AltWidget App Group issue 2023-10-23 10:12:09 -04:00
naturecodevoid
4f52743be8 Revert most of xcodeproj changes 2023-10-21 20:44:49 -07:00
naturecodevoid
32cae7a5b2 Revert "Attempt to fix submodule dependencies for GH runner"
This reverts commit 5cff914ff3.
2023-10-21 20:30:32 -07:00
naturecodevoid
c2c0e3b790 Use forked libplist 2023-10-21 20:30:23 -07:00
nythepegasus
6d36a30787 [skip ci] Bump nightly to 0.5.3
Signed-off-by: nythepegasus <nythepegasus84@gmail.com>
2023-10-21 21:02:41 -04:00
nythepegasus
48a86ec6de Update Roxas 2023-10-21 20:35:32 -04:00
nythepegasus
5cff914ff3 Attempt to fix submodule dependencies for GH runner 2023-10-21 20:34:44 -04:00
nythepegasus
70ea725ce3 Update limd/libplist submodules 2023-10-20 22:04:47 -04:00
nythepegasus
78f12e45f9 Add iOS 17 JIT error notice with other errors 2023-10-20 21:51:24 -04:00
nythepegasus
e5061acc20 Hardcode SideStore's URL scheme for now 2023-10-20 21:51:24 -04:00
nythepegasus
2d7bc51d30 Revert this change 2023-10-20 21:51:24 -04:00
nythepegasus
9128b67ee8 Add newly compiled AltBackup 2023-10-20 21:51:24 -04:00
Bogdan Seniuc
551c004476 Use provisioning profile details instead of guessing active app limit 2023-10-20 21:50:50 -04:00
Spidy123222
ed6a8d1379 [skip ci] Remove emuthreeds from trusted sources 2023-10-18 21:44:55 -07:00
nythepegasus
766fb89e0b Change this to be hardcoded SideStore search 2023-10-17 17:38:09 -04:00
nythepegasus
c5b8cb4459 Remove buggy retry code finally 2023-10-17 17:37:29 -04:00
naturecodevoid
0deae92829 Bump version to 0.5.2 so nightly builds have a higher SemVer version than stable 2023-09-18 16:18:05 -07:00
naturecodevoid
cc5d2f1813 Build nightly with latest minimuxer changes to attempt to fix plist_from_memory crash 2023-09-18 16:17:14 -07:00
naturecodevoid
41151d0d49 0.5.1 2023-09-17 14:01:13 -07:00
Spidy123222
52702264a3 Change version to 0.5.2 2023-09-17 12:36:44 -07:00
naturecodevoid
6e297e1278 Update Swift Packages and submodules (#469)
* Update Swift Packages

* Update submodules

* make sure it builds

---------

Signed-off-by: naturecodevoid <44983869+naturecodevoid@users.noreply.github.com>
2023-09-17 10:45:55 -07:00
naturecodevoid
e3bb9b425f [skip ci] Add more information to staging errors (#468)
* Point to my forks and attempt to add more information to staging errors

* Improve error message a bit

* Revert fetch-prebuilt.sh changes

* Undo some whitespace changes

* missed one

* oops

* [skip ci]

* [skip ci]

* [skip ci] remove staging directory from install app error

Signed-off-by: naturecodevoid <44983869+naturecodevoid@users.noreply.github.com>

---------

Signed-off-by: naturecodevoid <44983869+naturecodevoid@users.noreply.github.com>
Co-authored-by: Dadoum <dadoum@protonmail.com>
2023-09-17 10:37:49 -07:00
Spidy123222
79255be79c Update Altsign (August 6) (#467)
This changes the git commit or be our latest altsign version.
2023-09-16 01:51:35 -07:00
nythepegasus
7c836f5ba1 Update emuplace source
Signed-off-by: nythepegasus <nythepegasus84@gmail.com>
2023-08-13 11:54:00 -04:00
Spidy123222
938bcd14ad Add ignited source
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-08-06 14:15:51 -07:00
Joelle Stickney
229d79fc05 Removed Quantum Source
Signed-off-by: Joelle Stickney <joellestickney+commit@gmail.com>
2023-08-06 16:26:24 -04:00
Joelle Stickney
2d3dac2e1d Added Quantum Source to trusted sources
Signed-off-by: Joelle Stickney <joellestickney+commit@gmail.com>
2023-08-06 15:30:21 -04:00
nythepegasus
e23f5e7894 [skip ci] Change Discord custom invite to static website invite
Signed-off-by: nythepegasus <nythepegasus84@gmail.com>
2023-08-04 13:17:02 -04:00
Spidy123222
571d27c814 Fix message and put in proper spot.
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-07-27 23:42:32 -07:00
Spidy123222
dde6bd4fe3 Make Notification explanation smaller for refresh
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-07-27 23:17:58 -07:00
Nythepegasus
6e6dbd9329 Bump version to 0.5.0 2023-07-27 06:56:51 -04:00
Nythepegasus
258268f5ef Update default anisette server 2023-07-27 06:55:31 -04:00
Nythepegasus
9ae49977fb Fix going to the home screen 2023-07-27 06:23:26 -04:00
Nythepegasus
d61c54fa60 Reintroduce notification/pop-up 2023-07-27 06:23:26 -04:00
Nythepegasus
980699af6f Remove extra returns and make sure to decrement 2023-07-27 06:23:26 -04:00
Nythepegasus
cc5c280882 Finally fix retries for minimuxer calls 2023-07-27 06:23:26 -04:00
nythepegasus
090456bba1 [skip ci] Merge pull request #419 from Nythepegasus/chore/up-fixes
[Chore] Pull upstream changes from AltStore
2023-07-27 06:22:54 -04:00
nythepegasus
5354d4eb76 Merge pull request #414 from SideStore/patch/fix-widget
[Patch] Change Widget entitlements to search hardcoded group first
2023-07-27 06:11:48 -04:00
Riley Testut
b986fae611 Enforces 77x31 minimum size for PillButton 2023-07-27 04:47:44 -04:00
Riley Testut
cfcfc3e928 Fixes incorrect cell height for some News items
We need to take layoutMargins into account when calculating the height of the prototype cell.
2023-07-27 04:47:44 -04:00
Riley Testut
f97548fc3a Fixes UIDocumentPickerViewController deprecation warnings 2023-07-27 04:47:44 -04:00
Riley Testut
36913b425c Fixes “variable mutated after capture by sendable closure” warning 2023-07-27 04:47:44 -04:00
Riley Testut
822ea08d89 Fixes AppViewController deprecation warnings 2023-07-27 04:47:43 -04:00
Riley Testut
98dd6f3fe7 Fixes CollapsingTextView “TextKit 1 compatibility mode” runtime warning 2023-07-27 04:47:38 -04:00
Nythepegasus
b3f0dbb155 Change circle and logo to just be circle for now 2023-07-27 02:59:30 -04:00
nythepegasus
6904d931c3 Change the lock screen icon to be legible
Signed-off-by: nythepegasus <me@nythepegas.us>
2023-07-27 02:25:09 -04:00
Nythepegasus
529466a9f7 Merge branch 'develop' into patch/fix-widget 2023-07-24 09:29:03 -04:00
Nythepegasus
77dc695ba1 Revert the retries here as these seem buggier 2023-07-24 09:22:34 -04:00
Nythepegasus
e17776f651 Remove unused Riley and Shane images from bundle 2023-07-24 07:54:20 -04:00
Nythepegasus
0d2f355a74 Update AltWidget assets 2023-07-24 07:18:42 -04:00
Nythepegasus
2ce1576016 Move the first app group to be known shared group 2023-07-24 05:49:36 -04:00
Nythepegasus
0f3be3c494 Update AltWidget/ReleaseEntitlements.plist
Signed-off-by: Nythepegasus <me@nythepegas.us>
2023-07-24 05:40:51 -04:00
Nythepegasus
8c1ca8503a Fix Actions builds for AltWidget 2023-07-24 05:28:26 -04:00
Wes Bryie
32a59c17f4 [skip ci] em_proxy link update (#412)
Signed-off-by: Wes Bryie <wes@wesbryie.tech>
2023-07-21 20:04:44 -07:00
Riley Testut
b4b4ceab0b Fixes updating apps with manually-removed app extensions (e.g. uYou+) 2023-07-17 12:15:04 -04:00
Nythepegasus
be1f27bb9e Revert "Fix building on Xcode 15"
This reverts commit 3de24dcfce.
2023-07-11 02:00:49 -04:00
Nythepegasus
ed10ddb1cb Go to home screen instead of Safari/notif combo 2023-07-11 01:45:14 -04:00
Nythepegasus
dbdb4b0f32 Add various retries to the minimuxer calls 2023-07-11 01:44:11 -04:00
Nythepegasus
59e537362e Xcode 15 keeps adding imobiledevice.swift 2023-07-10 14:33:53 -04:00
Nythepegasus
6d96bf414f These vars don't change, let's use let keyword 2023-07-10 14:32:41 -04:00
Nythepegasus
e7ba778a5f Update AltSign and OpenSSL packages 2023-07-09 14:00:02 -04:00
Nythepegasus
933d349cd5 Fix libfragmentzip's search path 2023-07-09 14:00:02 -04:00
Nythepegasus
3de24dcfce Fix building on Xcode 15 2023-07-09 13:59:55 -04:00
Spidy123222
3275d16b8b [skip ci] use odyssey team unified source
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-07-08 23:53:53 -07:00
Spidy123222
5bb4cd1dad [skip ci] Add Taurine
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-07-08 23:32:41 -07:00
Nythepegasus
16b14441fa Update Macley omnisette server IP
Signed-off-by: Nythepegasus <nythepegasus84@gmail.com>
2023-07-03 10:47:54 -04:00
Joshua Laymon
93a6272d30 Merge pull request #387 from bogotesr/develop
Fix up patreon screen and add socials
2023-06-21 21:58:04 -07:00
Spidy123222
0dc526f778 Replace old servers with macley v3 ansiette 2023-06-14 13:56:12 -07:00
bogotesr
183e185812 Change Patreon screen again
Refresh to "support us" and include social media.
2023-06-13 23:14:01 -07:00
Stern
e02453598c Update pr.yml
Signed-off-by: Stern <xsternent@gmail.com>
2023-06-13 20:31:37 -04:00
Stern
24af1b5b5f Update pr.yml
Signed-off-by: Stern <xsternent@gmail.com>
2023-06-13 20:30:41 -04:00
Spidy123222
5864c283f6 Add EmuPalace Source 2023-06-12 20:35:36 -07:00
Spidy123222
be78fa4b91 Upload config (#383)
Signed-off-by: Spidy123222 <64176728+Spidy123222@users.noreply.github.com>
2023-06-12 09:39:20 -07:00
70 changed files with 1141 additions and 441 deletions

2
.github/CODEOWNERS vendored
View File

@@ -1 +1 @@
* @JoeMatt @lonkelle * @JoeMatt @lonkelle @nythepegasus @Spidy123222 @SternXD

View File

@@ -10,7 +10,7 @@ body:
value: | value: |
Thanks for taking the time to fill out this bug report! Before you continue filling out the report, please **[search in GitHub Issues](https://github.com/SideStore/SideStore/issues?q=is%3Aissue+is%3Aopen) for the bug you are experiencing** in case it has already been reported. Thanks for taking the time to fill out this bug report! Before you continue filling out the report, please **[search in GitHub Issues](https://github.com/SideStore/SideStore/issues?q=is%3Aissue+is%3Aopen) for the bug you are experiencing** in case it has already been reported.
**Please use [Discord](https://discord.gg/RgpFBX3Q3k) or [GitHub Discussions](https://github.com/SideStore/SideStore/discussions) for support.** **Please use [Discord](https://discord.gg/sidestore-949183273383395328) or [GitHub Discussions](https://github.com/SideStore/SideStore/discussions) for support.**
- type: textarea - type: textarea
id: description id: description
attributes: attributes:

View File

@@ -3,7 +3,7 @@ blank_issues_enabled: false
contact_links: contact_links:
- name: Discord - name: Discord
url: https://discord.gg/RgpFBX3Q3k url: https://discord.gg/sidestore-949183273383395328
about: If you need support, please go here first instead of making an issue! about: If you need support, please go here first instead of making an issue!
- name: GitHub Discussions - name: GitHub Discussions
url: https://github.com/SideStore/SideStore/discussions url: https://github.com/SideStore/SideStore/discussions

View File

@@ -10,7 +10,7 @@ body:
value: | value: |
Thanks for taking the time to fill out this feature request! Before you continue filling out the form, please **[search in GitHub Issues](https://github.com/SideStore/SideStore/issues?q=is%3Aissue+is%3Aopen) for the feature you are suggestion** in case it has already been suggested. Thanks for taking the time to fill out this feature request! Before you continue filling out the form, please **[search in GitHub Issues](https://github.com/SideStore/SideStore/issues?q=is%3Aissue+is%3Aopen) for the feature you are suggestion** in case it has already been suggested.
**Please use [Discord](https://discord.gg/RgpFBX3Q3k) or [GitHub Discussions](https://github.com/SideStore/SideStore/discussions) for support.** **Please use [Discord](https://discord.gg/sidestore-949183273383395328) or [GitHub Discussions](https://github.com/SideStore/SideStore/discussions) for support.**
- type: textarea - type: textarea
id: description id: description
attributes: attributes:

2
.gitmodules vendored
View File

@@ -9,7 +9,7 @@
url = https://github.com/libimobiledevice/libusbmuxd.git url = https://github.com/libimobiledevice/libusbmuxd.git
[submodule "Dependencies/libplist"] [submodule "Dependencies/libplist"]
path = Dependencies/libplist path = Dependencies/libplist
url = https://github.com/libimobiledevice/libplist.git url = https://github.com/SideStore/libplist.git
[submodule "Dependencies/MarkdownAttributedString"] [submodule "Dependencies/MarkdownAttributedString"]
path = Dependencies/MarkdownAttributedString path = Dependencies/MarkdownAttributedString
url = https://github.com/chockenberry/MarkdownAttributedString.git url = https://github.com/chockenberry/MarkdownAttributedString.git

View File

@@ -5,9 +5,9 @@
"color-space" : "srgb", "color-space" : "srgb",
"components" : { "components" : {
"alpha" : "1.000", "alpha" : "1.000",
"blue" : "0.518", "blue" : "175",
"green" : "0.502", "green" : "4",
"red" : "0.004" "red" : "115"
} }
}, },
"idiom" : "universal" "idiom" : "universal"
@@ -23,9 +23,9 @@
"color-space" : "srgb", "color-space" : "srgb",
"components" : { "components" : {
"alpha" : "1.000", "alpha" : "1.000",
"blue" : "0.404", "blue" : "150",
"green" : "0.322", "green" : "3",
"red" : "0.008" "red" : "99"
} }
}, },
"idiom" : "universal" "idiom" : "universal"

View File

@@ -8,13 +8,39 @@
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
03F06CD52942C27E001C4D68 /* Bundle+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */; }; 03F06CD52942C27E001C4D68 /* Bundle+AltStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF1E314122A05D4C00370A3C /* Bundle+AltStore.swift */; };
0E1A1F912AE36A9700364CAD /* bytearray.c in Sources */ = {isa = PBXBuildFile; fileRef = 0E1A1F902AE36A9600364CAD /* bytearray.c */; };
0E764E172ADFF5740043DD4E /* AltBackup.ipa in Resources */ = {isa = PBXBuildFile; fileRef = 0E764E162ADFF5740043DD4E /* AltBackup.ipa */; };
0EA1665B2ADFE0D2003015C1 /* out-limd.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166472ADFE0D1003015C1 /* out-limd.c */; };
0EA1665C2ADFE0D2003015C1 /* out-default.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166522ADFE0D2003015C1 /* out-default.c */; };
0EA1665D2ADFE0D2003015C1 /* out-plutil.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166552ADFE0D2003015C1 /* out-plutil.c */; };
0EA1665E2ADFE0D2003015C1 /* oplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166562ADFE0D2003015C1 /* oplist.c */; };
0EA166682ADFE122003015C1 /* jsmn.h in Headers */ = {isa = PBXBuildFile; fileRef = 0EA166632ADFE122003015C1 /* jsmn.h */; };
0EA166692ADFE140003015C1 /* Array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166452ADFE0D1003015C1 /* Array.cpp */; };
0EA1666A2ADFE140003015C1 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166492ADFE0D1003015C1 /* String.cpp */; };
0EA1666B2ADFE140003015C1 /* Boolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA1664E2ADFE0D1003015C1 /* Boolean.cpp */; };
0EA1666C2ADFE140003015C1 /* Integer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166532ADFE0D2003015C1 /* Integer.cpp */; };
0EA1666D2ADFE140003015C1 /* Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166432ADFE0D1003015C1 /* Data.cpp */; };
0EA1666E2ADFE140003015C1 /* ptrarray.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166512ADFE0D2003015C1 /* ptrarray.c */; };
0EA1666F2ADFE140003015C1 /* hashtable.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA1664F2ADFE0D1003015C1 /* hashtable.c */; };
0EA166702ADFE140003015C1 /* Node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166502ADFE0D2003015C1 /* Node.cpp */; };
0EA166712ADFE140003015C1 /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166582ADFE0D2003015C1 /* Key.cpp */; };
0EA166732ADFE140003015C1 /* Dictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166462ADFE0D1003015C1 /* Dictionary.cpp */; };
0EA166742ADFE140003015C1 /* Date.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166422ADFE0D1003015C1 /* Date.cpp */; };
0EA166752ADFE140003015C1 /* Real.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166542ADFE0D2003015C1 /* Real.cpp */; };
0EA166762ADFE140003015C1 /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA1664A2ADFE0D1003015C1 /* base64.c */; };
0EA166772ADFE140003015C1 /* jplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166412ADFE0D1003015C1 /* jplist.c */; };
0EA166782ADFE140003015C1 /* jsmn.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166572ADFE0D2003015C1 /* jsmn.c */; };
0EA166792ADFE140003015C1 /* bplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166442ADFE0D1003015C1 /* bplist.c */; };
0EA1667A2ADFE140003015C1 /* Uid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA1664B2ADFE0D1003015C1 /* Uid.cpp */; };
0EA1667B2ADFE140003015C1 /* Structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 0EA1665A2ADFE0D2003015C1 /* Structure.cpp */; };
0EA1667D2ADFE140003015C1 /* xplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA166592ADFE0D2003015C1 /* xplist.c */; };
0EA1667E2ADFE140003015C1 /* time64.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA1664C2ADFE0D1003015C1 /* time64.c */; };
0EA4B9BC2AE4A414009209CE /* plist.c in Sources */ = {isa = PBXBuildFile; fileRef = 0EA4B9BB2AE4A3F6009209CE /* plist.c */; };
19104D952909BAEA00C49C7B /* libimobiledevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BF45872B2298D31600BD7491 /* libimobiledevice.a */; }; 19104D952909BAEA00C49C7B /* libimobiledevice.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BF45872B2298D31600BD7491 /* libimobiledevice.a */; };
19104DB52909C06D00C49C7B /* EmotionalDamage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19104DB42909C06D00C49C7B /* EmotionalDamage.swift */; }; 19104DB52909C06D00C49C7B /* EmotionalDamage.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19104DB42909C06D00C49C7B /* EmotionalDamage.swift */; };
19104DBC2909C4E500C49C7B /* libEmotionalDamage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19104DB22909C06C00C49C7B /* libEmotionalDamage.a */; }; 19104DBC2909C4E500C49C7B /* libEmotionalDamage.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 19104DB22909C06C00C49C7B /* libEmotionalDamage.a */; };
191E5FB4290A5DA0001A3B7C /* libminimuxer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 191E5FAB290A5D92001A3B7C /* libminimuxer.a */; }; 191E5FB4290A5DA0001A3B7C /* libminimuxer.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 191E5FAB290A5D92001A3B7C /* libminimuxer.a */; };
191E5FDC290AFA5C001A3B7C /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 191E5FDB290AFA5C001A3B7C /* OpenSSL */; }; 191E5FDC290AFA5C001A3B7C /* OpenSSL in Frameworks */ = {isa = PBXBuildFile; productRef = 191E5FDB290AFA5C001A3B7C /* OpenSSL */; };
191E607D290B2EA5001A3B7C /* jsmn.c in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FD0290A651D001A3B7C /* jsmn.c */; };
191E607E290B2EA7001A3B7C /* jplist.c in Sources */ = {isa = PBXBuildFile; fileRef = 191E5FCF290A651D001A3B7C /* jplist.c */; };
1920B04F2924AC8300744F60 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1920B04E2924AC8300744F60 /* Settings.bundle */; }; 1920B04F2924AC8300744F60 /* Settings.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 1920B04E2924AC8300744F60 /* Settings.bundle */; };
19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; }; 19B9B7452845E6DF0076EF69 /* SelectTeamViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */; };
4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; }; 4879A95F2861046500FC1BBD /* AltSign in Frameworks */ = {isa = PBXBuildFile; productRef = 4879A95E2861046500FC1BBD /* AltSign */; };
@@ -25,7 +51,6 @@
99F87D1829D8E4C900B40039 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F87D1629D8E4C900B40039 /* SwiftBridgeCore.swift */; }; 99F87D1829D8E4C900B40039 /* SwiftBridgeCore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F87D1629D8E4C900B40039 /* SwiftBridgeCore.swift */; };
99F87D1929D8E4C900B40039 /* minimuxer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F87D1729D8E4C900B40039 /* minimuxer.swift */; }; 99F87D1929D8E4C900B40039 /* minimuxer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F87D1729D8E4C900B40039 /* minimuxer.swift */; };
B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; }; B3146ED2284F581E00BBC3FD /* Roxas.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; };
B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = B3146ECD284F580500BBC3FD /* Roxas.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
B33FFBA8295F8E98002259E6 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B343F894295F7F9B002B1159 /* libfragmentzip.a */; }; B33FFBA8295F8E98002259E6 /* libfragmentzip.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B343F894295F7F9B002B1159 /* libfragmentzip.a */; };
B33FFBAA295F8F78002259E6 /* preboard.c in Sources */ = {isa = PBXBuildFile; fileRef = B33FFBA9295F8F78002259E6 /* preboard.c */; }; B33FFBAA295F8F78002259E6 /* preboard.c in Sources */ = {isa = PBXBuildFile; fileRef = B33FFBA9295F8F78002259E6 /* preboard.c */; };
B33FFBAC295F8F98002259E6 /* companion_proxy.c in Sources */ = {isa = PBXBuildFile; fileRef = B33FFBAB295F8F98002259E6 /* companion_proxy.c */; }; B33FFBAC295F8F98002259E6 /* companion_proxy.c in Sources */ = {isa = PBXBuildFile; fileRef = B33FFBAB295F8F98002259E6 /* companion_proxy.c */; };
@@ -74,7 +99,6 @@
BF41B808233433C100C593A3 /* LoadingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF41B807233433C100C593A3 /* LoadingState.swift */; }; BF41B808233433C100C593A3 /* LoadingState.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF41B807233433C100C593A3 /* LoadingState.swift */; };
BF42345A25101C35006D1EB2 /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF42345825101C1D006D1EB2 /* WidgetView.swift */; }; BF42345A25101C35006D1EB2 /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF42345825101C1D006D1EB2 /* WidgetView.swift */; };
BF44EEF0246B08BA002A52F2 /* BackupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEEF246B08BA002A52F2 /* BackupController.swift */; }; BF44EEF0246B08BA002A52F2 /* BackupController.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEEF246B08BA002A52F2 /* BackupController.swift */; };
BF44EEF3246B3A17002A52F2 /* AltBackup.ipa in Resources */ = {isa = PBXBuildFile; fileRef = BF44EEF2246B3A17002A52F2 /* AltBackup.ipa */; };
BF44EEFC246B4550002A52F2 /* RemoveAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */; }; BF44EEFC246B4550002A52F2 /* RemoveAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */; };
BF4587F82298D3AB00BD7491 /* service.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4587C82298D3A800BD7491 /* service.h */; }; BF4587F82298D3AB00BD7491 /* service.h in Headers */ = {isa = PBXBuildFile; fileRef = BF4587C82298D3A800BD7491 /* service.h */; };
BF4587F92298D3AB00BD7491 /* diagnostics_relay.c in Sources */ = {isa = PBXBuildFile; fileRef = BF4587C92298D3A800BD7491 /* diagnostics_relay.c */; }; BF4587F92298D3AB00BD7491 /* diagnostics_relay.c in Sources */ = {isa = PBXBuildFile; fileRef = BF4587C92298D3A800BD7491 /* diagnostics_relay.c */; };
@@ -254,34 +278,6 @@
BFD2477A2284B9A700981D42 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFD247782284B9A700981D42 /* LaunchScreen.storyboard */; }; BFD2477A2284B9A700981D42 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = BFD247782284B9A700981D42 /* LaunchScreen.storyboard */; };
BFD2478C2284C4C300981D42 /* AppIconImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2478B2284C4C300981D42 /* AppIconImageView.swift */; }; BFD2478C2284C4C300981D42 /* AppIconImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2478B2284C4C300981D42 /* AppIconImageView.swift */; };
BFD2478F2284C8F900981D42 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2478E2284C8F900981D42 /* Button.swift */; }; BFD2478F2284C8F900981D42 /* Button.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFD2478E2284C8F900981D42 /* Button.swift */; };
BFD52C0122A1A9CB000B7ED1 /* ptrarray.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BE522A1A9CA000B7ED1 /* ptrarray.c */; };
BFD52C0222A1A9CB000B7ED1 /* base64.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BE622A1A9CA000B7ED1 /* base64.c */; };
BFD52C0322A1A9CB000B7ED1 /* hashtable.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BE722A1A9CA000B7ED1 /* hashtable.c */; };
BFD52C0422A1A9CB000B7ED1 /* Dictionary.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BE822A1A9CA000B7ED1 /* Dictionary.cpp */; };
BFD52C0522A1A9CB000B7ED1 /* ptrarray.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BE922A1A9CA000B7ED1 /* ptrarray.h */; };
BFD52C0622A1A9CB000B7ED1 /* bplist.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BEA22A1A9CA000B7ED1 /* bplist.c */; };
BFD52C0722A1A9CB000B7ED1 /* String.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BEB22A1A9CA000B7ED1 /* String.cpp */; };
BFD52C0822A1A9CB000B7ED1 /* time64.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BEC22A1A9CA000B7ED1 /* time64.c */; };
BFD52C0922A1A9CB000B7ED1 /* plist.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BED22A1A9CA000B7ED1 /* plist.h */; };
BFD52C0A22A1A9CB000B7ED1 /* plist.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BEE22A1A9CA000B7ED1 /* plist.c */; };
BFD52C0B22A1A9CB000B7ED1 /* hashtable.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BEF22A1A9CA000B7ED1 /* hashtable.h */; };
BFD52C0C22A1A9CB000B7ED1 /* Date.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF022A1A9CA000B7ED1 /* Date.cpp */; };
BFD52C0D22A1A9CB000B7ED1 /* Uid.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF122A1A9CA000B7ED1 /* Uid.cpp */; };
BFD52C0E22A1A9CB000B7ED1 /* Boolean.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF222A1A9CA000B7ED1 /* Boolean.cpp */; };
BFD52C0F22A1A9CB000B7ED1 /* Real.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF322A1A9CA000B7ED1 /* Real.cpp */; };
BFD52C1022A1A9CB000B7ED1 /* strbuf.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BF422A1A9CA000B7ED1 /* strbuf.h */; };
BFD52C1122A1A9CB000B7ED1 /* bytearray.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF522A1A9CA000B7ED1 /* bytearray.c */; };
BFD52C1222A1A9CB000B7ED1 /* base64.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BF622A1A9CA000B7ED1 /* base64.h */; };
BFD52C1322A1A9CB000B7ED1 /* Data.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF722A1A9CA000B7ED1 /* Data.cpp */; };
BFD52C1422A1A9CB000B7ED1 /* Array.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF822A1A9CB000B7ED1 /* Array.cpp */; };
BFD52C1522A1A9CB000B7ED1 /* Node.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BF922A1A9CB000B7ED1 /* Node.cpp */; };
BFD52C1622A1A9CB000B7ED1 /* bytearray.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BFA22A1A9CB000B7ED1 /* bytearray.h */; };
BFD52C1722A1A9CB000B7ED1 /* Key.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BFB22A1A9CB000B7ED1 /* Key.cpp */; };
BFD52C1822A1A9CB000B7ED1 /* Integer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BFC22A1A9CB000B7ED1 /* Integer.cpp */; };
BFD52C1922A1A9CB000B7ED1 /* Structure.cpp in Sources */ = {isa = PBXBuildFile; fileRef = BFD52BFD22A1A9CB000B7ED1 /* Structure.cpp */; };
BFD52C1A22A1A9CB000B7ED1 /* time64_limits.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BFE22A1A9CB000B7ED1 /* time64_limits.h */; };
BFD52C1B22A1A9CB000B7ED1 /* time64.h in Headers */ = {isa = PBXBuildFile; fileRef = BFD52BFF22A1A9CB000B7ED1 /* time64.h */; };
BFD52C1C22A1A9CB000B7ED1 /* xplist.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C0022A1A9CB000B7ED1 /* xplist.c */; };
BFD52C2022A1A9EC000B7ED1 /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C1D22A1A9EC000B7ED1 /* node.c */; }; BFD52C2022A1A9EC000B7ED1 /* node.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C1D22A1A9EC000B7ED1 /* node.c */; };
BFD52C2122A1A9EC000B7ED1 /* node_list.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C1E22A1A9EC000B7ED1 /* node_list.c */; }; BFD52C2122A1A9EC000B7ED1 /* node_list.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C1E22A1A9EC000B7ED1 /* node_list.c */; };
BFD52C2222A1A9EC000B7ED1 /* cnary.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C1F22A1A9EC000B7ED1 /* cnary.c */; }; BFD52C2222A1A9EC000B7ED1 /* cnary.c in Sources */ = {isa = PBXBuildFile; fileRef = BFD52C1F22A1A9EC000B7ED1 /* cnary.c */; };
@@ -336,6 +332,7 @@
D57FE84428C7DB7100216002 /* ErrorLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57FE84328C7DB7100216002 /* ErrorLogViewController.swift */; }; D57FE84428C7DB7100216002 /* ErrorLogViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = D57FE84328C7DB7100216002 /* ErrorLogViewController.swift */; };
D58916FE28C7C55C00E39C8B /* LoggedError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58916FD28C7C55C00E39C8B /* LoggedError.swift */; }; D58916FE28C7C55C00E39C8B /* LoggedError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D58916FD28C7C55C00E39C8B /* LoggedError.swift */; };
D593F1942717749A006E82DE /* PatchAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D593F1932717749A006E82DE /* PatchAppOperation.swift */; }; D593F1942717749A006E82DE /* PatchAppOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D593F1932717749A006E82DE /* PatchAppOperation.swift */; };
D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */; };
D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; }; D5CA0C4B280E141900469595 /* ManagedPatron.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4A280E141900469595 /* ManagedPatron.swift */; };
D5CA0C4E280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */; }; D5CA0C4E280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel in Sources */ = {isa = PBXBuildFile; fileRef = D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */; };
D5DAE0942804B0B80034D8D4 /* ScreenshotProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5DAE0932804B0B80034D8D4 /* ScreenshotProcessor.swift */; }; D5DAE0942804B0B80034D8D4 /* ScreenshotProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5DAE0932804B0B80034D8D4 /* ScreenshotProcessor.swift */; };
@@ -482,7 +479,6 @@
dstPath = ""; dstPath = "";
dstSubfolderSpec = 10; dstSubfolderSpec = 10;
files = ( files = (
B3146ED3284F581E00BBC3FD /* Roxas.framework in Embed Frameworks */,
BF1614F2250822F100767AEA /* Roxas.framework in Embed Frameworks */, BF1614F2250822F100767AEA /* Roxas.framework in Embed Frameworks */,
BF66EE862501AE50007EE018 /* AltStoreCore.framework in Embed Frameworks */, BF66EE862501AE50007EE018 /* AltStoreCore.framework in Embed Frameworks */,
); );
@@ -503,12 +499,45 @@
/* End PBXCopyFilesBuildPhase section */ /* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */ /* Begin PBXFileReference section */
0E1A1F902AE36A9600364CAD /* bytearray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bytearray.c; path = src/bytearray.c; sourceTree = "<group>"; };
0E764E162ADFF5740043DD4E /* AltBackup.ipa */ = {isa = PBXFileReference; lastKnownFileType = file; name = AltBackup.ipa; path = AltStore/Resources/AltBackup.ipa; sourceTree = SOURCE_ROOT; };
0EA166412ADFE0D1003015C1 /* jplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jplist.c; path = Dependencies/libplist/src/jplist.c; sourceTree = SOURCE_ROOT; };
0EA166422ADFE0D1003015C1 /* Date.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Date.cpp; path = Dependencies/libplist/src/Date.cpp; sourceTree = SOURCE_ROOT; };
0EA166432ADFE0D1003015C1 /* Data.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Data.cpp; path = Dependencies/libplist/src/Data.cpp; sourceTree = SOURCE_ROOT; };
0EA166442ADFE0D1003015C1 /* bplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = bplist.c; path = Dependencies/libplist/src/bplist.c; sourceTree = SOURCE_ROOT; };
0EA166452ADFE0D1003015C1 /* Array.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Array.cpp; path = Dependencies/libplist/src/Array.cpp; sourceTree = SOURCE_ROOT; };
0EA166462ADFE0D1003015C1 /* Dictionary.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Dictionary.cpp; path = Dependencies/libplist/src/Dictionary.cpp; sourceTree = SOURCE_ROOT; };
0EA166472ADFE0D1003015C1 /* out-limd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "out-limd.c"; path = "Dependencies/libplist/src/out-limd.c"; sourceTree = SOURCE_ROOT; };
0EA166492ADFE0D1003015C1 /* String.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = String.cpp; path = Dependencies/libplist/src/String.cpp; sourceTree = SOURCE_ROOT; };
0EA1664A2ADFE0D1003015C1 /* base64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = base64.c; path = Dependencies/libplist/src/base64.c; sourceTree = SOURCE_ROOT; };
0EA1664B2ADFE0D1003015C1 /* Uid.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Uid.cpp; path = Dependencies/libplist/src/Uid.cpp; sourceTree = SOURCE_ROOT; };
0EA1664C2ADFE0D1003015C1 /* time64.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = time64.c; path = Dependencies/libplist/src/time64.c; sourceTree = SOURCE_ROOT; };
0EA1664E2ADFE0D1003015C1 /* Boolean.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Boolean.cpp; path = Dependencies/libplist/src/Boolean.cpp; sourceTree = SOURCE_ROOT; };
0EA1664F2ADFE0D1003015C1 /* hashtable.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = hashtable.c; path = Dependencies/libplist/src/hashtable.c; sourceTree = SOURCE_ROOT; };
0EA166502ADFE0D2003015C1 /* Node.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Node.cpp; path = Dependencies/libplist/src/Node.cpp; sourceTree = SOURCE_ROOT; };
0EA166512ADFE0D2003015C1 /* ptrarray.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = ptrarray.c; path = Dependencies/libplist/src/ptrarray.c; sourceTree = SOURCE_ROOT; };
0EA166522ADFE0D2003015C1 /* out-default.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "out-default.c"; path = "Dependencies/libplist/src/out-default.c"; sourceTree = SOURCE_ROOT; };
0EA166532ADFE0D2003015C1 /* Integer.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Integer.cpp; path = Dependencies/libplist/src/Integer.cpp; sourceTree = SOURCE_ROOT; };
0EA166542ADFE0D2003015C1 /* Real.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Real.cpp; path = Dependencies/libplist/src/Real.cpp; sourceTree = SOURCE_ROOT; };
0EA166552ADFE0D2003015C1 /* out-plutil.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = "out-plutil.c"; path = "Dependencies/libplist/src/out-plutil.c"; sourceTree = SOURCE_ROOT; };
0EA166562ADFE0D2003015C1 /* oplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = oplist.c; path = Dependencies/libplist/src/oplist.c; sourceTree = SOURCE_ROOT; };
0EA166572ADFE0D2003015C1 /* jsmn.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jsmn.c; path = Dependencies/libplist/src/jsmn.c; sourceTree = SOURCE_ROOT; };
0EA166582ADFE0D2003015C1 /* Key.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Key.cpp; path = Dependencies/libplist/src/Key.cpp; sourceTree = SOURCE_ROOT; };
0EA166592ADFE0D2003015C1 /* xplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = xplist.c; path = Dependencies/libplist/src/xplist.c; sourceTree = SOURCE_ROOT; };
0EA1665A2ADFE0D2003015C1 /* Structure.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; name = Structure.cpp; path = Dependencies/libplist/src/Structure.cpp; sourceTree = SOURCE_ROOT; };
0EA1665F2ADFE122003015C1 /* time64_limits.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = time64_limits.h; path = Dependencies/libplist/src/time64_limits.h; sourceTree = SOURCE_ROOT; };
0EA166602ADFE122003015C1 /* time64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = time64.h; path = Dependencies/libplist/src/time64.h; sourceTree = SOURCE_ROOT; };
0EA166612ADFE122003015C1 /* bytearray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = bytearray.h; path = Dependencies/libplist/src/bytearray.h; sourceTree = SOURCE_ROOT; };
0EA166622ADFE122003015C1 /* ptrarray.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = ptrarray.h; path = Dependencies/libplist/src/ptrarray.h; sourceTree = SOURCE_ROOT; };
0EA166632ADFE122003015C1 /* jsmn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jsmn.h; path = Dependencies/libplist/src/jsmn.h; sourceTree = SOURCE_ROOT; };
0EA166642ADFE122003015C1 /* plist.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = plist.h; path = Dependencies/libplist/src/plist.h; sourceTree = SOURCE_ROOT; };
0EA166652ADFE122003015C1 /* hashtable.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = hashtable.h; path = Dependencies/libplist/src/hashtable.h; sourceTree = SOURCE_ROOT; };
0EA166662ADFE122003015C1 /* base64.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = base64.h; path = Dependencies/libplist/src/base64.h; sourceTree = SOURCE_ROOT; };
0EA166672ADFE122003015C1 /* strbuf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = strbuf.h; path = Dependencies/libplist/src/strbuf.h; sourceTree = SOURCE_ROOT; };
0EA4B9BB2AE4A3F6009209CE /* plist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = plist.c; path = Dependencies/libplist/src/plist.c; sourceTree = SOURCE_ROOT; };
19104DB22909C06C00C49C7B /* libEmotionalDamage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libEmotionalDamage.a; sourceTree = BUILT_PRODUCTS_DIR; }; 19104DB22909C06C00C49C7B /* libEmotionalDamage.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libEmotionalDamage.a; sourceTree = BUILT_PRODUCTS_DIR; };
19104DB42909C06D00C49C7B /* EmotionalDamage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmotionalDamage.swift; sourceTree = "<group>"; }; 19104DB42909C06D00C49C7B /* EmotionalDamage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EmotionalDamage.swift; sourceTree = "<group>"; };
191E5FAB290A5D92001A3B7C /* libminimuxer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libminimuxer.a; sourceTree = BUILT_PRODUCTS_DIR; }; 191E5FAB290A5D92001A3B7C /* libminimuxer.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libminimuxer.a; sourceTree = BUILT_PRODUCTS_DIR; };
191E5FCF290A651D001A3B7C /* jplist.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jplist.c; path = Dependencies/libplist/src/jplist.c; sourceTree = SOURCE_ROOT; };
191E5FD0290A651D001A3B7C /* jsmn.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; name = jsmn.c; path = Dependencies/libplist/src/jsmn.c; sourceTree = SOURCE_ROOT; };
191E5FD1290A651D001A3B7C /* jsmn.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = jsmn.h; path = Dependencies/libplist/src/jsmn.h; sourceTree = SOURCE_ROOT; };
1920B04E2924AC8300744F60 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; }; 1920B04E2924AC8300744F60 /* Settings.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = Settings.bundle; sourceTree = "<group>"; };
19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = "<group>"; }; 19B9B7442845E6DF0076EF69 /* SelectTeamViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SelectTeamViewController.swift; sourceTree = "<group>"; };
9961EC2D29BE9F2E00AF2C6F /* minimuxer-helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "minimuxer-helpers.swift"; path = "Dependencies/minimuxer/minimuxer-helpers.swift"; sourceTree = SOURCE_ROOT; }; 9961EC2D29BE9F2E00AF2C6F /* minimuxer-helpers.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = "minimuxer-helpers.swift"; path = "Dependencies/minimuxer/minimuxer-helpers.swift"; sourceTree = SOURCE_ROOT; };
@@ -573,7 +602,6 @@
BF41B807233433C100C593A3 /* LoadingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingState.swift; sourceTree = "<group>"; }; BF41B807233433C100C593A3 /* LoadingState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingState.swift; sourceTree = "<group>"; };
BF42345825101C1D006D1EB2 /* WidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetView.swift; sourceTree = "<group>"; }; BF42345825101C1D006D1EB2 /* WidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetView.swift; sourceTree = "<group>"; };
BF44EEEF246B08BA002A52F2 /* BackupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupController.swift; sourceTree = "<group>"; }; BF44EEEF246B08BA002A52F2 /* BackupController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackupController.swift; sourceTree = "<group>"; };
BF44EEF2246B3A17002A52F2 /* AltBackup.ipa */ = {isa = PBXFileReference; lastKnownFileType = file; path = AltBackup.ipa; sourceTree = "<group>"; };
BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAppOperation.swift; sourceTree = "<group>"; }; BF44EEFB246B4550002A52F2 /* RemoveAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoveAppOperation.swift; sourceTree = "<group>"; };
BF45872B2298D31600BD7491 /* libimobiledevice.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libimobiledevice.a; sourceTree = BUILT_PRODUCTS_DIR; }; BF45872B2298D31600BD7491 /* libimobiledevice.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libimobiledevice.a; sourceTree = BUILT_PRODUCTS_DIR; };
BF4587C82298D3A800BD7491 /* service.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = service.h; path = Dependencies/libimobiledevice/src/service.h; sourceTree = SOURCE_ROOT; }; BF4587C82298D3A800BD7491 /* service.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = service.h; path = Dependencies/libimobiledevice/src/service.h; sourceTree = SOURCE_ROOT; };
@@ -759,34 +787,6 @@
BFD2479E2284FBD000981D42 /* UIColor+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+AltStore.swift"; sourceTree = "<group>"; }; BFD2479E2284FBD000981D42 /* UIColor+AltStore.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "UIColor+AltStore.swift"; sourceTree = "<group>"; };
BFD44605241188C300EAB90A /* CodableServerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableServerError.swift; sourceTree = "<group>"; }; BFD44605241188C300EAB90A /* CodableServerError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodableServerError.swift; sourceTree = "<group>"; };
BFD52BD222A06EFB000B7ED1 /* ALTConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTConstants.h; sourceTree = "<group>"; }; BFD52BD222A06EFB000B7ED1 /* ALTConstants.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ALTConstants.h; sourceTree = "<group>"; };
BFD52BE522A1A9CA000B7ED1 /* ptrarray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = ptrarray.c; path = Dependencies/libplist/src/ptrarray.c; sourceTree = SOURCE_ROOT; };
BFD52BE622A1A9CA000B7ED1 /* base64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = base64.c; path = Dependencies/libplist/src/base64.c; sourceTree = SOURCE_ROOT; };
BFD52BE722A1A9CA000B7ED1 /* hashtable.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = hashtable.c; path = Dependencies/libplist/src/hashtable.c; sourceTree = SOURCE_ROOT; };
BFD52BE822A1A9CA000B7ED1 /* Dictionary.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Dictionary.cpp; path = Dependencies/libplist/src/Dictionary.cpp; sourceTree = SOURCE_ROOT; };
BFD52BE922A1A9CA000B7ED1 /* ptrarray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ptrarray.h; path = Dependencies/libplist/src/ptrarray.h; sourceTree = SOURCE_ROOT; };
BFD52BEA22A1A9CA000B7ED1 /* bplist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bplist.c; path = Dependencies/libplist/src/bplist.c; sourceTree = SOURCE_ROOT; };
BFD52BEB22A1A9CA000B7ED1 /* String.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = String.cpp; path = Dependencies/libplist/src/String.cpp; sourceTree = SOURCE_ROOT; };
BFD52BEC22A1A9CA000B7ED1 /* time64.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = time64.c; path = Dependencies/libplist/src/time64.c; sourceTree = SOURCE_ROOT; };
BFD52BED22A1A9CA000B7ED1 /* plist.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = plist.h; path = Dependencies/libplist/src/plist.h; sourceTree = SOURCE_ROOT; };
BFD52BEE22A1A9CA000B7ED1 /* plist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = plist.c; path = Dependencies/libplist/src/plist.c; sourceTree = SOURCE_ROOT; };
BFD52BEF22A1A9CA000B7ED1 /* hashtable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = hashtable.h; path = Dependencies/libplist/src/hashtable.h; sourceTree = SOURCE_ROOT; };
BFD52BF022A1A9CA000B7ED1 /* Date.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Date.cpp; path = Dependencies/libplist/src/Date.cpp; sourceTree = SOURCE_ROOT; };
BFD52BF122A1A9CA000B7ED1 /* Uid.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Uid.cpp; path = Dependencies/libplist/src/Uid.cpp; sourceTree = SOURCE_ROOT; };
BFD52BF222A1A9CA000B7ED1 /* Boolean.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Boolean.cpp; path = Dependencies/libplist/src/Boolean.cpp; sourceTree = SOURCE_ROOT; };
BFD52BF322A1A9CA000B7ED1 /* Real.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Real.cpp; path = Dependencies/libplist/src/Real.cpp; sourceTree = SOURCE_ROOT; };
BFD52BF422A1A9CA000B7ED1 /* strbuf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = strbuf.h; path = Dependencies/libplist/src/strbuf.h; sourceTree = SOURCE_ROOT; };
BFD52BF522A1A9CA000B7ED1 /* bytearray.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = bytearray.c; path = Dependencies/libplist/src/bytearray.c; sourceTree = SOURCE_ROOT; };
BFD52BF622A1A9CA000B7ED1 /* base64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = base64.h; path = Dependencies/libplist/src/base64.h; sourceTree = SOURCE_ROOT; };
BFD52BF722A1A9CA000B7ED1 /* Data.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Data.cpp; path = Dependencies/libplist/src/Data.cpp; sourceTree = SOURCE_ROOT; };
BFD52BF822A1A9CB000B7ED1 /* Array.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Array.cpp; path = Dependencies/libplist/src/Array.cpp; sourceTree = SOURCE_ROOT; };
BFD52BF922A1A9CB000B7ED1 /* Node.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Node.cpp; path = Dependencies/libplist/src/Node.cpp; sourceTree = SOURCE_ROOT; };
BFD52BFA22A1A9CB000B7ED1 /* bytearray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = bytearray.h; path = Dependencies/libplist/src/bytearray.h; sourceTree = SOURCE_ROOT; };
BFD52BFB22A1A9CB000B7ED1 /* Key.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Key.cpp; path = Dependencies/libplist/src/Key.cpp; sourceTree = SOURCE_ROOT; };
BFD52BFC22A1A9CB000B7ED1 /* Integer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Integer.cpp; path = Dependencies/libplist/src/Integer.cpp; sourceTree = SOURCE_ROOT; };
BFD52BFD22A1A9CB000B7ED1 /* Structure.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Structure.cpp; path = Dependencies/libplist/src/Structure.cpp; sourceTree = SOURCE_ROOT; };
BFD52BFE22A1A9CB000B7ED1 /* time64_limits.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = time64_limits.h; path = Dependencies/libplist/src/time64_limits.h; sourceTree = SOURCE_ROOT; };
BFD52BFF22A1A9CB000B7ED1 /* time64.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = time64.h; path = Dependencies/libplist/src/time64.h; sourceTree = SOURCE_ROOT; };
BFD52C0022A1A9CB000B7ED1 /* xplist.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = xplist.c; path = Dependencies/libplist/src/xplist.c; sourceTree = SOURCE_ROOT; };
BFD52C1D22A1A9EC000B7ED1 /* node.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = node.c; path = Dependencies/libplist/libcnary/node.c; sourceTree = SOURCE_ROOT; }; BFD52C1D22A1A9EC000B7ED1 /* node.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = node.c; path = Dependencies/libplist/libcnary/node.c; sourceTree = SOURCE_ROOT; };
BFD52C1E22A1A9EC000B7ED1 /* node_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = node_list.c; path = Dependencies/libplist/libcnary/node_list.c; sourceTree = SOURCE_ROOT; }; BFD52C1E22A1A9EC000B7ED1 /* node_list.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = node_list.c; path = Dependencies/libplist/libcnary/node_list.c; sourceTree = SOURCE_ROOT; };
BFD52C1F22A1A9EC000B7ED1 /* cnary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cnary.c; path = Dependencies/libplist/libcnary/cnary.c; sourceTree = SOURCE_ROOT; }; BFD52C1F22A1A9EC000B7ED1 /* cnary.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; name = cnary.c; path = Dependencies/libplist/libcnary/cnary.c; sourceTree = SOURCE_ROOT; };
@@ -840,6 +840,7 @@
D57FE84328C7DB7100216002 /* ErrorLogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogViewController.swift; sourceTree = "<group>"; }; D57FE84328C7DB7100216002 /* ErrorLogViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ErrorLogViewController.swift; sourceTree = "<group>"; };
D58916FD28C7C55C00E39C8B /* LoggedError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedError.swift; sourceTree = "<group>"; }; D58916FD28C7C55C00E39C8B /* LoggedError.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoggedError.swift; sourceTree = "<group>"; };
D593F1932717749A006E82DE /* PatchAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatchAppOperation.swift; sourceTree = "<group>"; }; D593F1932717749A006E82DE /* PatchAppOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PatchAppOperation.swift; sourceTree = "<group>"; };
D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClearAppCacheOperation.swift; sourceTree = "<group>"; };
D5CA0C4A280E141900469595 /* ManagedPatron.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPatron.swift; sourceTree = "<group>"; }; D5CA0C4A280E141900469595 /* ManagedPatron.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ManagedPatron.swift; sourceTree = "<group>"; };
D5CA0C4C280E242500469595 /* AltStore 10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 10.xcdatamodel"; sourceTree = "<group>"; }; D5CA0C4C280E242500469595 /* AltStore 10.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "AltStore 10.xcdatamodel"; sourceTree = "<group>"; };
D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore9ToAltStore10.xcmappingmodel; sourceTree = "<group>"; }; D5CA0C4D280E249E00469595 /* AltStore9ToAltStore10.xcmappingmodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcmappingmodel; path = AltStore9ToAltStore10.xcmappingmodel; sourceTree = "<group>"; };
@@ -1192,37 +1193,41 @@
BF4588562298DC6D00BD7491 /* libplist */ = { BF4588562298DC6D00BD7491 /* libplist */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
BFD52BE622A1A9CA000B7ED1 /* base64.c */, 0EA166462ADFE0D1003015C1 /* Dictionary.cpp */,
BFD52BEA22A1A9CA000B7ED1 /* bplist.c */, 0E1A1F902AE36A9600364CAD /* bytearray.c */,
BFD52BF522A1A9CA000B7ED1 /* bytearray.c */, 0EA166442ADFE0D1003015C1 /* bplist.c */,
BFD52BE722A1A9CA000B7ED1 /* hashtable.c */, 0EA166432ADFE0D1003015C1 /* Data.cpp */,
191E5FCF290A651D001A3B7C /* jplist.c */, 0EA166422ADFE0D1003015C1 /* Date.cpp */,
191E5FD0290A651D001A3B7C /* jsmn.c */, 0EA1664F2ADFE0D1003015C1 /* hashtable.c */,
BFD52BEE22A1A9CA000B7ED1 /* plist.c */, 0EA166532ADFE0D2003015C1 /* Integer.cpp */,
BFD52BE522A1A9CA000B7ED1 /* ptrarray.c */, 0EA166562ADFE0D2003015C1 /* oplist.c */,
BFD52BEC22A1A9CA000B7ED1 /* time64.c */, 0EA166522ADFE0D2003015C1 /* out-default.c */,
BFD52C0022A1A9CB000B7ED1 /* xplist.c */, 0EA166472ADFE0D1003015C1 /* out-limd.c */,
BFD52BF822A1A9CB000B7ED1 /* Array.cpp */, 0EA166552ADFE0D2003015C1 /* out-plutil.c */,
BFD52BF222A1A9CA000B7ED1 /* Boolean.cpp */, 0EA166492ADFE0D1003015C1 /* String.cpp */,
BFD52BF722A1A9CA000B7ED1 /* Data.cpp */, 0EA1665A2ADFE0D2003015C1 /* Structure.cpp */,
BFD52BF022A1A9CA000B7ED1 /* Date.cpp */, 0EA166452ADFE0D1003015C1 /* Array.cpp */,
BFD52BE822A1A9CA000B7ED1 /* Dictionary.cpp */, 0EA1664A2ADFE0D1003015C1 /* base64.c */,
BFD52BFC22A1A9CB000B7ED1 /* Integer.cpp */, 0EA166572ADFE0D2003015C1 /* jsmn.c */,
BFD52BFB22A1A9CB000B7ED1 /* Key.cpp */, 0EA1664E2ADFE0D1003015C1 /* Boolean.cpp */,
BFD52BF922A1A9CB000B7ED1 /* Node.cpp */, 0EA4B9BB2AE4A3F6009209CE /* plist.c */,
BFD52BF322A1A9CA000B7ED1 /* Real.cpp */, 0EA166412ADFE0D1003015C1 /* jplist.c */,
BFD52BEB22A1A9CA000B7ED1 /* String.cpp */, 0EA166582ADFE0D2003015C1 /* Key.cpp */,
BFD52BFD22A1A9CB000B7ED1 /* Structure.cpp */, 0EA166512ADFE0D2003015C1 /* ptrarray.c */,
BFD52BF122A1A9CA000B7ED1 /* Uid.cpp */, 0EA1664C2ADFE0D1003015C1 /* time64.c */,
BFD52BF622A1A9CA000B7ED1 /* base64.h */, 0EA166502ADFE0D2003015C1 /* Node.cpp */,
BFD52BFA22A1A9CB000B7ED1 /* bytearray.h */, 0EA166542ADFE0D2003015C1 /* Real.cpp */,
BFD52BEF22A1A9CA000B7ED1 /* hashtable.h */, 0EA1664B2ADFE0D1003015C1 /* Uid.cpp */,
191E5FD1290A651D001A3B7C /* jsmn.h */, 0EA166592ADFE0D2003015C1 /* xplist.c */,
BFD52BED22A1A9CA000B7ED1 /* plist.h */, 0EA166662ADFE122003015C1 /* base64.h */,
BFD52BE922A1A9CA000B7ED1 /* ptrarray.h */, 0EA166652ADFE122003015C1 /* hashtable.h */,
BFD52BF422A1A9CA000B7ED1 /* strbuf.h */, 0EA166632ADFE122003015C1 /* jsmn.h */,
BFD52BFE22A1A9CB000B7ED1 /* time64_limits.h */, 0EA166642ADFE122003015C1 /* plist.h */,
BFD52BFF22A1A9CB000B7ED1 /* time64.h */, 0EA166612ADFE122003015C1 /* bytearray.h */,
0EA166622ADFE122003015C1 /* ptrarray.h */,
0EA166672ADFE122003015C1 /* strbuf.h */,
0EA1665F2ADFE122003015C1 /* time64_limits.h */,
0EA166602ADFE122003015C1 /* time64.h */,
BF4588892298DDEA00BD7491 /* libcnary */, BF4588892298DDEA00BD7491 /* libcnary */,
); );
path = libplist; path = libplist;
@@ -1619,7 +1624,7 @@
BFD247962284D7C100981D42 /* Resources */ = { BFD247962284D7C100981D42 /* Resources */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
BF44EEF2246B3A17002A52F2 /* AltBackup.ipa */, 0E764E162ADFF5740043DD4E /* AltBackup.ipa */,
BFD247762284B9A700981D42 /* Assets.xcassets */, BFD247762284B9A700981D42 /* Assets.xcassets */,
BF770E6822BD57DD002A40FE /* Silence.m4a */, BF770E6822BD57DD002A40FE /* Silence.m4a */,
); );
@@ -1694,6 +1699,7 @@
D57F2C9026E0070200B9FA39 /* EnableJITOperation.swift */, D57F2C9026E0070200B9FA39 /* EnableJITOperation.swift */,
D5DAE0952804DF430034D8D4 /* UpdatePatronsOperation.swift */, D5DAE0952804DF430034D8D4 /* UpdatePatronsOperation.swift */,
D5E1E7C028077DE90016FC96 /* FetchTrustedSourcesOperation.swift */, D5E1E7C028077DE90016FC96 /* FetchTrustedSourcesOperation.swift */,
D5ACE84428E3B8450021CAB9 /* ClearAppCacheOperation.swift */,
BF7B44062725A4B8005288A4 /* Patch App */, BF7B44062725A4B8005288A4 /* Patch App */,
); );
path = Operations; path = Operations;
@@ -1780,32 +1786,26 @@
isa = PBXHeadersBuildPhase; isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
0EA166682ADFE122003015C1 /* jsmn.h in Headers */,
BF4588112298D3AB00BD7491 /* misagent.h in Headers */, BF4588112298D3AB00BD7491 /* misagent.h in Headers */,
BF4588042298D3AB00BD7491 /* lockdown.h in Headers */, BF4588042298D3AB00BD7491 /* lockdown.h in Headers */,
BF45880B2298D3AB00BD7491 /* mobilesync.h in Headers */, BF45880B2298D3AB00BD7491 /* mobilesync.h in Headers */,
BF4588002298D3AB00BD7491 /* restore.h in Headers */, BF4588002298D3AB00BD7491 /* restore.h in Headers */,
BF4588152298D3AB00BD7491 /* mobilebackup.h in Headers */, BF4588152298D3AB00BD7491 /* mobilebackup.h in Headers */,
BF4588182298D3AB00BD7491 /* syslog_relay.h in Headers */, BF4588182298D3AB00BD7491 /* syslog_relay.h in Headers */,
BFD52C1022A1A9CB000B7ED1 /* strbuf.h in Headers */,
BF45881D2298D3AB00BD7491 /* file_relay.h in Headers */, BF45881D2298D3AB00BD7491 /* file_relay.h in Headers */,
BFD52C0922A1A9CB000B7ED1 /* plist.h in Headers */,
BF4587FD2298D3AB00BD7491 /* sbservices.h in Headers */, BF4587FD2298D3AB00BD7491 /* sbservices.h in Headers */,
BF4588362298D3C100BD7491 /* debug.h in Headers */, BF4588362298D3C100BD7491 /* debug.h in Headers */,
BF4588202298D3AB00BD7491 /* mobile_image_mounter.h in Headers */, BF4588202298D3AB00BD7491 /* mobile_image_mounter.h in Headers */,
BF4588122298D3AB00BD7491 /* house_arrest.h in Headers */, BF4588122298D3AB00BD7491 /* house_arrest.h in Headers */,
BF45881F2298D3AB00BD7491 /* device_link_service.h in Headers */, BF45881F2298D3AB00BD7491 /* device_link_service.h in Headers */,
BFD52C1A22A1A9CB000B7ED1 /* time64_limits.h in Headers */,
BF45880E2298D3AB00BD7491 /* debugserver.h in Headers */, BF45880E2298D3AB00BD7491 /* debugserver.h in Headers */,
BF4588102298D3AB00BD7491 /* heartbeat.h in Headers */, BF4588102298D3AB00BD7491 /* heartbeat.h in Headers */,
BF4587FA2298D3AB00BD7491 /* diagnostics_relay.h in Headers */, BF4587FA2298D3AB00BD7491 /* diagnostics_relay.h in Headers */,
BFD52C1622A1A9CB000B7ED1 /* bytearray.h in Headers */,
BFD52C1222A1A9CB000B7ED1 /* base64.h in Headers */,
BF4588192298D3AB00BD7491 /* webinspector.h in Headers */, BF4588192298D3AB00BD7491 /* webinspector.h in Headers */,
BF4588342298D3C100BD7491 /* userpref.h in Headers */, BF4588342298D3C100BD7491 /* userpref.h in Headers */,
BF45880A2298D3AB00BD7491 /* screenshotr.h in Headers */, BF45880A2298D3AB00BD7491 /* screenshotr.h in Headers */,
BFD52C0B22A1A9CB000B7ED1 /* hashtable.h in Headers */,
BF4587FE2298D3AB00BD7491 /* mobilebackup2.h in Headers */, BF4587FE2298D3AB00BD7491 /* mobilebackup2.h in Headers */,
BFD52C0522A1A9CB000B7ED1 /* ptrarray.h in Headers */,
BF45881C2298D3AB00BD7491 /* afc.h in Headers */, BF45881C2298D3AB00BD7491 /* afc.h in Headers */,
BF45881A2298D3AB00BD7491 /* mobileactivation.h in Headers */, BF45881A2298D3AB00BD7491 /* mobileactivation.h in Headers */,
BF4588052298D3AB00BD7491 /* idevice.h in Headers */, BF4588052298D3AB00BD7491 /* idevice.h in Headers */,
@@ -1813,7 +1813,6 @@
BF4587F82298D3AB00BD7491 /* service.h in Headers */, BF4587F82298D3AB00BD7491 /* service.h in Headers */,
BF4588252298D3AB00BD7491 /* property_list_service.h in Headers */, BF4588252298D3AB00BD7491 /* property_list_service.h in Headers */,
BF4588132298D3AB00BD7491 /* notification_proxy.h in Headers */, BF4588132298D3AB00BD7491 /* notification_proxy.h in Headers */,
BFD52C1B22A1A9CB000B7ED1 /* time64.h in Headers */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -2209,7 +2208,6 @@
BFE60738231ADF49002B0E8E /* Settings.storyboard in Resources */, BFE60738231ADF49002B0E8E /* Settings.storyboard in Resources */,
D57DF638271E32F000677701 /* PatchApp.storyboard in Resources */, D57DF638271E32F000677701 /* PatchApp.storyboard in Resources */,
BFD2477A2284B9A700981D42 /* LaunchScreen.storyboard in Resources */, BFD2477A2284B9A700981D42 /* LaunchScreen.storyboard in Resources */,
BF44EEF3246B3A17002A52F2 /* AltBackup.ipa in Resources */,
BF770E6922BD57DD002A40FE /* Silence.m4a in Resources */, BF770E6922BD57DD002A40FE /* Silence.m4a in Resources */,
BFD247772284B9A700981D42 /* Assets.xcassets in Resources */, BFD247772284B9A700981D42 /* Assets.xcassets in Resources */,
1920B04F2924AC8300744F60 /* Settings.bundle in Resources */, 1920B04F2924AC8300744F60 /* Settings.bundle in Resources */,
@@ -2217,6 +2215,7 @@
BFB6B22423187A3D0022A802 /* NewsCollectionViewCell.xib in Resources */, BFB6B22423187A3D0022A802 /* NewsCollectionViewCell.xib in Resources */,
BFD247752284B9A500981D42 /* Main.storyboard in Resources */, BFD247752284B9A500981D42 /* Main.storyboard in Resources */,
BFDB5B2622EFBBEA00F74113 /* BrowseCollectionViewCell.xib in Resources */, BFDB5B2622EFBBEA00F74113 /* BrowseCollectionViewCell.xib in Resources */,
0E764E172ADFF5740043DD4E /* AltBackup.ipa in Resources */,
BFE6073C231AE1E7002B0E8E /* SettingsHeaderFooterView.xib in Resources */, BFE6073C231AE1E7002B0E8E /* SettingsHeaderFooterView.xib in Resources */,
BF29012F2318F6B100D88A45 /* AppBannerView.xib in Resources */, BF29012F2318F6B100D88A45 /* AppBannerView.xib in Resources */,
BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */, BFE6325A22A83BEB00F30809 /* Authentication.storyboard in Resources */,
@@ -2292,69 +2291,73 @@
isa = PBXSourcesBuildPhase; isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
0E1A1F912AE36A9700364CAD /* bytearray.c in Sources */,
0EA1666E2ADFE140003015C1 /* ptrarray.c in Sources */,
0EA1665B2ADFE0D2003015C1 /* out-limd.c in Sources */,
0EA166742ADFE140003015C1 /* Date.cpp in Sources */,
0EA166712ADFE140003015C1 /* Key.cpp in Sources */,
0EA1665C2ADFE0D2003015C1 /* out-default.c in Sources */,
0EA1666A2ADFE140003015C1 /* String.cpp in Sources */,
0EA166732ADFE140003015C1 /* Dictionary.cpp in Sources */,
0EA1665D2ADFE0D2003015C1 /* out-plutil.c in Sources */,
0EA1665E2ADFE0D2003015C1 /* oplist.c in Sources */,
0EA166702ADFE140003015C1 /* Node.cpp in Sources */,
0EA166752ADFE140003015C1 /* Real.cpp in Sources */,
0EA166762ADFE140003015C1 /* base64.c in Sources */,
0EA1666D2ADFE140003015C1 /* Data.cpp in Sources */,
BF45881B2298D3AB00BD7491 /* house_arrest.c in Sources */, BF45881B2298D3AB00BD7491 /* house_arrest.c in Sources */,
BFD52C0622A1A9CB000B7ED1 /* bplist.c in Sources */, 0EA1666F2ADFE140003015C1 /* hashtable.c in Sources */,
BF4588232298D3AB00BD7491 /* mobilesync.c in Sources */, BF4588232298D3AB00BD7491 /* mobilesync.c in Sources */,
BF4588072298D3AB00BD7491 /* afc.c in Sources */, BF4588072298D3AB00BD7491 /* afc.c in Sources */,
191E607D290B2EA5001A3B7C /* jsmn.c in Sources */,
191E607E290B2EA7001A3B7C /* jplist.c in Sources */,
BF4588082298D3AB00BD7491 /* mobile_image_mounter.c in Sources */, BF4588082298D3AB00BD7491 /* mobile_image_mounter.c in Sources */,
BFD52C1122A1A9CB000B7ED1 /* bytearray.c in Sources */,
BF4588022298D3AB00BD7491 /* file_relay.c in Sources */, BF4588022298D3AB00BD7491 /* file_relay.c in Sources */,
BF45880F2298D3AB00BD7491 /* debugserver.c in Sources */, BF45880F2298D3AB00BD7491 /* debugserver.c in Sources */,
0EA166792ADFE140003015C1 /* bplist.c in Sources */,
0EA166772ADFE140003015C1 /* jplist.c in Sources */,
BF4588162298D3AB00BD7491 /* restore.c in Sources */, BF4588162298D3AB00BD7491 /* restore.c in Sources */,
BFD52C0422A1A9CB000B7ED1 /* Dictionary.cpp in Sources */,
BFD52C0222A1A9CB000B7ED1 /* base64.c in Sources */,
BFD52C2022A1A9EC000B7ED1 /* node.c in Sources */, BFD52C2022A1A9EC000B7ED1 /* node.c in Sources */,
BF4588092298D3AB00BD7491 /* installation_proxy.c in Sources */, BF4588092298D3AB00BD7491 /* installation_proxy.c in Sources */,
0EA1666B2ADFE140003015C1 /* Boolean.cpp in Sources */,
0EA1667E2ADFE140003015C1 /* time64.c in Sources */,
BF4587FF2298D3AB00BD7491 /* heartbeat.c in Sources */, BF4587FF2298D3AB00BD7491 /* heartbeat.c in Sources */,
BF4588222298D3AB00BD7491 /* mobileactivation.c in Sources */, BF4588222298D3AB00BD7491 /* mobileactivation.c in Sources */,
BFD52C1822A1A9CB000B7ED1 /* Integer.cpp in Sources */,
BF4588212298D3AB00BD7491 /* idevice.c in Sources */, BF4588212298D3AB00BD7491 /* idevice.c in Sources */,
B343F885295F7C5D002B1159 /* tlv.c in Sources */, B343F885295F7C5D002B1159 /* tlv.c in Sources */,
BFD52C1C22A1A9CB000B7ED1 /* xplist.c in Sources */,
BF4587F92298D3AB00BD7491 /* diagnostics_relay.c in Sources */, BF4587F92298D3AB00BD7491 /* diagnostics_relay.c in Sources */,
B343F87D295F7C5D002B1159 /* cbuf.c in Sources */, B343F87D295F7C5D002B1159 /* cbuf.c in Sources */,
BF4588062298D3AB00BD7491 /* webinspector.c in Sources */, BF4588062298D3AB00BD7491 /* webinspector.c in Sources */,
BFD52C1722A1A9CB000B7ED1 /* Key.cpp in Sources */,
B343F883295F7C5D002B1159 /* thread.c in Sources */, B343F883295F7C5D002B1159 /* thread.c in Sources */,
BF45880D2298D3AB00BD7491 /* mobilebackup.c in Sources */, BF45880D2298D3AB00BD7491 /* mobilebackup.c in Sources */,
BFD52C0C22A1A9CB000B7ED1 /* Date.cpp in Sources */,
BFD52C0A22A1A9CB000B7ED1 /* plist.c in Sources */,
BFD52C1322A1A9CB000B7ED1 /* Data.cpp in Sources */,
BF45883A2298D3C100BD7491 /* debug.c in Sources */, BF45883A2298D3C100BD7491 /* debug.c in Sources */,
B343F881295F7C5D002B1159 /* termcolors.c in Sources */, B343F881295F7C5D002B1159 /* termcolors.c in Sources */,
0EA1667D2ADFE140003015C1 /* xplist.c in Sources */,
B343F87E295F7C5D002B1159 /* collection.c in Sources */, B343F87E295F7C5D002B1159 /* collection.c in Sources */,
BFD52C0F22A1A9CB000B7ED1 /* Real.cpp in Sources */,
B33FFBAA295F8F78002259E6 /* preboard.c in Sources */, B33FFBAA295F8F78002259E6 /* preboard.c in Sources */,
B33FFBAC295F8F98002259E6 /* companion_proxy.c in Sources */, B33FFBAC295F8F98002259E6 /* companion_proxy.c in Sources */,
BF4587FB2298D3AB00BD7491 /* notification_proxy.c in Sources */, BF4587FB2298D3AB00BD7491 /* notification_proxy.c in Sources */,
BF4588352298D3C100BD7491 /* userpref.c in Sources */, BF4588352298D3C100BD7491 /* userpref.c in Sources */,
BFD52C0122A1A9CB000B7ED1 /* ptrarray.c in Sources */, 0EA1667A2ADFE140003015C1 /* Uid.cpp in Sources */,
B343F87C295F7C5D002B1159 /* opack.c in Sources */, B343F87C295F7C5D002B1159 /* opack.c in Sources */,
BFD52C0E22A1A9CB000B7ED1 /* Boolean.cpp in Sources */,
BFD52C0822A1A9CB000B7ED1 /* time64.c in Sources */,
B343F884295F7C5D002B1159 /* utils.c in Sources */, B343F884295F7C5D002B1159 /* utils.c in Sources */,
BFD52C2122A1A9EC000B7ED1 /* node_list.c in Sources */, BFD52C2122A1A9EC000B7ED1 /* node_list.c in Sources */,
B343F87F295F7C5D002B1159 /* glue.c in Sources */, B343F87F295F7C5D002B1159 /* glue.c in Sources */,
BFD52C1422A1A9CB000B7ED1 /* Array.cpp in Sources */,
BF4588242298D3AB00BD7491 /* property_list_service.c in Sources */, BF4588242298D3AB00BD7491 /* property_list_service.c in Sources */,
BF45881E2298D3AB00BD7491 /* misagent.c in Sources */, BF45881E2298D3AB00BD7491 /* misagent.c in Sources */,
0EA166692ADFE140003015C1 /* Array.cpp in Sources */,
B343F880295F7C5D002B1159 /* socket.c in Sources */, B343F880295F7C5D002B1159 /* socket.c in Sources */,
BF4587FC2298D3AB00BD7491 /* sbservices.c in Sources */, BF4587FC2298D3AB00BD7491 /* sbservices.c in Sources */,
BFD52C1522A1A9CB000B7ED1 /* Node.cpp in Sources */, 0EA166782ADFE140003015C1 /* jsmn.c in Sources */,
BF4588142298D3AB00BD7491 /* device_link_service.c in Sources */, BF4588142298D3AB00BD7491 /* device_link_service.c in Sources */,
BF4588172298D3AB00BD7491 /* screenshotr.c in Sources */, BF4588172298D3AB00BD7491 /* screenshotr.c in Sources */,
BFD52C0D22A1A9CB000B7ED1 /* Uid.cpp in Sources */,
BFD52C0322A1A9CB000B7ED1 /* hashtable.c in Sources */,
BF4588432298D40000BD7491 /* libusbmuxd.c in Sources */, BF4588432298D40000BD7491 /* libusbmuxd.c in Sources */,
0EA1667B2ADFE140003015C1 /* Structure.cpp in Sources */,
0EA1666C2ADFE140003015C1 /* Integer.cpp in Sources */,
BF4588032298D3AB00BD7491 /* syslog_relay.c in Sources */, BF4588032298D3AB00BD7491 /* syslog_relay.c in Sources */,
BF4588272298D3AB00BD7491 /* service.c in Sources */, BF4588272298D3AB00BD7491 /* service.c in Sources */,
BFD52C0722A1A9CB000B7ED1 /* String.cpp in Sources */,
BF4588262298D3AB00BD7491 /* lockdown.c in Sources */, BF4588262298D3AB00BD7491 /* lockdown.c in Sources */,
BFD52C2222A1A9EC000B7ED1 /* cnary.c in Sources */, BFD52C2222A1A9EC000B7ED1 /* cnary.c in Sources */,
BF45880C2298D3AB00BD7491 /* mobilebackup2.c in Sources */, BF45880C2298D3AB00BD7491 /* mobilebackup2.c in Sources */,
BFD52C1922A1A9CB000B7ED1 /* Structure.cpp in Sources */, 0EA4B9BC2AE4A414009209CE /* plist.c in Sources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
}; };
@@ -2504,6 +2507,7 @@
BFD6B03322DFF20800B86064 /* MyAppsComponents.swift in Sources */, BFD6B03322DFF20800B86064 /* MyAppsComponents.swift in Sources */,
BF41B808233433C100C593A3 /* LoadingState.swift in Sources */, BF41B808233433C100C593A3 /* LoadingState.swift in Sources */,
BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */, BFF0B69A2322D7D0007A79E1 /* UIScreen+CompactHeight.swift in Sources */,
D5ACE84528E3B8450021CAB9 /* ClearAppCacheOperation.swift in Sources */,
D5F2F6A92720B7C20081CCF5 /* PatchViewController.swift in Sources */, D5F2F6A92720B7C20081CCF5 /* PatchViewController.swift in Sources */,
B39F16132918D7C5002E9404 /* Consts.swift in Sources */, B39F16132918D7C5002E9404 /* Consts.swift in Sources */,
BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */, BF8F69C222E659F700049BA1 /* AppContentViewController.swift in Sources */,
@@ -3221,9 +3225,10 @@
); );
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Dependencies/fragmentzip", "$(PROJECT_DIR)/Dependencies/libfragmentzip",
"$(PROJECT_DIR)/Dependencies/libcurl", "$(PROJECT_DIR)/Dependencies/libcurl",
); );
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)"; PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";
@@ -3255,9 +3260,10 @@
); );
LIBRARY_SEARCH_PATHS = ( LIBRARY_SEARCH_PATHS = (
"$(inherited)", "$(inherited)",
"$(PROJECT_DIR)/Dependencies/fragmentzip", "$(PROJECT_DIR)/Dependencies/libfragmentzip",
"$(PROJECT_DIR)/Dependencies/libcurl", "$(PROJECT_DIR)/Dependencies/libcurl",
); );
OTHER_LDFLAGS = "";
PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)"; PRODUCT_BUNDLE_IDENTIFIER = "$(PRODUCT_BUNDLE_IDENTIFIER)";
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = ""; PROVISIONING_PROFILE_SPECIFIER = "";

View File

@@ -6,7 +6,7 @@
"location" : "https://github.com/SideStore/AltSign", "location" : "https://github.com/SideStore/AltSign",
"state" : { "state" : {
"branch" : "master", "branch" : "master",
"revision" : "7e0e7edcf8fbc44ac1e35da3e9030a297aa18b84" "revision" : "cc6189f0f7cd8e5bd24943af9322e0ff9420e9f4"
} }
}, },
{ {
@@ -14,8 +14,17 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/microsoft/appcenter-sdk-apple.git", "location" : "https://github.com/microsoft/appcenter-sdk-apple.git",
"state" : { "state" : {
"revision" : "8354a50fe01a7e54e196d3b5493b5ab53dd5866a", "revision" : "b2dc99cfedead0bad4e6573d86c5228c89cff332",
"version" : "4.4.2" "version" : "4.4.3"
}
},
{
"identity" : "imobiledevice.swift",
"kind" : "remoteSourceControl",
"location" : "https://github.com/SideStore/iMobileDevice.swift",
"state" : {
"revision" : "74e481106dd155c0cd21bca6795fd9fe5f751654",
"version" : "1.0.5"
} }
}, },
{ {
@@ -50,8 +59,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/krzyzanowskim/OpenSSL", "location" : "https://github.com/krzyzanowskim/OpenSSL",
"state" : { "state" : {
"revision" : "033fcb41dac96b1b6effa945ca1f9ade002370b2", "revision" : "0faf71a188bcfdf0245cab42886b9b240ca71c52",
"version" : "1.1.1501" "version" : "1.1.2200"
} }
}, },
{ {
@@ -59,8 +68,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/microsoft/PLCrashReporter.git", "location" : "https://github.com/microsoft/PLCrashReporter.git",
"state" : { "state" : {
"revision" : "6b27393cad517c067dceea85fadf050e70c4ceaa", "revision" : "81cdec2b3827feb03286cb297f4c501a8eb98df1",
"version" : "1.10.1" "version" : "1.10.2"
} }
}, },
{ {
@@ -68,8 +77,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/SwiftPackageIndex/SemanticVersion.git", "location" : "https://github.com/SwiftPackageIndex/SemanticVersion.git",
"state" : { "state" : {
"revision" : "fc670910dc0903cc269b3d0b776cda5703979c4e", "revision" : "a70840d5fca686ae3bd2fcf8aecc5ded0bd4f125",
"version" : "0.3.5" "version" : "0.3.6"
} }
}, },
{ {
@@ -77,8 +86,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/sparkle-project/Sparkle.git", "location" : "https://github.com/sparkle-project/Sparkle.git",
"state" : { "state" : {
"revision" : "286edd1fa22505a9e54d170e9fd07d775ea233f2", "revision" : "f0ceaf5cc9f3f23daa0ccb6dcebd79fc96ccc7d9",
"version" : "2.1.0" "version" : "2.5.0"
} }
}, },
{ {
@@ -86,8 +95,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/daltoniam/Starscream.git", "location" : "https://github.com/daltoniam/Starscream.git",
"state" : { "state" : {
"revision" : "df8d82047f6654d8e4b655d1b1525c64e1059d21", "revision" : "ac6c0fc9da221873e01bd1a0d4818498a71eef33",
"version" : "4.0.4" "version" : "4.0.6"
} }
}, },
{ {

View File

@@ -217,8 +217,8 @@ final class AppViewController: UIViewController
self._shouldResetLayout = false self._shouldResetLayout = false
} }
let statusBarHeight = UIApplication.shared.statusBarFrame.height let statusBarHeight = self.view.window?.windowScene?.statusBarManager?.statusBarFrame.height ?? 0
let cornerRadius = self.contentViewControllerShadowView.layer.cornerRadius let cornerRadius = self.contentViewControllerShadowView.layer.cornerRadius
let inset = 12 as CGFloat let inset = 12 as CGFloat
@@ -323,7 +323,7 @@ final class AppViewController: UIViewController
self.backButtonContainerView.layer.cornerRadius = self.backButtonContainerView.bounds.midY self.backButtonContainerView.layer.cornerRadius = self.backButtonContainerView.bounds.midY
self.scrollView.scrollIndicatorInsets.top = statusBarHeight self.scrollView.verticalScrollIndicatorInsets.top = statusBarHeight
// Adjust content offset + size. // Adjust content offset + size.
let contentOffset = self.scrollView.contentOffset let contentOffset = self.scrollView.contentOffset

View File

@@ -91,13 +91,18 @@ private extension AppIDsViewController
cell.bannerView.buttonLabel.isHidden = false cell.bannerView.buttonLabel.isHidden = false
let currentDate = Date() let formatter = DateComponentsFormatter()
formatter.unitsStyle = .full
formatter.includesApproximationPhrase = false
formatter.includesTimeRemainingPhrase = false
formatter.allowedUnits = [.minute, .hour, .day]
formatter.maximumUnitCount = 1
let numberOfDays = expirationDate.numberOfCalendarDays(since: currentDate) cell.bannerView.button.setTitle(formatter.string(from: Date(), to: expirationDate)?.uppercased(), for: .normal)
let numberOfDaysText = (numberOfDays == 1) ? NSLocalizedString("1 day", comment: "") : String(format: NSLocalizedString("%@ days", comment: ""), NSNumber(value: numberOfDays))
cell.bannerView.button.setTitle(numberOfDaysText.uppercased(), for: .normal)
attributedAccessibilityLabel.mutableString.append(String(format: NSLocalizedString("Expires in %@.", comment: ""), numberOfDaysText) + " ") formatter.includesTimeRemainingPhrase = true
attributedAccessibilityLabel.mutableString.append((formatter.string(from: Date(), to: expirationDate) ?? NSLocalizedString("Unknown", comment: "")) + " ")
} }
else else
{ {
@@ -206,7 +211,7 @@ extension AppIDsViewController: UICollectionViewDelegateFlowLayout
**App IDs can't be deleted**, but they do expire after one week. SideStore will automatically renew App IDs for all active apps once they've expired. **App IDs can't be deleted**, but they do expire after one week. SideStore will automatically renew App IDs for all active apps once they've expired.
""", comment: "") """, comment: "")
let attributedText = NSAttributedString(markdownRepresentation: text, attributes: [.font: headerView.textLabel.font as Any]) let attributedText = NSAttributedString(markdownRepresentation: text)
headerView.textLabel.attributedText = attributedText headerView.textLabel.attributedText = attributedText
} }
else else

View File

@@ -8,6 +8,7 @@
import UIKit import UIKit
import minimuxer
import AltStoreCore import AltStoreCore
import Roxas import Roxas
@@ -264,7 +265,13 @@ private extension BrowseViewController
previousProgress?.cancel() previousProgress?.cancel()
return return
} }
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
_ = AppManager.shared.install(app, presentingViewController: self) { (result) in _ = AppManager.shared.install(app, presentingViewController: self) { (result) in
DispatchQueue.main.async { DispatchQueue.main.async {
switch result switch result

View File

@@ -22,7 +22,7 @@ final class CollapsingTextView: UITextView
} }
} }
var lineSpacing: CGFloat = 2 { var lineSpacing: Double = 2 {
didSet { didSet {
self.setNeedsLayout() self.setNeedsLayout()
} }
@@ -34,7 +34,19 @@ final class CollapsingTextView: UITextView
{ {
super.awakeFromNib() super.awakeFromNib()
self.layoutManager.delegate = self self.initialize()
}
private func initialize()
{
if #available(iOS 16, *)
{
self.updateText()
}
else
{
self.layoutManager.delegate = self
}
self.textContainerInset = .zero self.textContainerInset = .zero
self.textContainer.lineFragmentPadding = 0 self.textContainer.lineFragmentPadding = 0
@@ -108,6 +120,25 @@ private extension CollapsingTextView
{ {
self.isCollapsed.toggle() self.isCollapsed.toggle()
} }
@available(iOS 16, *)
func updateText()
{
do
{
let style = NSMutableParagraphStyle()
style.lineSpacing = self.lineSpacing
var attributedText = try AttributedString(self.attributedText, including: \.uiKit)
attributedText[AttributeScopes.UIKitAttributes.ParagraphStyleAttribute.self] = style
self.attributedText = NSAttributedString(attributedText)
}
catch
{
print("[ALTLog] Failed to update CollapsingTextView line spacing:", error)
}
}
} }
extension CollapsingTextView: NSLayoutManagerDelegate extension CollapsingTextView: NSLayoutManagerDelegate

View File

@@ -8,6 +8,12 @@
import UIKit import UIKit
extension PillButton
{
static let minimumSize = CGSize(width: 77, height: 31)
static let contentInsets = NSDirectionalEdgeInsets(top: 7, leading: 13, bottom: 7, trailing: 13)
}
final class PillButton: UIButton final class PillButton: UIButton
{ {
override var accessibilityValue: String? { override var accessibilityValue: String? {
@@ -70,9 +76,7 @@ final class PillButton: UIButton
}() }()
override var intrinsicContentSize: CGSize { override var intrinsicContentSize: CGSize {
var size = super.intrinsicContentSize let size = self.sizeThatFits(CGSize(width: Double.infinity, height: .infinity))
size.width += 26
size.height += 3
return size return size
} }
@@ -88,6 +92,8 @@ final class PillButton: UIButton
self.layer.masksToBounds = true self.layer.masksToBounds = true
self.accessibilityTraits.formUnion([.updatesFrequently, .button]) self.accessibilityTraits.formUnion([.updatesFrequently, .button])
self.contentEdgeInsets = UIEdgeInsets(top: Self.contentInsets.top, left: Self.contentInsets.leading, bottom: Self.contentInsets.bottom, right: Self.contentInsets.trailing)
self.activityIndicatorView.style = .medium self.activityIndicatorView.style = .medium
self.activityIndicatorView.isUserInteractionEnabled = false self.activityIndicatorView.isUserInteractionEnabled = false
@@ -119,6 +125,15 @@ final class PillButton: UIButton
self.update() self.update()
} }
override func sizeThatFits(_ size: CGSize) -> CGSize
{
var size = super.sizeThatFits(size)
size.width = max(size.width, PillButton.minimumSize.width)
size.height = max(size.height, PillButton.minimumSize.height)
return size
}
} }
private extension PillButton private extension PillButton

View File

@@ -14,7 +14,7 @@
<key>ALTPairingFile</key> <key>ALTPairingFile</key>
<string>&lt;insert pairing file here&gt;</string> <string>&lt;insert pairing file here&gt;</string>
<key>ALTAnisetteURL</key> <key>ALTAnisetteURL</key>
<string>http://ani.sidestore.io:6969</string> <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>

View File

@@ -81,7 +81,7 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
} else { } else {
// Show an alert explaining the pairing file // Show an alert explaining the pairing file
// Create new Alert // Create new Alert
let dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://wiki.sidestore.io/guides/install#pairing-process", preferredStyle: .alert) let dialogMessage = UIAlertController(title: "Pairing File", message: "Select the pairing file for your device. For more information, go to https://wiki.sidestore.io/guides/getting-started/#pairing-file", preferredStyle: .alert)
// Create OK button with action handler // Create OK button with action handler
let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in let ok = UIAlertAction(title: "OK", style: .default, handler: { (action) -> Void in
@@ -155,7 +155,12 @@ final class LaunchViewController: RSTLaunchViewController, UIDocumentPickerDeleg
try! FileManager.default.removeItem(at: FileManager.default.documentsDirectory.appendingPathComponent("\(pairingFileName)")) try! FileManager.default.removeItem(at: FileManager.default.documentsDirectory.appendingPathComponent("\(pairingFileName)"))
displayError("minimuxer failed to start, please restart SideStore. \((error as? LocalizedError)?.failureReason ?? "UNKNOWN ERROR!!!!!! REPORT TO GITHUB ISSUES!")") displayError("minimuxer failed to start, please restart SideStore. \((error as? LocalizedError)?.failureReason ?? "UNKNOWN ERROR!!!!!! REPORT TO GITHUB ISSUES!")")
} }
start_auto_mounter(documentsDirectory) if #available(iOS 17, *) {
// TODO: iOS 17 and above have a new JIT implementation that is completely broken in SideStore :(
}
else {
start_auto_mounter(documentsDirectory)
}
} }
} }

View File

@@ -307,6 +307,16 @@ extension AppManager
presentingViewController.present(alertController, animated: true, completion: nil) presentingViewController.present(alertController, animated: true, completion: nil)
} }
} }
func clearAppCache(completion: @escaping (Result<Void, Error>) -> Void)
{
let clearAppCacheOperation = ClearAppCacheOperation()
clearAppCacheOperation.resultHandler = { result in
completion(result)
}
self.run([clearAppCacheOperation], context: nil)
}
} }
extension AppManager extension AppManager
@@ -754,6 +764,12 @@ extension AppManager
let progress = self.refreshProgress[app.bundleIdentifier] let progress = self.refreshProgress[app.bundleIdentifier]
return progress return progress
} }
func isActivelyManagingApp(withBundleID bundleID: String) -> Bool
{
let isActivelyManaging = self.installationProgress.keys.contains(bundleID) || self.refreshProgress.keys.contains(bundleID)
return isActivelyManaging
}
} }
extension AppManager extension AppManager
@@ -808,12 +824,6 @@ private extension AppManager
} }
} }
func isActivelyManagingApp(withBundleID bundleID: String) -> Bool
{
let isActivelyManaging = self.installationProgress.keys.contains(bundleID) || self.refreshProgress.keys.contains(bundleID)
return isActivelyManaging
}
@discardableResult @discardableResult
private func perform(_ operations: [AppOperation], presentingViewController: UIViewController?, group: RefreshGroup) -> RefreshGroup private func perform(_ operations: [AppOperation], presentingViewController: UIViewController?, group: RefreshGroup) -> RefreshGroup
{ {
@@ -1027,6 +1037,32 @@ private extension AppManager
verifyOperation.addDependency(downloadOperation) verifyOperation.addDependency(downloadOperation)
/* Refresh Anisette Data */
let refreshAnisetteDataOperation = FetchAnisetteDataOperation(context: group.context)
refreshAnisetteDataOperation.resultHandler = { (result) in
switch result
{
case .failure(let error): context.error = error
case .success(let anisetteData): group.context.session?.anisetteData = anisetteData
}
}
refreshAnisetteDataOperation.addDependency(verifyOperation)
/* Fetch Provisioning Profiles */
let fetchProvisioningProfilesOperation = FetchProvisioningProfilesOperation(context: context)
fetchProvisioningProfilesOperation.additionalEntitlements = additionalEntitlements
fetchProvisioningProfilesOperation.resultHandler = { (result) in
switch result
{
case .failure(let error): context.error = error
case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles
}
}
fetchProvisioningProfilesOperation.addDependency(refreshAnisetteDataOperation)
progress.addChild(fetchProvisioningProfilesOperation.progress, withPendingUnitCount: 5)
/* Deactivate Apps (if necessary) */ /* Deactivate Apps (if necessary) */
let deactivateAppsOperation = RSTAsyncBlockOperation { [weak self] (operation) in let deactivateAppsOperation = RSTAsyncBlockOperation { [weak self] (operation) in
do do
@@ -1042,6 +1078,12 @@ private extension AppManager
{ {
throw error throw error
} }
guard let profiles = context.provisioningProfiles else { throw OperationError.invalidParameters }
if !profiles.contains(where: { $1.isFreeProvisioningProfile == true }) {
operation.finish()
return
}
guard let app = context.app, let presentingViewController = context.authenticatedContext.presentingViewController else { throw OperationError.invalidParameters } guard let app = context.app, let presentingViewController = context.authenticatedContext.presentingViewController else { throw OperationError.invalidParameters }
@@ -1061,7 +1103,7 @@ private extension AppManager
operation.finish() operation.finish()
} }
} }
deactivateAppsOperation.addDependency(verifyOperation) deactivateAppsOperation.addDependency(fetchProvisioningProfilesOperation)
/* Patch App */ /* Patch App */
@@ -1136,32 +1178,6 @@ private extension AppManager
patchAppOperation.addDependency(deactivateAppsOperation) patchAppOperation.addDependency(deactivateAppsOperation)
/* Refresh Anisette Data */
let refreshAnisetteDataOperation = FetchAnisetteDataOperation(context: group.context)
refreshAnisetteDataOperation.resultHandler = { (result) in
switch result
{
case .failure(let error): context.error = error
case .success(let anisetteData): group.context.session?.anisetteData = anisetteData
}
}
refreshAnisetteDataOperation.addDependency(patchAppOperation)
/* Fetch Provisioning Profiles */
let fetchProvisioningProfilesOperation = FetchProvisioningProfilesOperation(context: context)
fetchProvisioningProfilesOperation.additionalEntitlements = additionalEntitlements
fetchProvisioningProfilesOperation.resultHandler = { (result) in
switch result
{
case .failure(let error): context.error = error
case .success(let provisioningProfiles): context.provisioningProfiles = provisioningProfiles
}
}
fetchProvisioningProfilesOperation.addDependency(refreshAnisetteDataOperation)
progress.addChild(fetchProvisioningProfilesOperation.progress, withPendingUnitCount: 5)
/* Resign */ /* Resign */
let resignAppOperation = ResignAppOperation(context: context) let resignAppOperation = ResignAppOperation(context: context)
resignAppOperation.resultHandler = { (result) in resignAppOperation.resultHandler = { (result) in
@@ -1171,7 +1187,7 @@ private extension AppManager
case .success(let resignedApp): context.resignedApp = resignedApp case .success(let resignedApp): context.resignedApp = resignedApp
} }
} }
resignAppOperation.addDependency(fetchProvisioningProfilesOperation) resignAppOperation.addDependency(patchAppOperation)
progress.addChild(resignAppOperation.progress, withPendingUnitCount: 20) progress.addChild(resignAppOperation.progress, withPendingUnitCount: 20)
@@ -1214,7 +1230,7 @@ private extension AppManager
progress.addChild(installOperation.progress, withPendingUnitCount: 30) progress.addChild(installOperation.progress, withPendingUnitCount: 30)
installOperation.addDependency(sendAppOperation) installOperation.addDependency(sendAppOperation)
let operations = [downloadOperation, verifyOperation, deactivateAppsOperation, patchAppOperation, refreshAnisetteDataOperation, fetchProvisioningProfilesOperation, resignAppOperation, sendAppOperation, installOperation] let operations = [downloadOperation, verifyOperation, refreshAnisetteDataOperation, fetchProvisioningProfilesOperation, deactivateAppsOperation, patchAppOperation, resignAppOperation, sendAppOperation, installOperation]
group.add(operations) group.add(operations)
self.run(operations, context: group.context) self.run(operations, context: group.context)

View File

@@ -10,10 +10,12 @@ import UIKit
import MobileCoreServices import MobileCoreServices
import Intents import Intents
import Combine import Combine
import UniformTypeIdentifiers
import AltStoreCore import AltStoreCore
import AltSign import AltSign
import Roxas import Roxas
import minimuxer
import Nuke import Nuke
@@ -327,21 +329,25 @@ private extension MyAppsViewController
let currentDate = Date() let currentDate = Date()
let numberOfDays = installedApp.expirationDate.numberOfCalendarDays(since: currentDate) let numberOfDays = installedApp.expirationDate.numberOfCalendarDays(since: currentDate)
let numberOfDaysText: String
if numberOfDays == 1 let formatter = DateComponentsFormatter()
{ formatter.unitsStyle = .full
numberOfDaysText = NSLocalizedString("1 day", comment: "") formatter.includesApproximationPhrase = false
} formatter.includesTimeRemainingPhrase = false
else
{ formatter.allowedUnits = [.day, .hour, .minute]
numberOfDaysText = String(format: NSLocalizedString("%@ days", comment: ""), NSNumber(value: numberOfDays))
} formatter.maximumUnitCount = 1
cell.bannerView.button.setTitle(formatter.string(from: currentDate, to: installedApp.expirationDate)?.uppercased(), for: .normal)
cell.bannerView.button.setTitle(numberOfDaysText.uppercased(), for: .normal)
cell.bannerView.button.accessibilityLabel = String(format: NSLocalizedString("Refresh %@", comment: ""), installedApp.name) cell.bannerView.button.accessibilityLabel = String(format: NSLocalizedString("Refresh %@", comment: ""), installedApp.name)
cell.bannerView.accessibilityLabel? += ". " + String(format: NSLocalizedString("Expires in %@", comment: ""), numberOfDaysText) formatter.includesTimeRemainingPhrase = true
cell.bannerView.accessibilityLabel? += ". " + (formatter.string(from: currentDate, to: installedApp.expirationDate) ?? NSLocalizedString("Unknown", comment: "")) + " "
// Make sure refresh button is correct size. // Make sure refresh button is correct size.
cell.layoutIfNeeded() cell.layoutIfNeeded()
@@ -639,6 +645,12 @@ private extension MyAppsViewController
@IBAction func refreshAllApps(_ sender: UIBarButtonItem) @IBAction func refreshAllApps(_ sender: UIBarButtonItem)
{ {
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
self.isRefreshingAllApps = true self.isRefreshingAllApps = true
self.collectionView.collectionViewLayout.invalidateLayout() self.collectionView.collectionViewLayout.invalidateLayout()
@@ -701,18 +713,15 @@ private extension MyAppsViewController
@IBAction func sideloadApp(_ sender: UIBarButtonItem) @IBAction func sideloadApp(_ sender: UIBarButtonItem)
{ {
let supportedTypes: [String] if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
if let types = UTTypeCreateAllIdentifiersForTag(kUTTagClassFilenameExtension, "ipa" as CFString, nil)?.takeRetainedValue() toastView.show(in: self)
{ return
supportedTypes = (types as NSArray).map { $0 as! String }
}
else
{
supportedTypes = ["com.apple.itunes.ipa"] // Declared by the system.
} }
let supportedTypes = UTType.types(tag: "ipa", tagClass: .filenameExtension, conformingTo: nil)
let documentPickerViewController = UIDocumentPickerViewController(documentTypes: supportedTypes, in: .import) let documentPickerViewController = UIDocumentPickerViewController(forOpeningContentTypes: supportedTypes, asCopy: true)
documentPickerViewController.delegate = self documentPickerViewController.delegate = self
self.present(documentPickerViewController, animated: true, completion: nil) self.present(documentPickerViewController, animated: true, completion: nil)
} }
@@ -1014,6 +1023,12 @@ private extension MyAppsViewController
func refresh(_ installedApp: InstalledApp) func refresh(_ installedApp: InstalledApp)
{ {
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
let previousProgress = AppManager.shared.refreshProgress(for: installedApp) let previousProgress = AppManager.shared.refreshProgress(for: installedApp)
guard previousProgress == nil else { guard previousProgress == nil else {
previousProgress?.cancel() previousProgress?.cancel()
@@ -1035,6 +1050,12 @@ private extension MyAppsViewController
func activate(_ installedApp: InstalledApp) func activate(_ installedApp: InstalledApp)
{ {
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
func finish(_ result: Result<InstalledApp, Error>) func finish(_ result: Result<InstalledApp, Error>)
{ {
do do
@@ -1111,6 +1132,11 @@ private extension MyAppsViewController
func deactivate(_ installedApp: InstalledApp, completionHandler: ((Result<InstalledApp, Error>) -> Void)? = nil) func deactivate(_ installedApp: InstalledApp, completionHandler: ((Result<InstalledApp, Error>) -> Void)? = nil)
{ {
guard installedApp.isActive else { return } guard installedApp.isActive else { return }
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
installedApp.isActive = false installedApp.isActive = false
AppManager.shared.deactivate(installedApp, presentingViewController: self) { (result) in AppManager.shared.deactivate(installedApp, presentingViewController: self) { (result) in
@@ -1172,6 +1198,11 @@ private extension MyAppsViewController
func backup(_ installedApp: InstalledApp) func backup(_ installedApp: InstalledApp)
{ {
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
let title = NSLocalizedString("Start Backup?", comment: "") let title = NSLocalizedString("Start Backup?", comment: "")
let message = NSLocalizedString("This will replace any previous backups. Please leave SideStore open until the backup is complete.", comment: "") let message = NSLocalizedString("This will replace any previous backups. Please leave SideStore open until the backup is complete.", comment: "")
@@ -1211,6 +1242,11 @@ private extension MyAppsViewController
func restore(_ installedApp: InstalledApp) func restore(_ installedApp: InstalledApp)
{ {
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
let message = String(format: NSLocalizedString("This will replace all data you currently have in %@.", comment: ""), installedApp.name) let message = String(format: NSLocalizedString("This will replace all data you currently have in %@.", comment: ""), installedApp.name)
let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to restore this backup?", comment: ""), message: message, preferredStyle: .actionSheet) let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to restore this backup?", comment: ""), message: message, preferredStyle: .actionSheet)
alertController.addAction(.cancel) alertController.addAction(.cancel)
@@ -1246,8 +1282,11 @@ private extension MyAppsViewController
{ {
guard let backupURL = FileManager.default.backupDirectoryURL(for: installedApp) else { return } guard let backupURL = FileManager.default.backupDirectoryURL(for: installedApp) else { return }
let documentPicker = UIDocumentPickerViewController(url: backupURL, in: .exportToService) let documentPicker = UIDocumentPickerViewController(forExporting: [backupURL], asCopy: true)
documentPicker.delegate = self
// Don't set delegate to avoid conflicting with import callbacks.
// documentPicker.delegate = self
self.present(documentPicker, animated: true, completion: nil) self.present(documentPicker, animated: true, completion: nil)
} }
@@ -1311,6 +1350,16 @@ private extension MyAppsViewController
@available(iOS 14, *) @available(iOS 14, *)
func enableJIT(for installedApp: InstalledApp) func enableJIT(for installedApp: InstalledApp)
{ {
if #available(iOS 17, *) {
let toastView = ToastView(error: OperationError.tooNewError)
toastView.show(in: self)
return
}
if !minimuxer.ready() {
let toastView = ToastView(error: MinimuxerError.NoConnection)
toastView.show(in: self)
return
}
AppManager.shared.enableJIT(for: installedApp) { result in AppManager.shared.enableJIT(for: installedApp) { result in
DispatchQueue.main.async { DispatchQueue.main.async {
switch result switch result
@@ -1318,7 +1367,7 @@ private extension MyAppsViewController
case .success: break case .success: break
case .failure(let error): case .failure(let error):
let toastView = ToastView(error: error) let toastView = ToastView(error: error)
toastView.show(in: self) toastView.show(in: self.navigationController?.view ?? self.view, duration: 5)
} }
} }
} }
@@ -1465,7 +1514,7 @@ extension MyAppsViewController
let registeredAppIDs = team.appIDs.count let registeredAppIDs = team.appIDs.count
let maximumAppIDCount = 10 let maximumAppIDCount = 10
let remainingAppIDs = max(maximumAppIDCount - registeredAppIDs, 0) let remainingAppIDs = maximumAppIDCount - registeredAppIDs
if remainingAppIDs == 1 if remainingAppIDs == 1
{ {
@@ -1476,7 +1525,7 @@ extension MyAppsViewController
footerView.textLabel.text = String(format: NSLocalizedString("%@ App IDs Remaining", comment: ""), NSNumber(value: remainingAppIDs)) footerView.textLabel.text = String(format: NSLocalizedString("%@ App IDs Remaining", comment: ""), NSNumber(value: remainingAppIDs))
} }
footerView.textLabel.isHidden = false footerView.textLabel.isHidden = remainingAppIDs < 0
case .individual, .organization, .unknown: footerView.textLabel.isHidden = true case .individual, .organization, .unknown: footerView.textLabel.isHidden = true
@unknown default: break @unknown default: break
@@ -2050,15 +2099,8 @@ extension MyAppsViewController: UIDocumentPickerDelegate
{ {
guard let fileURL = urls.first else { return } guard let fileURL = urls.first else { return }
switch controller.documentPickerMode self.sideloadApp(at: fileURL) { (result) in
{ print("Sideloaded app at \(fileURL) with result:", result)
case .import, .open:
self.sideloadApp(at: fileURL) { (result) in
print("Sideloaded app at \(fileURL) with result:", result)
}
case .exportToService, .moveToService: break
@unknown default: break
} }
} }
} }

View File

@@ -426,6 +426,10 @@ extension NewsViewController: UICollectionViewDelegateFlowLayout
return previousSize return previousSize
} }
// Take layout margins into account.
self.prototypeCell.layoutMargins.left = self.view.layoutMargins.left
self.prototypeCell.layoutMargins.right = self.view.layoutMargins.right
let widthConstraint = self.prototypeCell.contentView.widthAnchor.constraint(equalToConstant: collectionView.bounds.width) let widthConstraint = self.prototypeCell.contentView.widthAnchor.constraint(equalToConstant: collectionView.bounds.width)
NSLayoutConstraint.activate([widthConstraint]) NSLayoutConstraint.activate([widthConstraint])
defer { NSLayoutConstraint.deactivate([widthConstraint]) } defer { NSLayoutConstraint.deactivate([widthConstraint]) }

View File

@@ -12,6 +12,7 @@ import Network
import AltStoreCore import AltStoreCore
import AltSign import AltSign
import minimuxer
enum AuthenticationError: LocalizedError enum AuthenticationError: LocalizedError
{ {
@@ -593,7 +594,7 @@ private extension AuthenticationOperation
func registerCurrentDevice(for team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result<ALTDevice, Error>) -> Void) func registerCurrentDevice(for team: ALTTeam, session: ALTAppleAPISession, completionHandler: @escaping (Result<ALTDevice, Error>) -> Void)
{ {
guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else { guard let udid = fetch_udid()?.toString() else {
return completionHandler(.failure(OperationError.unknownUDID)) return completionHandler(.failure(OperationError.unknownUDID))
} }

View File

@@ -105,8 +105,13 @@ final class BackgroundRefreshAppsOperation: ResultOperation<[String: Result<Inst
} catch { } catch {
self.finish(.failure(error)) self.finish(.failure(error))
} }
start_auto_mounter(documentsDirectory) if #available(iOS 17, *) {
// TODO: iOS 17 and above have a new JIT implementation that is completely broken in SideStore :(
}
else {
start_auto_mounter(documentsDirectory)
}
self.managedObjectContext.perform { self.managedObjectContext.perform {
print("Apps to refresh:", self.installedApps.map(\.bundleIdentifier)) print("Apps to refresh:", self.installedApps.map(\.bundleIdentifier))

View File

@@ -29,6 +29,9 @@ class BackupAppOperation: ResultOperation<Void>
private var appName: String? private var appName: String?
private var timeoutTimer: Timer? private var timeoutTimer: Timer?
private weak var applicationWillReturnObserver: NSObjectProtocol?
private weak var backupResponseObserver: NSObjectProtocol?
init(action: Action, context: InstallAppOperationContext) init(action: Action, context: InstallAppOperationContext)
{ {
self.action = action self.action = action
@@ -43,10 +46,7 @@ class BackupAppOperation: ResultOperation<Void>
do do
{ {
if let error = self.context.error if let error = self.context.error { throw error }
{
throw error
}
guard let installedApp = self.context.installedApp, let context = installedApp.managedObjectContext else { throw OperationError.invalidParameters } guard let installedApp = self.context.installedApp, let context = installedApp.managedObjectContext else { throw OperationError.invalidParameters }
context.perform { context.perform {
@@ -55,9 +55,8 @@ class BackupAppOperation: ResultOperation<Void>
let appName = installedApp.name let appName = installedApp.name
self.appName = appName self.appName = appName
guard let altstoreApp = InstalledApp.fetchAltStore(in: context) else { throw OperationError.appNotFound } let altstoreOpenURL = URL(string: "sidestore://")!
let altstoreOpenURL = altstoreApp.openAppURL
var returnURLComponents = URLComponents(url: altstoreOpenURL, resolvingAgainstBaseURL: false) var returnURLComponents = URLComponents(url: altstoreOpenURL, resolvingAgainstBaseURL: false)
returnURLComponents?.host = "appBackupResponse" returnURLComponents?.host = "appBackupResponse"
guard let returnURL = returnURLComponents?.url else { throw OperationError.openAppFailed(name: appName) } guard let returnURL = returnURLComponents?.url else { throw OperationError.openAppFailed(name: appName) }
@@ -153,8 +152,11 @@ private extension BackupAppOperation
{ {
func registerObservers() func registerObservers()
{ {
var applicationWillReturnObserver: NSObjectProtocol! self.applicationWillReturnObserver = NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main) { [weak self] (notification) in
applicationWillReturnObserver = NotificationCenter.default.addObserver(forName: UIApplication.willEnterForegroundNotification, object: nil, queue: .main) { [weak self] (notification) in defer {
self?.applicationWillReturnObserver.map { NotificationCenter.default.removeObserver($0) }
}
guard let self = self, !self.isFinished else { return } guard let self = self, !self.isFinished else { return }
self.timeoutTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { [weak self] (timer) in self.timeoutTimer = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { [weak self] (timer) in
@@ -166,18 +168,17 @@ private extension BackupAppOperation
self.finish(.failure(OperationError.timedOut)) self.finish(.failure(OperationError.timedOut))
} }
} }
NotificationCenter.default.removeObserver(applicationWillReturnObserver!)
} }
var backupResponseObserver: NSObjectProtocol! self.backupResponseObserver = NotificationCenter.default.addObserver(forName: AppDelegate.appBackupDidFinish, object: nil, queue: nil) { [weak self] (notification) in
backupResponseObserver = NotificationCenter.default.addObserver(forName: AppDelegate.appBackupDidFinish, object: nil, queue: nil) { [weak self] (notification) in defer {
self?.backupResponseObserver.map { NotificationCenter.default.removeObserver($0) }
}
self?.timeoutTimer?.invalidate() self?.timeoutTimer?.invalidate()
let result = notification.userInfo?[AppDelegate.appBackupResultKey] as? Result<Void, Error> ?? .failure(OperationError.unknownResult) let result = notification.userInfo?[AppDelegate.appBackupResultKey] as? Result<Void, Error> ?? .failure(OperationError.unknownResult)
self?.finish(result) self?.finish(result)
NotificationCenter.default.removeObserver(backupResponseObserver!)
} }
} }
} }

View File

@@ -0,0 +1,208 @@
//
// ClearAppCacheOperation.swift
// AltStore
//
// Created by Riley Testut on 9/27/22.
// Copyright © 2022 Riley Testut. All rights reserved.
//
import Foundation
import AltStoreCore
/*
struct BatchError: ALTLocalizedError
{
enum Code: Int, ALTErrorCode
{
typealias Error = BatchError
case batchError
}
var code: Code = .batchError
var underlyingErrors: [Error]
var errorTitle: String?
var errorFailure: String?
init(errors: [Error])
{
self.underlyingErrors = errors
}
var errorFailureReason: String {
guard !self.underlyingErrors.isEmpty else { return NSLocalizedString("An unknown error occured.", comment: "") }
let errorMessages = self.underlyingErrors.map { $0.localizedDescription }
let message = errorMessages.joined(separator: "\n\n")
return message
}
}
*/
@objc(ClearAppCacheOperation)
class ClearAppCacheOperation: ResultOperation<Void>
{
private let coordinator = NSFileCoordinator()
private let coordinatorQueue = OperationQueue()
override init()
{
self.coordinatorQueue.name = "AltStore - ClearAppCacheOperation Queue"
}
override func main()
{
super.main()
var allErrors = [Error]()
self.clearTemporaryDirectory { result in
switch result
{
//case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors)
case .failure(let error): allErrors.append(error)
case .success: break
}
self.removeUninstalledAppBackupDirectories { result in
switch result
{
//case .failure(let batchError as BatchError): allErrors.append(contentsOf: batchError.underlyingErrors)
case .failure(let error): allErrors.append(error)
case .success: break
}
if allErrors.isEmpty
{
self.finish(.success(()))
}
else
{
self.finish(.failure(OperationError.cacheClearError(errors: allErrors.map({ error in
return error.localizedDescription
}))))
}
}
}
}
}
private extension ClearAppCacheOperation
{
func clearTemporaryDirectory(completion: @escaping (Result<Void, Error>) -> Void)
{
let intent = NSFileAccessIntent.writingIntent(with: FileManager.default.temporaryDirectory, options: [.forDeleting])
self.coordinator.coordinate(with: [intent], queue: self.coordinatorQueue) { (error) in
do
{
if let error
{
throw error
}
let fileURLs = try FileManager.default.contentsOfDirectory(at: intent.url,
includingPropertiesForKeys: [],
options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles])
var errors = [Error]()
for fileURL in fileURLs
{
do
{
print("[ALTLog] Removing item from temporary directory:", fileURL.lastPathComponent)
try FileManager.default.removeItem(at: fileURL)
}
catch
{
print("[ALTLog] Failed to remove \(fileURL.lastPathComponent) from temporary directory.", error)
errors.append(error)
}
}
if !errors.isEmpty
{
completion(.failure(OperationError.cacheClearError(errors: errors.map({ error in
return error.localizedDescription
}))))
}
else
{
completion(.success(()))
}
}
catch
{
completion(.failure(error))
}
}
}
func removeUninstalledAppBackupDirectories(completion: @escaping (Result<Void, Error>) -> Void)
{
guard let backupsDirectory = FileManager.default.appBackupsDirectory else { return completion(.failure(OperationError.missingAppGroup)) }
DatabaseManager.shared.persistentContainer.performBackgroundTask { context in
let installedAppBundleIDs = Set(InstalledApp.all(in: context).map { $0.bundleIdentifier })
let intent = NSFileAccessIntent.writingIntent(with: backupsDirectory, options: [.forDeleting])
self.coordinator.coordinate(with: [intent], queue: self.coordinatorQueue) { (error) in
do
{
if let error
{
throw error
}
var isDirectory: ObjCBool = false
guard FileManager.default.fileExists(atPath: intent.url.path, isDirectory: &isDirectory), isDirectory.boolValue else {
completion(.success(()))
return
}
let fileURLs = try FileManager.default.contentsOfDirectory(at: intent.url,
includingPropertiesForKeys: [.isDirectoryKey, .nameKey],
options: [.skipsSubdirectoryDescendants, .skipsHiddenFiles])
var errors = [Error]()
for backupDirectory in fileURLs
{
do
{
let resourceValues = try backupDirectory.resourceValues(forKeys: [.isDirectoryKey, .nameKey])
guard let isDirectory = resourceValues.isDirectory, let bundleID = resourceValues.name else { continue }
if isDirectory && !installedAppBundleIDs.contains(bundleID) && !AppManager.shared.isActivelyManagingApp(withBundleID: bundleID)
{
print("[ALTLog] Removing backup directory for uninstalled app:", bundleID)
try FileManager.default.removeItem(at: backupDirectory)
}
}
catch
{
print("[ALTLog] Failed to remove app backup directory:", error)
errors.append(error)
}
}
if !errors.isEmpty
{
completion(.failure(OperationError.cacheClearError(errors: errors.map({ error in
return error.localizedDescription
}))))
}
else
{
completion(.success(()))
}
}
catch
{
print("[ALTLog] Failed to remove app backup directory:", error)
completion(.failure(error))
}
}
}
}
}

View File

@@ -31,11 +31,7 @@ final class DeactivateAppOperation: ResultOperation<InstalledApp>
{ {
super.main() super.main()
if let error = self.context.error if let error = self.context.error { return self.finish(.failure(error)) }
{
self.finish(.failure(error))
return
}
DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in
let installedApp = context.object(with: self.app.objectID) as! InstalledApp let installedApp = context.object(with: self.app.objectID) as! InstalledApp
@@ -45,14 +41,14 @@ final class DeactivateAppOperation: ResultOperation<InstalledApp>
for profile in allIdentifiers { for profile in allIdentifiers {
do { do {
try remove_provisioning_profile(profile) try remove_provisioning_profile(profile)
self.progress.completedUnitCount += 1
installedApp.isActive = false
self.finish(.success(installedApp))
break
} catch { } catch {
return self.finish(.failure(error)) self.finish(.failure(error))
} }
} }
self.progress.completedUnitCount += 1
installedApp.isActive = false
self.finish(.success(installedApp))
} }
} }
} }

View File

@@ -45,13 +45,19 @@ final class EnableJITOperation<Context: EnableJITContext>: ResultOperation<Void>
guard let installedApp = self.context.installedApp else { return self.finish(.failure(OperationError.invalidParameters)) } guard let installedApp = self.context.installedApp else { return self.finish(.failure(OperationError.invalidParameters)) }
installedApp.managedObjectContext?.perform { installedApp.managedObjectContext?.perform {
do { var retries = 3
try debug_app(installedApp.resignedBundleIdentifier) while (retries > 0){
} catch { do {
return self.finish(.failure(error)) try debug_app(installedApp.resignedBundleIdentifier)
self.finish(.success(()))
retries = 0
} catch {
retries -= 1
if (retries <= 0){
self.finish(.failure(error))
}
}
} }
self.finish(.success(()))
} }
} }
} }

View File

@@ -218,7 +218,7 @@ final class FetchAnisetteDataOperation: ResultOperation<ALTAnisetteData>, WebSoc
self.socket.connect() self.socket.connect()
} }
func didReceive(event: WebSocketEvent, client: WebSocket) { func didReceive(event: WebSocketEvent, client: WebSocketClient) {
switch event { switch event {
case .text(let string): case .text(let string):
do { do {
@@ -429,7 +429,7 @@ final class FetchAnisetteDataOperation: ResultOperation<ALTAnisetteData>, WebSoc
} }
} }
extension WebSocket { extension WebSocketClient {
func json(_ dictionary: [String: String]) { func json(_ dictionary: [String: String]) {
let data = try! JSONSerialization.data(withJSONObject: dictionary, options: []) let data = try! JSONSerialization.data(withJSONObject: dictionary, options: [])
self.write(string: String(data: data, encoding: .utf8)!) self.write(string: String(data: data, encoding: .utf8)!)

View File

@@ -262,10 +262,6 @@ extension FetchProvisioningProfilesOperation
{ {
throw OperationError.maximumAppIDLimitReached(application: application, requiredAppIDs: requiredAppIDs, availableAppIDs: availableAppIDs, nextExpirationDate: expirationDate) throw OperationError.maximumAppIDLimitReached(application: application, requiredAppIDs: requiredAppIDs, availableAppIDs: availableAppIDs, nextExpirationDate: expirationDate)
} }
else
{
throw ALTAppleAPIError(.maximumAppIDLimitReached)
}
} }
} }
//App ID name must be ascii. If the name is not ascii, using bundleID instead //App ID name must be ascii. If the name is not ascii, using bundleID instead

View File

@@ -41,7 +41,8 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
guard guard
let certificate = self.context.certificate, let certificate = self.context.certificate,
let resignedApp = self.context.resignedApp let resignedApp = self.context.resignedApp,
let provisioningProfiles = self.context.provisioningProfiles
else { return self.finish(.failure(OperationError.invalidParameters)) } else { return self.finish(.failure(OperationError.invalidParameters)) }
let backgroundContext = DatabaseManager.shared.persistentContainer.newBackgroundContext() let backgroundContext = DatabaseManager.shared.persistentContainer.newBackgroundContext()
@@ -116,8 +117,7 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
// Temporary directory and resigned .ipa no longer needed, so delete them now to ensure AltStore doesn't quit before we get the chance to. // Temporary directory and resigned .ipa no longer needed, so delete them now to ensure AltStore doesn't quit before we get the chance to.
self.cleanUp() self.cleanUp()
var activeProfiles: Set<String>? if let sideloadedAppsLimit = UserDefaults.standard.activeAppsLimit, provisioningProfiles.contains(where: { $1.isFreeProvisioningProfile == true })
if let sideloadedAppsLimit = UserDefaults.standard.activeAppsLimit
{ {
// When installing these new profiles, AltServer will remove all non-active profiles to ensure we remain under limit. // When installing these new profiles, AltServer will remove all non-active profiles to ensure we remain under limit.
@@ -142,15 +142,14 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
installedApp.isActive = false installedApp.isActive = false
} }
} }
}
activeProfiles = Set(activeApps.flatMap { (installedApp) -> [String] in else
let appExtensionProfiles = installedApp.appExtensions.map { $0.resignedBundleIdentifier } {
return [installedApp.resignedBundleIdentifier] + appExtensionProfiles installedApp.isActive = true
})
} }
var installing = true var installing = true
if installedApp.storeApp?.bundleIdentifier == Bundle.Info.appbundleIdentifier { if installedApp.storeApp?.bundleIdentifier.range(of: Bundle.Info.appbundleIdentifier) != nil {
// Reinstalling ourself will hang until we leave the app, so we need to exit it without force closing // Reinstalling ourself will hang until we leave the app, so we need to exit it without force closing
DispatchQueue.main.asyncAfter(deadline: .now() + 3) { DispatchQueue.main.asyncAfter(deadline: .now() + 3) {
if UIApplication.shared.applicationState != .active { if UIApplication.shared.applicationState != .active {
@@ -162,30 +161,26 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
return return
} }
print("We are still installing after 3 seconds") print("We are still installing after 3 seconds")
UNUserNotificationCenter.current().getNotificationSettings { settings in UNUserNotificationCenter.current().getNotificationSettings { settings in
switch (settings.authorizationStatus) { switch (settings.authorizationStatus) {
case .authorized, .ephemeral, .provisional: case .authorized, .ephemeral, .provisional:
print("Notifications are enabled") print("Notifications are enabled")
let content = UNMutableNotificationContent() let content = UNMutableNotificationContent()
content.title = "Refreshing..." content.title = "Refreshing..."
content.body = "To finish refreshing, SideStore must be moved to the background, which it does by opening Safari. Please reopen SideStore after it is done refreshing!" content.body = "SideStore will automatically move to the homescreen to finish refreshing!"
let notification = UNNotificationRequest(identifier: Bundle.Info.appbundleIdentifier + ".FinishRefreshNotification", content: content, trigger: UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false)) let notification = UNNotificationRequest(identifier: Bundle.Info.appbundleIdentifier + ".FinishRefreshNotification", content: content, trigger: UNTimeIntervalNotificationTrigger(timeInterval: 2, repeats: false))
UNUserNotificationCenter.current().add(notification) UNUserNotificationCenter.current().add(notification)
DispatchQueue.main.async { UIApplication.shared.open(URL(string: "x-web-search://")!) }
break break
default: default:
print("Notifications are not enabled") print("Notifications are not enabled")
let alert = UIAlertController(title: "Finish Refresh", message: "To finish refreshing, SideStore must be moved to the background. To do this, you can either go to the Home Screen or open Safari by pressing Continue. Please reopen SideStore after doing this.", preferredStyle: .alert) let alert = UIAlertController(title: "Finish Refresh", message: "Please reopen SideStore after the process is finished.To finish refreshing, SideStore must be moved to the background. To do this, you can either go to the Home Screen manually or by hitting Continue. Please reopen SideStore after doing this.", preferredStyle: .alert)
alert.addAction(UIAlertAction(title: NSLocalizedString("Continue", comment: ""), style: .default, handler: { _ in alert.addAction(UIAlertAction(title: NSLocalizedString("Continue", comment: ""), style: .default, handler: { _ in
print("Opening Safari") print("Going home")
DispatchQueue.main.async { UIApplication.shared.open(URL(string: "x-web-search://")!) } UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
})) }))
DispatchQueue.main.async { DispatchQueue.main.async {
let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first let keyWindow = UIApplication.shared.windows.filter { $0.isKeyWindow }.first
if var topController = keyWindow?.rootViewController { if var topController = keyWindow?.rootViewController {
@@ -194,27 +189,24 @@ final class InstallAppOperation: ResultOperation<InstalledApp>
} }
topController.present(alert, animated: true) topController.present(alert, animated: true)
} else { } else {
print("No key window? Let's just open Safari") print("No key window? Let's just go home")
UIApplication.shared.open(URL(string: "x-web-search://")!)
} }
} }
break
} }
} }
UIApplication.shared.perform(#selector(NSXPCConnection.suspend))
} }
} }
do { do {
try install_ipa(installedApp.bundleIdentifier) try install_ipa(installedApp.bundleIdentifier)
installing = false installing = false
} catch { installedApp.refreshedDate = Date()
self.finish(.success(installedApp))
} catch let error {
installing = false installing = false
return self.finish(.failure(error)) self.finish(.failure(error))
} }
installedApp.refreshedDate = Date()
self.finish(.success(installedApp))
} }
} }

View File

@@ -34,10 +34,14 @@ enum OperationError: LocalizedError
case openAppFailed(name: String) case openAppFailed(name: String)
case missingAppGroup case missingAppGroup
case noWiFi
case tooNewError
case anisetteV1Error(message: String) case anisetteV1Error(message: String)
case provisioningError(result: String, message: String?) case provisioningError(result: String, message: String?)
case anisetteV3Error(message: String) case anisetteV3Error(message: String)
case cacheClearError(errors: [String])
var failureReason: String? { var failureReason: String? {
switch self { switch self {
case .unknown: return NSLocalizedString("An unknown error occured.", comment: "") case .unknown: return NSLocalizedString("An unknown error occured.", comment: "")
@@ -53,9 +57,12 @@ enum OperationError: LocalizedError
case .openAppFailed(let name): return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), name) case .openAppFailed(let name): return String(format: NSLocalizedString("SideStore was denied permission to launch %@.", comment: ""), name)
case .missingAppGroup: return NSLocalizedString("SideStore's shared app group could not be found.", comment: "") case .missingAppGroup: return NSLocalizedString("SideStore's shared app group could not be found.", comment: "")
case .maximumAppIDLimitReached: return NSLocalizedString("Cannot register more than 10 App IDs.", comment: "") case .maximumAppIDLimitReached: return NSLocalizedString("Cannot register more than 10 App IDs.", comment: "")
case .noWiFi: return NSLocalizedString("You do not appear to be connected to WiFi!\nSideStore will never be able to install or refresh applications without WiFi.", comment: "")
case .tooNewError: return NSLocalizedString("iOS 17 has changed how JIT is enabled therefore SideStore cannot enable it at this time, sorry for any inconvenience.\nWe will let everyone know once we have a solution!", comment: "")
case .anisetteV1Error(let message): return String(format: NSLocalizedString("An error occurred when getting anisette data from a V1 server: %@. Try using another anisette server.", comment: ""), message) case .anisetteV1Error(let message): return String(format: NSLocalizedString("An error occurred when getting anisette data from a V1 server: %@. Try using another anisette server.", comment: ""), message)
case .provisioningError(let result, let message): return String(format: NSLocalizedString("An error occurred when provisioning: %@%@. Please try again. If the issue persists, report it on GitHub Issues!", comment: ""), result, message != nil ? (" (" + message! + ")") : "") case .provisioningError(let result, let message): return String(format: NSLocalizedString("An error occurred when provisioning: %@%@. Please try again. If the issue persists, report it on GitHub Issues!", comment: ""), result, message != nil ? (" (" + message! + ")") : "")
case .anisetteV3Error(let message): return String(format: 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: ""), message) case .anisetteV3Error(let message): return String(format: 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: ""), message)
case .cacheClearError(let errors): return String(format: NSLocalizedString("An error occurred while clearing cache: %@", comment: ""), errors.joined(separator: "\n"))
} }
} }
@@ -138,8 +145,8 @@ extension MinimuxerError: LocalizedError {
return self.createService(name: "AFC") return self.createService(name: "AFC")
case .RwAfc: case .RwAfc:
return NSLocalizedString("AFC was unable to manage files on the device", comment: "") return NSLocalizedString("AFC was unable to manage files on the device", comment: "")
case .InstallApp: case .InstallApp(let message):
return NSLocalizedString("Unable to install the app from the staging directory", comment: "") return NSLocalizedString("Unable to install the app: \(message.toString())", comment: "")
case .UninstallApp: case .UninstallApp:
return NSLocalizedString("Unable to uninstall the app", comment: "") return NSLocalizedString("Unable to uninstall the app", comment: "")

View File

@@ -35,31 +35,28 @@ final class RefreshAppOperation: ResultOperation<InstalledApp>
do do
{ {
if let error = self.context.error if let error = self.context.error { return self.finish(.failure(error)) }
{
throw error
}
guard let profiles = self.context.provisioningProfiles else { throw OperationError.invalidParameters } guard let profiles = self.context.provisioningProfiles else { return self.finish(.failure(OperationError.invalidParameters)) }
guard let app = self.context.app else { return self.finish(.failure(OperationError.appNotFound)) }
guard let app = self.context.app else { throw OperationError.appNotFound } for p in profiles {
do {
DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in let bytes = p.value.data.toRustByteSlice()
print("Sending refresh app request...") try install_provisioning_profile(bytes.forRust())
} catch {
self.finish(.failure(MinimuxerError.ProfileInstall))
}
for p in profiles { DatabaseManager.shared.persistentContainer.performBackgroundTask { (context) in
do { print("Sending refresh app request...")
let bytes = p.value.data.toRustByteSlice()
try install_provisioning_profile(bytes.forRust())
} catch {
return self.finish(.failure(error))
}
self.progress.completedUnitCount += 1 self.progress.completedUnitCount += 1
let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.bundleIdentifier), app.bundleIdentifier) let predicate = NSPredicate(format: "%K == %@", #keyPath(InstalledApp.bundleIdentifier), app.bundleIdentifier)
self.managedObjectContext.perform { self.managedObjectContext.perform {
guard let installedApp = InstalledApp.first(satisfying: predicate, in: self.managedObjectContext) else { guard let installedApp = InstalledApp.first(satisfying: predicate, in: self.managedObjectContext) else {
self.finish(.failure(OperationError.appNotFound))
return return
} }
installedApp.update(provisioningProfile: p.value) installedApp.update(provisioningProfile: p.value)
@@ -72,9 +69,5 @@ final class RefreshAppOperation: ResultOperation<InstalledApp>
} }
} }
} }
catch
{
self.finish(.failure(error))
}
} }
} }

View File

@@ -11,6 +11,7 @@ import Roxas
import AltStoreCore import AltStoreCore
import AltSign import AltSign
import minimuxer
@objc(ResignAppOperation) @objc(ResignAppOperation)
final class ResignAppOperation: ResultOperation<ALTApplication> final class ResignAppOperation: ResultOperation<ALTApplication>
@@ -181,7 +182,7 @@ private extension ResignAppOperation
if app.isAltStoreApp if app.isAltStoreApp
{ {
guard let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) 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] = pairingFileString additionalValues[Bundle.Info.devicePairingString] = pairingFileString
additionalValues[Bundle.Info.deviceID] = udid additionalValues[Bundle.Info.deviceID] = udid
@@ -202,7 +203,7 @@ private extension ResignAppOperation
// The embedded certificate + certificate identifier are already in app bundle, no need to update them. // The embedded certificate + certificate identifier are already in app bundle, no need to update them.
} }
} }
else if infoDictionary.keys.contains(Bundle.Info.deviceID), let udid = Bundle.main.object(forInfoDictionaryKey: Bundle.Info.deviceID) as? String else if infoDictionary.keys.contains(Bundle.Info.deviceID), let udid = fetch_udid()?.toString() as? String
{ {
// There is an ALTDeviceID entry, so assume the app is using AltKit and replace it with the device's UDID. // There is an ALTDeviceID entry, so assume the app is using AltKit and replace it with the device's UDID.
additionalValues[Bundle.Info.deviceID] = udid additionalValues[Bundle.Info.deviceID] = udid
@@ -227,6 +228,7 @@ private extension ResignAppOperation
// Prepare app // Prepare app
try prepare(appBundle, additionalInfoDictionaryValues: additionalValues) try prepare(appBundle, additionalInfoDictionaryValues: additionalValues)
try self.removeMissingAppExtensionReferences(from: appBundle)
if let directory = appBundle.builtInPlugInsURL, let enumerator = FileManager.default.enumerator(at: directory, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants]) if let directory = appBundle.builtInPlugInsURL, let enumerator = FileManager.default.enumerator(at: directory, includingPropertiesForKeys: nil, options: [.skipsSubdirectoryDescendants])
{ {
@@ -267,4 +269,28 @@ private extension ResignAppOperation
return progress return progress
} }
func removeMissingAppExtensionReferences(from bundle: Bundle) throws
{
// If app extensions have been removed from an app (either by AltStore or the developer),
// we must remove all references to them from SC_Info/Manifest.plist (if it exists).
let scInfoURL = bundle.bundleURL.appendingPathComponent("SC_Info")
let manifestPlistURL = scInfoURL.appendingPathComponent("Manifest.plist")
guard let manifestPlist = NSMutableDictionary(contentsOf: manifestPlistURL), let sinfReplicationPaths = manifestPlist["SinfReplicationPaths"] as? [String] else { return }
// Remove references to missing files.
let filteredReplicationPaths = sinfReplicationPaths.filter { path in
guard let fileURL = URL(string: path, relativeTo: bundle.bundleURL) else { return false }
let fileExists = FileManager.default.fileExists(atPath: fileURL.path)
return fileExists
}
manifestPlist["SinfReplicationPaths"] = filteredReplicationPaths
// Save updated Manifest.plist to disk.
try manifestPlist.write(to: manifestPlistURL)
}
} }

View File

@@ -33,8 +33,7 @@ final class SendAppOperation: ResultOperation<()>
if let error = self.context.error if let error = self.context.error
{ {
self.finish(.failure(error)) return self.finish(.failure(error))
return
} }
guard let resignedApp = self.context.resignedApp else { return self.finish(.failure(OperationError.invalidParameters)) } guard let resignedApp = self.context.resignedApp else { return self.finish(.failure(OperationError.invalidParameters)) }
@@ -49,15 +48,16 @@ final class SendAppOperation: ResultOperation<()>
do { do {
let bytes = Data(data).toRustByteSlice() let bytes = Data(data).toRustByteSlice()
try yeet_app_afc(app.bundleIdentifier, bytes.forRust()) try yeet_app_afc(app.bundleIdentifier, bytes.forRust())
self.progress.completedUnitCount += 1
self.finish(.success(()))
} catch { } catch {
return self.finish(.failure(error)) self.finish(.failure(MinimuxerError.RwAfc))
self.progress.completedUnitCount += 1
self.finish(.success(()))
} }
self.progress.completedUnitCount += 1
self.finish(.success(()))
} else { } else {
print("IPA doesn't exist????") print("IPA doesn't exist????")
self.finish(.failure(ALTServerError(.underlyingError))) self.finish(.failure(OperationError.appNotFound))
} }
} }
} }

Binary file not shown.

View File

@@ -1 +1,158 @@
{"images":[{"size":"60x60","expected-size":"180","filename":"180.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"40x40","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"60x60","expected-size":"120","filename":"120.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"57x57","expected-size":"57","filename":"57.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"1x"},{"size":"29x29","expected-size":"87","filename":"87.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"57x57","expected-size":"114","filename":"114.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"2x"},{"size":"20x20","expected-size":"60","filename":"60.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"iphone","scale":"3x"},{"size":"1024x1024","filename":"1024.png","expected-size":"1024","idiom":"ios-marketing","folder":"Assets.xcassets/AppIcon.appiconset/","scale":"1x"},{"size":"40x40","expected-size":"80","filename":"80.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"72x72","expected-size":"72","filename":"72.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"76x76","expected-size":"152","filename":"152.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"50x50","expected-size":"100","filename":"100.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"29x29","expected-size":"58","filename":"58.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"76x76","expected-size":"76","filename":"76.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"29x29","expected-size":"29","filename":"29.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"50x50","expected-size":"50","filename":"50.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"72x72","expected-size":"144","filename":"144.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"40x40","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"83.5x83.5","expected-size":"167","filename":"167.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"},{"size":"20x20","expected-size":"20","filename":"20.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"1x"},{"size":"20x20","expected-size":"40","filename":"40.png","folder":"Assets.xcassets/AppIcon.appiconset/","idiom":"ipad","scale":"2x"}]} {
"images" : [
{
"filename" : "40.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "60.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "87.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"filename" : "80.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"filename" : "57.png",
"idiom" : "iphone",
"scale" : "1x",
"size" : "57x57"
},
{
"filename" : "114.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "57x57"
},
{
"filename" : "120.png",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "180.png",
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"filename" : "20.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "20x20"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "20x20"
},
{
"filename" : "29.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"filename" : "58.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"filename" : "40.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"filename" : "80.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"filename" : "50.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "50x50"
},
{
"filename" : "100.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "50x50"
},
{
"filename" : "72.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "72x72"
},
{
"filename" : "144.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "72x72"
},
{
"filename" : "76.png",
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"filename" : "152.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"filename" : "167.png",
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"filename" : "1024.png",
"idiom" : "ios-marketing",
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -1,12 +0,0 @@
{
"images" : [
{
"filename" : "riley.jpg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

View File

@@ -1,12 +0,0 @@
{
"images" : [
{
"filename" : "shane.jpeg",
"idiom" : "universal"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 KiB

View File

@@ -0,0 +1,21 @@
{
"images" : [
{
"filename" : "1024.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View File

@@ -30,9 +30,9 @@
</array> </array>
<key>Values</key> <key>Values</key>
<array> <array>
<string>http://ani.sidestore.io:6969</string> <string>https://ani.sidestore.io</string>
<string>http://us1.sternserv.tech</string> <string>http://5.249.163.88:6969/</string>
<string>http://de1.sternserv.tech</string> <string>http://45.132.246.138:6969/</string>
<string>https://sign.rheaa.xyz</string> <string>https://sign.rheaa.xyz</string>
<string>https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx</string> <string>https://sideloadly.io/anisette/irGb3Quww8zrhgqnzmrx</string>
<string>http://45.33.29.114</string> <string>http://45.33.29.114</string>

View File

@@ -1,27 +1,27 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21225" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="21507" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" useSafeAreas="YES" colorMatched="YES">
<device id="retina6_1" orientation="portrait" appearance="light"/> <device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21207"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="21505"/>
<capability name="Named colors" minToolsVersion="9.0"/> <capability name="Named colors" minToolsVersion="9.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/> <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
<collectionReusableView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="AboutHeader" id="xq2-Pl-zaG" customClass="AboutPatreonHeaderView" customModule="AltStore" customModuleProvider="target"> <collectionReusableView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" reuseIdentifier="AboutHeader" id="xq2-Pl-zaG" customClass="AboutPatreonHeaderView" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="0.0" width="375" height="445"/> <rect key="frame" x="0.0" y="0.0" width="390" height="682"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" axis="vertical" spacing="25" translatesAutoresizingMaskIntoConstraints="NO" id="XiA-Jf-XMp"> <stackView opaque="NO" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" axis="vertical" spacing="25" translatesAutoresizingMaskIntoConstraints="NO" id="XiA-Jf-XMp">
<rect key="frame" x="16" y="2" width="343" height="393"/> <rect key="frame" x="16" y="2" width="358" height="630"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="5Ol-zN-wYv"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="5Ol-zN-wYv">
<rect key="frame" x="0.0" y="0.0" width="343" height="317"/> <rect key="frame" x="0.0" y="0.0" width="358" height="426"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="f7H-EV-7Sx"> <stackView opaque="NO" contentMode="scaleToFill" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="f7H-EV-7Sx">
<rect key="frame" x="0.0" y="0.0" width="343" height="55"/> <rect key="frame" x="0.0" y="0.0" width="358" height="55"/>
<subviews> <subviews>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SideStore" translatesAutoresizingMaskIntoConstraints="NO" id="pn6-Ic-MJm"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="SideStore" translatesAutoresizingMaskIntoConstraints="NO" id="pn6-Ic-MJm">
<rect key="frame" x="0.0" y="0.0" width="55" height="55"/> <rect key="frame" x="0.0" y="0.0" width="55" height="55"/>
@@ -31,7 +31,7 @@
</constraints> </constraints>
</imageView> </imageView>
<stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="si2-MA-3RH"> <stackView opaque="NO" contentMode="scaleToFill" distribution="equalSpacing" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="si2-MA-3RH">
<rect key="frame" x="65" y="0.0" width="278" height="55"/> <rect key="frame" x="65" y="0.0" width="293" height="55"/>
<subviews> <subviews>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="hkS-oz-wiT"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="hkS-oz-wiT">
<rect key="frame" x="0.0" y="0.0" width="83" height="55"/> <rect key="frame" x="0.0" y="0.0" width="83" height="55"/>
@@ -51,7 +51,7 @@
</subviews> </subviews>
</stackView> </stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="TFB-qo-cbh"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="2" translatesAutoresizingMaskIntoConstraints="NO" id="TFB-qo-cbh">
<rect key="frame" x="195" y="0.0" width="83" height="55"/> <rect key="frame" x="210" y="0.0" width="83" height="55"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Zpb-k3-y7l"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" minimumScaleFactor="0.5" translatesAutoresizingMaskIntoConstraints="NO" id="Zpb-k3-y7l">
<rect key="frame" x="0.0" y="0.0" width="83" height="50"/> <rect key="frame" x="0.0" y="0.0" width="83" height="50"/>
@@ -75,11 +75,13 @@
</constraints> </constraints>
</stackView> </stackView>
<textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FeG-e5-LJl"> <textView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" scrollEnabled="NO" editable="NO" textAlignment="natural" selectable="NO" translatesAutoresizingMaskIntoConstraints="NO" id="FeG-e5-LJl">
<rect key="frame" x="0.0" y="65" width="343" height="252"/> <rect key="frame" x="0.0" y="65" width="358" height="361"/>
<color key="backgroundColor" white="1" alpha="0.13" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="backgroundColor" white="1" alpha="0.13" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<string key="text">Hello, thank you for using SideStore! <string key="text">Thank you for using SideStore!
If you would subscribe to the patreon that would support us and make sure we can continue developing SideStore for you. Subscribing to the patreon supports us and makes sure we can continue developing SideStore for you.
Following us on social media allows us to give quick updates and spread the word about sideloading!
-SideTeam</string> -SideTeam</string>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -89,10 +91,10 @@ If you would subscribe to the patreon that would support us and make sure we can
</subviews> </subviews>
</stackView> </stackView>
<stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="13" translatesAutoresizingMaskIntoConstraints="NO" id="QS9-vO-bj8"> <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="13" translatesAutoresizingMaskIntoConstraints="NO" id="QS9-vO-bj8">
<rect key="frame" x="0.0" y="342" width="343" height="51"/> <rect key="frame" x="0.0" y="451" width="358" height="179"/>
<subviews> <subviews>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yEi-L6-kQ8"> <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="yEi-L6-kQ8">
<rect key="frame" x="0.0" y="0.0" width="343" height="51"/> <rect key="frame" x="0.0" y="0.0" width="358" height="51"/>
<color key="backgroundColor" name="SettingsHighlighted"/> <color key="backgroundColor" name="SettingsHighlighted"/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="51" id="l4o-vb-cMy"/> <constraint firstAttribute="height" constant="51" id="l4o-vb-cMy"/>
@@ -102,6 +104,28 @@ If you would subscribe to the patreon that would support us and make sure we can
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state> </state>
</button> </button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="hov-Ce-LaM" userLabel="Twitter Button">
<rect key="frame" x="0.0" y="64" width="358" height="51"/>
<color key="backgroundColor" name="SettingsHighlighted"/>
<constraints>
<constraint firstAttribute="height" constant="51" id="m0M-GX-KKG"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="19"/>
<state key="normal" title="Follow us on Twitter!">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
<button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="system" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="VdY-7Q-amF" userLabel="Twitter Button">
<rect key="frame" x="0.0" y="128" width="358" height="51"/>
<color key="backgroundColor" name="SettingsHighlighted"/>
<constraints>
<constraint firstAttribute="height" constant="51" id="kDo-b8-6tZ"/>
</constraints>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="19"/>
<state key="normal" title="Follow us on Instagram!">
<color key="titleColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</state>
</button>
</subviews> </subviews>
</stackView> </stackView>
</subviews> </subviews>
@@ -114,19 +138,21 @@ If you would subscribe to the patreon that would support us and make sure we can
<constraint firstItem="XiA-Jf-XMp" firstAttribute="top" secondItem="xq2-Pl-zaG" secondAttribute="top" constant="2" id="j8p-JX-Dcz"/> <constraint firstItem="XiA-Jf-XMp" firstAttribute="top" secondItem="xq2-Pl-zaG" secondAttribute="top" constant="2" id="j8p-JX-Dcz"/>
</constraints> </constraints>
<connections> <connections>
<outlet property="instagramButton" destination="VdY-7Q-amF" id="5kj-9x-k4F"/>
<outlet property="rileyImageView" destination="pn6-Ic-MJm" id="60i-Q0-ojz"/> <outlet property="rileyImageView" destination="pn6-Ic-MJm" id="60i-Q0-ojz"/>
<outlet property="rileyLabel" destination="DTd-Yu-HXr" id="O0y-JB-gWp"/> <outlet property="rileyLabel" destination="DTd-Yu-HXr" id="O0y-JB-gWp"/>
<outlet property="shaneLabel" destination="Zpb-k3-y7l" id="aQN-6B-s5T"/> <outlet property="shaneLabel" destination="Zpb-k3-y7l" id="aQN-6B-s5T"/>
<outlet property="supportButton" destination="yEi-L6-kQ8" id="Dzo-vd-SnD"/> <outlet property="supportButton" destination="yEi-L6-kQ8" id="Dzo-vd-SnD"/>
<outlet property="textView" destination="FeG-e5-LJl" id="K0M-lF-I6u"/> <outlet property="textView" destination="FeG-e5-LJl" id="K0M-lF-I6u"/>
<outlet property="twitterButton" destination="hov-Ce-LaM" id="gib-Lt-qtY"/>
</connections> </connections>
<point key="canvasLocation" x="138" y="138"/> <point key="canvasLocation" x="147.82608695652175" y="58.258928571428569"/>
</collectionReusableView> </collectionReusableView>
</objects> </objects>
<resources> <resources>
<image name="SideStore" width="180" height="180"/> <image name="SideStore" width="1024" height="1024"/>
<namedColor name="SettingsHighlighted"> <namedColor name="SettingsHighlighted">
<color red="0.23529411764705882" green="0.0" blue="0.40392156862745099" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> <color red="0.38823529411764707" green="0.011764705882352941" blue="0.58823529411764708" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</namedColor> </namedColor>
</resources> </resources>
</document> </document>

View File

@@ -56,6 +56,8 @@ final class PatronsFooterView: UICollectionReusableView
final class AboutPatreonHeaderView: UICollectionReusableView final class AboutPatreonHeaderView: UICollectionReusableView
{ {
@IBOutlet var supportButton: UIButton! @IBOutlet var supportButton: UIButton!
@IBOutlet var twitterButton: UIButton!
@IBOutlet var instagramButton: UIButton!
@IBOutlet var accountButton: UIButton! @IBOutlet var accountButton: UIButton!
@IBOutlet var textView: UITextView! @IBOutlet var textView: UITextView!
@@ -79,12 +81,12 @@ final class AboutPatreonHeaderView: UICollectionReusableView
imageView.layer.cornerRadius = imageView.bounds.midY imageView.layer.cornerRadius = imageView.bounds.midY
} }
for button in [self.supportButton, self.accountButton].compactMap({ $0 }) for button in [self.supportButton, self.accountButton, self.twitterButton, self.instagramButton].compactMap({ $0 })
{ {
button.clipsToBounds = true button.clipsToBounds = true
button.layer.cornerRadius = 16 button.layer.cornerRadius = 16
} }
} }
override func layoutMarginsDidChange() override func layoutMarginsDidChange()
{ {

View File

@@ -111,7 +111,9 @@ private extension PatreonViewController
headerView.layoutMargins = self.view.layoutMargins headerView.layoutMargins = self.view.layoutMargins
headerView.supportButton.addTarget(self, action: #selector(PatreonViewController.openPatreonURL(_:)), for: .primaryActionTriggered) headerView.supportButton.addTarget(self, action: #selector(PatreonViewController.openPatreonURL(_:)), for: .primaryActionTriggered)
headerView.twitterButton.addTarget(self, action: #selector(PatreonViewController.openTwitterURL(_:)), for: .primaryActionTriggered)
headerView.instagramButton.addTarget(self, action: #selector(PatreonViewController.openInstagramURL(_:)), for: .primaryActionTriggered)
let defaultSupportButtonTitle = NSLocalizedString("Become a patron", comment: "") let defaultSupportButtonTitle = NSLocalizedString("Become a patron", comment: "")
let isPatronSupportButtonTitle = NSLocalizedString("View Patreon", comment: "") let isPatronSupportButtonTitle = NSLocalizedString("View Patreon", comment: "")
@@ -180,6 +182,24 @@ private extension PatreonViewController
self.present(safariViewController, animated: true, completion: nil) self.present(safariViewController, animated: true, completion: nil)
} }
@objc func openTwitterURL(_ sender: UIButton)
{
let twitterURL = URL(string: "https://twitter.com/SideStore_io")!
let safariViewController = SFSafariViewController(url: twitterURL)
safariViewController.preferredControlTintColor = self.view.tintColor
self.present(safariViewController, animated: true, completion: nil)
}
@objc func openInstagramURL(_ sender: UIButton)
{
let twitterURL = URL(string: "https://instagram.com/sidestore.io")!
let safariViewController = SFSafariViewController(url: twitterURL)
safariViewController.preferredControlTintColor = self.view.tintColor
self.present(safariViewController, animated: true, completion: nil)
}
@IBAction func authenticate(_ sender: UIBarButtonItem) @IBAction func authenticate(_ sender: UIBarButtonItem)
{ {
PatreonAPI.shared.authenticate { (result) in PatreonAPI.shared.authenticate { (result) in

View File

@@ -21,7 +21,7 @@
<color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="tintColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<color key="separatorColor" white="1" alpha="0.25" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="separatorColor" white="1" alpha="0.25" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<label key="tableFooterView" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SideStore 1.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bUR-rp-Nw2"> <label key="tableFooterView" opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="SideStore 1.0" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" id="bUR-rp-Nw2">
<rect key="frame" x="0.0" y="1194" width="375" height="25"/> <rect key="frame" x="0.0" y="1245" width="375" height="25"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/> <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="0.69999999999999996" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
@@ -167,8 +167,8 @@
<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="Join the beta" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Il-5a-5Zp"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Support the team" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3Il-5a-5Zp">
<rect key="frame" x="30" y="15.5" width="106" height="20.5"/> <rect key="frame" x="30" y="15.5" width="142.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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
@@ -359,22 +359,22 @@
<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="UI Designer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oqY-wY-1Vf"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="UI Designer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="oqY-wY-1Vf">
<rect key="frame" x="30" y="15.5" width="89" height="20.5"/> <rect key="frame" x="30" y="15.5" width="89" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<stackView opaque="NO" contentMode="scaleToFill" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="gUq-6Q-t5X"> <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="gUq-6Q-t5X">
<rect key="frame" x="198" y="15.5" width="147" height="20.5"/> <rect key="frame" x="198" y="15.5" width="147" height="20.5"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Fabian (thdev)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ylE-VL-7Fq"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Fabian (thdev)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ylE-VL-7Fq">
<rect key="frame" x="0.0" y="0.0" width="115" height="20.5"/> <rect key="frame" x="0.0" y="0.0" width="115" height="20.5"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/> <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="e3L-vR-Jae"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="e3L-vR-Jae">
<rect key="frame" x="129" y="0.0" width="18" height="20.5"/> <rect key="frame" x="129" y="0.0" width="18" height="20.5"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -403,22 +403,22 @@
<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="Asset Designer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fGU-Fp-XgM"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Asset Designer" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="fGU-Fp-XgM">
<rect key="frame" x="30" y="15.5" width="115.5" height="20.5"/> <rect key="frame" x="30" y="15.5" width="115.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<stackView opaque="NO" contentMode="scaleToFill" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="R8B-DW-7mY"> <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" spacing="14" translatesAutoresizingMaskIntoConstraints="NO" id="R8B-DW-7mY">
<rect key="frame" x="206" y="15.5" width="139" height="20.5"/> <rect key="frame" x="206" y="15.5" width="139" height="20.5"/>
<subviews> <subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Chris (LitRitt)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hId-3P-41T"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Chris (LitRitt)" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hId-3P-41T">
<rect key="frame" x="0.0" y="0.0" width="107" height="20.5"/> <rect key="frame" x="0.0" y="0.0" width="107" height="20.5"/>
<fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/> <fontDescription key="fontDescription" type="system" weight="semibold" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="baq-cE-fMY"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="baq-cE-fMY">
<rect key="frame" x="121" y="0.0" width="18" height="20.5"/> <rect key="frame" x="121" y="0.0" width="18" height="20.5"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -447,13 +447,13 @@
<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="Licenses" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="D6b-cd-pVK"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Licenses" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="D6b-cd-pVK">
<rect key="frame" x="30" y="15.5" width="67.5" height="20.5"/> <rect key="frame" x="30" y="15.5" width="67.5" height="20.5"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/> <fontDescription key="fontDescription" type="system" pointSize="17"/>
<color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/> <color key="textColor" white="1" alpha="0.80000000000000004" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="s79-GQ-khr"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="s79-GQ-khr">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -487,13 +487,13 @@
<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="Send Feedback" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pMI-Aj-nQF"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Send Feedback" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pMI-Aj-nQF">
<rect key="frame" x="30" y="15.5" width="125.5" height="20.5"/> <rect key="frame" x="30" y="15.5" width="125.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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="Jyy-x0-Owj"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="Jyy-x0-Owj">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -520,13 +520,13 @@
<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="View Refresh Attempts" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sni-07-q0M"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="View Refresh Attempts" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="sni-07-q0M">
<rect key="frame" x="30" y="15.5" width="187.5" height="20.5"/> <rect key="frame" x="30" y="15.5" width="187.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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="4d3-me-Hqc"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="4d3-me-Hqc">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -556,13 +556,13 @@
<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="View Error Log" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PWC-OG-5jx"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="View Error Log" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="PWC-OG-5jx">
<rect key="frame" x="30" y="15.5" width="119" height="20.5"/> <rect key="frame" x="30" y="15.5" width="119" 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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="VfB-c5-5wG"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="VfB-c5-5wG">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -582,23 +582,56 @@
<userDefinedRuntimeAttribute type="boolean" keyPath="isSelectable" value="YES"/> <userDefinedRuntimeAttribute type="boolean" keyPath="isSelectable" value="YES"/>
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
<connections> <connections>
<segue destination="g8a-Rf-zWa" kind="show" identifier="showErrorLog" id="SSW-vL-86I"/> <segue destination="g8a-Rf-zWa" kind="show" id="vFC-Id-Ww6"/>
</connections> </connections>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="VNn-u4-cN8" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="eZ3-BT-q4D" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="1023" width="375" height="51"/> <rect key="frame" x="0.0" y="1023" width="375" height="51"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="eZ3-BT-q4D" id="17m-VV-hzf">
<rect key="frame" x="0.0" y="0.0" width="375" height="51"/>
<autoresizingMask key="autoresizingMask"/>
<subviews>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Clear Cache" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IbH-V1-ce3">
<rect key="frame" x="30" y="15.5" width="98.5" height="20.5"/>
<fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
<color key="textColor" white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="FZe-BJ-fOm">
<rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView>
</subviews>
<constraints>
<constraint firstItem="FZe-BJ-fOm" firstAttribute="centerY" secondItem="17m-VV-hzf" secondAttribute="centerY" id="bGv-Np-5aO"/>
<constraint firstAttribute="trailingMargin" secondItem="FZe-BJ-fOm" secondAttribute="trailing" id="ccb-JP-Eqi"/>
<constraint firstItem="IbH-V1-ce3" firstAttribute="centerY" secondItem="17m-VV-hzf" secondAttribute="centerY" id="iQJ-gN-sRF"/>
<constraint firstItem="IbH-V1-ce3" firstAttribute="leading" secondItem="17m-VV-hzf" secondAttribute="leadingMargin" id="m1g-Y6-aT5"/>
</constraints>
</tableViewCellContentView>
<color key="backgroundColor" white="1" alpha="0.14999999999999999" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
<edgeInsets key="layoutMargins" top="8" left="30" bottom="8" right="30"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="style">
<integer key="value" value="2"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="isSelectable" value="YES"/>
</userDefinedRuntimeAttributes>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="VNn-u4-cN8" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="1074" width="375" height="51"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VNn-u4-cN8" id="4bh-qe-l2N"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="VNn-u4-cN8" id="4bh-qe-l2N">
<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="Reset Pairing File" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ysS-9s-dXm"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Reset Pairing File" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ysS-9s-dXm">
<rect key="frame" x="30" y="15.5" width="140" height="20.5"/> <rect key="frame" x="30" y="15.5" width="140" 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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="r09-mH-pOD"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="r09-mH-pOD">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -619,19 +652,19 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="e7s-hL-kv9" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="e7s-hL-kv9" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="1074" width="375" height="51"/> <rect key="frame" x="0.0" y="1125" width="375" height="51"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="e7s-hL-kv9" id="yjL-Mu-HTk"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="e7s-hL-kv9" id="yjL-Mu-HTk">
<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="Reset adi.pb" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eds-Dj-36y"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Reset adi.pb" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eds-Dj-36y">
<rect key="frame" x="30" y="15.5" width="102" height="20.5"/> <rect key="frame" x="30" y="15.5" width="102" 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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="0dh-yd-7i9"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="0dh-yd-7i9">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -652,19 +685,19 @@
</userDefinedRuntimeAttributes> </userDefinedRuntimeAttributes>
</tableViewCell> </tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="fj2-EJ-Z98" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target"> <tableViewCell clipsSubviews="YES" contentMode="scaleToFill" preservesSuperviewLayoutMargins="YES" selectionStyle="default" indentationWidth="10" rowHeight="51" id="fj2-EJ-Z98" customClass="InsetGroupTableViewCell" customModule="SideStore" customModuleProvider="target">
<rect key="frame" x="0.0" y="1125" width="375" height="51"/> <rect key="frame" x="0.0" y="1176" width="375" height="51"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fj2-EJ-Z98" id="BcT-Fs-KNg"> <tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" preservesSuperviewLayoutMargins="YES" insetsLayoutMarginsFromSafeArea="NO" tableViewCell="fj2-EJ-Z98" id="BcT-Fs-KNg">
<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="Advanced Settings" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OcM-OM-uDE"> <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" text="Advanced Settings" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="OcM-OM-uDE">
<rect key="frame" x="30" y="15.5" width="154" height="20.5"/> <rect key="frame" x="30" y="15.5" width="154" 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"/>
<nil key="highlightedColor"/> <nil key="highlightedColor"/>
</label> </label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="Pcu-Sy-yfZ"> <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" ambiguous="YES" image="Next" translatesAutoresizingMaskIntoConstraints="NO" id="Pcu-Sy-yfZ">
<rect key="frame" x="327" y="16.5" width="18" height="18"/> <rect key="frame" x="327" y="16.5" width="18" height="18"/>
</imageView> </imageView>
</subviews> </subviews>
@@ -917,7 +950,7 @@ Settings by i cons from the Noun Project</string>
</objects> </objects>
<point key="canvasLocation" x="1697" y="313"/> <point key="canvasLocation" x="1697" y="313"/>
</scene> </scene>
<!--Patreon--> <!--Support us-->
<scene sceneID="Lnh-9P-HnL"> <scene sceneID="Lnh-9P-HnL">
<objects> <objects>
<collectionViewController id="dp8-8j-vt9" customClass="PatreonViewController" customModule="SideStore" customModuleProvider="target" sceneMemberID="viewController"> <collectionViewController id="dp8-8j-vt9" customClass="PatreonViewController" customModule="SideStore" customModuleProvider="target" sceneMemberID="viewController">
@@ -964,7 +997,7 @@ Settings by i cons from the Noun Project</string>
<outlet property="delegate" destination="dp8-8j-vt9" id="790-Kr-6l7"/> <outlet property="delegate" destination="dp8-8j-vt9" id="790-Kr-6l7"/>
</connections> </connections>
</collectionView> </collectionView>
<navigationItem key="navigationItem" title="Patreon" largeTitleDisplayMode="always" id="uUV-1f-xEq"/> <navigationItem key="navigationItem" title="Support us" largeTitleDisplayMode="always" id="uUV-1f-xEq"/>
</collectionViewController> </collectionViewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="qq3-Hj-S9f" userLabel="First Responder" sceneMemberID="firstResponder"/> <placeholder placeholderIdentifier="IBFirstResponder" id="qq3-Hj-S9f" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects> </objects>

View File

@@ -53,9 +53,11 @@ extension SettingsViewController
case sendFeedback case sendFeedback
case refreshAttempts case refreshAttempts
case errorLog case errorLog
case clearCache
case resetPairingFile case resetPairingFile
case resetAdiPb case resetAdiPb
case advancedSettings case advancedSettings
} }
} }
@@ -178,11 +180,11 @@ private extension SettingsViewController
case .patreon: case .patreon:
if isHeader if isHeader
{ {
settingsHeaderFooterView.primaryLabel.text = NSLocalizedString("PATREON", comment: "") settingsHeaderFooterView.primaryLabel.text = NSLocalizedString("SUPPORT US", comment: "")
} }
else else
{ {
settingsHeaderFooterView.secondaryLabel.text = NSLocalizedString("Support the SideStore Team by becoming a patron!", comment: "") settingsHeaderFooterView.secondaryLabel.text = NSLocalizedString("Support the SideStore Team by following our socials or becoming a patron!", comment: "")
} }
case .account: case .account:
@@ -291,6 +293,39 @@ private extension SettingsViewController
self.present(viewController, animated: true, completion: nil) self.present(viewController, animated: true, completion: nil)
} }
func clearCache()
{
let alertController = UIAlertController(title: NSLocalizedString("Are you sure you want to clear SideStore's cache?", comment: ""),
message: NSLocalizedString("This will remove all temporary files as well as backups for uninstalled apps.", comment: ""),
preferredStyle: .actionSheet)
alertController.addAction(UIAlertAction(title: UIAlertAction.cancel.title, style: UIAlertAction.cancel.style) { [weak self] _ in
self?.tableView.indexPathForSelectedRow.map { self?.tableView.deselectRow(at: $0, animated: true) }
})
alertController.addAction(UIAlertAction(title: NSLocalizedString("Clear Cache", comment: ""), style: .destructive) { [weak self] _ in
AppManager.shared.clearAppCache { result in
DispatchQueue.main.async {
self?.tableView.indexPathForSelectedRow.map { self?.tableView.deselectRow(at: $0, animated: true) }
switch result
{
case .success: break
case .failure(let error):
let alertController = UIAlertController(title: NSLocalizedString("Unable to Clear Cache", comment: ""), message: error.localizedDescription, preferredStyle: .alert)
alertController.addAction(.ok)
self?.present(alertController, animated: true)
}
}
}
})
if let popoverController = alertController.popoverPresentationController {
popoverController.sourceView = self.view
popoverController.sourceRect = CGRect(x: self.view.bounds.midX, y: self.view.bounds.midY, width: 0, height: 0)
}
self.present(alertController, animated: true)
}
@IBAction func handleDebugModeGesture(_ gestureRecognizer: UISwipeGestureRecognizer) @IBAction func handleDebugModeGesture(_ gestureRecognizer: UISwipeGestureRecognizer)
{ {
self.debugGestureCounter += 1 self.debugGestureCounter += 1
@@ -470,6 +505,7 @@ extension SettingsViewController
self.addRefreshAppsShortcut() self.addRefreshAppsShortcut()
} }
case .credits: case .credits:
let row = CreditsRow.allCases[indexPath.row] let row = CreditsRow.allCases[indexPath.row]
switch row switch row
@@ -507,6 +543,9 @@ extension SettingsViewController
let toastView = ToastView(text: NSLocalizedString("Cannot Send Mail", comment: ""), detailText: nil) let toastView = ToastView(text: NSLocalizedString("Cannot Send Mail", comment: ""), detailText: nil)
toastView.show(in: self) toastView.show(in: self)
} }
case .clearCache: self.clearCache()
case .resetPairingFile: case .resetPairingFile:
let filename = "ALTPairingFile.mobiledevicepairing" let filename = "ALTPairingFile.mobiledevicepairing"
let fm = FileManager.default let fm = FileManager.default
@@ -559,6 +598,7 @@ extension SettingsViewController
ELOG("UIApplication.openSettingsURLString invalid") ELOG("UIApplication.openSettingsURLString invalid")
} }
case .refreshAttempts, .errorLog: break case .refreshAttempts, .errorLog: break
} }
default: break default: break

View File

@@ -192,7 +192,7 @@ public extension InstalledApp
class func fetchAppsForRefreshingAll(in context: NSManagedObjectContext) -> [InstalledApp] class func fetchAppsForRefreshingAll(in context: NSManagedObjectContext) -> [InstalledApp]
{ {
var predicate = NSPredicate(format: "%K == YES AND %K != %@", #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.bundleIdentifier), StoreApp.altstoreAppID) let predicate = NSPredicate(format: "%K == YES AND %K != %@", #keyPath(InstalledApp.isActive), #keyPath(InstalledApp.bundleIdentifier), StoreApp.altstoreAppID)
print("Fetch Apps for Refreshing All 'AltStore' predicate: \(String(describing: predicate))") print("Fetch Apps for Refreshing All 'AltStore' predicate: \(String(describing: predicate))")
// if let patreonAccount = DatabaseManager.shared.patreonAccount(in: context), patreonAccount.isPatron, PatreonAPI.shared.isAuthenticated // if let patreonAccount = DatabaseManager.shared.patreonAccount(in: context), patreonAccount.isPatron, PatreonAPI.shared.isAuthenticated
@@ -223,7 +223,7 @@ public extension InstalledApp
// Date 6 hours before now. // Date 6 hours before now.
let date = Date().addingTimeInterval(-1 * 6 * 60 * 60) let date = Date().addingTimeInterval(-1 * 6 * 60 * 60)
var predicate = NSPredicate(format: "(%K == YES) AND (%K < %@) AND (%K != %@)", let predicate = NSPredicate(format: "(%K == YES) AND (%K < %@) AND (%K != %@)",
#keyPath(InstalledApp.isActive), #keyPath(InstalledApp.isActive),
#keyPath(InstalledApp.refreshedDate), date as NSDate, #keyPath(InstalledApp.refreshedDate), date as NSDate,
#keyPath(InstalledApp.bundleIdentifier), StoreApp.altstoreAppID) #keyPath(InstalledApp.bundleIdentifier), StoreApp.altstoreAppID)

Binary file not shown.

After

Width:  |  Height:  |  Size: 846 KiB

View File

@@ -5,12 +5,12 @@
"scale" : "1x" "scale" : "1x"
}, },
{ {
"filename" : "Group 23_120.png", "filename" : "1024.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "2x" "scale" : "2x"
}, },
{ {
"filename" : "Group 23_180.png", "filename" : "1024.png",
"idiom" : "universal", "idiom" : "universal",
"scale" : "3x" "scale" : "3x"
} }

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

View File

@@ -1,7 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "group16Copy2.pdf", "filename" : "sidestore-logo.svg",
"idiom" : "universal" "idiom" : "universal"
} }
], ],

View File

@@ -0,0 +1,17 @@
<svg version="1.2" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" width="100" height="100">
<title>sidestore-logo-svg</title>
<style>
.s0 { fill: none }
.s1 { fill: #bebbb4 }
</style>
<g id="Layer">
<g id="Layer">
<path id="Main" class="s0" />
<g id="Main1">
<g id="Layer">
<path id="Layer" fill-rule="evenodd" class="s1" d="m86 50c0 2.3-1.9 4.2-4.2 4.2h-50.9c-2.3 0-4.2-1.9-4.2-4.2 0-2.3 1.9-4.2 4.2-4.2h50.9c2.3 0 4.2 1.9 4.2 4.2zm-31.8-23.3v2.1c0 3.4-1.3 6.6-3.7 9-2.4 2.4-5.6 3.7-9 3.7h-10.6c-2.2 0-4.4 0.9-5.9 2.5-1.6 1.6-2.5 3.8-2.5 6 0 2.2 0.9 4.4 2.5 6 1.5 1.6 3.7 2.5 5.9 2.5h10.6c3.4 0 6.6 1.3 9 3.7 2.4 2.4 3.7 5.6 3.7 9v10.8c0 1.1-0.4 2.1-1.1 2.8-0.8 0.8-1.8 1.2-2.9 1.2h-0.4c-1.1 0-2.1-0.4-2.9-1.2-0.7-0.7-1.1-1.7-1.1-2.8v-10.8c0-1.1-0.5-2.2-1.3-3-0.8-0.8-1.8-1.3-3-1.3h-10.6c-4.5 0-8.8-1.7-11.9-4.9-3.2-3.2-5-7.5-5-12 0-4.5 1.8-8.8 5-12 3.1-3.2 7.4-4.9 11.9-4.9h10.6c1.2 0 2.2-0.5 3-1.3 0.8-0.8 1.3-1.9 1.3-3v-2.1h-4.3l8.5-12.7 8.5 12.7zm12.7 55.3c0 2.2-1.8 4-4 4h-0.5c-2.2 0-4-1.8-4-4v-19.5c0-2.2 1.8-4 4-4h0.5c2.2 0 4 1.8 4 4z"/>
</g>
</g>
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -1,7 +1,7 @@
{ {
"images" : [ "images" : [
{ {
"filename" : "altminicon.pdf", "filename" : "cir.svg",
"idiom" : "universal" "idiom" : "universal"
} }
], ],

View File

@@ -0,0 +1,3 @@
<svg width="100" height="100" version="1.1" viewBox="0 0 100 100" xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="50" fill="#fff" stroke-width=".265"/>
</svg>

After

Width:  |  Height:  |  Size: 175 B

View File

@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>XYZ0123456.com.SideStore.SideStore.AltWidget</string>
<key>com.apple.developer.team-identifier</key>
<string>XYZ0123456</string>
<key>com.apple.security.application-groups</key>
<array>
<string>group.com.SideStore.SideStore</string>
</array>
<key>get-task-allow</key>
<true/>
</dict>
</plist>

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.4.0 MARKETING_VERSION = 0.5.3
CURRENT_PROJECT_VERSION = 4000 CURRENT_PROJECT_VERSION = 5030
// 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

@@ -7,7 +7,7 @@ There are many ways to contribute to SideStore, so if you aren't a developer, th
- [Writing documentation](https://github.com/SideStore/SideStore-Docs) - [Writing documentation](https://github.com/SideStore/SideStore-Docs)
- [Submitting detailed bug reports and suggesting new features](https://github.com/SideStore/SideStore/issues/new/choose) - [Submitting detailed bug reports and suggesting new features](https://github.com/SideStore/SideStore/issues/new/choose)
- Helping out with support - Helping out with support
- [Discord](https://discord.gg/RgpFBX3Q3k) - [Discord](https://discord.gg/sidestore-949183273383395328)
- [GitHub Discussions](https://github.com/SideStore/SideStore/discussions) - [GitHub Discussions](https://github.com/SideStore/SideStore/discussions)
However, this guide will focus on the development side of things. For now, we will only have setup information here, but you can [join our Discord](https://discord.gg/RgpFBX3Q3k) if you need help However, this guide will focus on the development side of things. For now, we will only have setup information here, but you can [join our Discord](https://discord.gg/RgpFBX3Q3k) if you need help

View File

@@ -171,6 +171,7 @@ build:
fakesign: fakesign:
rm -rf archive.xcarchive/Products/Applications/SideStore.app/Frameworks/AltStoreCore.framework/Frameworks/ rm -rf archive.xcarchive/Products/Applications/SideStore.app/Frameworks/AltStoreCore.framework/Frameworks/
ldid -SAltStore/Resources/ReleaseEntitlements.plist archive.xcarchive/Products/Applications/SideStore.app/SideStore ldid -SAltStore/Resources/ReleaseEntitlements.plist archive.xcarchive/Products/Applications/SideStore.app/SideStore
ldid -SAltWidget/Resources/ReleaseEntitlements.plist archive.xcarchive/Products/Applications/SideStore.app/PlugIns/AltWidgetExtension.appex/AltWidgetExtension
ipa: ipa:
mkdir Payload mkdir Payload

View File

@@ -9,7 +9,7 @@
![Alt](https://repobeats.axiom.co/api/embed/3a329ce95955690b9a9366f8d5598626a847d96c.svg "Repobeats analytics image") ![Alt](https://repobeats.axiom.co/api/embed/3a329ce95955690b9a9366f8d5598626a847d96c.svg "Repobeats analytics image")
SideStore is an iOS application that allows you to sideload apps onto your iOS device with just your Apple ID. SideStore resigns apps with your personal development certificate, and then uses a [specially designed VPN](https://github.com/jkcoxson/Secret-Tunnel) in order to trick iOS into installing them. SideStore will periodically "refresh" your apps in the background, to keep their normal 7-day development period from expiring. SideStore is an iOS application that allows you to sideload apps onto your iOS device with just your Apple ID. SideStore resigns apps with your personal development certificate, and then uses a [specially designed VPN](https://github.com/jkcoxson/em_proxy) in order to trick iOS into installing them. SideStore will periodically "refresh" your apps in the background, to keep their normal 7-day development period from expiring.
SideStore's goal is to provide an untethered sideloading experience. It's a community driven fork of [AltStore](https://github.com/rileytestut/AltStore), and has already implemented some of the community's most-requested features. SideStore's goal is to provide an untethered sideloading experience. It's a community driven fork of [AltStore](https://github.com/rileytestut/AltStore), and has already implemented some of the community's most-requested features.

View File

@@ -56,7 +56,7 @@ public extension Bundle
public extension Bundle public extension Bundle
{ {
static var baseAltStoreAppGroupID = "group." + Bundle.Info.appbundleIdentifier static var baseAltStoreAppGroupID = "group." + Bundle.Info.appbundleIdentifier
var appGroups: [String] { var appGroups: [String] {
return self.infoDictionary?[Bundle.Info.appGroups] as? [String] ?? [] return self.infoDictionary?[Bundle.Info.appGroups] as? [String] ?? []
} }

9
SideStore.conf Normal file
View File

@@ -0,0 +1,9 @@
[Interface]
PrivateKey = AIIeeUDvk3NeAFJ9BWCQvPJize/9WZibMnGJ/0rt5k4=
Address = 10.7.0.10/24
[Peer]
PublicKey = kHDoekeYhBvfW9a9UQ+UCmpbG423eejTjcjW+DT+JF0=
AllowedIPs = 10.7.0.1/32
Endpoint = 127.0.0.1:51820
PersistentKeepalive = 25

View File

@@ -32,9 +32,17 @@
"identifier": "eu.pokemmo.altstore", "identifier": "eu.pokemmo.altstore",
"sourceURL": "https://pokemmo.eu/altstore/" "sourceURL": "https://pokemmo.eu/altstore/"
}, },
{
"identifier": "dev.theodyssey.sidestore",
"sourceURL": "https://theodyssey.dev/altstore/odysseysource.json"
},
{ {
"identifier": "stream.yattee", "identifier": "stream.yattee",
"sourceURL": "https://repos.yattee.stream/alt/apps.json" "sourceURL": "https://repos.yattee.stream/alt/apps.json"
},
{
"identifier": "com.litritt.litsource",
"sourceURL": "https://altstore.ignitedemulator.com/"
} }
] ]
} }