diff --git a/.gitignore b/.gitignore index 748d4b1c..d0030620 100644 --- a/.gitignore +++ b/.gitignore @@ -82,10 +82,14 @@ Dependencies/ # For more information about the recommended setup visit: # https://docs.fastlane.tools/best-practices/source-control/#source-control -fastlane/report.xml -fastlane/Preview.html -fastlane/screenshots/**/*.png -fastlane/test_output +**/fastlane/report.xml +**/fastlane/Preview.html +**/fastlane/screenshots/**/*.png +**/fastlane/BuildOutputs + +**/fastlane/.env.default + +**Gemfile.lock # Code Injection # After new code Injection tools there's a generated folder /iOSInjectionProject @@ -111,10 +115,9 @@ iOSInjectionProject/ Config.swift Gemfile.lock report.xml -Runnect-iOS/fastlane/.env.default ### Runniest project - git ignore setting ### -Runnect-iOS/Runnect-iOS/Info.plist +/Runnect-iOS/Runnect-iOS/Info.plist Runnect-iOS/Info.plist Info.plist diff --git a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj index 93fb542e..4e5f85cd 100644 --- a/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj +++ b/Runnect-iOS/Runnect-iOS.xcodeproj/project.pbxproj @@ -1709,9 +1709,11 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "Runnect-iOS/Runnect-iOSDebug.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1.0.8; - DEVELOPMENT_TEAM = 8Q4H7X3Q58; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 2024.0122.2217; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8Q4H7X3Q58; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = "Runnect-iOS/Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = Runnect; @@ -1732,6 +1734,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.runnect.Runnect-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.runnect.Runnect-iOS"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; @@ -1750,9 +1753,11 @@ ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; CODE_SIGN_ENTITLEMENTS = "Runnect-iOS/Runnect-iOS.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; - CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 1.0.8; - DEVELOPMENT_TEAM = 8Q4H7X3Q58; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Manual; + CURRENT_PROJECT_VERSION = 2024.0122.2217; + DEVELOPMENT_TEAM = ""; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 8Q4H7X3Q58; GENERATE_INFOPLIST_FILE = NO; INFOPLIST_FILE = "Runnect-iOS/Info.plist"; INFOPLIST_KEY_CFBundleDisplayName = Runnect; @@ -1773,6 +1778,7 @@ PRODUCT_BUNDLE_IDENTIFIER = "com.runnect.Runnect-iOS"; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "match Development com.runnect.Runnect-iOS"; SUPPORTED_PLATFORMS = "iphoneos iphonesimulator"; SUPPORTS_MACCATALYST = NO; SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; diff --git a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift index f9862441..67ae4351 100644 --- a/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift +++ b/Runnect-iOS/Runnect-iOS/Global/UIComponents/MapView/RNMapView.swift @@ -392,6 +392,9 @@ extension RNMapView: NMFMapViewCameraDelegate, NMFMapViewTouchDelegate { self.makeMarker(at: latlng) } + func mapView(_ mapView: NMFMapView, cameraWillChangeByReason reason: Int, animated: Bool) { + } + // 지도 이동 멈췄을 때 호출되는 메서드 func mapViewCameraIdle(_ mapView: NMFMapView) { let latitude = mapView.cameraPosition.target.lat diff --git a/Runnect-iOS/Runnect-iOS/Info.plist b/Runnect-iOS/Runnect-iOS/Info.plist index 5b9801d3..647447a4 100644 --- a/Runnect-iOS/Runnect-iOS/Info.plist +++ b/Runnect-iOS/Runnect-iOS/Info.plist @@ -2,6 +2,8 @@ + CFBundleIconName + AppIcon CFBundleDevelopmentRegion $(DEVELOPMENT_LANGUAGE) CFBundleDisplayName @@ -17,7 +19,7 @@ CFBundlePackageType $(PRODUCT_BUNDLE_PACKAGE_TYPE) CFBundleShortVersionString - 1.0.8 + 1.0.10 CFBundleURLTypes @@ -42,7 +44,7 @@ CFBundleVersion - 2023.0712.2207 + 2024.0122.2217 LSApplicationQueriesSchemes kakaokompassauth diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseDiscoveryVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseDiscoveryVC.swift index a048ff5a..5e4d635f 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseDiscoveryVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDiscovery/Views/VC/CourseDiscoveryVC.swift @@ -162,6 +162,8 @@ extension CourseDiscoveryVC { @objc private func pushToCourseSelectVC() { guard UserManager.shared.userType != .visitor else { self.showToastOnWindow(text: "러넥트에 가입하면 코스를 업로드할 수 있어요.") + + analyze(buttonName: GAEvent.Button.clickJoinInCourseDiscovery) return } @@ -452,10 +454,10 @@ extension CourseDiscoveryVC: ScrapStateDelegate { } func didRemoveCourse(publicCourseId: Int) { -// if let index = courseList.firstIndex(where: { $0.id == publicCourseId }) { -// courseList.remove(at: index) -// self.mapCollectionView.reloadData() -// } + // if let index = courseList.firstIndex(where: { $0.id == publicCourseId }) { + // courseList.remove(at: index) + // self.mapCollectionView.reloadData() + // } // ⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️⭐️ // 원래 해당하는 데이터(index) 만 가지고, 그 데이터 삭제 후 courseList를 받아야하는데, 삭제가 이미되어버려서 if let index 부분이 안들어옴 // 왜??? 이미 데이터는 삭제가 되어서 $0.id 랑 publicCourseId 가 같은게 매치가 될 수 없어!!! diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift index af6c4282..61f5e5cb 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingHomeVC.swift @@ -50,6 +50,12 @@ extension CourseDrawingHomeVC { // MARK: - @objc Function extension CourseDrawingHomeVC { @objc private func pushToDepartureSearchVC() { + guard UserManager.shared.userType != .visitor else { + self.showToastOnWindow(text: "러넥트에 가입하면 코스를 업로드할 수 있어요.") + + analyze(buttonName: GAEvent.Button.clickJoinInCourseDrawing) + return + } analyze(buttonName: GAEvent.Button.clickCourseDrawing) diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift index e61af314..bc073fb2 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/CourseDrawingVC.swift @@ -262,7 +262,7 @@ extension CourseDrawingVC { bottomSheetVC.modalPresentationStyle = .overFullScreen bottomSheetVC.completeButtonTapAction = { [weak self] text in guard let self = self else { return } - guard handleVisitor() else { return } + guard bottomSheetVC.handleVisitor() else { return } // 사실상 여기까지 못 들어오는게 맞음 (코스 그리기에서 막았다.) self.courseName = text self.mapView.capturePathImage() self.dismiss(animated: false) diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift index 71d494a9..08d8643e 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseDrawing/VC/DepartureSearchVC.swift @@ -107,12 +107,16 @@ extension DepartureSearchVC { selectDirectionView.gesture().sink { [weak self] _ in guard let self = self else { return } SelectedInfo.shared.type = .other + + analyze(buttonName: GAEvent.Button.clickCurrentLocate) self.setLocation() }.store(in: cancelBag) selectMapView.gesture().sink { [weak self] _ in guard let self = self else { return } SelectedInfo.shared.type = .map + + analyze(buttonName: GAEvent.Button.clickMapLocate) self.setLocation() }.store(in: cancelBag) } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift index 996a3489..748c7baf 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/VC/CourseStorageVC.swift @@ -216,6 +216,7 @@ extension CourseStorageVC { guard UserManager.shared.userType != .visitor else { self.showSignInRequestEmptyView() + analyze(buttonName: GAEvent.Button.clickJoinInStorage) return } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/ScrapCourseListView.swift b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/ScrapCourseListView.swift index 5424cbf5..d8e27823 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/ScrapCourseListView.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/CourseStorage/Views/CourseListView/ScrapCourseListView.swift @@ -156,6 +156,8 @@ extension ScrapCourseListView: UICollectionViewDelegateFlowLayout { extension ScrapCourseListView: ListEmptyViewDelegate { func emptyViewButtonTapped() { + analyze(buttonName: GAEvent.Button.clickScrapCourse) + self.scrapButtonTapped.send() } } diff --git a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift index 5f9ad7a5..76e3b305 100644 --- a/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift +++ b/Runnect-iOS/Runnect-iOS/Presentation/MyPage/VC/MyPageVC.swift @@ -293,6 +293,7 @@ extension MyPageVC { private func setLayout() { guard UserManager.shared.userType != .visitor else { self.showSignInRequestEmptyView() + analyze(buttonName: GAEvent.Button.clickJoinInMyPage) return } diff --git a/Runnect-iOS/fastlane/Appfile b/Runnect-iOS/fastlane/Appfile index 83428cd7..8ddf4725 100644 --- a/Runnect-iOS/fastlane/Appfile +++ b/Runnect-iOS/fastlane/Appfile @@ -1,8 +1,8 @@ -app_identifier("com.runnect.Runnect-iOS") # The bundle identifier of your app +app_identifier(ENV["APP_IDENTIFIER"]) # The bundle identifier of your app apple_id(ENV["APPLE_ID"]) # Your Apple Developer Portal username -itc_team_id("125287287") # App Store Connect Team ID -team_id("8Q4H7X3Q58") # Developer Portal Team ID +itc_team_id(ENV["ITC_TEAM_ID"]) # App Store Connect Team ID +team_id(ENV["TEAM_ID"]) # Developer Portal Team ID # For more information about the Appfile, see: -# https://docs.fastlane.tools/advanced/#appfile +# https://docs.fastlane.tools/advanced/#appfile \ No newline at end of file diff --git a/Runnect-iOS/fastlane/Fastfile b/Runnect-iOS/fastlane/Fastfile index 336c397a..9bdfebf5 100644 --- a/Runnect-iOS/fastlane/Fastfile +++ b/Runnect-iOS/fastlane/Fastfile @@ -16,6 +16,11 @@ default_platform(:ios) platform :ios do + + + ############# version ############# + + desc "Set Marketing and Build version" lane :set_version do |version| increment_version_number( @@ -29,8 +34,12 @@ platform :ios do ) end - desc "Testflight Upload" - lane :upload_testflight do |version| + + ############# beta ############# + + + desc "Push a new beta build to TestFlight" + lane :beta do |version| version = version[:version] match( @@ -50,14 +59,45 @@ platform :ios do ) end - build_app( - output_directory:"./BuildOutputs", - scheme: "Runnect-iOS" - ) + build_app(workspace: "Runnect-iOS.xcworkspace", scheme: "Runnect-iOS") upload_to_testflight(skip_waiting_for_build_processing: true) + + # ✅ Slack 설정. + slack( + username: "이명진", + message: "TestFlight 배포 성공.", + icon_url: "https://is1-ssl.mzstatic.com/image/thumb/Purple116/v4/a6/68/d0/a668d049-8c1a-0e7b-19c3-287093c0a501/AppIcon-1x_U007emarketing-0-7-0-85-220.png/1024x1024bb.png", + slack_url: ENV["RUNNECT_SLACK"], + payload: { "Version": version } + ) + # ✅ 에러 처리. + error do |lane, exception, options| + slack( + message: "에러 발생 : #{exception}", + success: false, + slack_url: "https://hooks.slack.com/…" + ) + end end + + + ############# Device Management ############# + + desc "Register Devices" + lane :register_new_device do |options| + device_name = prompt(text: "Enter the device name: ") + device_udid = prompt(text: "Enter the device UDID: ") + device_hash = {} + device_hash[device_name] = device_udid + register_devices(devices: device_hash) + match(type: "development", force_for_new_devices: true) + end + + ############# match ############# + + desc "Match all code signing" lane :match_read_only do match( diff --git a/Runnect-iOS/fastlane/Matchfile b/Runnect-iOS/fastlane/Matchfile index 8fd4c8fa..778caf1d 100644 --- a/Runnect-iOS/fastlane/Matchfile +++ b/Runnect-iOS/fastlane/Matchfile @@ -1,12 +1,11 @@ -git_url("git@github.com:lsj8706/fastlane-match.git") -git_branch("runnect") +git_url("https://github.com/thingineeer/fastlane-match") +git_branch("master") storage_mode("git") type("appstore") # The default type, can be: appstore, adhoc, enterprise or development -app_identifier(["com.runnect.Runnect-iOS"]) - +app_identifier(ENV["APP_IDENTIFIER"]) # username("user@fastlane.tools") # Your Apple Developer Portal username # For all available options run `fastlane match --help` diff --git a/Runnect-iOS/fastlane/README.md b/Runnect-iOS/fastlane/README.md index e481f731..2b71c45e 100644 --- a/Runnect-iOS/fastlane/README.md +++ b/Runnect-iOS/fastlane/README.md @@ -23,13 +23,21 @@ For _fastlane_ installation instructions, see [Installing _fastlane_](https://do Set Marketing and Build version -### ios upload_testflight +### ios beta ```sh -[bundle exec] fastlane ios upload_testflight +[bundle exec] fastlane ios beta ``` -Testflight Upload +Push a new beta build to TestFlight + +### ios register_new_device + +```sh +[bundle exec] fastlane ios register_new_device +``` + +Register Devices ### ios match_read_only