Skip to content

Conversation

@youz2me
Copy link
Member

@youz2me youz2me commented May 24, 2025

👻 PULL REQUEST

📄 작업 내용

  • 현재 버전이 앱스토어 버전보다 낮을 때 강제 업데이트를 진행하는 기능을 구현했어요.
  • 테스트플라이트 업데이트 시 수출 규정 누락 항목 표시 방지를 위해 info.plist를 수정했어요.
구현 내용 IPhone 15 pro
GIF

💻 주요 코드 설명

버전 확인 및 강제 업데이트 기능 구현

func checkForceUpdate() {
        let appVersion = Bundle.main.infoDictionary?["CFBundleShortVersionString"] as? String
        let itunesLookupURL = "https://itunes.apple.com/kr/lookup?bundleId=com.wable.Wable-iOS&country=kr"
        
        guard let url = URL(string: itunesLookupURL) else {
            proceedToAppLaunch()
            
            return
        }
        
        URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
            guard let self = self else { return }
            
            if let error = error {
                WableLogger.log("앱스토어 버전 확인 실패: \(error.localizedDescription)", for: .error)
                DispatchQueue.main.async {
                    self.proceedToAppLaunch()
                }
                return
            }
            
            guard let data = data,
                  let json = try? JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any],
                  let results = json["results"] as? [[String: Any]],
                  let appStoreInfo = results.first,
                  let appStoreVersion = appStoreInfo["version"] as? String,
                  let currentVersion = appVersion
            else {
                WableLogger.log("앱스토어 데이터 파싱 실패", for: .error)
                
                DispatchQueue.main.async {
                    self.proceedToAppLaunch()
                }
                
                return
            }
            
            DispatchQueue.main.async {
                WableLogger.log(
                    "currentVersion: \(currentVersion), appStoreVersion: \(appStoreVersion)",
                    for: .debug
                )
                
                let isUpdateNeeded = self.isForceUpdateNeeded(
                    currentVersion: currentVersion,
                    appStoreVersion: appStoreVersion
                )
                
                isUpdateNeeded ? self.showForceUpdateAlert() : self.proceedToAppLaunch()
            }
            
        }.resume()
    }
  • 번들에서 현재 앱 버전을 추출하고 와블 앱스토어 URL을 dataTask를 이용해 추출해 서로 비교합니다.
  • 이후 현재 앱 버전의 메이저, 마이너, 패치 번호를 순차적으로 비교해 앱스토어 버전보다 낮을 경우 강제 업데이트 팝업을 표시합니다.

👀 기타 더 이야기해볼 점

  • 200번째 이슈는 제가 가져갑니닷. ㅋㅋ

🔗 연결된 이슈

@youz2me youz2me requested a review from JinUng41 May 24, 2025 18:24
@youz2me youz2me self-assigned this May 24, 2025
@youz2me youz2me added the ✨ feat 기능 또는 객체 구현 label May 24, 2025
@youz2me youz2me added ⚙️ setting 프로젝트 관련 설정 변경 시 사용 🦉 유진 🛌🛌🛌🛌🛌🛌🛌🛌🛌🛌 labels May 24, 2025
@coderabbitai
Copy link

coderabbitai bot commented May 24, 2025

Walkthrough

The app's launch flow in SceneDelegate.swift was refactored to introduce a forced update check before auto-login logic. Helper methods for version comparison and update alert presentation were added. The Info.plist was updated to declare non-exempt encryption usage.

Changes

File(s) Change Summary
Wable-iOS/App/SceneDelegate.swift Refactored app launch flow to add forced update logic, version comparison, and update alert methods.
Wable-iOS/Resource/Info.plist Added ITSAppUsesNonExemptEncryption key with value false.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant SceneDelegate
    participant AppStore

    User->>SceneDelegate: Launches App
    SceneDelegate->>AppStore: Fetch latest app version
    AppStore-->>SceneDelegate: Return latest version info
    alt Force update needed
        SceneDelegate->>User: Show force update alert
        User->>AppStore: (Optionally) Open App Store link
    else No update needed
        SceneDelegate->>SceneDelegate: Proceed to auto-login check
        alt Auto-login success
            SceneDelegate->>User: Show main screen
        else Auto-login failure
            SceneDelegate->>User: Show login screen
        end
    end
Loading

Assessment against linked issues

Objective Addressed Explanation
Implement forced update logic before app launch (#200)

Poem

A hop and a skip, the app checks anew,
Is your version the latest, or must you pursue?
If not, an alert with a gentle nudge,
To the App Store you’ll go, no need to begrudge.
Now with each launch, the bunny is sure—
Only the freshest can hop through the door! 🐇✨

Note

⚡️ AI Code Reviews for VS Code, Cursor, Windsurf

CodeRabbit now has a plugin for VS Code, Cursor and Windsurf. This brings AI code reviews directly in the code editor. Each commit is reviewed immediately, finding bugs before the PR is raised. Seamless context handoff to your AI code agent ensures that you can easily incorporate review feedback.
Learn more here.

✨ Finishing Touches
  • 📝 Generate Docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Collaborator

@JinUng41 JinUng41 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

@github-project-automation github-project-automation bot moved this to In Review in Wable-iOS May 24, 2025
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (3)
Wable-iOS/App/SceneDelegate.swift (3)

137-137: Replace ternary operator with if-else statement.

Using ternary operators to call void functions reduces readability.

Apply this diff:

-                    isAutologinEnabled ? owner.configureMainScreen() : owner.configureLoginScreen()
+                    if isAutologinEnabled {
+                        owner.configureMainScreen()
+                    } else {
+                        owner.configureLoginScreen()
+                    }
🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 137-137: Using ternary to call Void functions should be avoided

(void_function_in_ternary)


181-181: Replace unused closure parameter with underscore.

The response parameter is not used in the closure.

Apply this diff:

-        URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
+        URLSession.shared.dataTask(with: url) { [weak self] (data, _, error) in
🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 181-181: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


219-219: Replace ternary operator with if-else statement.

Using ternary operators to call void functions reduces readability.

Apply this diff:

-                isUpdateNeeded ? self.showForceUpdateAlert() : self.proceedToAppLaunch()
+                if isUpdateNeeded {
+                    self.showForceUpdateAlert()
+                } else {
+                    self.proceedToAppLaunch()
+                }
🧰 Tools
🪛 SwiftLint (0.57.0)

[Warning] 219-219: Using ternary to call Void functions should be avoided

(void_function_in_ternary)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 395caad and 2e7a62c.

📒 Files selected for processing (2)
  • Wable-iOS/App/SceneDelegate.swift (3 hunks)
  • Wable-iOS/Resource/Info.plist (1 hunks)
🧰 Additional context used
🪛 SwiftLint (0.57.0)
Wable-iOS/App/SceneDelegate.swift

[Warning] 137-137: Using ternary to call Void functions should be avoided

(void_function_in_ternary)


[Warning] 181-181: Unused parameter in a closure should be replaced with _

(unused_closure_parameter)


[Warning] 219-219: Using ternary to call Void functions should be avoided

(void_function_in_ternary)

🔇 Additional comments (6)
Wable-iOS/Resource/Info.plist (1)

5-6: LGTM!

Standard compliance declaration for App Store submission. Setting ITSAppUsesNonExemptEncryption to false correctly indicates the app doesn't use encryption subject to export compliance.

Wable-iOS/App/SceneDelegate.swift (5)

48-48: Good architectural decision!

Checking for forced updates before proceeding with app launch ensures users are on the latest version before accessing app functionality.


225-249: Confirm the non-dismissible alert behavior.

The update alert doesn't provide a cancel option, forcing users to update. While appropriate for a "forced update" feature, please confirm this is the intended user experience.


251-264: Well-implemented version comparison logic!

The method correctly compares semantic version components in the proper order (major → minor → patch).


266-273: Robust version parsing implementation!

The method safely handles version strings with missing components and follows Swift best practices.


173-173:

Details

✅ Verification successful

Verify the hardcoded bundle identifier.

The iTunes lookup URL contains a hardcoded bundle ID. Ensure this matches your app's actual bundle identifier.

Run the following script to verify the bundle identifier:


🏁 Script executed:

#!/bin/bash
# Description: Verify that the hardcoded bundle ID matches the actual bundle ID in the project

# Search for CFBundleIdentifier in Info.plist files
fd -e plist -x plutil -p {} \; | grep -A1 "CFBundleIdentifier" | grep -v "CFBundleIdentifier"

# Also check for bundle ID references in project configuration
rg "PRODUCT_BUNDLE_IDENTIFIER" -A 1

Length of output: 575


Bundle identifier verification passed
The hardcoded bundle ID "com.wable.Wable-iOS" matches the PRODUCT_BUNDLE_IDENTIFIER in Wable-iOS.xcodeproj/project.pbxproj. No changes are needed here.

)

view.addAction(.init(title: "지금 업데이트", style: .primary, handler: {
let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/id6670352454"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Verification agent

🧩 Analysis chain

Verify the hardcoded App Store ID.

The App Store URL contains a hardcoded app ID. Ensure this matches your app's actual App Store ID.


🌐 Web query:

What is the App Store ID for the Wable iOS app with bundle identifier com.wable.Wable-iOS?

💡 Result:

Based on the search results, I can provide you with the App Store ID for the Wable iOS app.

The App Store ID for Wable, which is described as "the connection app for the willing and able" designed for neurodivergent people, is 6471232366[1].

You can find this ID in the app's App Store URL. For iOS apps, the App Store ID typically appears after "id" in the URL. In Wable's case, the URL is https://apps.apple.com/au/app/wable/id6471232366, which confirms the ID is 6471232366[1][2].

This App Store ID is a unique identifier that distinguishes the Wable app from others within Apple's ecosystem, similar to how the bundle ID (com.wable.Wable-iOS) uniquely identifies the app package[5][7].

The Wable app is free to download and use, though it does offer in-app purchases such as "Upgrade to Premium" for $9.99[1]. It's designed specifically for neurodivergent people to find meaningful connections, whether for dating, friendship, or other social relationships.

Citations:


Update hardcoded App Store ID

The App Store URL in SceneDelegate.swift is using the old ID 6670352454; it should be updated to the correct ID 6471232366.

• File: Wable-iOS/App/SceneDelegate.swift (line 232)
• Method: showForceUpdateAlert()

Diff:

- let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/id6670352454"
+ let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/id6471232366"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/id6670352454"
let appStoreOpenUrlString = "itms-apps://itunes.apple.com/app/apple-store/id6471232366"
🤖 Prompt for AI Agents
In Wable-iOS/App/SceneDelegate.swift at line 232, update the hardcoded App Store
URL by replacing the old app ID 6670352454 with the correct Wable app ID
6471232366. This ensures the URL points to the correct app in the App Store.

@youz2me youz2me merged commit 632c315 into develop May 24, 2025
1 check passed
@youz2me youz2me deleted the feat/#200-force-update branch May 24, 2025 18:29
@github-project-automation github-project-automation bot moved this from In Review to Done in Wable-iOS May 24, 2025
@cherry-p0p
Copy link

Group 1

Wow Sexy Code 🥵🥵

@coderabbitai coderabbitai bot mentioned this pull request May 28, 2025
youz2me added a commit that referenced this pull request Oct 26, 2025
[Feat] 강제 업데이트 기능 구현
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ feat 기능 또는 객체 구현 ⚙️ setting 프로젝트 관련 설정 변경 시 사용 🦉 유진 🛌🛌🛌🛌🛌🛌🛌🛌🛌🛌

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[Feat] 강제 업데이트 로직 구현

4 participants