From 58b36ca0b25cf870595f29f5b67fce22a7b41f0c Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Sat, 13 Jun 2026 23:06:21 +0900 Subject: [PATCH 1/2] =?UTF-8?q?fix:=20SwiftLint=EB=A5=BC=20maintainer=20?= =?UTF-8?q?=EC=A0=84=EC=9A=A9=20workflow=EB=A1=9C=20=EB=B6=84=EB=A6=AC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../NexaClient.xcodeproj/project.pbxproj | 393 ++++++++++++++++++ .../NexaClient/NexaClient/ContentView.swift | 34 ++ .../NexaClient/NexaClient/NexaClientApp.swift | 17 + .../NexaClient/NexaIntegrationPreview.swift | 44 ++ Package.resolved | 15 - Package.swift | 27 +- README.ko.md | 13 + README.md | 13 + 8 files changed, 517 insertions(+), 39 deletions(-) create mode 100644 Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj create mode 100644 Examples/NexaClient/NexaClient/ContentView.swift create mode 100644 Examples/NexaClient/NexaClient/NexaClientApp.swift create mode 100644 Examples/NexaClient/NexaClient/NexaIntegrationPreview.swift delete mode 100644 Package.resolved diff --git a/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj b/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj new file mode 100644 index 0000000..ab3f0b7 --- /dev/null +++ b/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj @@ -0,0 +1,393 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 3A6C19D889DFC0D5AAAE7398 /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C3CC707D1B1D4215893D0C24 /* ContentView.swift */; }; + 8B618FC9B82424737A92D3E3 /* NexaIntegrationPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9398B6CF8522A7EC915B1B82 /* NexaIntegrationPreview.swift */; }; + 8ED7BD97F368F2CA777F8285 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E4507C23C16857EDCCB7C77 /* Foundation.framework */; }; + A97E7CFF74509C5A91E5098F /* Nexa in Frameworks */ = {isa = PBXBuildFile; productRef = 4EE316A66ED03685DB9E966E /* Nexa */; }; + F7945339318AA5C557A99AC2 /* NexaClientApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 602E17E5451FC46F0B078998 /* NexaClientApp.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 1E4507C23C16857EDCCB7C77 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS18.0.sdk/System/Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; + 602E17E5451FC46F0B078998 /* NexaClientApp.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NexaClientApp.swift; path = NexaClient/NexaClientApp.swift; sourceTree = ""; }; + 9398B6CF8522A7EC915B1B82 /* NexaIntegrationPreview.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = NexaIntegrationPreview.swift; path = NexaClient/NexaIntegrationPreview.swift; sourceTree = ""; }; + C3CC707D1B1D4215893D0C24 /* ContentView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ContentView.swift; path = NexaClient/ContentView.swift; sourceTree = ""; }; + EBFB666B6AFCF02FCBA1B5A2 /* NexaClient.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; name = NexaClient.app; path = NexaClient.app; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 754911A3FA0DBF9FAD0C7526 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 8ED7BD97F368F2CA777F8285 /* Foundation.framework in Frameworks */, + A97E7CFF74509C5A91E5098F /* Nexa in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 7784E35CFE5E1E3433A70B28 /* Frameworks */ = { + isa = PBXGroup; + children = ( + D376C651B9B2AD20A647CAB9 /* iOS */, + ); + name = Frameworks; + sourceTree = ""; + }; + B2FA96F6F04489E5DFD3E12C /* NexaClient */ = { + isa = PBXGroup; + children = ( + 602E17E5451FC46F0B078998 /* NexaClientApp.swift */, + C3CC707D1B1D4215893D0C24 /* ContentView.swift */, + 9398B6CF8522A7EC915B1B82 /* NexaIntegrationPreview.swift */, + ); + name = NexaClient; + sourceTree = ""; + }; + B52E150D37F32D27FA0A729C /* Products */ = { + isa = PBXGroup; + children = ( + EBFB666B6AFCF02FCBA1B5A2 /* NexaClient.app */, + ); + name = Products; + sourceTree = ""; + }; + BF07C52AA8C5AC55278D97A7 = { + isa = PBXGroup; + children = ( + B52E150D37F32D27FA0A729C /* Products */, + 7784E35CFE5E1E3433A70B28 /* Frameworks */, + B2FA96F6F04489E5DFD3E12C /* NexaClient */, + ); + sourceTree = ""; + }; + D376C651B9B2AD20A647CAB9 /* iOS */ = { + isa = PBXGroup; + children = ( + 1E4507C23C16857EDCCB7C77 /* Foundation.framework */, + ); + name = iOS; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + EF703ECBA955D444DBE92BAD /* NexaClient */ = { + isa = PBXNativeTarget; + buildConfigurationList = 298FA4CA2241778D123C5C69 /* Build configuration list for PBXNativeTarget "NexaClient" */; + buildPhases = ( + 2F0AF08ABBBF9C1487B3928E /* Sources */, + 754911A3FA0DBF9FAD0C7526 /* Frameworks */, + 27CB2B3B5AB2F8E735E5FC02 /* Resources */, + DA5A107A8CEB140707BED83D /* SwiftLint */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = NexaClient; + packageProductDependencies = ( + 4EE316A66ED03685DB9E966E /* Nexa */, + ); + productName = NexaClient; + productReference = EBFB666B6AFCF02FCBA1B5A2 /* NexaClient.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 91ED3ED9706ECE1760D410E9 /* Project object */ = { + isa = PBXProject; + attributes = { + LastSwiftUpdateCheck = 1630; + LastUpgradeCheck = 1630; + }; + buildConfigurationList = B45845FBBAB82DB2EABBFB79 /* Build configuration list for PBXProject "NexaClient" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = BF07C52AA8C5AC55278D97A7; + minimizedProjectReferenceProxies = 0; + packageReferences = ( + 65D8F3F8C1D94A137FC0D0D9 /* XCLocalSwiftPackageReference ".." */, + ); + preferredProjectObjectVersion = 77; + productRefGroup = B52E150D37F32D27FA0A729C /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + EF703ECBA955D444DBE92BAD /* NexaClient */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 27CB2B3B5AB2F8E735E5FC02 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + DA5A107A8CEB140707BED83D /* SwiftLint */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + ); + name = SwiftLint; + outputFileListPaths = ( + ); + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "if ! command -v swiftlint >/dev/null 2>&1; then\n echo \"error: SwiftLint not installed. Install it with 'brew install swiftlint'.\"\n exit 1\nfi\n\nREPO_ROOT=\"${SRCROOT}/../..\"\ncd \"$REPO_ROOT\"\nswiftlint --config .swiftlint.yml lint\n"; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 2F0AF08ABBBF9C1487B3928E /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + F7945339318AA5C557A99AC2 /* NexaClientApp.swift in Sources */, + 3A6C19D889DFC0D5AAAE7398 /* ContentView.swift in Sources */, + 8B618FC9B82424737A92D3E3 /* NexaIntegrationPreview.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 4C37B22DADCCF5AE227FE5A0 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = ""; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = ""; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.opfic.NexaClient; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 7F9C3EB924C3536E2F797DBC /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + 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; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 9168CDAAB740F1B5608A7EC1 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = ""; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = ""; + CLANG_ENABLE_OBJC_WEAK = NO; + CODE_SIGNING_ALLOWED = NO; + CODE_SIGNING_REQUIRED = NO; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + ENABLE_USER_SCRIPT_SANDBOXING = NO; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + IPHONEOS_DEPLOYMENT_TARGET = 15.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = dev.opfic.NexaClient; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; + SWIFT_VERSION = 6.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 9DC19AC9F852AD1143B6E8EC /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_CXX_LIBRARY = "libc++"; + 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; + GCC_C_LANGUAGE_STANDARD = gnu11; + 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; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_NAME = "$(TARGET_NAME)"; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 298FA4CA2241778D123C5C69 /* Build configuration list for PBXNativeTarget "NexaClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 9168CDAAB740F1B5608A7EC1 /* Release */, + 4C37B22DADCCF5AE227FE5A0 /* Debug */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + B45845FBBAB82DB2EABBFB79 /* Build configuration list for PBXProject "NexaClient" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7F9C3EB924C3536E2F797DBC /* Debug */, + 9DC19AC9F852AD1143B6E8EC /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCLocalSwiftPackageReference section */ + 65D8F3F8C1D94A137FC0D0D9 /* XCLocalSwiftPackageReference ".." */ = { + isa = XCLocalSwiftPackageReference; + relativePath = ../..; + }; +/* End XCLocalSwiftPackageReference section */ + +/* Begin XCSwiftPackageProductDependency section */ + 4EE316A66ED03685DB9E966E /* Nexa */ = { + isa = XCSwiftPackageProductDependency; + package = 65D8F3F8C1D94A137FC0D0D9 /* XCLocalSwiftPackageReference ".." */; + productName = Nexa; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 91ED3ED9706ECE1760D410E9 /* Project object */; +} diff --git a/Examples/NexaClient/NexaClient/ContentView.swift b/Examples/NexaClient/NexaClient/ContentView.swift new file mode 100644 index 0000000..84ca2be --- /dev/null +++ b/Examples/NexaClient/NexaClient/ContentView.swift @@ -0,0 +1,34 @@ +// +// ContentView.swift +// NexaClient +// +// Created by opfic on 6/13/26. +// + +import SwiftUI + +struct ContentView: View { + private let preview = NexaIntegrationPreview() + + var body: some View { + NavigationView { + List { + Section("Purpose") { + Text("Build-only integration host for Nexa maintainers.") + Text("This app is not distributed to package consumers.") + } + + Section("Package Surface") { + Text(preview.clientDescription) + Text(preview.typedRequestDescription) + Text(preview.rawRequestDescription) + } + } + .navigationTitle("NexaClient") + } + } +} + +#Preview { + ContentView() +} diff --git a/Examples/NexaClient/NexaClient/NexaClientApp.swift b/Examples/NexaClient/NexaClient/NexaClientApp.swift new file mode 100644 index 0000000..b71724e --- /dev/null +++ b/Examples/NexaClient/NexaClient/NexaClientApp.swift @@ -0,0 +1,17 @@ +// +// NexaClientApp.swift +// NexaClient +// +// Created by opfic on 6/13/26. +// + +import SwiftUI + +@main +struct NexaClientApp: App { + var body: some Scene { + WindowGroup { + ContentView() + } + } +} diff --git a/Examples/NexaClient/NexaClient/NexaIntegrationPreview.swift b/Examples/NexaClient/NexaClient/NexaIntegrationPreview.swift new file mode 100644 index 0000000..cd17bc4 --- /dev/null +++ b/Examples/NexaClient/NexaClient/NexaIntegrationPreview.swift @@ -0,0 +1,44 @@ +// +// NexaIntegrationPreview.swift +// NexaClient +// +// Created by opfic on 6/13/26. +// + +import Foundation +import Nexa + +struct NexaIntegrationPreview { + private let client = NXAPIClient( + configuration: NXClientConfiguration( + baseURL: URL(string: "https://api.example.com")! + ) + ) + + var clientDescription: String { + "Client: \(String(describing: type(of: client)))" + } + + var typedRequestDescription: String { + let request = client + .get("/users/me", as: ExampleUser.self) + .query("include", "profile") + .accept("application/json") + + return "Typed request: \(String(describing: type(of: request)))" + } + + var rawRequestDescription: String { + let request = client + .post("/users") + .header("X-Trace-Id", "preview") + .contentType("application/json") + + return "Raw request: \(String(describing: type(of: request)))" + } +} + +private struct ExampleUser: Decodable { + let id: Int + let name: String +} diff --git a/Package.resolved b/Package.resolved deleted file mode 100644 index c077fb6..0000000 --- a/Package.resolved +++ /dev/null @@ -1,15 +0,0 @@ -{ - "originHash" : "ad35d098c124469a4fc73d3816067de2ce44f79beb6c4fe782c09e74ddb0341d", - "pins" : [ - { - "identity" : "swiftlintplugins", - "kind" : "remoteSourceControl", - "location" : "https://github.com/SimplyDanny/SwiftLintPlugins.git", - "state" : { - "revision" : "8a4640d14777685ba8f14e832373160498fbab92", - "version" : "0.63.2" - } - } - ], - "version" : 3 -} diff --git a/Package.swift b/Package.swift index 15afee5..65d94ee 100644 --- a/Package.swift +++ b/Package.swift @@ -4,8 +4,6 @@ import Foundation import PackageDescription -let isRunningInXcode = ProcessInfo.processInfo.environment["__CFBundleIdentifier"] == "com.apple.dt.Xcode" - let package = Package( name: "Nexa", platforms: [ @@ -19,33 +17,14 @@ let package = Package( targets: ["Nexa"] ), ], - dependencies: isRunningInXcode - ? [ - .package( - url: "https://github.com/SimplyDanny/SwiftLintPlugins.git", - exact: "0.63.2" - ), - ] - : [], + dependencies: [], 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. - .target( - name: "Nexa", - plugins: isRunningInXcode - ? [ - .plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLintPlugins") - ] - : [] - ), + .target(name: "Nexa"), .testTarget( name: "NexaTests", - dependencies: ["Nexa"], - plugins: isRunningInXcode - ? [ - .plugin(name: "SwiftLintBuildToolPlugin", package: "SwiftLintPlugins") - ] - : [] + dependencies: ["Nexa"] ), ], swiftLanguageModes: [.v6] diff --git a/README.ko.md b/README.ko.md index cc0ca59..7d9f01d 100644 --- a/README.ko.md +++ b/README.ko.md @@ -16,6 +16,7 @@ Nexa는 `URLSession` 기반의 SwiftUI 스타일 선언형 네트워킹 라이 - [빠른 시작](#빠른-시작) - [Endpoint API](#endpoint-api) - [설정](#설정) +- [개발](#개발) - [테스트](#테스트) ## 기능 @@ -321,6 +322,18 @@ let client = NXAPIClient(configuration: configuration) - 토큰 갱신 및 재시도 처리 - 스터빙 및 격리 테스트를 위한 커스텀 transport +## 개발 + +Nexa는 배포되는 package graph에서 SwiftLint를 분리하여 패키지 소비자가 maintainer용 lint 규칙을 함께 받지 않도록 구성합니다. + +로컬 라이브러리 개발 시에는 `Examples/NexaClient/NexaClient.xcodeproj`를 사용하면 됩니다. + +- Xcode에서 `NexaClient` 타깃을 build하여 local package integration 경로를 확인 +- app target build 시 repo 루트 기준으로 `swiftlint` 실행 +- 로컬에 `swiftlint`가 없으면 script phase가 설치 안내와 함께 실패 + +이 project는 maintainer 전용 integration host이며 Swift Package Manager로 Nexa를 사용하는 앱에는 필요하지 않습니다. + ## 테스트 Nexa는 요청 실행을 테스트하기 쉽도록 설계되었습니다. `NXHTTPTransport`를 통해 실제 네트워킹을 커스텀 transport로 교체하고 발신 요청과 디코딩된 응답을 검증할 수 있습니다. diff --git a/README.md b/README.md index 45b46e7..8002c4a 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Nexa is a SwiftUI-inspired declarative networking library built on `URLSession`. - [Quick Start](#quick-start) - [Endpoint API](#endpoint-api) - [Configuration](#configuration) +- [Development](#development) - [Testing](#testing) ## Features @@ -321,6 +322,18 @@ Nexa currently supports: - Token refresh and retry handling - Custom transports for stubbing and isolated tests +## Development + +Nexa keeps SwiftLint out of the distributable package graph so package consumers do not inherit maintainer lint rules. + +For local library development, use `Examples/NexaClient/NexaClient.xcodeproj`. + +- Build the `NexaClient` target in Xcode to validate the local package integration path +- The app target runs `swiftlint` against the repository root during build +- If `swiftlint` is missing locally, the script phase fails with an installation hint + +This project is a maintainer-only integration host. It is not required for apps that depend on Nexa through Swift Package Manager. + ## Testing Nexa was designed to keep request execution testable. `NXHTTPTransport` lets you replace live networking with a custom transport and validate the outgoing request and decoded response. From 34e1b14237c2317d44f5f6ca337195c2699e6743 Mon Sep 17 00:00:00 2001 From: opficdev <162981733+opficdev@users.noreply.github.com> Date: Sat, 13 Jun 2026 23:27:42 +0900 Subject: [PATCH 2/2] =?UTF-8?q?fix:=20NexaClient=20SwiftLint=20script?= =?UTF-8?q?=EC=9D=98=20PATH=EB=A5=BC=20=EB=B3=B4=EA=B0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj b/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj index ab3f0b7..4524580 100644 --- a/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj +++ b/Examples/NexaClient/NexaClient.xcodeproj/project.pbxproj @@ -161,7 +161,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "if ! command -v swiftlint >/dev/null 2>&1; then\n echo \"error: SwiftLint not installed. Install it with 'brew install swiftlint'.\"\n exit 1\nfi\n\nREPO_ROOT=\"${SRCROOT}/../..\"\ncd \"$REPO_ROOT\"\nswiftlint --config .swiftlint.yml lint\n"; + shellScript = "export PATH=\"/opt/homebrew/bin:/usr/local/bin:$PATH\"\n\nif ! command -v swiftlint >/dev/null 2>&1; then\n echo \"error: SwiftLint not installed. Install it with 'brew install swiftlint'.\"\n exit 1\nfi\n\nREPO_ROOT=\"${SRCROOT}/../..\"\ncd \"$REPO_ROOT\"\nswiftlint --config .swiftlint.yml lint\n"; }; /* End PBXShellScriptBuildPhase section */