Skip to content
This repository has been archived by the owner on Dec 23, 2023. It is now read-only.

Commit

Permalink
Merge pull request #12 from andreas16700/main
Browse files Browse the repository at this point in the history
BIG Stability improvements
  • Loading branch information
haxi0 authored Nov 15, 2022
2 parents bd994ed + 58ae203 commit ae766fb
Show file tree
Hide file tree
Showing 7 changed files with 320 additions and 25 deletions.
129 changes: 129 additions & 0 deletions TrollApps/TrollApps.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* Begin PBXBuildFile section */
028DC81B2922695F000F484F /* AsyncButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 028DC81A2922695F000F484F /* AsyncButton.swift */; };
0299094129225B3B006D62D9 /* TrollAppsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0299094029225B3B006D62D9 /* TrollAppsUITests.swift */; };
0299094329225B3B006D62D9 /* TrollAppsUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0299094229225B3B006D62D9 /* TrollAppsUITestsLaunchTests.swift */; };
6D78B4672920ED7500EFB2FD /* SDWebImageSwiftUI in Frameworks */ = {isa = PBXBuildFile; productRef = 6D78B4662920ED7500EFB2FD /* SDWebImageSwiftUI */; };
6D8817C6291ECB97007139C6 /* TrollAppsApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D8817C5291ECB97007139C6 /* TrollAppsApp.swift */; };
6D8817C8291ECB97007139C6 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D8817C7291ECB97007139C6 /* ContentView.swift */; };
Expand All @@ -18,7 +21,21 @@
6D8817DA291EE5C9007139C6 /* Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6D8817D9291EE5C9007139C6 /* Extensions.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
0299094429225B3B006D62D9 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6D8817BA291ECB97007139C6 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 6D8817C1291ECB97007139C6;
remoteInfo = TrollApps;
};
/* End PBXContainerItemProxy section */

/* Begin PBXFileReference section */
028DC81A2922695F000F484F /* AsyncButton.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AsyncButton.swift; sourceTree = "<group>"; };
0299093E29225B3B006D62D9 /* TrollAppsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = TrollAppsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
0299094029225B3B006D62D9 /* TrollAppsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrollAppsUITests.swift; sourceTree = "<group>"; };
0299094229225B3B006D62D9 /* TrollAppsUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrollAppsUITestsLaunchTests.swift; sourceTree = "<group>"; };
6D78B4882921088000EFB2FD /* TrollApps-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "TrollApps-Bridging-Header.h"; sourceTree = "<group>"; };
6D8817C2291ECB97007139C6 /* TrollApps.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = TrollApps.app; sourceTree = BUILT_PRODUCTS_DIR; };
6D8817C5291ECB97007139C6 /* TrollAppsApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TrollAppsApp.swift; sourceTree = "<group>"; };
Expand All @@ -32,6 +49,13 @@
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
0299093B29225B3B006D62D9 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
6D8817BF291ECB97007139C6 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -43,10 +67,20 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
0299093F29225B3B006D62D9 /* TrollAppsUITests */ = {
isa = PBXGroup;
children = (
0299094029225B3B006D62D9 /* TrollAppsUITests.swift */,
0299094229225B3B006D62D9 /* TrollAppsUITestsLaunchTests.swift */,
);
path = TrollAppsUITests;
sourceTree = "<group>";
};
6D8817B9291ECB97007139C6 = {
isa = PBXGroup;
children = (
6D8817C4291ECB97007139C6 /* TrollApps */,
0299093F29225B3B006D62D9 /* TrollAppsUITests */,
6D8817C3291ECB97007139C6 /* Products */,
);
sourceTree = "<group>";
Expand All @@ -55,6 +89,7 @@
isa = PBXGroup;
children = (
6D8817C2291ECB97007139C6 /* TrollApps.app */,
0299093E29225B3B006D62D9 /* TrollAppsUITests.xctest */,
);
name = Products;
sourceTree = "<group>";
Expand All @@ -67,6 +102,7 @@
6D8817C9291ECB9B007139C6 /* Assets.xcassets */,
6D8817CB291ECB9B007139C6 /* Preview Content */,
6D8817D3291ED9D7007139C6 /* JSONStuff.swift */,
028DC81A2922695F000F484F /* AsyncButton.swift */,
6D8817D5291EDA19007139C6 /* AppsView.swift */,
6D8817D7291EDAC7007139C6 /* OtherView.swift */,
6D8817D9291EE5C9007139C6 /* Extensions.swift */,
Expand All @@ -86,6 +122,24 @@
/* End PBXGroup section */

/* Begin PBXNativeTarget section */
0299093D29225B3B006D62D9 /* TrollAppsUITests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 0299094629225B3B006D62D9 /* Build configuration list for PBXNativeTarget "TrollAppsUITests" */;
buildPhases = (
0299093A29225B3B006D62D9 /* Sources */,
0299093B29225B3B006D62D9 /* Frameworks */,
0299093C29225B3B006D62D9 /* Resources */,
);
buildRules = (
);
dependencies = (
0299094529225B3B006D62D9 /* PBXTargetDependency */,
);
name = TrollAppsUITests;
productName = TrollAppsUITests;
productReference = 0299093E29225B3B006D62D9 /* TrollAppsUITests.xctest */;
productType = "com.apple.product-type.bundle.ui-testing";
};
6D8817C1291ECB97007139C6 /* TrollApps */ = {
isa = PBXNativeTarget;
buildConfigurationList = 6D8817D0291ECB9B007139C6 /* Build configuration list for PBXNativeTarget "TrollApps" */;
Expand Down Expand Up @@ -116,6 +170,10 @@
LastSwiftUpdateCheck = 1410;
LastUpgradeCheck = 1410;
TargetAttributes = {
0299093D29225B3B006D62D9 = {
CreatedOnToolsVersion = 14.1;
TestTargetID = 6D8817C1291ECB97007139C6;
};
6D8817C1291ECB97007139C6 = {
CreatedOnToolsVersion = 14.1;
LastSwiftMigration = 1410;
Expand All @@ -139,11 +197,19 @@
projectRoot = "";
targets = (
6D8817C1291ECB97007139C6 /* TrollApps */,
0299093D29225B3B006D62D9 /* TrollAppsUITests */,
);
};
/* End PBXProject section */

/* Begin PBXResourcesBuildPhase section */
0299093C29225B3B006D62D9 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
6D8817C0291ECB97007139C6 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
Expand All @@ -156,11 +222,21 @@
/* End PBXResourcesBuildPhase section */

/* Begin PBXSourcesBuildPhase section */
0299093A29225B3B006D62D9 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
0299094329225B3B006D62D9 /* TrollAppsUITestsLaunchTests.swift in Sources */,
0299094129225B3B006D62D9 /* TrollAppsUITests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
6D8817BE291ECB97007139C6 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
6D8817D6291EDA19007139C6 /* AppsView.swift in Sources */,
028DC81B2922695F000F484F /* AsyncButton.swift in Sources */,
6D8817DA291EE5C9007139C6 /* Extensions.swift in Sources */,
6D8817C8291ECB97007139C6 /* ContentView.swift in Sources */,
6D8817D4291ED9D7007139C6 /* JSONStuff.swift in Sources */,
Expand All @@ -171,7 +247,51 @@
};
/* End PBXSourcesBuildPhase section */

/* Begin PBXTargetDependency section */
0299094529225B3B006D62D9 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 6D8817C1291ECB97007139C6 /* TrollApps */;
targetProxy = 0299094429225B3B006D62D9 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */

/* Begin XCBuildConfiguration section */
0299094729225B3B006D62D9 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = A999YUQPG2;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.andreas16700.TrollAppsUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = TrollApps;
};
name = Debug;
};
0299094829225B3B006D62D9 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = A999YUQPG2;
GENERATE_INFOPLIST_FILE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 14.0;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.andreas16700.TrollAppsUITests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_EMIT_LOC_STRINGS = NO;
SWIFT_VERSION = 5.0;
TARGETED_DEVICE_FAMILY = "1,2";
TEST_TARGET_NAME = TrollApps;
};
name = Release;
};
6D8817CE291ECB9B007139C6 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
Expand Down Expand Up @@ -362,6 +482,15 @@
/* End XCBuildConfiguration section */

/* Begin XCConfigurationList section */
0299094629225B3B006D62D9 /* Build configuration list for PBXNativeTarget "TrollAppsUITests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
0299094729225B3B006D62D9 /* Debug */,
0299094829225B3B006D62D9 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
6D8817BD291ECB97007139C6 /* Build configuration list for PBXProject "TrollApps" */ = {
isa = XCConfigurationList;
buildConfigurations = (
Expand Down
84 changes: 67 additions & 17 deletions TrollApps/TrollApps/AppsView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,33 @@ import SDWebImageSwiftUI

struct AppsView: View {
@Environment(\.openURL) var openURL
@Environment(\.scenePhase) var scenePhase
@State private var isshowingdesc = false

@State private var apps: [stuff] = []
@State private var installedAppsBundleIDs = [String]()
@ViewBuilder
func appButton(json: stuff)->some View{
if isAppInstalled(json.bundleid){
Button("OPEN") {
OpenApp(json.bundleid)
}
}else{
Button("GET") {
openURL(URL(string: json.link)!)
}
}
}
var body: some View {
NavigationView {
Form {
ForEach(FetchApps()) { json in
let form = Form {
ForEach(apps) { json in
Section(header: Text(json.title)) {
Label {
HStack {
Text(json.title)
Spacer()
Button(IsAppInstalled(json.bundleid) ? "OPEN" : "GET") {
if IsAppInstalled(json.bundleid) {
OpenApp(json.bundleid)
} else {
openURL(URL(string: json.link)!)
}
}
.buttonStyle(appstorestyle())
appButton(json: json)
.buttonStyle(appstorestyle())
}
} icon: {
WebImage(url: URL(string: json.urlimg))
Expand All @@ -53,14 +61,56 @@ struct AppsView: View {
.environment(\.defaultMinListRowHeight, 50)
.navigationTitle("Apps")
.toolbar {
Button {
withAnimation {
isshowingdesc.toggle()
}
} label: {
Image(systemName: "info.circle")
ToolbarItem(placement: .navigationBarLeading){
Button {
withAnimation {
isshowingdesc.toggle()
}
} label: {
Image(systemName: "info.circle")
}
}
}
// from https://www.hackingwithswift.com/books/ios-swiftui/how-to-be-notified-when-your-swiftui-app-moves-to-the-background
.onChange(of: scenePhase) { newPhase in
if newPhase == .active {
print("Active, will refresh")
Task(operation: refresh)
}
}
if #available(iOS 15.0, *) {
form
.refreshable {
Task{await refresh()}
}
} else {
form
.toolbar{
ToolbarItem(placement: .navigationBarTrailing){
AsyncButton(action: refresh){
Image(systemName: "arrow.clockwise")
}
}
}
}
}
}
@Sendable
func refresh()async{
let currentInstalledAppsBundleIDs = GetApps()
DispatchQueue.main.async {
withAnimation{
self.installedAppsBundleIDs=currentInstalledAppsBundleIDs
}
}
guard let updatedApps = await FetchApps() else {return}
DispatchQueue.main.async {
withAnimation{
self.apps=updatedApps
}
}
}
func isAppInstalled(_ BundleID: String) -> Bool {
installedAppsBundleIDs.contains(BundleID)
}
}
44 changes: 44 additions & 0 deletions TrollApps/TrollApps/AsyncButton.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
//
// AsyncButton.swift
//
// Borrowed from https://www.swiftbysundell.com/articles/building-an-async-swiftui-button/
//

import Foundation
import SwiftUI

struct AsyncButton<Label: View>: View {
var action: () async -> Void
@ViewBuilder var label: () -> Label

@State private var isPerformingTask = false

var body: some View {
Button(
action: {
withAnimation{
isPerformingTask = true
}
Task {
await action()
withAnimation{
isPerformingTask = false
}
}
},
label: {
ZStack {
// We hide the label by setting its opacity
// to zero, since we don't want the button's
// size to change while its task is performed:
label().opacity(isPerformingTask ? 0 : 1)

if isPerformingTask {
ProgressView()
}
}
}
)
.disabled(isPerformingTask)
}
}
4 changes: 0 additions & 4 deletions TrollApps/TrollApps/Extensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,6 @@ public struct somebuttonstyle: ButtonStyle {
}
}

func IsAppInstalled(_ BundleID: String) -> Bool {
return GetApps().contains(BundleID)
}

func GetApps() -> [String] {
var apps: [String] = []
for app in LSApplicationWorkspace().allInstalledApplications() as! [LSApplicationProxy] {
Expand Down
Loading

0 comments on commit ae766fb

Please sign in to comment.