-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. Weโll occasionally send you account related emails.
Already on GitHub? Sign in to your account
๐ :: [#68] ๋ฐ๋ํ ์์ฑ ๊ธฐ๋ฅ์ถ๊ฐ #69
Conversation
reate API
Walkthrough์ด๋ฒ ํ ๋ฆฌํ์คํธ์ ๋ณ๊ฒฝ ์ฌํญ์ ์ฌ๋ฌ ํ์ผ์ ๋ํ ์์ ์ผ๋ก ๊ตฌ์ฑ๋๋ฉฐ, ์๋ก์ด ๊ธฐ๋ฅ์ ๋์
๊ณผ ๊ธฐ์กด ๊ธฐ๋ฅ์ ์
๋ฐ์ดํธ๋ฅผ ํฌํจํฉ๋๋ค. ์ฃผ์ ์
๋ฐ์ดํธ๋ก๋ ์ด๋ฏธ์ง ํฌ๊ธฐ ์กฐ์ ๋ฐ ์์ถ์ ์ํ ์๋ก์ด Swift ํ์ผ ์ถ๊ฐ, Expo ์ ํ๋ฆฌ์ผ์ด์
๋ทฐ์ ๋ฆฌํฉํ ๋ง, Expo ์์ฑ์ ์ํ ์ฌ๋ฌ ์๋ก์ด ๋ชจ๋ธ ๋ฐ API ์ฒ๋ฆฌ์ ๋์
์ด ์์ต๋๋ค. ๋ํ, Changes
Poem
๐ Recent review detailsConfiguration used: CodeRabbit UI ๐ Files selected for processing (1)
๐ง Files skipped from review as they are similar to previous changes (1)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? ๐ชง TipsChatThere are 3 ways to chat with CodeRabbit:
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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 8
๐งน Outside diff range and nitpick comments (9)
Projects/App/Sources/Extension/UIImageSize.swift (1)
12-26
: Add documentation and input validationWhile the implementation is solid, consider these improvements:
- Add documentation comments explaining the parameters and return value
- Add validation for edge cases
Here's a suggested improvement:
+ /// Resizes and compresses an image while maintaining aspect ratio + /// - Parameters: + /// - maxWidth: Maximum width of the output image (default: 512) + /// - maxHeight: Maximum height of the output image (default: 512) + /// - compressionQuality: JPEG compression quality between 0 and 1 (default: 0.7) + /// - Returns: A compressed and resized UIImage, or nil if processing fails func compressedAndResized(maxWidth: CGFloat = 512, maxHeight: CGFloat = 512, compressionQuality: CGFloat = 0.7) -> UIImage? { + guard maxWidth > 0, maxHeight > 0, compressionQuality > 0, compressionQuality <= 1 else { return nil } + guard self.size.width > 0, self.size.height > 0 else { return nil } let scale = min(maxWidth / self.size.width, maxHeight / self.size.height, 1)Projects/App/Sources/Feature/ExpoEditFeature/Sources/ExpoEditView.swift (1)
Line range hint
150-154
: Update the hint text to match the new date formatThe hint text still shows the old format ("yyyy.mm.dd") while the actual implementation uses hyphens ("yyyy-mm-dd"). This inconsistency could confuse users.
Apply this diff to update the hint text:
- Text("์์์ผ๊ณผ ๋ง๊ฐ์ผ ์ ๋ ฅ์ ' yyyy.mm.dd ' ํ์์ผ๋ก ์ ๋ ฅํด์ฃผ์ธ์") + Text("์์์ผ๊ณผ ๋ง๊ฐ์ผ ์ ๋ ฅ์ ' yyyy-mm-dd ' ํ์์ผ๋ก ์ ๋ ฅํด์ฃผ์ธ์")Projects/App/Sources/Feature/TabBarFeature/Sources/TabBarView.swift (1)
MainView implementation is specific to expo listings and shouldn't be reused across tabs
The MainView implementation is specifically designed for displaying expo listings with features like:
- Expo logo display
- Sorting functionality for expo entries
- List of expo events with dates, titles, and descriptions
Using this same view for "Home" and "Profile" tabs is incorrect as these tabs would require different content and functionality. Each tab should have its dedicated view:
HomeView
for the home tabExpoListView
(rename current MainView) for the expo listings tabProfileView
for the profile tab๐ Analysis chain
Line range hint
19-50
: Verify MainView implementation for different tabsThe same
MainView()
is being used for three different tabs (Home, Expo List, and Profile) without any customization. This might not provide the intended unique functionality for each tab.Consider creating separate view components for each tab to maintain better separation of concerns and provide tab-specific functionality.
The previous ast-grep pattern might have failed due to syntax issues with Swift. Let's try these alternative approaches to locate and understand the MainView implementation.
I see that MainView exists in a separate feature module, but we need to examine its implementation to understand if it's designed to handle different tab contexts or if it's a generic view being incorrectly reused.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Check MainView implementation ast-grep --pattern 'struct MainView: View { $$$ }'Length of output: 54
Script:
#!/bin/bash # Let's try different approaches to find MainView implementation # 1. Search for MainView using ripgrep rg "MainView" -A 5 # 2. Try finding Swift view files that might contain MainView fd -e swift . | xargs rg "MainView" # 3. Look for files with MainView in their name fd "MainView"Length of output: 3693
Script:
#!/bin/bash # Let's examine the MainView implementation to understand its content cat Projects/App/Sources/Feature/MainFeature/Sources/MainView.swiftLength of output: 5074
Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoCreateView.swift (3)
127-127
: Clarify the date format in the warning messageThe warning message specifies the date format as
' yyyy-mm-dd '
, including extra spaces and apostrophes. Consider updating it toyyyy-MM-dd
without additional characters for better clarity.
155-194
: Refactor duplicated code for program sectionsThe code for "์ผ๋ฐ ํ๋ก๊ทธ๋จ" and "์ฐ์์ ํ๋ก๊ทธ๋จ" sections is nearly identical. Consider creating a reusable view component for these sections to reduce code duplication and enhance maintainability.
28-41
: Adjust navigation bar layout for better alignmentThe current navigation bar layout might cause misalignment of the back button and title, especially on devices with different screen sizes. Consider using
ToolbarItem
andnavigationTitle
modifiers to ensure consistent alignment across all devices.Projects/Domain/Sources/Services/Expo/ExpoAPI.swift (1)
16-59
: Externalize base URL and endpoints for flexibilityCurrently, the base URL is hardcoded, which can make it difficult to manage different environments (development, staging, production). Consider externalizing the base URL and endpoints using configuration files or environment variables.
Projects/Domain/Sources/Extension/ExpoToken.swift (1)
Line range hint
38-63
: Prevent logging of sensitive token dataPrinting token information, such as in
print("Token ์ ์ฅ ์๋ฃ: \(tokenString)")
, can expose sensitive data. Remove these statements to enhance security.Apply this diff to eliminate sensitive logging:
if let encodedData = try? JSONEncoder().encode(tokenData), let tokenString = String(data: encodedData, encoding: .utf8) { create(key: key, token: tokenString) - print("Token ์ ์ฅ ์๋ฃ: \(tokenString)") + print("Token saved successfully") } else { print("TokenData ์ธ์ฝ๋ฉ ์คํจ") }Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoCreateViewModel.swift (1)
123-125
: Provide user feedback on network errorsWhen a network error occurs, the app currently prints the error description. Consider informing the user with an alert or UI message to improve the user experience.
๐ Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
๐ Files selected for processing (13)
.gitignore
(1 hunks)Projects/App/Sources/Extension/UIImageSize.swift
(1 hunks)Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoCreateView.swift
(8 hunks)Projects/App/Sources/Feature/ExpoApplicationFeature/Sources/ExpoCreateViewModel.swift
(1 hunks)Projects/App/Sources/Feature/ExpoEditFeature/Sources/ExpoEditView.swift
(1 hunks)Projects/App/Sources/Feature/PostDetailFeature/Sources/PostDetailView.swift
(1 hunks)Projects/App/Sources/Feature/SigninFeature/Sources/SigninView.swift
(1 hunks)Projects/App/Sources/Feature/TabBarFeature/Sources/TabBarView.swift
(2 hunks)Projects/Domain/Sources/Extension/ExpoToken.swift
(2 hunks)Projects/Domain/Sources/Model/Expo/Response/ExpoCreateResponse.swift
(1 hunks)Projects/Domain/Sources/Request/ExpoCreate/ExpoCreateRequest.swift
(1 hunks)Projects/Domain/Sources/Services/Expo/ExpoAPI.swift
(1 hunks)Scripts/.swiftlint.yml
(1 hunks)
โ Files skipped from review due to trivial changes (3)
- Projects/Domain/Sources/Model/Expo/Response/ExpoCreateResponse.swift
- .gitignore
- Scripts/.swiftlint.yml
๐ Additional comments (5)
Projects/App/Sources/Extension/UIImageSize.swift (2)
1-10
: LGTM! File structure follows best practices
The file header and import statement are properly structured following Swift conventions.
18-20
: LGTM! Proper memory management with defer
The use of defer
ensures proper cleanup of the graphics context, preventing memory leaks.
Projects/App/Sources/Feature/ExpoEditFeature/Sources/ExpoEditView.swift (1)
Line range hint 265-277
: LGTM on the date formatting implementation
The formatDateInput
function:
- Correctly handles partial input
- Maintains the required 10-character length for form validation
- Properly sanitizes input by filtering numbers
Projects/App/Sources/Feature/TabBarFeature/Sources/TabBarView.swift (1)
30-30
: Verify tab bar image assets and enhance accessibility
The tab bar uses conditional image assets for selected/unselected states. Let's ensure these assets exist and consider accessibility improvements.
Consider adding accessibility labels to the tab items. Apply this enhancement:
Image(selectedTab == 1 ? "onHome" : "offHome")
+ .accessibilityLabel("ํ ํญ")
Text("ํ")
Also applies to: 38-38, 46-46
โ Verification successful
The previous command didn't show the assets, so let's try a different approach to locate the asset catalogs and image sets first. This will help us understand where to look for these specific images.
Tab bar image assets verified, accessibility improvements recommended
All required tab bar image assets are present in the Assets.xcassets:
- onCheck/offCheck
- onExpo/offExpo
- onHome/offHome
- onUser/offUser
The suggested accessibility improvements would enhance user experience and should be implemented as proposed in the original review.
๐ Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Check if all required image assets exist
for img in "onHome" "offHome" "onCheck" "offCheck" "onExpo" "offExpo" "onUser" "offUser"; do
fd -e xcassets -e pdf -e png "$img"
done
Length of output: 1037
Script:
#!/bin/bash
# Let's try a different approach to find image assets
# First, let's find all asset catalogs
fd -e xcassets
# Then let's try to find any image set files that might contain these images
fd -e imageset
Length of output: 1780
Projects/Domain/Sources/Extension/ExpoToken.swift (1)
38-38
: Confirm the necessity of changing method access level to public
The saveTokenWithExpiration
method has been changed to public
. Ensure this change is necessary for external access and does not violate encapsulation principles.
@@ -16,7 +16,7 @@ struct PostDetailView: View { | |||
@State private var drawMap: Bool = true | |||
@State private var showMessageSheet = false | |||
@State private var showQrcodeSheet = false | |||
@State private var link: String = "https://github.com/School-of-Company/Expo-iOS" | |||
@State private var link: String = "https://github.com/xixn2" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
๐ ๏ธ Refactor suggestion
Review: GitHub link points to personal profile
The QR code generation link has been changed from the project repository to a personal GitHub profile. This might be unintentional and could affect the functionality of the QR code feature.
- @State private var link: String = "https://github.com/xixn2"
+ @State private var link: String = "https://github.com/School-of-Company/Expo-iOS"
Consider moving the URL to a configuration file or environment variable instead of hardcoding it:
@State private var link: String = Configuration.shared.repositoryURL
// ๋ทฐ ๋ชจ๋ธ์ @StateObject๋ก ์ ์ธ | ||
@StateObject private var expoCreateViewModel = ExpoCreateViewModel() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove duplicate ViewModel instantiation
The ExpoCreateViewModel is currently instantiated twice:
- As a @StateObject at line 15
- Again when creating ExpoCreateView at line 36
This could lead to state management issues as you're maintaining two separate instances of the same ViewModel.
Apply this fix to use the shared instance:
@StateObject private var expoCreateViewModel = ExpoCreateViewModel()
// Later in the TabView...
-ExpoCreateView(viewModel: ExpoCreateViewModel())
+ExpoCreateView(viewModel: expoCreateViewModel)
Committable suggestion skipped: line range outside the PR's diff.
if let base64ImageString = viewModel.convertImageToBase64String(image: selectedImage) { | ||
viewModel.setupCoverImage(image: selectedImage) | ||
} else { | ||
print("Failed to convert image to Base64") | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Handle image conversion failure to prevent unintended behavior
In the expoCreate
function, if the image fails to convert to a Base64 string, the coverImage
is not set, but the code continues execution. This could lead to an API call with incomplete data. Consider adding error handling to stop the process if the image conversion fails.
Apply this diff to handle the error:
if let selectedImage = selectedImage {
if let base64ImageString = viewModel.convertImageToBase64String(image: selectedImage) {
viewModel.setupCoverImage(image: selectedImage)
} else {
print("Failed to convert image to Base64")
+ return
}
}
Committable suggestion skipped: line range outside the PR's diff.
public struct ExpoCreateRequest: Codable { | ||
var title: String | ||
var description: String | ||
var startedDay: String | ||
var finishedDay: String | ||
var location: String | ||
var coverImage: String | ||
var x: Float | ||
var y: Float | ||
|
||
public init( | ||
title: String, | ||
description: String, | ||
startedDay: String, | ||
finishedDay: String, | ||
location: String, | ||
coverImage: String, | ||
x: Float, | ||
y: Float | ||
) { | ||
self.title = title | ||
self.description = description | ||
self.startedDay = startedDay | ||
self.finishedDay = finishedDay | ||
self.location = location | ||
self.coverImage = coverImage | ||
self.x = x | ||
self.y = y | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Make properties public
for external access
The ExpoCreateRequest
struct is declared as public
, but its properties are not. This restricts access to these properties from other modules. To allow proper initialization and usage, consider making all properties public
.
Apply this diff to update property access levels:
public struct ExpoCreateRequest: Codable {
- var title: String
- var description: String
- var startedDay: String
- var finishedDay: String
- var location: String
- var coverImage: String
- var x: Float
- var y: Float
+ public var title: String
+ public var description: String
+ public var startedDay: String
+ public var finishedDay: String
+ public var location: String
+ public var coverImage: String
+ public var x: Float
+ public var y: Float
public init(
title: String,
description: String,
startedDay: String,
finishedDay: String,
location: String,
coverImage: String,
x: Float,
y: Float
) {
self.title = title
self.description = description
self.startedDay = startedDay
self.finishedDay = finishedDay
self.location = location
self.coverImage = coverImage
self.x = x
self.y = y
}
}
๐ 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.
public struct ExpoCreateRequest: Codable { | |
var title: String | |
var description: String | |
var startedDay: String | |
var finishedDay: String | |
var location: String | |
var coverImage: String | |
var x: Float | |
var y: Float | |
public init( | |
title: String, | |
description: String, | |
startedDay: String, | |
finishedDay: String, | |
location: String, | |
coverImage: String, | |
x: Float, | |
y: Float | |
) { | |
self.title = title | |
self.description = description | |
self.startedDay = startedDay | |
self.finishedDay = finishedDay | |
self.location = location | |
self.coverImage = coverImage | |
self.x = x | |
self.y = y | |
} | |
} | |
public struct ExpoCreateRequest: Codable { | |
public var title: String | |
public var description: String | |
public var startedDay: String | |
public var finishedDay: String | |
public var location: String | |
public var coverImage: String | |
public var x: Float | |
public var y: Float | |
public init( | |
title: String, | |
description: String, | |
startedDay: String, | |
finishedDay: String, | |
location: String, | |
coverImage: String, | |
x: Float, | |
y: Float | |
) { | |
self.title = title | |
self.description = description | |
self.startedDay = startedDay | |
self.finishedDay = finishedDay | |
self.location = location | |
self.coverImage = coverImage | |
self.x = x | |
self.y = y | |
} | |
} |
if let tokenData = KeyChain.shared.loadTokenWithExpiration(key: Const.KeyChainKey.accessToken), | ||
!KeyChain.shared.isTokenExpired(key: Const.KeyChainKey.accessToken) { | ||
print("Token found: \(tokenData.token)") | ||
return [ | ||
"Content-Type": "application/json", | ||
"Authorization": "Bearer \(tokenData.token)" | ||
] | ||
} else { | ||
print("No valid token found, using default headers") | ||
return ["Content-Type": "application/json"] | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Avoid logging sensitive token information
Printing the access token in logs can lead to security vulnerabilities if logs are exposed. Remove any print statements that output token values.
Apply this diff to remove the sensitive log:
if let tokenData = KeyChain.shared.loadTokenWithExpiration(key: Const.KeyChainKey.accessToken),
!KeyChain.shared.isTokenExpired(key: Const.KeyChainKey.accessToken) {
- print("Token found: \(tokenData.token)")
return [
"Content-Type": "application/json",
"Authorization": "Bearer \(tokenData.token)"
]
} else {
print("No valid token found, using default headers")
return ["Content-Type": "application/json"]
}
๐ 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.
if let tokenData = KeyChain.shared.loadTokenWithExpiration(key: Const.KeyChainKey.accessToken), | |
!KeyChain.shared.isTokenExpired(key: Const.KeyChainKey.accessToken) { | |
print("Token found: \(tokenData.token)") | |
return [ | |
"Content-Type": "application/json", | |
"Authorization": "Bearer \(tokenData.token)" | |
] | |
} else { | |
print("No valid token found, using default headers") | |
return ["Content-Type": "application/json"] | |
} | |
} | |
if let tokenData = KeyChain.shared.loadTokenWithExpiration(key: Const.KeyChainKey.accessToken), | |
!KeyChain.shared.isTokenExpired(key: Const.KeyChainKey.accessToken) { | |
return [ | |
"Content-Type": "application/json", | |
"Authorization": "Bearer \(tokenData.token)" | |
] | |
} else { | |
print("No valid token found, using default headers") | |
return ["Content-Type": "application/json"] | |
} | |
} |
๐ก ๊ฐ์
๐ ์์ ๋ด์ฉ
Summary by CodeRabbit
Release Notes
New Features
Bug Fixes
Chores
.gitignore
๋ฅผ ๊ฐ์ ํ์ต๋๋ค.Refactor