diff --git a/src/iOS/.vscode/settings.json b/src/iOS/.vscode/settings.json index fbe887f1..9892690e 100644 --- a/src/iOS/.vscode/settings.json +++ b/src/iOS/.vscode/settings.json @@ -1,3 +1,7 @@ { - "editor.quickSuggestions": false + "editor.quickSuggestions": { + "comments": "off", + "strings": "off", + "other": "off" + } } \ No newline at end of file diff --git a/src/iOS/KickTube/KickTube.xcodeproj/project.pbxproj b/src/iOS/KickTube/KickTube.xcodeproj/project.pbxproj index 6f6bc7ce..45e3b41e 100644 --- a/src/iOS/KickTube/KickTube.xcodeproj/project.pbxproj +++ b/src/iOS/KickTube/KickTube.xcodeproj/project.pbxproj @@ -16,7 +16,6 @@ 532F31892D364BCE00D2C67E /* ReactorKit in Frameworks */ = {isa = PBXBuildFile; productRef = 532F31882D364BCE00D2C67E /* ReactorKit */; }; 532F318B2D364C2E00D2C67E /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = 532F318A2D364C2E00D2C67E /* .gitignore */; }; 53A863DC2D4FB72E009FF8E2 /* RxDataSources in Frameworks */ = {isa = PBXBuildFile; productRef = 53A863DB2D4FB72E009FF8E2 /* RxDataSources */; }; - 53FDEFDD2D3E12C400825962 /* ManipulateDataModel in Frameworks */ = {isa = PBXBuildFile; productRef = 5351F2E02D392C600093EB87 /* ManipulateDataModel */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -96,8 +95,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 5305C58C2D62471500144DFF /* ManipulateDataModel in Frameworks */, - 53FDEFDD2D3E12C400825962 /* ManipulateDataModel in Frameworks */, 532F31862D364BC200D2C67E /* RxSwift in Frameworks */, 532F31842D364BC200D2C67E /* RxCocoa in Frameworks */, 5320CF812D5206BB00EF722E /* YouTubeiOSPlayerHelper in Frameworks */, @@ -168,7 +165,6 @@ 532F31832D364BC200D2C67E /* RxCocoa */, 532F31852D364BC200D2C67E /* RxSwift */, 532F31882D364BCE00D2C67E /* ReactorKit */, - 5351F2E02D392C600093EB87 /* ManipulateDataModel */, 53C955992D40BC23004D4DA2 /* ManipulateDataModel */, 53A863DB2D4FB72E009FF8E2 /* RxDataSources */, 5320CF802D5206BB00EF722E /* YouTubeiOSPlayerHelper */, @@ -253,7 +249,6 @@ 532F317F2D364BB200D2C67E /* XCRemoteSwiftPackageReference "SnapKit" */, 532F31822D364BC200D2C67E /* XCRemoteSwiftPackageReference "RxSwift" */, 532F31872D364BCE00D2C67E /* XCRemoteSwiftPackageReference "ReactorKit" */, - 53C955982D40BC23004D4DA2 /* XCLocalSwiftPackageReference "../ManipulateDataModel" */, 53A863DA2D4FB72E009FF8E2 /* XCRemoteSwiftPackageReference "RxDataSources" */, 5320CF7F2D5206BB00EF722E /* XCRemoteSwiftPackageReference "youtube-ios-player-helper" */, ); @@ -625,13 +620,6 @@ }; /* End XCConfigurationList section */ -/* Begin XCLocalSwiftPackageReference section */ - 53C955982D40BC23004D4DA2 /* XCLocalSwiftPackageReference "../ManipulateDataModel" */ = { - isa = XCLocalSwiftPackageReference; - relativePath = ../ManipulateDataModel; - }; -/* End XCLocalSwiftPackageReference section */ - /* Begin XCRemoteSwiftPackageReference section */ 5320CF7F2D5206BB00EF722E /* XCRemoteSwiftPackageReference "youtube-ios-player-helper" */ = { isa = XCRemoteSwiftPackageReference; @@ -701,10 +689,6 @@ package = 532F31872D364BCE00D2C67E /* XCRemoteSwiftPackageReference "ReactorKit" */; productName = ReactorKit; }; - 5351F2E02D392C600093EB87 /* ManipulateDataModel */ = { - isa = XCSwiftPackageProductDependency; - productName = ManipulateDataModel; - }; 53A863DB2D4FB72E009FF8E2 /* RxDataSources */ = { isa = XCSwiftPackageProductDependency; package = 53A863DA2D4FB72E009FF8E2 /* XCRemoteSwiftPackageReference "RxDataSources" */; diff --git a/src/iOS/KickTube/KickTube/Features/Home/Reactor/ChatReactor.swift b/src/iOS/KickTube/KickTube/Features/Home/Reactor/ChatReactor.swift index bee05efe..68aae3cc 100644 --- a/src/iOS/KickTube/KickTube/Features/Home/Reactor/ChatReactor.swift +++ b/src/iOS/KickTube/KickTube/Features/Home/Reactor/ChatReactor.swift @@ -48,7 +48,6 @@ final class ChatReactor: Reactor { return getUnreadMessage() case .getNewMessage: // let newMessage = SampleTest.unreads[0].toModel().toModel() - // return .just(.appendNewMessage(newMessage)) return .empty() case .sendMessage(let message): diff --git a/src/iOS/KickTube/KickTube/Features/Home/Reactor/PlayListViewModel.swift b/src/iOS/KickTube/KickTube/Features/Home/Reactor/PlayListViewModel.swift index 790a7522..25a280a2 100644 --- a/src/iOS/KickTube/KickTube/Features/Home/Reactor/PlayListViewModel.swift +++ b/src/iOS/KickTube/KickTube/Features/Home/Reactor/PlayListViewModel.swift @@ -42,7 +42,6 @@ final class PlayListViewModel { let playlistSubject = BehaviorSubject<[KickRoomPlaylistViewModel]>(value: playlist) let videoListSubject = PublishSubject<[YoutubeVideoViewModel]>() let validVideoSubject = PublishSubject<[YoutubeVideoViewModel]>() - playlistSubject .take(1) @@ -50,7 +49,8 @@ final class PlayListViewModel { guard let self else { return .error(NetworkError.unknown) } let youtubeID = playlist.compactMap { $0.url.youtubeID } - return self.getYoutubeSearchResult(with: youtubeID) + + return self.getYoutubeSearchResult(with: youtubeID) } .subscribe(with: self) { owner, value in owner.videoList = value @@ -132,6 +132,17 @@ final class PlayListViewModel { } .disposed(by: disposeBag) + videoListSubject + .subscribe(with: self) { owner, value in + guard let roomID = owner.roomID else { return } + + let playlist = value.enumerated().map { PlaylistRequestDTO(url: $0.element.id.youtubeLink, order: $0.offset) } + let request = RoomPlaylistRequestDTO(roomID: roomID, playlist: playlist) + + owner.changePlaylist(request) + } + .disposed(by: disposeBag) + return Output(playlist: videoListSubject, validVideo: validVideoSubject) } @@ -177,9 +188,11 @@ final class PlayListViewModel { Task { do { _ = try await self.session.send(playlistRequest) + print("success") } catch { print(error) } } } } + diff --git a/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/HomeViewController.swift b/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/HomeViewController.swift index 49e47fc7..5675f964 100644 --- a/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/HomeViewController.swift +++ b/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/HomeViewController.swift @@ -67,7 +67,7 @@ final class HomeViewController: BaseViewController { cellIdentifier: HomeVideoCollectionViewCell.reuseIdentifier, cellType: HomeVideoCollectionViewCell.self )) { row, element, cell in - if let videoID = element.videoID, + if let videoID = element.playlistURL?.youtubeID, element.videoThumbnail == nil { reactor.action.onNext(.getVideoThumbnail(idx: row, id: videoID)) } @@ -84,8 +84,10 @@ final class HomeViewController: BaseViewController { .asDriver(onErrorJustReturn: "") .drive(with: self) { owner, value in let vc = KickRoomViewController(KickRoomReactor(value)) - - owner.navigationController?.pushViewController(vc, animated: false) + + vc.modalPresentationStyle = .overFullScreen + + owner.present(vc, animated: true) } .disposed(by: disposeBag) } diff --git a/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/KickRoomViewController.swift b/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/KickRoomViewController.swift index 6e1e368d..e1e04a5f 100644 --- a/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/KickRoomViewController.swift +++ b/src/iOS/KickTube/KickTube/Features/Home/View/ViewController/KickRoomViewController.swift @@ -93,14 +93,8 @@ final class KickRoomViewController: BaseViewController { override func viewDidLoad() { super.viewDidLoad() - navigationController?.interactivePopGestureRecognizer?.delegate = self - navigationController?.interactivePopGestureRecognizer?.isEnabled = true - setNotification() - } - - override func viewDidAppear(_ animated: Bool) { - + setPopView() } override func viewWillDisappear(_ animated: Bool) { @@ -225,6 +219,12 @@ final class KickRoomViewController: BaseViewController { ) } + private func setPopView() { + let panGesture = UIPanGestureRecognizer(target: self, action: #selector(handlePanGesture(_:))) + + view.addGestureRecognizer(panGesture) + } + private func presentChattingView() { guard let roomID = reactor.currentState.roomInfo?.roomDetail.roomInfo.roomID else { return } @@ -270,6 +270,22 @@ final class KickRoomViewController: BaseViewController { } } + @objc + private func handlePanGesture(_ gesture: UIPanGestureRecognizer) { + let translation = gesture.translation(in: view) + + if translation.y > 0 { + if gesture.velocity(in: view).y > 1000 { + navigationController?.popViewController(animated: true) + self.dismiss(animated: true, completion: nil) + } + } + + if gesture.state == .ended || gesture.state == .cancelled { + gesture.setTranslation(.zero, in: view) + } + } + // MARK: - configure UI @@ -362,5 +378,3 @@ extension KickRoomViewController: YTPlayerViewDelegate { timeTrackingTimer = nil } } - -extension KickRoomViewController: UIGestureRecognizerDelegate {} diff --git a/src/iOS/KickTube/KickTube/Features/Login/LoginViewController.swift b/src/iOS/KickTube/KickTube/Features/Login/LoginViewController.swift index ebf42af0..b4f215d0 100644 --- a/src/iOS/KickTube/KickTube/Features/Login/LoginViewController.swift +++ b/src/iOS/KickTube/KickTube/Features/Login/LoginViewController.swift @@ -27,12 +27,12 @@ final class LoginViewController: BaseViewController { } private let idTextField = LightStrokeTextField().then { $0.setPlacehodler("아이디") - $0.textfield.text = "a@sg.com" + $0.textfield.text = SampleTest.id } private let pwTextField = LightStrokeTextField().then { $0.setPlacehodler("비밀번호") $0.setPWStyle() - $0.textfield.text = "!1234qwer" + $0.textfield.text = SampleTest.password } private let saveIDCheckBox = CheckBoxView("아이디 저장") private let loginButton = RoundButton("로그인") diff --git a/src/iOS/KickTube/KickTube/Features/MyRoom/View/MyRoomViewController.swift b/src/iOS/KickTube/KickTube/Features/MyRoom/View/MyRoomViewController.swift index c658282a..f18f4b34 100644 --- a/src/iOS/KickTube/KickTube/Features/MyRoom/View/MyRoomViewController.swift +++ b/src/iOS/KickTube/KickTube/Features/MyRoom/View/MyRoomViewController.swift @@ -25,7 +25,7 @@ final class MyRoomViewController: BaseViewController { return UICollectionViewCell() } - if let videoID = room.videoID, + if let videoID = room.playlistURL?.youtubeID, room.videoThumbnail == nil { self.reactor.action.onNext(.getVideoThumbnail(idx: indexPath, id: videoID)) } @@ -48,7 +48,7 @@ final class MyRoomViewController: BaseViewController { return UICollectionViewCell() } - if let videoID = room.videoID, + if let videoID = room.playlistURL?.youtubeID, room.videoThumbnail == nil { self.reactor.action.onNext(.getVideoThumbnail(idx: indexPath, id: videoID)) } diff --git a/src/iOS/ManipulateDataModel/.gitignore b/src/iOS/ManipulateDataModel/.gitignore deleted file mode 100644 index 0023a534..00000000 --- a/src/iOS/ManipulateDataModel/.gitignore +++ /dev/null @@ -1,8 +0,0 @@ -.DS_Store -/.build -/Packages -xcuserdata/ -DerivedData/ -.swiftpm/configuration/registries.json -.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata -.netrc diff --git a/src/iOS/ManipulateDataModel/.swiftpm/xcode/xcuserdata/sk.xcuserdatad/xcschemes/xcschememanagement.plist b/src/iOS/ManipulateDataModel/.swiftpm/xcode/xcuserdata/sk.xcuserdatad/xcschemes/xcschememanagement.plist new file mode 100644 index 00000000..ac1ee88c --- /dev/null +++ b/src/iOS/ManipulateDataModel/.swiftpm/xcode/xcuserdata/sk.xcuserdatad/xcschemes/xcschememanagement.plist @@ -0,0 +1,19 @@ + + + + + SchemeUserState + + ManipulateDataModel.xcscheme_^#shared#^_ + + orderHint + 1 + + ManipulateDataModelClient.xcscheme_^#shared#^_ + + orderHint + 0 + + + + diff --git a/src/iOS/ManipulateDataModel/Package.resolved b/src/iOS/ManipulateDataModel/Package.resolved deleted file mode 100644 index 6dc9da3a..00000000 --- a/src/iOS/ManipulateDataModel/Package.resolved +++ /dev/null @@ -1,15 +0,0 @@ -{ - "originHash" : "a08336aba7c54c41f2753238a099a29c98df4938d4c14e7bf558300a0c171596", - "pins" : [ - { - "identity" : "swift-syntax", - "kind" : "remoteSourceControl", - "location" : "https://github.com/swiftlang/swift-syntax.git", - "state" : { - "revision" : "0687f71944021d616d34d922343dcef086855920", - "version" : "600.0.1" - } - } - ], - "version" : 3 -} diff --git a/src/iOS/ManipulateDataModel/Package.swift b/src/iOS/ManipulateDataModel/Package.swift deleted file mode 100644 index c1f33c16..00000000 --- a/src/iOS/ManipulateDataModel/Package.swift +++ /dev/null @@ -1,51 +0,0 @@ -// swift-tools-version: 6.0 -// The swift-tools-version declares the minimum version of Swift required to build this package. - -import PackageDescription -import CompilerPluginSupport - -let package = Package( - name: "ManipulateDataModel", - platforms: [.macOS(.v10_15), .iOS(.v13), .tvOS(.v13), .watchOS(.v6), .macCatalyst(.v13)], - products: [ - // Products define the executables and libraries a package produces, making them visible to other packages. - .library( - name: "ManipulateDataModel", - targets: ["ManipulateDataModel"] - ), - .executable( - name: "ManipulateDataModelClient", - targets: ["ManipulateDataModelClient"] - ), - ], - dependencies: [ - .package(url: "https://github.com/swiftlang/swift-syntax.git", from: "600.0.0-latest"), - ], - 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. - // Macro implementation that performs the source transformation of a macro. - .macro( - name: "ManipulateDataModelMacros", - dependencies: [ - .product(name: "SwiftSyntaxMacros", package: "swift-syntax"), - .product(name: "SwiftCompilerPlugin", package: "swift-syntax") - ] - ), - - // Library that exposes a macro as part of its API, which is used in client programs. - .target(name: "ManipulateDataModel", dependencies: ["ManipulateDataModelMacros"]), - - // A client of the library, which is able to use the macro in its own code. - .executableTarget(name: "ManipulateDataModelClient", dependencies: ["ManipulateDataModel"]), - - // A test target used to develop the macro implementation. - .testTarget( - name: "ManipulateDataModelTests", - dependencies: [ - "ManipulateDataModelMacros", - .product(name: "SwiftSyntaxMacrosTestSupport", package: "swift-syntax"), - ] - ), - ] -) diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModel/ManipulateDataModel.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModel/ManipulateDataModel.swift deleted file mode 100644 index f5f78198..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModel/ManipulateDataModel.swift +++ /dev/null @@ -1,47 +0,0 @@ -// The Swift Programming Language -// https://docs.swift.org/swift-book - -import Foundation -/// A macro that produces both a value and a string containing the -/// source code that generated the value. For example, -/// -/// #stringify(x + y) -/// -/// produces a tuple `(x + y, "x + y")`. -@freestanding(expression) -public macro stringify(_ value: T) -> (T, String) = #externalMacro(module: "ManipulateDataModelMacros", type: "StringifyMacro") - - -// MARK: - DecodeDTO with Auto Create CodingKeys - -@attached(extension, conformances: Decodable) -@attached(member, names: named(CodingKeys)) -public macro DecodeDTO() = #externalMacro(module: "ManipulateDataModelMacros", type: "DTOMacro") - - -// MARK: - EncodeDTO with Auto Create CodingKeys - -@attached(extension, conformances: Encodable) -@attached(member, names: named(CodingKeys)) -public macro EncodeDTO() = #externalMacro(module: "ManipulateDataModelMacros", type: "DTOMacro") - - -// MARK: - Create CodingKeys - -@attached(peer) -public macro Key(_: String? = nil) = #externalMacro(module: "ManipulateDataModelMacros", type: "KeyMacro") - - -// MARK: - Convert DTO to DomainModel - -@attached(member, names: named(toModel)) -public macro ConvertToDomainModel() = #externalMacro(module: "ManipulateDataModelMacros", type: "DataModelMappingMacro") - - -// MARK: - Convert DomainModel to DTO -@attached(member, names: named(toModel)) -public macro ConvertToDTOModel() = #externalMacro(module: "ManipulateDataModelMacros", type: "DataModelMappingMacro") - - -public protocol DTOMappable {} -public protocol DomainMappable {} diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelClient/main.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelClient/main.swift deleted file mode 100644 index e30bd9f5..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelClient/main.swift +++ /dev/null @@ -1,49 +0,0 @@ -import ManipulateDataModel -import Foundation - -let a = 17 -let b = 25 - -let (result, code) = #stringify(a + b) - -print("The value \(result) was produced by the code \"\(code)\"") - -@DecodeDTO -struct TestDTO { - let test: String -} - -@DecodeDTO -struct Model { - @Key("receiver_id") let receiverID: Int -} - - -@ConvertToDomainModel -struct ResponseModel { - let id: Int - let name: String - let createdAt: Date -} - - -@ConvertToDTOModel -struct DomainModel: DTOMappable { - let id: Int - let name: String - let createdAt: Date -} - - -struct RequestModel: DomainMappable { - let id: Int - let name: String - let createdAt: Date -} - - -let c = ResponseModel(id: 1, name: "sd", createdAt: Date()) -var d = c.toModel() -print(d) - - diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/DTOMacro.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/DTOMacro.swift deleted file mode 100644 index 0a33af85..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/DTOMacro.swift +++ /dev/null @@ -1,83 +0,0 @@ -// -// DTOMacro.swift -// ManipulateDataModel -// -// Created by 김수경 on 1/16/25. -// - -import SwiftCompilerPlugin -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros - -public struct DTOMacro {} - -extension DTOMacro: ExtensionMacro { - public static func expansion( - of node: SwiftSyntax.AttributeSyntax, - attachedTo declaration: some SwiftSyntax.DeclGroupSyntax, - providingExtensionsOf type: some SwiftSyntax.TypeSyntaxProtocol, - conformingTo protocols: [SwiftSyntax.TypeSyntax], - in context: some SwiftSyntaxMacros.MacroExpansionContext - ) throws -> [SwiftSyntax.ExtensionDeclSyntax] { - guard let macroName = node.attributeName.as(IdentifierTypeSyntax.self) else { - return [] - } - - if macroName.name.text == "DecodeDTO" { - return try [.init("extension \(raw: type.trimmedDescription): Decodable {}")] - } else if macroName.name.text == "EncodeDTO" { - return try [.init("extension \(raw: type.trimmedDescription): Encodable {}")] - } - - return [] - } -} - - -extension DTOMacro: MemberMacro { - public static func expansion( - of node: AttributeSyntax, - providingMembersOf declaration: some DeclGroupSyntax, - in context: some MacroExpansionContext - ) throws -> [DeclSyntax] { - guard let structDecl = declaration as? StructDeclSyntax else { - return [] - } - - let properties = structDecl.memberBlock.members.compactMap { member -> (name: String, key: String)? in - guard let variable = member.decl.as(VariableDeclSyntax.self), - let pattern = variable.bindings.first?.pattern.as(IdentifierPatternSyntax.self) - else { - return nil - } - - let name = pattern.identifier.text - let key = variable.attributes.compactMap { attr -> String? in - guard let attr = attr.as(AttributeSyntax.self), - attr.attributeName.description == "Key", - let arguemnts = attr.arguments?.as(LabeledExprListSyntax.self), - let stringLiteral = arguemnts.first?.expression.as(StringLiteralExprSyntax.self) - else { - return nil - } - - return stringLiteral.segments.description - }.first ?? name - - return (name: name, key: key) - } - - let codingKeySyntax = try EnumDeclSyntax("enum CodingKeys: String, CodingKey") { - for property in properties { - if property.name == property.key { - try EnumCaseDeclSyntax("case \(raw: property.name)") - } else { - try EnumCaseDeclSyntax("case \(raw: property.name) = \(literal: property.key)") - } - } - } - - return [DeclSyntax(codingKeySyntax)] - } -} diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/DataModelMappingMacro.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/DataModelMappingMacro.swift deleted file mode 100644 index 96d47b7d..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/DataModelMappingMacro.swift +++ /dev/null @@ -1,54 +0,0 @@ -// -// DTOToDomainModelMacro.swift -// DataModelMappingMacro -// -// Created by 김수경 on 1/16/25. -// - -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros - -public struct DataModelMappingMacro {} - -extension DataModelMappingMacro: MemberMacro { - public static func expansion( - of attribute: AttributeSyntax, - providingMembersOf declaration: some DeclGroupSyntax, - in context: some MacroExpansionContext - ) throws -> [DeclSyntax] { - guard let returnModelType = attribute.attributeName.as(IdentifierTypeSyntax.self)? - .genericArgumentClause? - .arguments.first? - .argument else { - return [] - } - - guard let structDecl = declaration.as(StructDeclSyntax.self) else { - return [] - } - - let members = structDecl.memberBlock.members - let variableDecls = members.compactMap { $0.decl.as(VariableDeclSyntax.self) } - let variables = variableDecls.compactMap { variableDecl -> (String, String)? in - guard let binding = variableDecl.bindings.first else { - return nil - } - - let name = binding.pattern.description.trimmingCharacters(in: .whitespacesAndNewlines) - let type = binding.typeAnnotation?.description ?? "" - - return (name, type) - } - - let initializer = try FunctionDeclSyntax("func toModel() -> \(returnModelType)") { - CodeBlockItemListSyntax { - let returnExpression = ExprSyntax("\(returnModelType)(\(raw: variables.map { "\($0.0): self.\($0.0)" }.joined(separator: ", ")))") - - CodeBlockItemSyntax(item: .stmt(StmtSyntax(ReturnStmtSyntax(expression: returnExpression)))) - } - } - - return [DeclSyntax(initializer)] - } -} diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/KeyMacro.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/KeyMacro.swift deleted file mode 100644 index c975b695..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/KeyMacro.swift +++ /dev/null @@ -1,23 +0,0 @@ -// -// KeyMacro.swift -// ManipulateDataModel -// -// Created by 김수경 on 1/16/25. -// - -import SwiftCompilerPlugin -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros - -public struct KeyMacro {} - -extension KeyMacro: PeerMacro { - public static func expansion( - of node: AttributeSyntax, - providingPeersOf declaration: some DeclSyntaxProtocol, - in context: some MacroExpansionContext - ) throws -> [DeclSyntax] { - return [] - } -} diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/ManipulateDataModelMacro.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/ManipulateDataModelMacro.swift deleted file mode 100644 index fb0e2b25..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/ManipulateDataModelMacro.swift +++ /dev/null @@ -1,26 +0,0 @@ -import SwiftCompilerPlugin -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros - -/// Implementation of the `stringify` macro, which takes an expression -/// of any type and produces a tuple containing the value of that expression -/// and the source code that produced the value. For example -/// -/// #stringify(x + y) -/// -/// will expand to -/// -/// (x + y, "x + y") -public struct StringifyMacro: ExpressionMacro { - public static func expansion( - of node: some FreestandingMacroExpansionSyntax, - in context: some MacroExpansionContext - ) -> ExprSyntax { - guard let argument = node.arguments.first?.expression else { - fatalError("compiler bug: the macro does not have any arguments") - } - - return "(\(argument), \(literal: argument.description))" - } -} diff --git a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/ManipulateDataModelPlugin.swift b/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/ManipulateDataModelPlugin.swift deleted file mode 100644 index 0d212543..00000000 --- a/src/iOS/ManipulateDataModel/Sources/ManipulateDataModelMacros/ManipulateDataModelPlugin.swift +++ /dev/null @@ -1,21 +0,0 @@ -// -// ManipulateDataModelPlugin.swift -// ManipulateDataModel -// -// Created by 김수경 on 1/16/25. -// - -import SwiftCompilerPlugin -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros - -@main -struct ManipulateDataModelPlugin: CompilerPlugin { - let providingMacros: [Macro.Type] = [ - StringifyMacro.self, - DTOMacro.self, - KeyMacro.self, - DataModelMappingMacro.self - ] -} diff --git a/src/iOS/ManipulateDataModel/Tests/ManipulateDataModelTests/ManipulateDataModelTests.swift b/src/iOS/ManipulateDataModel/Tests/ManipulateDataModelTests/ManipulateDataModelTests.swift deleted file mode 100644 index 4b084f73..00000000 --- a/src/iOS/ManipulateDataModel/Tests/ManipulateDataModelTests/ManipulateDataModelTests.swift +++ /dev/null @@ -1,180 +0,0 @@ -import SwiftSyntax -import SwiftSyntaxBuilder -import SwiftSyntaxMacros -import SwiftSyntaxMacrosTestSupport -import XCTest - -// Macro implementations build for the host, so the corresponding module is not available when cross-compiling. Cross-compiled tests may still make use of the macro itself in end-to-end tests. -#if canImport(ManipulateDataModelMacros) -import ManipulateDataModelMacros - -let testMacros: [String: Macro.Type] = [ - "stringify": StringifyMacro.self, -] -#endif - -final class ManipulateDataModelTests: XCTestCase { - func testMacro() throws { -#if canImport(ManipulateDataModelMacros) - assertMacroExpansion( - """ - #stringify(a + b) - """, - expandedSource: """ - (a + b, "a + b") - """, - macros: testMacros - ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif - } - - func testMacroWithStringLiteral() throws { -#if canImport(ManipulateDataModelMacros) - assertMacroExpansion( - #""" - #stringify("Hello, \(name)") - """#, - expandedSource: #""" - ("Hello, \(name)", #""Hello, \(name)""#) - """#, - macros: testMacros - ) -#else - throw XCTSkip("macros are only supported when running tests for the host platform") -#endif - } - - func testMacro_디코딩시_기본_코딩키가_자동으로_생성되는지() throws { - assertMacroExpansion( - """ - @DecodeDTO - struct TestDTO { - let test: String - } - """, - expandedSource: """ - struct TestDTO { - let test: String - - enum CodingKeys: String, CodingKey { - case test - } - } - - extension TestDTO: Decodable { - } - """, - macros: [ - "DecodeDTO": DTOMacro.self - ] - ) - } - - func testMacro_인코딩시_기본_코딩키가_자동으로_생성되는지() throws { - assertMacroExpansion( - """ - @EncodeDTO - struct TestDTO { - let test: String - } - """, - expandedSource: """ - struct TestDTO { - let test: String - - enum CodingKeys: String, CodingKey { - case test - } - } - - extension TestDTO: Encodable { - } - """, - macros: [ - "EncodeDTO": DTOMacro.self - ] - ) - } - - func testMacro_디코딩시_코딩키가_자동으로_생성되는지() throws { - assertMacroExpansion( - """ - @DecodeDTO - struct TestDTO { - @Key("test_id") let testId: String - } - """, - expandedSource: """ - struct TestDTO { - @Key("test_id") let testId: String - - enum CodingKeys: String, CodingKey { - case testId = "test_id" - } - } - - extension TestDTO: Decodable { - } - """, - macros: [ - "DecodeDTO": DTOMacro.self - ] - ) - } - - func testMacro_DTO_에서_DomainModel_로_매핑하는_함수가_생성되는지() throws { - assertMacroExpansion( - """ - @ConvertToDomainModel - struct ResponseModel { - let id: Int - let name: String - let createdAt: Date - } - """, - expandedSource: """ - struct ResponseModel { - let id: Int - let name: String - let createdAt: Date - - func toModel() -> DomainModel { - return DomainModel(id: self.id, name: self.name, createdAt: self.createdAt) - } - } - """, - macros: [ - "ConvertToDomainModel": DataModelMappingMacro.self - ] - ) - } - - func testMacro_DomainModel_에서_DTO_로_매핑하는_함수가_생성되는지() throws { - assertMacroExpansion( - """ - @ConvertToDTOModel - struct DomainModel { - let id: Int - let name: String - let createdAt: Date - } - """, - expandedSource: """ - struct DomainModel { - let id: Int - let name: String - let createdAt: Date - - func toModel() -> RequestModel { - return RequestModel(id: self.id, name: self.name, createdAt: self.createdAt) - } - } - """, - macros: [ - "ConvertToDTOModel": DataModelMappingMacro.self - ] - ) - } -}