diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..fd3904e Binary files /dev/null and b/.DS_Store differ diff --git a/2qw/2qw.xcodeproj/project.pbxproj b/2qw/2qw.xcodeproj/project.pbxproj new file mode 100644 index 0000000..30b66b7 --- /dev/null +++ b/2qw/2qw.xcodeproj/project.pbxproj @@ -0,0 +1,413 @@ +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXFileReference section */ + 4D4C76A52D4E9104005E2F9B /* 2qw.xpc */ = {isa = PBXFileReference; explicitFileType = "wrapper.xpc-service"; includeInIndex = 0; path = 2qw.xpc; sourceTree = BUILT_PRODUCTS_DIR; }; + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.framework"; path = MyBuildToolPlugin; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFileSystemSynchronizedBuildFileExceptionSet section */ + 4D4C76B02D4E9104005E2F9B /* Exceptions for "2qw" folder in "2qw" target */ = { + isa = PBXFileSystemSynchronizedBuildFileExceptionSet; + membershipExceptions = ( + Info.plist, + ); + target = 4D4C76A42D4E9104005E2F9B /* 2qw */; + }; +/* End PBXFileSystemSynchronizedBuildFileExceptionSet section */ + +/* Begin PBXFileSystemSynchronizedRootGroup section */ + 4D4C76A72D4E9104005E2F9B /* 2qw */ = { + isa = PBXFileSystemSynchronizedRootGroup; + exceptions = ( + 4D4C76B02D4E9104005E2F9B /* Exceptions for "2qw" folder in "2qw" target */, + ); + path = 2qw; + sourceTree = ""; + }; +/* End PBXFileSystemSynchronizedRootGroup section */ + +/* Begin PBXFrameworksBuildPhase section */ + 4D4C76A22D4E9104005E2F9B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */ = {isa = PBXBuildFile; fileRef = 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */; }; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 4D4C769C2D4E9104005E2F9B = { + isa = PBXGroup; + children = ( + 4D4C76A72D4E9104005E2F9B /* 2qw */, + 4D4C76A62D4E9104005E2F9B /* Products */, + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */, + ); + sourceTree = ""; + }; + 4D4C76A62D4E9104005E2F9B /* Products */ = { + isa = PBXGroup; + children = ( + 4D4C76A52D4E9104005E2F9B /* 2qw.xpc */, + ); + name = Products; + sourceTree = ""; + }; + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */ = { + isa = PBXGroup; + children = ( + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */, + ); + name = MyBuildToolPlugin; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 4D4C76A42D4E9104005E2F9B /* 2qw */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4D4C76B12D4E9104005E2F9B /* Build configuration list for PBXNativeTarget "2qw" */; + buildPhases = ( + 4D4C76A12D4E9104005E2F9B /* Sources */, + 4D4C76A22D4E9104005E2F9B /* Frameworks */, + 4D4C76A32D4E9104005E2F9B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 4D4C76A72D4E9104005E2F9B /* 2qw */, + ); + name = 2qw; + packageProductDependencies = ( + ); + productName = 2qw; + productReference = 4D4C76A52D4E9104005E2F9B /* 2qw.xpc */; + productType = "com.apple.product-type.xpc-service"; + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */ = { + isa = PBXNativeTarget; + buildConfigurationList = 4D4C76B12D4E9104005E2F9B /* Build configuration list for PBXNativeTarget "MyBuildToolPlugin" */; + buildPhases = ( + 4D4C76A12D4E9104005E2F9B /* Sources */, + 4D4C76A22D4E9104005E2F9B /* Frameworks */, + 4D4C76A32D4E9104005E2F9B /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + fileSystemSynchronizedGroups = ( + 4D4C76A72D4E9104005E2F9B /* MyBuildToolPlugin */, + ); + name = MyBuildToolPlugin; + packageProductDependencies = ( + ); + productName = MyBuildToolPlugin; + productReference = 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */; + productType = "com.apple.product-type.framework"; + }; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 4D4C769D2D4E9104005E2F9B /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1620; + LastUpgradeCheck = 1620; + TargetAttributes = { + 4D4C76A42D4E9104005E2F9B = { + CreatedOnToolsVersion = 16.2; + }; + }; + }; + buildConfigurationList = 4D4C76A02D4E9104005E2F9B /* Build configuration list for PBXProject "2qw" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 4D4C769C2D4E9104005E2F9B; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 4D4C76A62D4E9104005E2F9B /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 4D4C76A42D4E9104005E2F9B /* 2qw */, + 4D4C76A52D4E9104005E2F9B /* MyBuildToolPlugin */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 4D4C76A32D4E9104005E2F9B /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 4D4C76A12D4E9104005E2F9B /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 4D4C76B22D4E9104005E2F9B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = 2qw/_qw.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = S9ZL84LCM9; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = 2qw/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = 2qw; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "p.-qw"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 4D4C76B32D4E9104005E2F9B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = 2qw/_qw.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = S9ZL84LCM9; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = 2qw/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = 2qw; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "p.-qw"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 4D4C76B42D4E9104005E2F9B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 15.2; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = macosx; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 4D4C76B52D4E9104005E2F9B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MACOSX_DEPLOYMENT_TARGET = 15.2; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; + }; + name = Release; + }; + 4D4C76B62D4E9104005E2F9B /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = 2qw/_qw.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = S9ZL84LCM9; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = 2qw/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = 2qw; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "p.-qw"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 4D4C76B72D4E9104005E2F9B /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CODE_SIGN_ENTITLEMENTS = 2qw/_qw.entitlements; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_TEAM = S9ZL84LCM9; + ENABLE_HARDENED_RUNTIME = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = 2qw/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = 2qw; + INFOPLIST_KEY_NSHumanReadableCopyright = ""; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = "p.-qw"; + PRODUCT_NAME = "$(TARGET_NAME)"; + SKIP_INSTALL = YES; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 4D4C76A02D4E9104005E2F9B /* Build configuration list for PBXProject "2qw" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D4C76B42D4E9104005E2F9B /* Debug */, + 4D4C76B52D4E9104005E2F9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4D4C76B12D4E9104005E2F9B /* Build configuration list for PBXNativeTarget "2qw" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D4C76B22D4E9104005E2F9B /* Debug */, + 4D4C76B32D4E9104005E2F9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 4D4C76B82D4E9104005E2F9B /* Build configuration list for PBXNativeTarget "MyBuildToolPlugin" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 4D4C76B62D4E9104005E2F9B /* Debug */, + 4D4C76B72D4E9104005E2F9B /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + }; + rootObject = 4D4C769D2D4E9104005E2F9B /* Project object */; +} diff --git a/2qw/2qw.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/2qw/2qw.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..cf50759 --- /dev/null +++ b/2qw/2qw.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/2qw/2qw.xcodeproj/project.xcworkspace/xcuserdata/patrik8393.xcuserdatad/UserInterfaceState.xcuserstate b/2qw/2qw.xcodeproj/project.xcworkspace/xcuserdata/patrik8393.xcuserdatad/UserInterfaceState.xcuserstate new file mode 100644 index 0000000..bcf77f1 Binary files /dev/null and b/2qw/2qw.xcodeproj/project.xcworkspace/xcuserdata/patrik8393.xcuserdatad/UserInterfaceState.xcuserstate differ diff --git a/2qw/2qw.xcodeproj/xcshareddata/xcschemes/2qw.xcscheme b/2qw/2qw.xcodeproj/xcshareddata/xcschemes/2qw.xcscheme new file mode 100644 index 0000000..2382910 --- /dev/null +++ b/2qw/2qw.xcodeproj/xcshareddata/xcschemes/2qw.xcscheme @@ -0,0 +1,113 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/2qw/2qw.xcodeproj/xcuserdata/patrik8393.xcuserdatad/xcschemes/xcschememanagement.plist b/2qw/2qw.xcodeproj/xcuserdata/patrik8393.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 0000000..1f06c15 --- /dev/null +++ b/2qw/2qw.xcodeproj/xcuserdata/patrik8393.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,32 @@ + + + + + SchemeUserState + + 2qw.xcscheme_^#shared#^_ + + orderHint + 0 + + MyBuildToolPlugin.xcscheme_^#shared#^_ + + orderHint + 1 + + + SuppressBuildableAutocreation + + 4D4C76A42D4E9104005E2F9B + + primary + + + 4D4C76A52D4E9104005E2F9B + + primary + + + + + diff --git a/2qw/2qw/Info.plist b/2qw/2qw/Info.plist new file mode 100644 index 0000000..c123a5d --- /dev/null +++ b/2qw/2qw/Info.plist @@ -0,0 +1,11 @@ + + + + + XPCService + + ServiceType + Application + + + diff --git a/2qw/2qw/_qw.entitlements b/2qw/2qw/_qw.entitlements new file mode 100644 index 0000000..852fa1a --- /dev/null +++ b/2qw/2qw/_qw.entitlements @@ -0,0 +1,8 @@ + + + + + com.apple.security.app-sandbox + + + diff --git a/2qw/2qw/_qw.swift b/2qw/2qw/_qw.swift new file mode 100644 index 0000000..e7a113e --- /dev/null +++ b/2qw/2qw/_qw.swift @@ -0,0 +1,18 @@ +// +// _qw.swift +// 2qw +// +// Created by PF on 01/02/2025. +// + +import Foundation + +/// This object implements the protocol which we have defined. It provides the actual behavior for the service. It is 'exported' by the service to make it available to the process hosting the service over an NSXPCConnection. +class _qw: NSObject, _qwProtocol { + + /// This implements the example protocol. Replace the body of this class with the implementation of this service's protocol. + @objc func performCalculation(firstNumber: Int, secondNumber: Int, with reply: @escaping (Int) -> Void) { + let response = firstNumber + secondNumber + reply(response) + } +} diff --git a/2qw/2qw/_qwProtocol.swift b/2qw/2qw/_qwProtocol.swift new file mode 100644 index 0000000..e2c9909 --- /dev/null +++ b/2qw/2qw/_qwProtocol.swift @@ -0,0 +1,35 @@ +// +// _qwProtocol.swift +// 2qw +// +// Created by PF on 01/02/2025. +// + +import Foundation + +/// The protocol that this service will vend as its API. This protocol will also need to be visible to the process hosting the service. +@objc protocol _qwProtocol { + + /// Replace the API of this protocol with an API appropriate to the service you are vending. + func performCalculation(firstNumber: Int, secondNumber: Int, with reply: @escaping (Int) -> Void) +} + +/* + To use the service from an application or other process, use NSXPCConnection to establish a connection to the service by doing something like this: + + connectionToService = NSXPCConnection(serviceName: "p.-qw") + connectionToService.remoteObjectInterface = NSXPCInterface(with: _qwProtocol.self) + connectionToService.resume() + + Once you have a connection to the service, you can use it like this: + + if let proxy = connectionToService.remoteObjectProxy as? _qwProtocol { + proxy.performCalculation(firstNumber: 23, secondNumber: 19) { result in + NSLog("Result of calculation is: \(result)") + } + } + + And, when you are finished with the service, clean up the connection like this: + + connectionToService.invalidate() +*/ diff --git a/2qw/2qw/main.swift b/2qw/2qw/main.swift new file mode 100644 index 0000000..27dccea --- /dev/null +++ b/2qw/2qw/main.swift @@ -0,0 +1,39 @@ +// +// main.swift +// 2qw +// +// Created by PF on 01/02/2025. +// + +import Foundation + +class ServiceDelegate: NSObject, NSXPCListenerDelegate { + + /// This method is where the NSXPCListener configures, accepts, and resumes a new incoming NSXPCConnection. + func listener(_ listener: NSXPCListener, shouldAcceptNewConnection newConnection: NSXPCConnection) -> Bool { + + // Configure the connection. + // First, set the interface that the exported object implements. + newConnection.exportedInterface = NSXPCInterface(with: _qwProtocol.self) + + // Next, set the object that the connection exports. All messages sent on the connection to this service will be sent to the exported object to handle. The connection retains the exported object. + let exportedObject = _qw() + newConnection.exportedObject = exportedObject + + // Resuming the connection allows the system to deliver more incoming messages. + newConnection.resume() + + // Returning true from this method tells the system that you have accepted this connection. If you want to reject the connection for some reason, call invalidate() on the connection and return false. + return true + } +} + +// Create the delegate for the service. +let delegate = ServiceDelegate() + +// Set up the one NSXPCListener for this service. It will handle all incoming connections. +let listener = NSXPCListener.service() +listener.delegate = delegate + +// Resuming the serviceListener starts this service. This method does not return. +listener.resume() diff --git a/MyBuildToolPlugin/.gitignore b/MyBuildToolPlugin/.gitignore new file mode 100644 index 0000000..0023a53 --- /dev/null +++ b/MyBuildToolPlugin/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +/.build +/Packages +xcuserdata/ +DerivedData/ +.swiftpm/configuration/registries.json +.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata +.netrc diff --git a/MyBuildToolPlugin/Package.swift b/MyBuildToolPlugin/Package.swift new file mode 100644 index 0000000..364980d --- /dev/null +++ b/MyBuildToolPlugin/Package.swift @@ -0,0 +1,22 @@ +import PackageDescription + +let package = Package( + name: "MyBuildToolPlugin", + products: [ + // Products can be used to vend plugins, making them visible to other packages. + .plugin( + name: "MyBuildToolPlugin", + targets: ["MyBuildToolPlugin"]), + ], + dependencies: [ + .package(url: "https://github.com/apple/swift-tools-support-core.git", from: "0.1.0"), + ], + targets: [ + // Targets are the basic building blocks of a package, defining a module or a test suite. + // Targets can depend on other targets in this package and products from dependencies. + .plugin( + name: "MyBuildToolPlugin", + capability: .buildTool() + ), + ] +) diff --git a/MyBuildToolPlugin/Plugins/MyBuildToolPlugin.swift b/MyBuildToolPlugin/Plugins/MyBuildToolPlugin.swift new file mode 100644 index 0000000..606c7a7 --- /dev/null +++ b/MyBuildToolPlugin/Plugins/MyBuildToolPlugin.swift @@ -0,0 +1,88 @@ +import PackagePlugin + +@main +struct MyBuildToolPlugin: BuildToolPlugin { + /// Entry point for creating build commands for targets in Swift packages. + func createBuildCommands(context: PluginContext, target: Target) async throws -> [Command] { + // This plugin only runs for package targets that can have source files. + guard let sourceFiles = target.sourceModule?.sourceFiles else { return [] } + + // Find the code generator tool to run (replace this with the actual one). + let generatorTool = try context.tool(named: "my-code-generator") + + // Construct a build command for each source file with a particular suffix. + return sourceFiles.map(\.path).compactMap { + createBuildCommand(for: $0, in: context.pluginWorkDirectory, with: generatorTool.path) + } + } + + /// New function to create test commands for MyBuildToolPlugin + func createTestCommands(context: PluginContext, target: Target) async throws -> [Command] { + // This plugin only runs for package targets that can have source files. + guard let sourceFiles = target.sourceModule?.sourceFiles else { return [] } + + // Find the test tool to run (replace this with the actual one). + let testTool = try context.tool(named: "my-test-tool") + + // Construct a test command for each source file with a particular suffix. + return sourceFiles.map(\.path).compactMap { + createTestCommand(for: $0, in: context.pluginWorkDirectory, with: testTool.path) + } + } +} + +#if canImport(XcodeProjectPlugin) +import XcodeProjectPlugin + +extension MyBuildToolPlugin: XcodeBuildToolPlugin { + // Entry point for creating build commands for targets in Xcode projects. + func createBuildCommands(context: XcodePluginContext, target: XcodeTarget) throws -> [Command] { + // Find the code generator tool to run (replace this with the actual one). + let generatorTool = try context.tool(named: "my-code-generator") + + // Construct a build command for each source file with a particular suffix. + return target.inputFiles.map(\.path).compactMap { + createBuildCommand(for: $0, in: context.pluginWorkDirectory, with: generatorTool.path) + } + } +} + +#endif + +extension MyBuildToolPlugin { + /// Shared function that returns a configured build command if the input files is one that should be processed. + func createBuildCommand(for inputPath: Path, in outputDirectoryPath: Path, with generatorToolPath: Path) -> Command? { + // Skip any file that doesn't have the extension we're looking for (replace this with the actual one). + guard inputPath.extension == "my-input-suffix" else { return .none } + + // Return a command that will run during the build to generate the output file. + let inputName = inputPath.lastComponent + let outputName = inputPath.stem + ".swift" + let outputPath = outputDirectoryPath.appending(outputName) + return .buildCommand( + displayName: "Generating \(outputName) from \(inputName)", + executable: generatorToolPath, + arguments: ["\(inputPath)", "-o", "\(outputPath)"], + inputFiles: [inputPath], + outputFiles: [outputPath] + ) + } + + /// Shared function that returns a configured test command if the input files is one that should be processed. + func createTestCommand(for inputPath: Path, in outputDirectoryPath: Path, with testToolPath: Path) -> Command? { + // Skip any file that doesn't have the extension we're looking for (replace this with the actual one). + guard inputPath.extension == "my-input-suffix" else { return .none } + + // Return a command that will run during the build to generate the output file. + let inputName = inputPath.lastComponent + let outputName = inputPath.stem + ".test" + let outputPath = outputDirectoryPath.appending(outputName) + return .buildCommand( + displayName: "Testing \(outputName) from \(inputName)", + executable: testToolPath, + arguments: ["\(inputPath)", "-o", "\(outputPath)"], + inputFiles: [inputPath], + outputFiles: [outputPath] + ) + } +} diff --git a/README.md b/README.md index 54fb9fc..a1ceecd 100644 --- a/README.md +++ b/README.md @@ -23,4 +23,8 @@ Please report issues [here](https://github.com/fuse-x/studio/issues). The source code is available for contributors. Please contact us for details. +## MyBuildToolPlugin + +The `MyBuildToolPlugin` is a new plugin added to the project. It provides a build tool capability for generating code during the build process. The plugin is defined in the `MyBuildToolPlugin/Package.swift` file and the main source file is `MyBuildToolPlugin/Plugins/MyBuildToolPlugin.swift`. +