Skip to content

Commit

Permalink
Release-1.0.0 앱 심사 배포 리젝 문제 해결 & 앱스토어 최초 배포 (#88)
Browse files Browse the repository at this point in the history
* refactor: 중복 로그인 에러 문구 수정

* refactor: privacy manifest 수정
- other user content 추가
- 앱 클립 삭제
- customer support & other user content의 privacy collected data type tracking false 설정

* refactor: 앱 버전 0.0.0 → 1.0.0으로 수정

* fix: ITMS-91055 Invalid API reason 문제 해결
- privacy manifets의 value들에 잘못된 값이 들어 있있던 부분 수정

* refactor: xcconfig세팅에 맞게 entitlements 분리

* refactor: 1.2.0Safety: User Generated Content 심사통과를 위한 리팩토링
- 신고 완료 알림의 message에 신고 처리 세부 내용 추가
- 노트 작성 시 경고 메세지를 placeholder에 추가

* refactor : 1.2.0 Safety: User Generated Content 심사 통과를 위한 유저 차단/차단 해제 기능 추가
- A mechanism for users to block abusive users

위 요건을 충족하기 위해
- 노트 또는 댓글에서 작성자를 차단할 수 있는 기능 추가
- 설정 페이지에서 차단 리스트 및 차단 해제를 할 수 있는 페이지 & 기능 추가

* feat: DisplayName 수정
- dev, qa, prod모두 같은 Feelin이라는 앱 이름 때문에 테스트시 헷갈리다는 의견을 반영하여
bundleDisplayName을 deploymentTarget에 따라서 변경되도록 수정
  • Loading branch information
inwoodev authored Nov 30, 2024
1 parent be09d78 commit d38d407
Show file tree
Hide file tree
Showing 57 changed files with 1,370 additions and 62 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import ProjectDescription
// 두 번째 자리1은 기능 리뉴얼과 기능 중규모 업데이트
// 세 번째 자리는 자잘한 디버깅 및 소소한 수정 업데이트

private let currentAppVersion: String = "0.0.1"
private let currentAppVersion: String = "1.0.0"

public extension Project {
enum Environment {
Expand Down Expand Up @@ -94,25 +94,25 @@ public extension Project {
trackingDomains: [],
collectedDataTypes: [
[
"NSPrivacyCollectedDataType": "User ID",
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypeUserID",
"NSPrivacyCollectedDataTypeLinked": true,
"NSPrivacyCollectedDataTypeTracking": false,
"NSPrivacyCollectedDataTypePurposes": [
"NSPrivacyCollectedDataTypePurposeAppFunctionality",
],
],
[
"NSPrivacyCollectedDataType": "Device ID",
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypeDeviceID",
"NSPrivacyCollectedDataTypeLinked": true,
"NSPrivacyCollectedDataTypeTracking": false,
"NSPrivacyCollectedDataTypePurposes": [
"NSPrivacyCollectedDataTypePurposeAppFunctionality",
],
],
[
"NSPrivacyCollectedDataType": "Customer support",
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypeCustomerSupport",
"NSPrivacyCollectedDataTypeLinked": true,
"NSPrivacyCollectedDataTypeTracking": true,
"NSPrivacyCollectedDataTypeTracking": false,
"NSPrivacyCollectedDataTypePurposes": [
"NSPrivacyCollectedDataTypeCustomerSupport",
],
Expand All @@ -122,20 +122,19 @@ public extension Project {
],
],
[
"NSPrivacyCollectedDataType": "Emails or text messages",
"NSPrivacyCollectedDataType": "NSPrivacyCollectedDataTypeOtherUserContent",
"NSPrivacyCollectedDataTypeLinked": true,
"NSPrivacyCollectedDataTypeTracking": true,
"NSPrivacyCollectedDataTypeTracking": false,
"NSPrivacyCollectedDataTypePurposes": [
"NSPrivacyCollectedDataTypeCustomerSupport",
"NSPrivacyCollectedDataTypeOtherUserContent",
],
],
],
accessedApiTypes: [
[
"NSPrivacyAccessedAPIType": "NSPrivacyAccessedAPICategoryUserDefaults",
"NSPrivacyAccessedAPITypeReasons": [
"User Defaults - CA92.1: Access info from same app, per documentation",
"User Defaults - 1C8F.1: Used to read and write app-specific information that is exclusively accessible within an App Clip environment",
"CA92.1",
],
],
]
Expand All @@ -144,20 +143,26 @@ public extension Project {
public static func appInfoPlist(deploymentTarget: ProjectDeploymentTarget) -> InfoPlist {
var kakaoNativeAppKey: String = ""
var baseServerURL: String = ""
var displayName: String = ""

switch deploymentTarget {
case .dev:
kakaoNativeAppKey = "${KAKAO_NATIVE_APP_KEY_DEV}"
baseServerURL = "${BASE_SERVER_URL_DEV}"
displayName = "\(Environment.appName)-\(deploymentTarget.rawValue)"
case .qa:
kakaoNativeAppKey = "${KAKAO_NATIVE_APP_KEY_QA}"
baseServerURL = "${BASE_SERVER_URL_QA}"
displayName = "\(Environment.appName)-\(deploymentTarget.rawValue)"
case .prod:
kakaoNativeAppKey = "${KAKAO_NATIVE_APP_KEY_PROD}"
baseServerURL = "${BASE_SERVER_URL_PROD}"
displayName = Environment.appName
}

return .extendingDefault(with: [
"CFBundleShortVersionString": "\(currentAppVersion)",
"CFBundleDisplayName": "\(displayName)",
"CFBundleVersion": "1",
"UILaunchStoryboardName": "LaunchScreen",
"NSAppTransportSecurity": ["NSAllowsArbitraryLoads": true],
Expand Down
File renamed without changes.
10 changes: 10 additions & 0 deletions Projects/App/Feelin-PROD.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
</dict>
</plist>
10 changes: 10 additions & 0 deletions Projects/App/Feelin-QA.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.applesignin</key>
<array>
<string>Default</string>
</array>
</dict>
</plist>
6 changes: 3 additions & 3 deletions Projects/App/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ let appTargets: [Target] = [
deploymentTarget: .dev,
factory: .init(
infoPlist: Project.Environment.appInfoPlist(deploymentTarget: .dev),
entitlements: "Feelin.entitlements",
entitlements: "Feelin-DEV.entitlements",
dependencies: [
.coordinator
],
Expand All @@ -33,7 +33,7 @@ let appTargets: [Target] = [
deploymentTarget: .qa,
factory: .init(
infoPlist: Project.Environment.appInfoPlist(deploymentTarget: .qa),
entitlements: "Feelin.entitlements",
entitlements: "Feelin-QA.entitlements",
dependencies: [
.coordinator
],
Expand All @@ -45,7 +45,7 @@ let appTargets: [Target] = [
deploymentTarget: .prod,
factory: .init(
infoPlist: Project.Environment.appInfoPlist(deploymentTarget: .prod),
entitlements: "Feelin.entitlements",
entitlements: "Feelin-PROD.entitlements",
dependencies: [
.coordinator
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,12 @@ public final class HomeCoordinator: Coordinator {

return NotificationAPIService(networkProvider: networkProvider)
}

DIContainer.standard.register(.userProfileAPIService) { resolver in
let networkProvider = try resolver.resolve(.networkProvider)

return UserProfileAPIService(networkProvider: networkProvider)
}

DIContainer.registerUserProfileService()
}
Expand Down Expand Up @@ -279,6 +285,7 @@ extension HomeCoordinator {
let deleteNoteUseCase = DeleteNoteUseCase(noteAPIService: noteAPIService)
let getHasUncheckedNotificationUseCase = GetHasUncheckedNotificationUseCase(notificationAPIService: notificationAPIService)
let checkFirstVisitorUseCase = CheckFirstVisitorUseCase(userProfileAPIService: userProfileAPIService)
let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = HomeViewModel(
getNotesUseCase: getNoteUseCase,
Expand All @@ -287,7 +294,8 @@ extension HomeCoordinator {
setBookmarkUseCase: setBookmarkUseCase,
deleteNoteUseCase: deleteNoteUseCase,
getHasUncheckedNotificationUseCase: getHasUncheckedNotificationUseCase,
checkFirstVisitorUseCase: checkFirstVisitorUseCase
checkFirstVisitorUseCase: checkFirstVisitorUseCase,
blockUserUseCase: blockUserUseCase
)

return viewModel
Expand Down Expand Up @@ -348,6 +356,7 @@ extension HomeCoordinator {

@Injected(.noteAPIService) var noteAPIService: NoteAPIServiceInterface
@Injected(.commentAPIService) var commentAPIService: CommentAPIServiceInterface
@Injected(.userProfileAPIService) var userProfileAPIService: UserProfileAPIServiceInterface
let tokenStorage = TokenStorage()

let setNoteLikeUseCase = SetNoteLikeUseCase(noteAPIService: noteAPIService)
Expand All @@ -357,6 +366,7 @@ extension HomeCoordinator {
let writeCommentUseCase = WriteCommentUseCase(commentAPIService: commentAPIService)
let deleteCommentUseCase = DeleteCommentUseCase(commentAPIService: commentAPIService)
let logoutUseCase = LogoutUseCase(tokenStorage: tokenStorage)
let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = NoteCommentsViewModel(
noteID: noteID,
Expand All @@ -366,7 +376,8 @@ extension HomeCoordinator {
getNoteWithCommentsUseCase: getNoteWithCommentsUseCase,
writeCommentUseCase: writeCommentUseCase,
deleteCommentUseCase: deleteCommentUseCase,
logoutUseCase: logoutUseCase
logoutUseCase: logoutUseCase,
blockUserUseCase: blockUserUseCase
)

return viewModel
Expand All @@ -377,6 +388,7 @@ extension HomeCoordinator {
@Injected(.notePaginationService) var notePaginationService: NotePaginationServiceInterface
@Injected(.artistAPIService) var artistAPIService: ArtistAPIServiceInterface
@Injected(.notificationAPIService) var notificationAPIService: NotificationAPIServiceInterface
@Injected(.userProfileAPIService) var userProfileAPIService: UserProfileAPIServiceInterface
let tokenStorage = TokenStorage()

let getArtistUseCase = GetArtistUseCase(artistAPIService: artistAPIService)
Expand All @@ -390,6 +402,7 @@ extension HomeCoordinator {
let setFavoriteArtistUseCase = SetFavoriteArtistUseCase(artistAPIService: artistAPIService)
let getHasUncheckedNotificationUseCase = GetHasUncheckedNotificationUseCase(notificationAPIService: notificationAPIService)
let logoutUseCase = LogoutUseCase(tokenStorage: tokenStorage)
let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = CommunityMainViewModel(
artistID: artistID,
Expand All @@ -400,7 +413,8 @@ extension HomeCoordinator {
deleteNoteUseCase: deleteNoteUseCase,
setFavoriteArtistUseCase: setFavoriteArtistUseCase,
getHasUncheckedNotificationUseCase: getHasUncheckedNotificationUseCase,
logoutUseCase: logoutUseCase
logoutUseCase: logoutUseCase,
blockUserUseCase: blockUserUseCase
)
return viewModel
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,8 @@ extension MyPageCoordinator: MyPageViewControllerDelegate,
InternalWebViewControllerDelegate,
DeleteUserViewControllerDelegate,
UserProfileViewControllerDelegate,
UserLinkedWebViewControllerDelegate {
UserLinkedWebViewControllerDelegate,
BlockedUsersViewControllerDelegate {
public func didFinish() {
didFinish(childCoordinator: self)
}
Expand Down Expand Up @@ -194,6 +195,13 @@ extension MyPageCoordinator: MyPageViewControllerDelegate,
viewController.coordinator = self
navigationController.pushViewController(viewController, animated: true)
}

public func pushBlockedUsersViewController() {
let viewModel = blockedUsersDependencies()
let viewController = BlockedUsersViewController(viewModel: viewModel)
viewController.coordinator = self
navigationController.pushViewController(viewController, animated: true)
}

public func pushEditUserInfoViewController(model: UserProfile) {
let viewModel = editUserDependencies(model: model)
Expand All @@ -216,6 +224,7 @@ private extension MyPageCoordinator {
@Injected(.noteAPIService) var noteAPIService: NoteAPIServiceInterface
@Injected(.commentAPIService) var commentAPIService: CommentAPIServiceInterface
let tokenStorage = TokenStorage()
@Injected(.userProfileAPIService) var userProfileAPIService: UserProfileAPIServiceInterface

let setNoteLikeUseCase = SetNoteLikeUseCase(noteAPIService: noteAPIService)
let setBookmarkUseCase = SetBookmarkUseCase(noteAPIService: noteAPIService)
Expand All @@ -224,6 +233,7 @@ private extension MyPageCoordinator {
let writeCommentUseCase = WriteCommentUseCase(commentAPIService: commentAPIService)
let deleteCommentUseCase = DeleteCommentUseCase(commentAPIService: commentAPIService)
let logoutUseCase = LogoutUseCase(tokenStorage: tokenStorage)
let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = NoteCommentsViewModel(
noteID: noteID,
Expand All @@ -233,7 +243,8 @@ private extension MyPageCoordinator {
getNoteWithCommentsUseCase: getNoteWithCommentsUseCase,
writeCommentUseCase: writeCommentUseCase,
deleteCommentUseCase: deleteCommentUseCase,
logoutUseCase: logoutUseCase
logoutUseCase: logoutUseCase,
blockUserUseCase: blockUserUseCase
)

return viewModel
Expand Down Expand Up @@ -355,4 +366,18 @@ private extension MyPageCoordinator {

return viewModel
}

func blockedUsersDependencies() -> BlockedUsersViewModel {
@Injected(.userProfileAPIService) var userProfileAPIService: UserProfileAPIServiceInterface

let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)
let fetchBlockedUsersUseCase = FetchBlockedUsersUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = BlockedUsersViewModel(
blockUserUseCase: blockUserUseCase,
fetchBlockedUsersUseCase: fetchBlockedUsersUseCase
)

return viewModel
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,11 @@ public final class SearchNoteCoordinator: Coordinator {
let networkProvider = try resolver.resolve(.networkProvider)
return NoteAPIService(networkProvider: networkProvider)
}
DIContainer.standard.register(.userProfileAPIService) { resolver in
let networkProvider = try resolver.resolve(.networkProvider)

return UserProfileAPIService(networkProvider: networkProvider)
}

DIContainer.registerReportNoteService()
}
Expand Down Expand Up @@ -130,6 +135,7 @@ private extension SearchNoteCoordinator {

func noteDetailDependencies(selectedNote: SearchedNote) -> NoteDetailViewModel {
@Injected(.noteAPIService) var noteAPIService: NoteAPIServiceInterface
@Injected(.userProfileAPIService) var userProfileAPIService: UserProfileAPIServiceInterface
let tokenStorage = TokenStorage()

let getSongDetailUseCase = GetSongDetailUseCase(noteAPIService: noteAPIService)
Expand All @@ -146,6 +152,8 @@ private extension SearchNoteCoordinator {
let deleteNoteUseCase = DeleteNoteUseCase(noteAPIService: noteAPIService)

let logoutUseCase = LogoutUseCase(tokenStorage: tokenStorage)

let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = NoteDetailViewModel(
songID: selectedNote.songID,
Expand All @@ -154,7 +162,8 @@ private extension SearchNoteCoordinator {
setNoteLikeUseCase: setNoteLikeUseCase,
setBookmarkUseCase: setBookmarkUseCase,
deleteNoteUseCase: deleteNoteUseCase,
logoutUseCase: logoutUseCase
logoutUseCase: logoutUseCase,
blockUserUseCase: blockUserUseCase
)

return viewModel
Expand All @@ -181,6 +190,7 @@ private extension SearchNoteCoordinator {

@Injected(.noteAPIService) var noteAPIService: NoteAPIServiceInterface
@Injected(.commentAPIService) var commentAPIService: CommentAPIServiceInterface
@Injected(.userProfileAPIService) var userProfileAPIService: UserProfileAPIServiceInterface
let tokenStorage = TokenStorage()

let setNoteLikeUseCase = SetNoteLikeUseCase(noteAPIService: noteAPIService)
Expand All @@ -190,6 +200,7 @@ private extension SearchNoteCoordinator {
let writeCommentUseCase = WriteCommentUseCase(commentAPIService: commentAPIService)
let deleteCommentUseCase = DeleteCommentUseCase(commentAPIService: commentAPIService)
let logoutUseCase = LogoutUseCase(tokenStorage: tokenStorage)
let blockUserUseCase = BlockUserUseCase(userProfileAPIService: userProfileAPIService)

let viewModel = NoteCommentsViewModel(
noteID: noteID,
Expand All @@ -199,7 +210,8 @@ private extension SearchNoteCoordinator {
getNoteWithCommentsUseCase: getNoteWithCommentsUseCase,
writeCommentUseCase: writeCommentUseCase,
deleteCommentUseCase: deleteCommentUseCase,
logoutUseCase: logoutUseCase
logoutUseCase: logoutUseCase,
blockUserUseCase: blockUserUseCase
)

return viewModel
Expand Down
Loading

0 comments on commit d38d407

Please sign in to comment.