Skip to content

Commit

Permalink
1.1.0
Browse files Browse the repository at this point in the history
feat: server - FCM
refactor: app - compose
feat: app - FCM
  • Loading branch information
taetae98coding committed Nov 16, 2024
1 parent ddc1e5d commit 75fa65e
Show file tree
Hide file tree
Showing 146 changed files with 6,246 additions and 3,229 deletions.
32 changes: 31 additions & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -84,5 +84,35 @@ jobs:
echo '${{ secrets.APPLE_REAL_DEBUG_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealDebug/GoogleService-Info.plist
echo '${{ secrets.APPLE_REAL_RELEASE_GOOGLE_SERVICE_INFO_PLIST }}' >> Diary/Secret/RealRelease/GoogleService-Info.plist
- name: Install the Apple certificate and provisioning profile
env:
BUILD_CERTIFICATE_BASE64: ${{ secrets.APPLE_DISTRIBUTION_CERTIFICATE }}
P12_PASSWORD: ${{ secrets.APPLE_DISTRIBUTION_CERTIFICATE_PASSWORD }}
BUILD_PROVISION_PROFILE_BASE64: ${{ secrets.APPLE_DISTRIBUTION_PROFILE }}
KEYCHAIN_PASSWORD: ${{ secrets.APPLE_DISTRIBUTION_TEMPORARY_KEYCHAIN_PASSWORD }}
run: |
# create variables
CERTIFICATE_PATH=$RUNNER_TEMP/build_certificate.p12
PP_PATH=$RUNNER_TEMP/build_pp.mobileprovision
KEYCHAIN_PATH=$RUNNER_TEMP/app-signing.keychain-db
# import certificate and provisioning profile from secrets
echo -n "$BUILD_CERTIFICATE_BASE64" | base64 --decode -o $CERTIFICATE_PATH
echo -n "$BUILD_PROVISION_PROFILE_BASE64" | base64 --decode -o $PP_PATH
# create temporary keychain
security create-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security set-keychain-settings -lut 21600 $KEYCHAIN_PATH
security unlock-keychain -p "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
# import certificate to keychain
security import $CERTIFICATE_PATH -P "$P12_PASSWORD" -A -t cert -f pkcs12 -k $KEYCHAIN_PATH
security set-key-partition-list -S apple-tool:,apple: -k "$KEYCHAIN_PASSWORD" $KEYCHAIN_PATH
security list-keychain -d user -s $KEYCHAIN_PATH
# apply provisioning profile
mkdir -p ~/Library/MobileDevice/Provisioning\ Profiles
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Build iOS
run: xcodebuild -project Diary/Diary.xcodeproj -scheme CI -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.0'
run: xcodebuild -project Diary/Diary.xcodeproj -scheme RealRelease -destination 'platform=iOS Simulator,name=iPhone 16,OS=18.0'
4 changes: 2 additions & 2 deletions .github/workflows/firebase_app_distribution.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ jobs:
cp $PP_PATH ~/Library/MobileDevice/Provisioning\ Profiles
- name: Archive xcarchive
run: xcodebuild -project Diary/Diary.xcodeproj -scheme CI archive -archivePath Diary/build/Diary.xcarchive -allowProvisioningUpdates
run: xcodebuild -project Diary/Diary.xcodeproj -scheme RealRelease archive -archivePath Diary/build/Diary.xcarchive -allowProvisioningUpdates

- name: Export ipa
run: xcodebuild -exportArchive -archivePath Diary/build/Diary.xcarchive -exportPath Diary/build -exportOptionsPlist Diary/ExportOptions.plist -allowProvisioningUpdates
Expand All @@ -131,7 +131,7 @@ jobs:
uses: actions/upload-artifact@v4
with:
name: Diary.ipa
path: Diary/build/Apps/Diary.ipa
path: Diary/build/Diary.ipa

iOS-Distribution:
needs: [iOS-Build]
Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@

**/xcuserdata
**/dev.xcconfig
**/real.xcconfig
**/real.xcconfig
**/*.podspec
128 changes: 81 additions & 47 deletions Diary/Diary.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/firebase/firebase-ios-sdk",
"state" : {
"revision" : "8328630971a8fdd8072b36bb22bef732eb15e1f0",
"version" : "11.4.0"
"revision" : "dbdfdc44bee8b8e4eaa5ec27eb12b9338f3f2bc1",
"version" : "11.5.0"
}
},
{
Expand Down Expand Up @@ -69,8 +69,8 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/google/gtm-session-fetcher.git",
"state" : {
"revision" : "5cfe5f090c982de9c58605d2a82a4fc77b774fbd",
"version" : "4.1.0"
"revision" : "a2ab612cb980066ee56d90d60d8462992c07f24b",
"version" : "3.5.0"
}
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "RealRelease"
buildConfiguration = "DevRelease"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "RealRelease"
buildConfiguration = "DevRelease"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
Expand All @@ -52,7 +52,7 @@
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "RealRelease"
buildConfiguration = "DevRelease"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
Expand All @@ -69,10 +69,10 @@
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "RealRelease">
buildConfiguration = "DevRelease">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "RealRelease"
buildConfiguration = "DevRelease"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
47 changes: 40 additions & 7 deletions Diary/Diary/AppDelegate.swift
Original file line number Diff line number Diff line change
@@ -1,12 +1,45 @@
import SwiftUI
import FirebaseCore

import Firebase
import UserNotifications

class AppDelegate: NSObject, UIApplicationDelegate {
func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
FirebaseApp.configure()

initRemoteNotifications(application: application)
initFirebaseMessaging()

return true
}

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
Messaging.messaging().apnsToken = deviceToken
}


func initRemoteNotifications(application: UIApplication) {
UNUserNotificationCenter.current().delegate = self

let authOptions: UNAuthorizationOptions = [.alert, .badge, .sound]
UNUserNotificationCenter.current().requestAuthorization(
options: authOptions,
completionHandler: { _, _ in }
)

application.registerForRemoteNotifications()
}

func initFirebaseMessaging() {
Messaging.messaging().delegate = self
}
}

extension AppDelegate: UNUserNotificationCenterDelegate {

}

return true
}
extension AppDelegate: MessagingDelegate {
func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
print("Firebase registration token: \(String(describing: fcmToken))")
}
}
8 changes: 8 additions & 0 deletions Diary/Diary/Diary.entitlements
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?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>aps-environment</key>
<string>development</string>
</dict>
</plist>
5 changes: 5 additions & 0 deletions Diary/Diary/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,10 @@
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIBackgroundModes</key>
<array>
<string>fetch</string>
<string>remote-notification</string>
</array>
</dict>
</plist>
11 changes: 2 additions & 9 deletions Diary/ExportOptions.plist
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,13 @@
<string>export</string>
<key>method</key>
<string>release-testing</string>
<key>provisioningProfiles</key>
<dict>
<key>io.github.taetae98coding.diary</key>
<string>adhoc</string>
</dict>
<key>signingCertificate</key>
<string>Apple Distribution</string>
<key>signingStyle</key>
<string>manual</string>
<string>automatic</string>
<key>stripSwiftSymbols</key>
<true/>
<key>teamID</key>
<string>4TV6L66XZ8</string>
<key>thinning</key>
<string>&lt;thin-for-all-variants&gt;</string>
<string>&lt;none&gt;</string>
</dict>
</plist>
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package io.github.taetae98coding.diary.core.coroutines

import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import kotlinx.coroutines.CoroutineScope
import org.koin.core.annotation.ComponentScan
import org.koin.core.annotation.Module
import org.koin.core.annotation.Singleton
Expand All @@ -12,4 +14,9 @@ public class CoroutinesModule {
internal fun providesAppLifecycleOwner(): LifecycleOwner {
return getAppLifecycleOwner()
}

@Singleton
internal fun providesAppCoroutineScope(lifecycleOwner: LifecycleOwner): CoroutineScope {
return lifecycleOwner.lifecycleScope
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,7 @@ import io.github.taetae98coding.diary.core.model.memo.MemoDto
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.update
import org.koin.core.annotation.Singleton

@OptIn(ExperimentalCoroutinesApi::class)
Expand All @@ -16,7 +14,6 @@ internal class MemoBackupMemoryDao(
private val memoMemoryDao: MemoMemoryDao,
) : MemoBackupDao {
private val flow = MutableStateFlow<Map<String, Set<String>>>(emptyMap())
private val updateFlow = mutableMapOf<String, MutableStateFlow<Int>>()

override suspend fun upsert(uid: String, memoId: String) {
val set = buildSet {
Expand All @@ -28,20 +25,6 @@ internal class MemoBackupMemoryDao(
put(uid, set)
}

flow.emit(map)
getInternalUpdateFlow(uid).update { it + 1 }
}

override suspend fun delete(uid: String, memoId: String) {
val set = buildSet {
flow.value[uid]?.let { addAll(it) }
remove(memoId)
}
val map = buildMap {
putAll(flow.value)
put(uid, set)
}

flow.emit(map)
}

Expand All @@ -59,10 +42,6 @@ internal class MemoBackupMemoryDao(
flow.emit(map)
}

override fun getUpdateFlow(uid: String): Flow<Int> {
return getInternalUpdateFlow(uid).asStateFlow()
}

override fun countByUid(uid: String): Flow<Int> {
return flow.mapLatest { it[uid]?.size ?: 0 }
}
Expand All @@ -72,8 +51,4 @@ internal class MemoBackupMemoryDao(
map.values.filter { it.owner == uid }
}
}

private fun getInternalUpdateFlow(uid: String): MutableStateFlow<Int> {
return updateFlow.getOrPut(uid) { MutableStateFlow(0) }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,6 @@ import io.github.taetae98coding.diary.core.diary.database.room.mapper.toDto
import io.github.taetae98coding.diary.core.model.memo.MemoDto
import io.github.taetae98coding.diary.library.coroutines.mapCollectionLatest
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.update
import org.koin.core.annotation.Factory

@Factory
Expand All @@ -19,21 +16,12 @@ internal class MemoBackupRoomDao(
) : MemoBackupDao {
override suspend fun upsert(uid: String, memoId: String) {
database.memoBackup().upsert(MemoBackupEntity(uid, memoId))
getInternalUpdateFlow(uid).update { it + 1 }
}

override suspend fun delete(uid: String, memoId: String) {
database.memoBackup().delete(MemoBackupEntity(uid, memoId))
}

override suspend fun deleteByMemoIds(memoIds: List<String>) {
database.memoBackup().deleteByMemoIds(memoIds)
}

override fun getUpdateFlow(uid: String): Flow<Int> {
return getInternalUpdateFlow(uid).asStateFlow()
}

override fun countByUid(uid: String): Flow<Int> {
return database.memoBackup().countByUid(uid)
}
Expand All @@ -42,12 +30,4 @@ internal class MemoBackupRoomDao(
return database.memoBackup().findByUid(uid)
.mapCollectionLatest(MemoEntity::toDto)
}

companion object {
private val updateFlow = mutableMapOf<String, MutableStateFlow<Int>>()

private fun getInternalUpdateFlow(uid: String): MutableStateFlow<Int> {
return updateFlow.getOrPut(uid) { MutableStateFlow(0) }
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,8 @@ import kotlinx.coroutines.flow.Flow

public interface MemoBackupDao {
public suspend fun upsert(uid: String, memoId: String)
public suspend fun delete(uid: String, memoId: String)
public suspend fun deleteByMemoIds(memoIds: List<String>)

public fun getUpdateFlow(uid: String): Flow<Int>
public fun countByUid(uid: String): Flow<Int>
public fun findByUid(uid: String): Flow<List<MemoDto>>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package io.github.taetae98coding.diary.core.diary.service.fcm

import io.github.taetae98coding.diary.common.model.request.fcm.DeleteFCMRequest
import io.github.taetae98coding.diary.common.model.request.fcm.UpsertFCMRequest
import io.github.taetae98coding.diary.core.diary.service.DiaryServiceModule
import io.github.taetae98coding.diary.core.diary.service.ext.getOrThrow
import io.ktor.client.HttpClient
import io.ktor.client.request.post
import io.ktor.client.request.setBody
import io.ktor.http.ContentType
import io.ktor.http.contentType
import org.koin.core.annotation.Factory
import org.koin.core.annotation.Named

@Factory
public class FCMService internal constructor(
@Named(DiaryServiceModule.DIARY_CLIENT)
private val client: HttpClient,
) {
public suspend fun upsert(token: String) {
return client.post("/fcm/upsert") {
contentType(ContentType.Application.Json)
setBody(UpsertFCMRequest(token))
}.getOrThrow()
}

public suspend fun delete(token: String) {
return client.post("/fcm/delete") {
contentType(ContentType.Application.Json)
setBody(DeleteFCMRequest(token))
}.getOrThrow()
}
}
1 change: 0 additions & 1 deletion app/data/account/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ kotlin {
commonMain {
dependencies {
implementation(project(":app:core:account-preferences"))
implementation(project(":app:core:diary-service"))
implementation(project(":app:domain:account"))
}
}
Expand Down
Loading

0 comments on commit 75fa65e

Please sign in to comment.