-
Notifications
You must be signed in to change notification settings - Fork 0
[Fix] QA 반영 #189
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
[Fix] QA 반영 #189
Conversation
- 내용이 둘 다 없는 경우, 안내 시트 없이 나가기
- 프로필 이미지 뷰 이미지 반영 방법 수정 - 콘텐츠 레이아웃 수정
WalkthroughThis update refactors and enhances various UI and logic components related to the Viewit and Community features. It introduces improved notification handling, asynchronous URL validation, layout adjustments, and new notification types. Several user interactions are now reactive, and button positions, image handling, and loading view layouts are updated for better user experience and QA feedback. Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant CreateViewitViewController
participant CreateViewitViewModel
participant CreateViewitUseCase
participant URLPreviewRepository
User->>CreateViewitViewController: Tap "Next"
CreateViewitViewController->>CreateViewitViewModel: nextRelay.send()
CreateViewitViewModel->>CreateViewitUseCase: validate(urlString)
CreateViewitUseCase->>URLPreviewRepository: fetchPreview(url)
URLPreviewRepository-->>CreateViewitUseCase: URLPreview or Error
CreateViewitUseCase-->>CreateViewitViewModel: Bool (success/failure)
CreateViewitViewModel-->>CreateViewitViewController: isPossibleToURLUpload (true/false)
CreateViewitViewController->>CreateViewitViewModel: User enters description, taps "Upload"
CreateViewitViewModel->>CreateViewitUseCase: execute(description)
CreateViewitUseCase-->>CreateViewitViewModel: Bool (success/failure)
CreateViewitViewModel-->>CreateViewitViewController: successUpload (true/false)
sequenceDiagram
participant User
participant CommunityViewController
participant CommunityViewModel
participant UNUserNotificationCenter
User->>CommunityViewController: Complete registration
CommunityViewController->>CommunityViewModel: checkNotificationAuthorizationRelay.send()
CommunityViewModel->>UNUserNotificationCenter: getNotificationSettings()
UNUserNotificationCenter-->>CommunityViewModel: authorizationStatus
CommunityViewModel-->>CommunityViewController: isNotificationAuthorized (true/false)
alt Not authorized
CommunityViewController->>User: Show alarm setting sheet
end
Assessment against linked issues
Poem
Note ⚡️ AI Code Reviews for VS Code, Cursor, WindsurfCodeRabbit 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. Note ⚡️ Faster reviews with cachingCodeRabbit now supports caching for code and dependencies, helping speed up reviews. This means quicker feedback, reduced wait times, and a smoother review experience overall. Cached data is encrypted and stored securely. This feature will be automatically enabled for all accounts on May 16th. To opt out, configure 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
✨ Finishing Touches
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. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
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: 1
🔭 Outside diff range comments (1)
Wable-iOS/Presentation/Viewit/Create/ViewModel/CreateViewitViewModel.swift (1)
80-97:⚠️ Potential issue
Uploadis enabled even when URL has not been validated – may trigger the issue above
writeButtonIsEnableddepends only on the description text.
Therefore a user can:
- Enter any description (non-empty)
- Never press Next / never validate URL
- Tap Upload →
executeis called withurlPreview == nil, producing.unknownError.Couple the enabled state (and the upload trigger) to successful URL validation:
-let writeButtonIsEnabled = descriptionRelay - .map { !$0.isEmpty } +let writeButtonIsEnabled = Publishers.CombineLatest(descriptionRelay, isPossibleToURLUpload) + .map { !$0.0.isEmpty && $0.1 } // both description and valid URL requiredAdditionally, you may want to gate the
executecall itself behindisPossibleToURLUploadto avoid unnecessary network calls.
🧹 Nitpick comments (6)
Wable-iOS/Presentation/Community/View/CommunityViewController.swift (1)
160-160: Consider adding more context to the log message.While logging community items is useful for debugging, adding more specific context about why they're being logged would make the logs more informative.
- WableLogger.log("커뮤니티 아이템: \(communityItems)", for: .debug) + WableLogger.log("커뮤니티 아이템 수신됨: \(communityItems.count)개", for: .debug)Wable-iOS/Presentation/Viewit/Create/View/CreateViewitViewController.swift (3)
163-169: Dispatch UI work explicitly on the main queue
sinkclosures are executed on whichever scheduler the upstream happens to emit.
AlthoughURLSessioncurrently delivers on the main run-loop in your pipeline, this is an implementation detail that can change. Calling UIKit APIs (becomeFirstResponder) from a background thread will crash in production builds.-output.isPossibleToURLUpload - .filter { $0 } - .sink { [weak self] _ in - self?.viewitInputView.descriptionTextField.becomeFirstResponder() - } +output.isPossibleToURLUpload + .filter { $0 } + .receive(on: RunLoop.main) // ✅ guarantee main queue + .sink { [weak self] _ in + self?.viewitInputView.descriptionTextField.becomeFirstResponder() + }
200-203: Dismiss keyboard on background tap for better UXCurrently the background tap only emits an event. Users usually expect the keyboard to fold when they tap outside an input field.
@objc func backgroundViewDidTap() { - backgroundTapRelay.send() + view.endEditing(true) // hides keyboard + backgroundTapRelay.send() }
246-254: Prevent retain-cycle inside action closure
confirmActioncapturesselfweakly – great – butWableSheetActionretains its handler until the sheet is deallocated.
If for any reason the sheet lives longer than the controller, the closure still referencesself(even though weak), so no issue arises.
Nonetheless, it is safer to explicitly nil-out the handler after execution to avoid accidental leaks when the action is reused.let confirmAction = WableSheetAction(title: "나가기", style: .primary) { [weak self] in self?.dismiss(animated: true) confirmAction.handler = nil // break potential retain-cycle }Wable-iOS/Domain/UseCase/Viewit/CreateViewitUseCase.swift (1)
30-34: Return a specific validation error instead of.unknownErrorFailing the basic scheme / host checks is a user-input error, not an “unknown” one.
Consider introducing (or re-using)WableError.validationExceptionto give the caller meaningful feedback.-else { - return .fail(.unknownError) -} +else { + return .fail(.validationException) +}Wable-iOS/Presentation/Viewit/Create/ViewModel/CreateViewitViewModel.swift (1)
66-77: Minor: Replace unused closure parameter with_to satisfy SwiftLintSwiftLint flagged
unused_closure_parameter.
The second element returned bywithUnretainedis not used, so underscore is fine:-.flatMap { owner, _ -> AnyPublisher<Bool, Never> in +.flatMap { owner, _ -> AnyPublisher<Bool, Never> in🧰 Tools
🪛 SwiftLint (0.57.0)
[Warning] 71-71: Unused parameter in a closure should be replaced with _
(unused_closure_parameter)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
Cache: Disabled due to data retention organization setting
Knowledge Base: Disabled due to data retention organization setting
📒 Files selected for processing (14)
Wable-iOS/Data/Mapper/NotificationMapper.swift(1 hunks)Wable-iOS/Data/RepositoryImpl/URLPreviewRepositoryImpl.swift(1 hunks)Wable-iOS/Domain/Enum/TriggerType.swift(1 hunks)Wable-iOS/Domain/UseCase/Viewit/CreateViewitUseCase.swift(1 hunks)Wable-iOS/Presentation/Community/View/CommunityViewController.swift(5 hunks)Wable-iOS/Presentation/Community/ViewModel/CommunityViewModel.swift(4 hunks)Wable-iOS/Presentation/Notification/Activity/Model/ActivityNotification+.swift(2 hunks)Wable-iOS/Presentation/Viewit/Create/View/CreateViewitViewController.swift(7 hunks)Wable-iOS/Presentation/Viewit/Create/View/Subview/ViewitInputView.swift(1 hunks)Wable-iOS/Presentation/Viewit/Create/ViewModel/CreateViewitViewModel.swift(4 hunks)Wable-iOS/Presentation/Viewit/List/View/Cell/ViewitListCell.swift(3 hunks)Wable-iOS/Presentation/Viewit/List/View/Subview/ViewitListView.swift(2 hunks)Wable-iOS/Presentation/WableComponent/Cell/NotificationCell.swift(1 hunks)Wable-iOS/Presentation/WableComponent/ViewController/LoadingViewController.swift(1 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (5)
Wable-iOS/Data/Mapper/NotificationMapper.swift (1)
Wable-iOS/Domain/Enum/TriggerType.swift (1)
from(30-37)
Wable-iOS/Domain/Enum/TriggerType.swift (1)
Wable-iOS/Core/Logger/WableLogger.swift (1)
log(14-25)
Wable-iOS/Presentation/WableComponent/ViewController/LoadingViewController.swift (1)
Wable-iOS/Presentation/Helper/Extension/ConstraintMaker+.swift (1)
adjustedWidthEqualTo(27-30)
Wable-iOS/Presentation/Community/ViewModel/CommunityViewModel.swift (1)
Wable-iOS/Core/Logger/WableLogger.swift (1)
log(14-25)
Wable-iOS/Domain/UseCase/Viewit/CreateViewitUseCase.swift (3)
Wable-iOS/Presentation/Viewit/Create/ViewModel/CreateViewitViewModel.swift (1)
validate(114-136)Wable-iOS/Data/RepositoryImpl/URLPreviewRepositoryImpl.swift (1)
fetchPreview(14-54)Wable-iOS/Data/RepositoryImpl/ViewitRepositoryImpl.swift (2)
createViewit(56-77)createViewit(184-194)
🪛 SwiftLint (0.57.0)
Wable-iOS/Presentation/Viewit/Create/ViewModel/CreateViewitViewModel.swift
[Warning] 71-71: Unused parameter in a closure should be replaced with _
(unused_closure_parameter)
🔇 Additional comments (29)
Wable-iOS/Presentation/WableComponent/ViewController/LoadingViewController.swift (1)
87-87: Improved vertical centering of loading components.The changes to the layout constraints provide better vertical alignment by positioning elements relative to the view's center rather than using fixed top offsets. This creates a more balanced visual appearance across different screen sizes.
Also applies to: 94-94
Wable-iOS/Presentation/Community/View/CommunityViewController.swift (5)
38-38: Good addition of notification authorization check relay.The
checkNotificationAuthorizationRelayfollows the established pattern for handling events with Combine, maintaining consistency with the rest of the code.
152-153: LGTM! Input parameter correctly updated.The ViewModel's
Inputis properly extended to include the new notification authorization check relay.
180-185: Good implementation of notification authorization flow.Filtering for unauthorized notification states to conditionally show the alarm setting sheet is a clean approach that aligns with reactive programming principles.
219-219: Improved user flow with notification check.The notification authorization check is now appropriately triggered after the registration completion sheet is dismissed, creating a more seamless user experience.
235-235: Good error handling improvement.Using the logger in the guard's else clause improves error visibility while maintaining clean control flow.
Wable-iOS/Presentation/Community/ViewModel/CommunityViewModel.swift (6)
10-10: Necessary import added.The
UserNotificationsframework import is required for the notification authorization functionality.
25-25: Well-structured ViewModel interface.The Input and Output structs are properly extended to support the new notification authorization check functionality, maintaining the MVVM pattern.
Also applies to: 32-32
106-114: Improved error handling with guard pattern.The community list update logic now safely handles the case when a team can't be found, using proper guard clauses and logging the issue for debugging.
117-133: Clean refactoring of communityItems mapping.The simplified mapping of community items improves readability while maintaining the same functionality, with a clear sorting to prioritize registered items.
139-148: Well-implemented notification authorization check.The
isNotificationAuthorizedpublisher is implemented correctly usingFutureto handle the asynchronous UNUserNotificationCenter API. This is a clean approach to bridging callback-based APIs with Combine.
153-154: Output struct properly updated.The Output struct initialization is updated to include the new isNotificationAuthorized property, maintaining consistency with the ViewModel interface.
Wable-iOS/Presentation/Viewit/Create/View/Subview/ViewitInputView.swift (1)
24-24: Icon update improves UI clarity.The change from what was likely
.addto.icLinkfor the URL input icon better represents the purpose of the field, providing users with a clearer visual cue about the expected input type.Wable-iOS/Presentation/WableComponent/Cell/NotificationCell.swift (1)
20-20: Improved profile image display.Changing from
.scaleAspectFitto.scaleAspectFillensures profile images fill the circular frame completely, which is the standard approach for profile pictures in modern UIs. This works well with the existingclipsToBounds = trueon the next line to maintain the circular shape.Wable-iOS/Data/Mapper/NotificationMapper.swift (1)
35-35: Enhanced error handling for notification type mapping.Using the
from(_:)method instead of direct raw value initialization improves traceability by logging debug messages when conversion fails. This matches the PR objective of enhancing enum initialization and will help identify issues with unexpected notification types.Wable-iOS/Presentation/Notification/Activity/Model/ActivityNotification+.swift (2)
13-13: Better fallback message for unknown notification types.Replacing an empty string with "알 수 없는 메세지" (Unknown message) provides clearer feedback to users when a notification type is nil, improving the user experience.
41-42: Support added for new viewitLike notification type.The implementation for the new
.viewitLikecase follows the established pattern of other notification messages, maintaining consistency in the UI while extending functionality.Wable-iOS/Domain/Enum/TriggerType.swift (2)
28-28: New notification type added for Viewit likesThe
viewitLikecase is appropriately added to handle notifications when a user likes another user's viewit content.
30-37: Good addition of a safer enum initializer with error loggingThis
from(_:)static method provides a safer alternative to raw value initialization with error tracking. It attempts to create an enum instance and logs a debug message if it fails, which improves traceability for debugging notification-related issues.// Example usage that benefits from this approach: -if let notificationType = ActivityNotification(rawValue: someString) { +if let notificationType = ActivityNotification.from(someString) { // Success case } else { // Failure case - with the new implementation, a debug log is also generated }Wable-iOS/Presentation/Viewit/List/View/Subview/ViewitListView.swift (2)
27-29: Modern button configuration approachThe change to use
UIButton(configuration: .plain())is a good modernization that aligns with current iOS best practices.
93-95: Improved button positioningThe adjustment to the trailing and bottom constraints provides better spacing and alignment for the create button.
Wable-iOS/Presentation/Viewit/List/View/Cell/ViewitListCell.swift (5)
26-27: Improved profile image displayChanging to
.scaleAspectFillensures the profile image properly fills the circular view without distortion, which is the standard approach for profile pictures.
226-227: Better vertical spacing for title labelRemoving the negative offset improves the spacing between the title and site name labels.
231-232: Proper constraint relationship between site name and like buttonUsing
lessThanOrEqualTowith the like button ensures the site name label won't overlap with the like button when content sizes vary.
236-237: Adjusted bottom padding for like buttonReducing the bottom offset from -8 to -4 provides better spacing at the bottom of the card.
314-318: Excellent UI responsiveness improvement for like buttonThis change provides immediate visual feedback when a user taps the like button by updating the UI state before the network call completes. This significantly improves perceived responsiveness.
Wable-iOS/Data/RepositoryImpl/URLPreviewRepositoryImpl.swift (3)
13-13: Simplified to a struct implementationConverting from a class to a struct is appropriate for this repository as it has no mutable state.
15-20: Improved session configuration with appropriate timeoutsCreating an ephemeral session with custom timeouts for each request is a good practice that:
- Prevents caching issues between requests
- Sets reasonable timeouts (5s for request, 10s for resource) to avoid long waiting times
- Improves the user experience by failing faster on slow connections
25-25: Type-safe error handling in tryMapThe explicit return type in the tryMap closure improves type safety and code clarity.
| private var urlPreview: URLPreview? | ||
|
|
||
| func execute(urlString: String, description: String) -> AnyPublisher<Void, WableError> { | ||
| func validate(_ urlString: String) -> AnyPublisher<Bool, WableError> { | ||
| let updatedURLString = checkURLScheme(urlString) | ||
|
|
||
| guard let url = URL(string: updatedURLString) else { | ||
| return .fail(.unknownError) | ||
| } | ||
|
|
||
| guard let scheme = url.scheme, !scheme.isEmpty, | ||
| let host = url.host, !host.isEmpty | ||
| else { | ||
| return .fail(.unknownError) | ||
| } | ||
|
|
||
| return urlPreviewRepository.fetchPreview(url: url) | ||
| .flatMap { [weak self] preview -> AnyPublisher<Void, WableError> in | ||
| guard let self else { | ||
| return .fail(.unknownError) | ||
| } | ||
|
|
||
| return viewitRepository.createViewit( | ||
| thumbnailImageURLString: preview.imageURLString, | ||
| urlString: updatedURLString, | ||
| title: preview.title, | ||
| text: description, | ||
| siteName: preview.siteName | ||
| ) | ||
| .eraseToAnyPublisher() | ||
| } | ||
| .handleEvents(receiveOutput: { [weak self] preview in | ||
| self?.urlPreview = preview | ||
| }) | ||
| .map { _ in true } | ||
| .eraseToAnyPublisher() | ||
| } | ||
|
|
||
| func execute(description: String) -> AnyPublisher<Bool, WableError> { | ||
| guard let urlPreview else { | ||
| return .fail(.unknownError) | ||
| } | ||
|
|
||
| return viewitRepository.createViewit( | ||
| thumbnailImageURLString: urlPreview.imageURLString, | ||
| urlString: urlPreview.urlString, | ||
| title: urlPreview.title, | ||
| text: description, | ||
| siteName: urlPreview.siteName | ||
| ) | ||
| .map { _ in true } | ||
| .eraseToAnyPublisher() | ||
| } |
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.
execute can run with a stale or nil urlPreview – causes wrong upload or crash
urlPreview is cached as mutable state:
validate(_: )sets it only on success.- If a user validates URL A (success) →
urlPreview = previewA,
then validates URL B (failure) →urlPreviewis not reset. - The user can still tap Upload (button is enabled independently of validation) and the post will be created with previewA, while the UI shows URL B – clear data inconsistency.
It can also be nil when the user skips validation altogether, leading to the .unknownError branch.
Recommended fix:
- Reset the cache as soon as a new validation starts.
- Disable Upload until a successful validation happened (see ViewModel comment).
- Pass the
URLPreviewthrough the publisher chain rather than storing mutable state.
private var urlPreview: URLPreview?
func validate(_ urlString: String) -> AnyPublisher<Bool, WableError> {
- let updatedURLString = checkURLScheme(urlString)
+ // Invalidate previous cache first
+ urlPreview = nil
+ let updatedURLString = checkURLScheme(urlString)
...
}
func execute(description: String) -> AnyPublisher<Bool, WableError> {
- guard let urlPreview else {
+ guard let urlPreview else { // still keep the guard for safety
return .fail(.unknownError)
}Long-term: make execute accept the URLPreview instance returned from validate to remove hidden coupling.
📝 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.
| private var urlPreview: URLPreview? | |
| func execute(urlString: String, description: String) -> AnyPublisher<Void, WableError> { | |
| func validate(_ urlString: String) -> AnyPublisher<Bool, WableError> { | |
| let updatedURLString = checkURLScheme(urlString) | |
| guard let url = URL(string: updatedURLString) else { | |
| return .fail(.unknownError) | |
| } | |
| guard let scheme = url.scheme, !scheme.isEmpty, | |
| let host = url.host, !host.isEmpty | |
| else { | |
| return .fail(.unknownError) | |
| } | |
| return urlPreviewRepository.fetchPreview(url: url) | |
| .flatMap { [weak self] preview -> AnyPublisher<Void, WableError> in | |
| guard let self else { | |
| return .fail(.unknownError) | |
| } | |
| return viewitRepository.createViewit( | |
| thumbnailImageURLString: preview.imageURLString, | |
| urlString: updatedURLString, | |
| title: preview.title, | |
| text: description, | |
| siteName: preview.siteName | |
| ) | |
| .eraseToAnyPublisher() | |
| } | |
| .handleEvents(receiveOutput: { [weak self] preview in | |
| self?.urlPreview = preview | |
| }) | |
| .map { _ in true } | |
| .eraseToAnyPublisher() | |
| } | |
| func execute(description: String) -> AnyPublisher<Bool, WableError> { | |
| guard let urlPreview else { | |
| return .fail(.unknownError) | |
| } | |
| return viewitRepository.createViewit( | |
| thumbnailImageURLString: urlPreview.imageURLString, | |
| urlString: urlPreview.urlString, | |
| title: urlPreview.title, | |
| text: description, | |
| siteName: urlPreview.siteName | |
| ) | |
| .map { _ in true } | |
| .eraseToAnyPublisher() | |
| } | |
| private var urlPreview: URLPreview? | |
| func validate(_ urlString: String) -> AnyPublisher<Bool, WableError> { | |
| // Invalidate previous cache first | |
| urlPreview = nil | |
| let updatedURLString = checkURLScheme(urlString) | |
| guard let url = URL(string: updatedURLString) else { | |
| return .fail(.unknownError) | |
| } | |
| guard let scheme = url.scheme, !scheme.isEmpty, | |
| let host = url.host, !host.isEmpty | |
| else { | |
| return .fail(.unknownError) | |
| } | |
| return urlPreviewRepository.fetchPreview(url: url) | |
| .handleEvents(receiveOutput: { [weak self] preview in | |
| self?.urlPreview = preview | |
| }) | |
| .map { _ in true } | |
| .eraseToAnyPublisher() | |
| } | |
| func execute(description: String) -> AnyPublisher<Bool, WableError> { | |
| guard let urlPreview else { // still keep the guard for safety | |
| return .fail(.unknownError) | |
| } | |
| return viewitRepository.createViewit( | |
| thumbnailImageURLString: urlPreview.imageURLString, | |
| urlString: urlPreview.urlString, | |
| title: urlPreview.title, | |
| text: description, | |
| siteName: urlPreview.siteName | |
| ) | |
| .map { _ in true } | |
| .eraseToAnyPublisher() | |
| } |
🤖 Prompt for AI Agents
In Wable-iOS/Domain/UseCase/Viewit/CreateViewitUseCase.swift between lines 21
and 58, the execute function uses a cached mutable urlPreview that can be stale
or nil, causing incorrect uploads or crashes. To fix this, reset urlPreview to
nil at the start of validate to clear stale data, avoid storing urlPreview as
mutable state, and instead pass the URLPreview instance through the publisher
chain from validate to execute. Also, ensure the UI disables the Upload button
until validation succeeds to prevent execution with invalid or missing previews.
Ultimately, refactor execute to accept URLPreview as a parameter to eliminate
hidden state dependency.
youz2me
left a comment
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.
LGTM! 조금만 더 힘내봅시드아
| private static let urlDetector: NSDataDetector? = { | ||
| do { | ||
| return try NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue) | ||
| } catch { | ||
| WableLogger.log("NSDataDetector 초기화 오류: \(error.localizedDescription)", for: .error) | ||
| return nil | ||
| } | ||
| }() |
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.
urlDetector = NSDataDetector(types: NSTextCheckingResult.CheckingType.link.rawValue)
이런 식으로는 선언이 불가능한건가 싶어서요, 이렇게 do-catch를 써서 선언하신 이유가 있을까요 ???
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.
do-catch를 사용한 것은 최소한의 오류를 출력해서 확인하기 위한 장치정도로 봐주시면 감사하겠습니다.
사실 static 프로퍼티가 아니여도 될 듯은 합니다만, 일단 한 번이라도 생성되면 문제없을 것이라 판단하고 타입 프로퍼티로 구현해보았습니다.
| @objc func likeDidTap() { | ||
| let newCount = likeButton.isLiked ? likeButton.likeCount - 1 : likeButton.likeCount + 1 | ||
|
|
||
| likeButton.configureButton(isLiked: !likeButton.isLiked, likeCount: newCount, postType: .content) | ||
|
|
||
| likeDidTapClosure?() | ||
| } |
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.
다른 페이지에서도 반복되는 로직인 것 같기도 하구요... 나중에 기회가 되면 합치도록 해볼게요!
👻 PULL REQUEST
📄 작업 내용
각 QA 사항은 커밋 단위로 확인해주세요!
💻 주요 코드 설명
📍 RawValue를 가지는 Enum을 확인가능한 방법으로 생성하기 위한 코드
rawValue생성자를 이용하여 생성하고 있습니다.TriggerType.ActivityNotification을 타입 메서드로 생성하기
📚 참고자료
👀 기타 더 이야기해볼 점
🔗 연결된 이슈
Summary by CodeRabbit
Summary by CodeRabbit
New Features
UI Improvements
Bug Fixes
Refactor