diff --git a/StikDebug.xcodeproj/project.pbxproj b/StikDebug.xcodeproj/project.pbxproj
index eff64665..c5bad727 100644
--- a/StikDebug.xcodeproj/project.pbxproj
+++ b/StikDebug.xcodeproj/project.pbxproj
@@ -7,6 +7,7 @@
objects = {
/* Begin PBXBuildFile section */
+ 17C744F02E20BED000834F17 /* Pipify in Frameworks */ = {isa = PBXBuildFile; productRef = 17C744EF2E20BED000834F17 /* Pipify */; };
68D569BE2E1B415700A5BA36 /* CodeEditorView in Frameworks */ = {isa = PBXBuildFile; productRef = 68D569BD2E1B415700A5BA36 /* CodeEditorView */; };
68D569C02E1B415700A5BA36 /* LanguageSupport in Frameworks */ = {isa = PBXBuildFile; productRef = 68D569BF2E1B415700A5BA36 /* LanguageSupport */; };
DC139F6E2DE97EA400F63846 /* WidgetKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DC139F6D2DE97EA400F63846 /* WidgetKit.framework */; };
@@ -149,6 +150,7 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
+ 17C744F02E20BED000834F17 /* Pipify in Frameworks */,
68D569C02E1B415700A5BA36 /* LanguageSupport in Frameworks */,
68D569BE2E1B415700A5BA36 /* CodeEditorView in Frameworks */,
);
@@ -262,6 +264,7 @@
packageProductDependencies = (
68D569BD2E1B415700A5BA36 /* CodeEditorView */,
68D569BF2E1B415700A5BA36 /* LanguageSupport */,
+ 17C744EF2E20BED000834F17 /* Pipify */,
);
productName = StikJIT;
productReference = DC6F1D372D94EADD0071B2B6 /* StikDebug.app */;
@@ -377,6 +380,7 @@
minimizedProjectReferenceProxies = 1;
packageReferences = (
68D569BC2E1B415700A5BA36 /* XCRemoteSwiftPackageReference "CodeEditorView" */,
+ 17C744EE2E20BED000834F17 /* XCRemoteSwiftPackageReference "swiftui-pipify" */,
);
preferredProjectObjectVersion = 77;
productRefGroup = DC6F1D382D94EADD0071B2B6 /* Products */;
@@ -971,6 +975,14 @@
/* End XCConfigurationList section */
/* Begin XCRemoteSwiftPackageReference section */
+ 17C744EE2E20BED000834F17 /* XCRemoteSwiftPackageReference "swiftui-pipify" */ = {
+ isa = XCRemoteSwiftPackageReference;
+ repositoryURL = "https://github.com/hugeBlack/swiftui-pipify";
+ requirement = {
+ branch = main;
+ kind = branch;
+ };
+ };
68D569BC2E1B415700A5BA36 /* XCRemoteSwiftPackageReference "CodeEditorView" */ = {
isa = XCRemoteSwiftPackageReference;
repositoryURL = "https://github.com/mchakravarty/CodeEditorView";
@@ -982,6 +994,11 @@
/* End XCRemoteSwiftPackageReference section */
/* Begin XCSwiftPackageProductDependency section */
+ 17C744EF2E20BED000834F17 /* Pipify */ = {
+ isa = XCSwiftPackageProductDependency;
+ package = 17C744EE2E20BED000834F17 /* XCRemoteSwiftPackageReference "swiftui-pipify" */;
+ productName = Pipify;
+ };
68D569BD2E1B415700A5BA36 /* CodeEditorView */ = {
isa = XCSwiftPackageProductDependency;
package = 68D569BC2E1B415700A5BA36 /* XCRemoteSwiftPackageReference "CodeEditorView" */;
diff --git a/StikJIT/Info.plist b/StikJIT/Info.plist
index 47f198b1..ece1afd5 100644
--- a/StikJIT/Info.plist
+++ b/StikJIT/Info.plist
@@ -18,8 +18,6 @@
UIBackgroundModes
audio
- processing
- fetch
UIFileSharingEnabled
diff --git a/StikJIT/JSSupport/PiPController.swift b/StikJIT/JSSupport/PiPController.swift
deleted file mode 100644
index ef0ba81b..00000000
--- a/StikJIT/JSSupport/PiPController.swift
+++ /dev/null
@@ -1,55 +0,0 @@
-//
-// PiPController.swift
-// StikDebug
-//
-// Created by Stossy11 on 10/07/2025.
-//
-
-
-import SwiftUI
-import AVKit
-import AVFoundation
-
-struct VideoPlayerView: UIViewRepresentable {
- let pipController: PiPController = PiPController.shared
- let view: any View
-
- func makeUIView(context: Context) -> UIView {
- let containerView = UIView()
-
- // Setup player layer
- let playerLayer = AVPlayerLayer()
- playerLayer.frame = CGRect(x: 0, y: 0, width: 200, height: 150)
-
- // Load video from bundle
- guard let videoURL = Bundle.main.url(forResource: "black", withExtension: "MP4") else {
- print("Could not find black.MP4 in bundle")
- return containerView
- }
-
- let asset = AVAsset(url: videoURL)
- let playerItem = AVPlayerItem(asset: asset)
- let player = AVPlayer(playerItem: playerItem)
-
- playerLayer.player = player
- player.isMuted = true
- player.allowsExternalPlayback = true
-
- containerView.layer.addSublayer(playerLayer)
-
- // Convert SwiftUI view to UIView using UIHostingController
- let hostingController = UIHostingController(rootView: AnyView(self.view))
- let swiftUIAsUIView = hostingController.view!
-
- // Set the converted UIView to the PiPController
- pipController.customUIView = swiftUIAsUIView
-
- pipController.setupPiP(with: playerLayer)
-
- return containerView
- }
-
- func updateUIView(_ uiView: UIView, context: Context) {
- // Update UI if needed
- }
-}
diff --git a/StikJIT/JSSupport/RunJSView.swift b/StikJIT/JSSupport/RunJSView.swift
index efc1c050..4b1d11fa 100644
--- a/StikJIT/JSSupport/RunJSView.swift
+++ b/StikJIT/JSSupport/RunJSView.swift
@@ -69,14 +69,14 @@ class RunJSViewModel: ObservableObject {
if let semaphore {
semaphore.signal()
}
- PiPController.shared.stopPiP()
DispatchQueue.main.async {
if let exception = self.context?.exception {
self.logs.append(exception.debugDescription)
}
- self.logs.append("Script Execution Completed, \nYou are safe to close the PIP Window.")
+ self.logs.append("Script Execution Completed")
+ self.logs.append("You are safe to close the PIP Window.")
}
}
}
@@ -99,6 +99,7 @@ struct RunJSViewPiP: View {
.onReceive(timer) { _ in
self.logs = model?.logs ?? []
}
+ .frame(width: 300, height: 150)
}
}
diff --git a/StikJIT/StikJIT-Bridging-Header.h b/StikJIT/StikJIT-Bridging-Header.h
index 7320cf86..c4ea98d7 100644
--- a/StikJIT/StikJIT-Bridging-Header.h
+++ b/StikJIT/StikJIT-Bridging-Header.h
@@ -6,4 +6,3 @@
#include "idevice/idevice.h"
#include "idevice/heartbeat.h"
#include "JSSupport/JSSupport.h"
-#include "Utilities/PiP/PiPController.h"
diff --git a/StikJIT/Utilities/PiP/PiPController.h b/StikJIT/Utilities/PiP/PiPController.h
deleted file mode 100644
index 7952f4de..00000000
--- a/StikJIT/Utilities/PiP/PiPController.h
+++ /dev/null
@@ -1,29 +0,0 @@
-//
-// PiPController.h
-// StikDebug
-//
-// Created by Stossy11 on 10/07/2025.
-//
-
-
-#import
-#import
-#import
-#import
-
-NS_ASSUME_NONNULL_BEGIN
-
-@interface PiPController : NSObject
-
-@property (nonatomic, assign) BOOL isPiPActive;
-@property (nonatomic, strong, nullable) UIView *customUIView;
-@property (class, nonatomic, readonly) PiPController *shared;
-
-- (void)setupPiPWithPlayerLayer:(AVPlayerLayer *)playerLayer;
-- (void)startPiP;
-- (void)stopPiP;
-- (void)togglePiP;
-
-@end
-
-NS_ASSUME_NONNULL_END
diff --git a/StikJIT/Utilities/PiP/PiPController.m b/StikJIT/Utilities/PiP/PiPController.m
deleted file mode 100644
index 83e939e8..00000000
--- a/StikJIT/Utilities/PiP/PiPController.m
+++ /dev/null
@@ -1,138 +0,0 @@
-//
-// PiPController.m
-// StikDebug
-//
-// Created by Stossy11 on 10/07/2025.
-//
-
-#import "PiPController.h"
-
-@interface PiPController ()
-@property (nonatomic, strong, nullable) AVPictureInPictureController *pipController;
-@property (nonatomic, strong, nullable) AVPlayerLayer *playerLayer;
-@property (nonatomic, strong, nullable) UIView *customView;
-@end
-
-@implementation PiPController
-
-+ (PiPController *)shared {
- static PiPController *sharedInstance = nil;
- static dispatch_once_t onceToken;
- dispatch_once(&onceToken, ^{
- sharedInstance = [[self alloc] init];
- });
- return sharedInstance;
-}
-
-- (instancetype)init {
- self = [super init];
- if (self) {
- _isPiPActive = NO;
- [self setupAudioSession];
- }
- return self;
-}
-
-- (void)setupAudioSession {
- NSError *error = nil;
- AVAudioSession *audioSession = [AVAudioSession sharedInstance];
-
- if (![audioSession setCategory:AVAudioSessionCategoryPlayback error:&error]) {
- NSLog(@"Audio session setup error: %@", error.localizedDescription);
- return;
- }
-
- if (![audioSession setActive:YES withOptions:AVAudioSessionSetActiveOptionNotifyOthersOnDeactivation error:&error]) {
- NSLog(@"Audio session setup error: %@", error.localizedDescription);
- }
-}
-
-- (void)setupPiPWithPlayerLayer:(AVPlayerLayer *)playerLayer {
- if (![AVPictureInPictureController isPictureInPictureSupported]) {
- NSLog(@"Picture in Picture not supported");
- return;
- }
-
- self.playerLayer = playerLayer;
-
- self.pipController = [[AVPictureInPictureController alloc] initWithPlayerLayer:playerLayer];
- self.pipController.delegate = self;
-
- // Set controls style (equivalent to setValue:forKey: in Swift)
- if ([self.pipController respondsToSelector:@selector(setControlsStyle:)]) {
- [self.pipController setValue:@(1) forKey:@"controlsStyle"];
- }
-}
-
-- (void)startPiP {
- if (self.pipController.isPictureInPictureActive) return;
-
- [self.pipController startPictureInPicture];
-}
-
-- (void)stopPiP {
- if (!self.pipController.isPictureInPictureActive) return;
-
- [self.pipController stopPictureInPicture];
-}
-
-- (void)togglePiP {
- if (self.isPiPActive) {
- [self stopPiP];
- } else {
- [self startPiP];
- }
-}
-
-#pragma mark - AVPictureInPictureControllerDelegate
-
-- (void)pictureInPictureControllerWillStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
- if (!self.customUIView) {
- NSLog(@"Fatal error: customUIView = nil");
- return;
- }
-
- dispatch_async(dispatch_get_main_queue(), ^{
- self.isPiPActive = YES;
- });
-
- self.customView = self.customUIView;
-
- UIWindow *window = [UIApplication sharedApplication].windows.firstObject;
- if (window && self.customView) {
- self.customView.backgroundColor = [UIColor clearColor];
- [window addSubview:self.customView];
-
- self.customView.translatesAutoresizingMaskIntoConstraints = NO;
- [NSLayoutConstraint activateConstraints:@[
- [self.customView.topAnchor constraintEqualToAnchor:window.topAnchor],
- [self.customView.leadingAnchor constraintEqualToAnchor:window.leadingAnchor],
- [self.customView.trailingAnchor constraintEqualToAnchor:window.trailingAnchor],
- [self.customView.bottomAnchor constraintEqualToAnchor:window.bottomAnchor]
- ]];
- }
-}
-
-
-- (void)pictureInPictureControllerDidStartPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
- NSLog(@"PiP started");
-}
-
-- (void)pictureInPictureControllerDidStopPictureInPicture:(AVPictureInPictureController *)pictureInPictureController {
- dispatch_async(dispatch_get_main_queue(), ^{
- self.isPiPActive = NO;
- });
-
- // Remove custom view
- [self.customView removeFromSuperview];
- self.customView = nil;
-}
-
-- (void)pictureInPictureController:(AVPictureInPictureController *)pictureInPictureController failedToStartPictureInPictureWithError:(NSError *)error {
- NSLog(@"Failed to start PiP: %@", error.localizedDescription);
- dispatch_async(dispatch_get_main_queue(), ^{
- self.isPiPActive = NO;
- });
-}
-
-@end
diff --git a/StikJIT/Views/HomeView.swift b/StikJIT/Views/HomeView.swift
index e062d0c8..89f78ffd 100644
--- a/StikJIT/Views/HomeView.swift
+++ b/StikJIT/Views/HomeView.swift
@@ -7,6 +7,7 @@
import SwiftUI
import UniformTypeIdentifiers
+import Pipify
extension UIDocumentPickerViewController {
@objc func fix_init(forOpeningContentTypes contentTypes: [UTType], asCopy: Bool) -> UIDocumentPickerViewController {
@@ -59,19 +60,6 @@ struct HomeView: View {
Color(colorScheme == .dark ? .black : .white)
.edgesIgnoringSafeArea(.all)
- if useDefaultScript {
- VideoPlayerView(view: RunJSViewPiP(model: $jsModel))
- .frame(width: 200, height: 150)
- .background(Color.clear)
- .cornerRadius(10)
- .onAppear() {
- Timer.scheduledTimer(withTimeInterval: 0.3, repeats: false) { _ in
- PiPController.shared.startPiP()
- }
- }
- .overlay(colorScheme == .dark ? .black : .white)
- }
-
VStack(spacing: 25) {
Spacer()
VStack(spacing: 5) {
@@ -237,12 +225,7 @@ struct HomeView: View {
.onReceive(timer) { _ in
refreshBackground()
checkPairingFileExists()
-
- if useDefaultScript {
- PiPController.shared.startPiP()
- } else {
- PiPController.shared.stopPiP()
- }
+
}
.fileImporter(isPresented: $isShowingPairingFilePicker, allowedContentTypes: [UTType(filenameExtension: "mobiledevicepairing", conformingTo: .data)!, .propertyList]) {result in
switch result {
@@ -320,6 +303,9 @@ struct HomeView: View {
startJITInBackground(with: selectedBundle)
}
}
+ .pipify(isPresented: $isProcessing) {
+ RunJSViewPiP(model: $jsModel)
+ }
.sheet(isPresented: $scriptViewShow) {
NavigationView {
if let jsModel {
@@ -328,6 +314,7 @@ struct HomeView: View {
ToolbarItem(placement: .topBarTrailing) {
Button("Done") {
scriptViewShow = false
+ isProcessing = false
}
}
}
@@ -433,6 +420,7 @@ struct HomeView: View {
DispatchQueue.global(qos: .background).async {
do {
try jsModel?.runScript(path: selectedScriptURL)
+ isProcessing = false
} catch {
showAlert(title: "Error Occurred While Executing the Default Script.".localized, message: error.localizedDescription, showOk: true)
}
diff --git a/StikJIT/black.MP4 b/StikJIT/black.MP4
deleted file mode 100644
index a9b39594..00000000
Binary files a/StikJIT/black.MP4 and /dev/null differ