diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 5c044bcc696830a87660c69451c1d99bed40e381..64104adf7649656bfdfd149ba9fd30bd0bd3ea76 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -47,6 +47,7 @@ 75BC052F29ECE8AC00E21941 /* ServerSwitchingViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC052E29ECE8AC00E21941 /* ServerSwitchingViewController.swift */; }; 75BC053229ED087000E21941 /* ServerSwitchingViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 75BC053129ED087000E21941 /* ServerSwitchingViewController.storyboard */; }; 75BC053429EDA23700E21941 /* MordalViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC053329EDA23700E21941 /* MordalViewController.swift */; }; + 75BC053629F8DFCC00E21941 /* ServerSwitchingTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC053529F8DFCC00E21941 /* ServerSwitchingTableViewController.swift */; }; 75EDD2272806618A0068B4BC /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EDD2262806618A0068B4BC /* WidgetView.swift */; }; 75EDD2282806618A0068B4BC /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EDD2262806618A0068B4BC /* WidgetView.swift */; }; 75EDD2292806618A0068B4BC /* WidgetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75EDD2262806618A0068B4BC /* WidgetView.swift */; }; @@ -252,6 +253,7 @@ 75BC052E29ECE8AC00E21941 /* ServerSwitchingViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSwitchingViewController.swift; sourceTree = ""; }; 75BC053129ED087000E21941 /* ServerSwitchingViewController.storyboard */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; path = ServerSwitchingViewController.storyboard; sourceTree = ""; }; 75BC053329EDA23700E21941 /* MordalViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MordalViewController.swift; sourceTree = ""; }; + 75BC053529F8DFCC00E21941 /* ServerSwitchingTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSwitchingTableViewController.swift; sourceTree = ""; }; 75EDD2262806618A0068B4BC /* WidgetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WidgetView.swift; sourceTree = ""; }; 75EF9CAC27E9E983003178A3 /* WidgetExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = WidgetExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; 75EF9CAD27E9E983003178A3 /* WidgetKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = WidgetKit.framework; path = System/Library/Frameworks/WidgetKit.framework; sourceTree = SDKROOT; }; @@ -512,6 +514,7 @@ 75BC052E29ECE8AC00E21941 /* ServerSwitchingViewController.swift */, 75BC053129ED087000E21941 /* ServerSwitchingViewController.storyboard */, 75BC053329EDA23700E21941 /* MordalViewController.swift */, + 75BC053529F8DFCC00E21941 /* ServerSwitchingTableViewController.swift */, ); path = View; sourceTree = ""; @@ -1441,6 +1444,7 @@ 76AE530725D3652400AFA45A /* LicenseViewBuilder.swift in Sources */, 3127EE1B241A2B4D00535CC7 /* TodayViewController.swift in Sources */, BDAABA1B24A361E90077EC69 /* PostDeviceEndpoint.swift in Sources */, + 75BC053629F8DFCC00E21941 /* ServerSwitchingTableViewController.swift in Sources */, 31AA002F24347BBD000177B4 /* ApprovalResponse.swift in Sources */, BD7A8008241A16B90040B418 /* LinkManager.swift in Sources */, C535772E2754D5C500EAA660 /* WebViewController.swift in Sources */, diff --git a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements index 6f5ee786c51a485eb983f97ead459084c6e61143..4db9e2bf5e881e68ca76df82107e86a401a6adde 100644 --- a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements +++ b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements @@ -6,7 +6,11 @@ development keychain-access-groups - $(AppIdentifierPrefix)jp.atled.AgileWorks + $(AppIdentifierPrefix)jp.atled.agileworks0 + $(AppIdentifierPrefix)jp.atled.agileworks1 + $(AppIdentifierPrefix)jp.atled.agileworks2 + $(AppIdentifierPrefix)jp.atled.agileworks3 + $(AppIdentifierPrefix)jp.atled.agileworks4 diff --git a/AgileWorks/AgileWorks/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index 6e82fe618a8e9b7d9c9c8d1b772dbf433674c72c..ace6f964c5cdcdb94d197820c51d483b5f81d70c 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -55,7 +55,7 @@ extension RootViewController { } // ログアウトアラート デフォルトボタンアクション生成 - func logoutDefaultAction(title: String) -> UIAlertAction { + func logoutDefaultAction(serverRemove: Bool, title: String) -> UIAlertAction { let defaultAction = UIAlertAction(title: title, style: .default) { _ in self.logout { result in switch result { @@ -67,14 +67,31 @@ extension RootViewController { KeychainDataStore().removeOAuthState() KeychainDataStore().removeAccessToken() KeychainDataStore().removeSessionID() + KeychainDataStore().removeServerName() KeychainDataStore().removeLanguage() KeychainDataStore().removeDeviceID() - DispatchQueue.main.async { - self.switchToLogout() - //ウィジェットの更新 - if #available(iOS 14.0, *) { - WidgetCenter.shared.reloadAllTimelines() + if serverRemove { + UserDefaultsDataStore().removeServer() + } + + let serverList = UserDefaultsDataStore().readServerList() + if serverList.isEmpty { + DispatchQueue.main.async { + self.switchToLogout() + //ウィジェットの更新 + if #available(iOS 14.0, *) { + WidgetCenter.shared.reloadAllTimelines() + } + } + } else { + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + DispatchQueue.main.async { + self.switchToMainScreen() + //ウィジェットの更新 + if #available(iOS 14.0, *) { + WidgetCenter.shared.reloadAllTimelines() + } } } } diff --git a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift index 13926adb9cbc0a9d90f3383794db3452928bcbb0..54a3c59425c37bac04098f5bada0a340bc1f0fc9 100644 --- a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift +++ b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift @@ -14,6 +14,7 @@ protocol LoginBuilder { struct LoginBuilderImpl: LoginBuilder { let identifier = "LoginViewController" + var navVC: UINavigationController? = nil func build() -> UIViewController { let viewController = storyboard() @@ -26,6 +27,12 @@ struct LoginBuilderImpl: LoginBuilder { ) return viewController } + + func naviBuild() -> UINavigationController { + let navVC = UINavigationController(rootViewController: build()) + navVC.modalPresentationStyle = .fullScreen + return navVC + } } extension LoginBuilderImpl { diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index d12e5f151fa59651dba0e01b258ea0dfdbe20874..58e6da2bb88f46f4ef500f67b60df99073082945 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -35,6 +35,8 @@ class LoginViewController: UIViewController { @IBOutlet private var qrCodeReadView: UIView! @IBOutlet private var qrCodeStartupButton: UIButton! @IBOutlet private var scrollViewBottomConstraint: NSLayoutConstraint! + //サーバー追加画面フラグ + private var addServerloginFlg = false private let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) @@ -58,28 +60,35 @@ class LoginViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - - //ログイン画面が表示されると通知を取得しない - - self.devcie { result in - switch result { - case .success: - break - case .failure(let error): - log.e(error) - } + if let navVC = self.parent as? UINavigationController { + addServerloginFlg = true + let leftButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped(_:))) + navVC.navigationBar.topItem!.leftBarButtonItem = leftButton } + //サーバー追加画面の場合は認証情報を削除しない + if !addServerloginFlg { + //ログイン画面が表示されると通知を取得しない + self.devcie { result in + switch result { + case .success: + break + case .failure(let error): + log.e(error) + } + } - //認証情報削除 - KeychainDataStore().removeOAuthState() - KeychainDataStore().removeAccessToken() - KeychainDataStore().removeSessionID() - KeychainDataStore().removeLanguage() - KeychainDataStore().removeDeviceID() - - //ウィジェットの更新 - if #available(iOS 14.0, *) { - WidgetCenter.shared.reloadAllTimelines() + //認証情報削除 + KeychainDataStore().removeOAuthState() + KeychainDataStore().removeAccessToken() + KeychainDataStore().removeSessionID() + KeychainDataStore().removeServerName() + KeychainDataStore().removeLanguage() + KeychainDataStore().removeDeviceID() + + //ウィジェットの更新 + if #available(iOS 14.0, *) { + WidgetCenter.shared.reloadAllTimelines() + } } clientCertificateSettingView.isHidden = (CertificateDataStore().readClientCertificate() == nil) @@ -87,10 +96,12 @@ class LoginViewController: UIViewController { setupFixedWording() //保存されたサーバー名・コンテキストパスの取得 - let server = Configuration.shared.awServer - let context = Configuration.shared.awContextPath - serverTextField.text = server - contextTextField.text = context + if !addServerloginFlg { + let server = Configuration.shared.awServer + let context = Configuration.shared.awContextPath + serverTextField.text = server + contextTextField.text = context + } loginButton.isEnabled = isTextFieldValue() view.addSubview(activityIndicator) @@ -114,6 +125,12 @@ class LoginViewController: UIViewController { func dismissKeyboard() { self.view.endEditing(true) } + + @objc private func cancelTapped(_ sender: UIBarButtonItem) { + var serverList = UserDefaultsDataStore().readServerList() + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) + } //ログイン画面の固定文言表示 private func setupFixedWording() { @@ -168,6 +185,14 @@ class LoginViewController: UIViewController { guard let context = context else { return } disableLogin() + + //サーバー切り替え + if let serverId = UserDefaultsDataStore().serchEmptyServerData() { + UserDefaultsDataStore().setGroupId(serverNumber: serverId) + } else { + //TODO: サーバー追加できない場合 + } + //サーバー名コンテキストパスの保存 KeychainDataStore().writeServerURL(serverURL: serverHost) KeychainDataStore().writeContextPath(contextPath: context) @@ -209,9 +234,16 @@ class LoginViewController: UIViewController { case .success(let response): setStringsName(language: response.user.displayLanguage) KeychainDataStore().writeSessionID(sessionID: response.sessionId) + KeychainDataStore().writeServerName(serverName: "サーバー識別名") //TODO response.server.name DispatchQueue.main.async { + UserDefaultsDataStore().addServerList() + let serverList = UserDefaultsDataStore().readServerList() + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() + if let nc = self.parent as? UINavigationController { + self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) + } } // セッション情報取得失敗 case .failure(let error): @@ -300,7 +332,7 @@ class LoginViewController: UIViewController { let message = getLocalizableStrings(key: "LoginErrorMessage", comment: "") let defaultAction: UIAlertAction if isLogout { - defaultAction = AppDelegate.shared.rootViewController.logoutDefaultAction(title: getLocalizableStrings(key: "OK", comment: "")) + defaultAction = AppDelegate.shared.rootViewController.logoutDefaultAction(serverRemove: false, title: getLocalizableStrings(key: "OK", comment: "")) } else { defaultAction = UIAlertAction(title: getLocalizableStrings(key: "OK", comment: ""), style: .default, handler: nil) } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift index 8474044a3d6f7235d1ef89f7a6792cabbb3b7281..a67e42a69e9db1d9b7a1f1cbc6e75f7033342483 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -10,14 +10,21 @@ import UIKit import FloatingPanel class MordalViewController: UIViewController { + @IBOutlet private var accessPoint: UILabel! + @IBOutlet private var addServer: UIButton! + override func viewDidLoad() { super.viewDidLoad() - - // Do any additional setup after loading the view. + accessPoint.text = getDisplayString(key: "ServerTitle", comment: "") } static func fromStoryboard(_ storyboard: UIStoryboard = UIStoryboard(name: "ServerSwitchingViewController", bundle: nil)) -> MordalViewController { let controller = storyboard.instantiateViewController(withIdentifier: "MordalViewController") as! MordalViewController return controller } + @IBAction private func addServerTapped(_ sender: Any) { + //モーダルの表示 + let navVC = LoginBuilderImpl().naviBuild() + self.present(navVC, animated: true) + } } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift new file mode 100644 index 0000000000000000000000000000000000000000..f540c2baa712a0d7cb8218213fd56f6d4b246a2b --- /dev/null +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -0,0 +1,115 @@ +// +// ServerSwitchingTableTableViewController.swift +// AgileWorks +// +// Created by Azuma Kasumi on 2023/04/26. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import UIKit + +class ServerSwitchingTableTableViewController: UITableViewController { + @IBOutlet var table: UITableView! + + override func viewDidLoad() { + super.viewDidLoad() + table.tableFooterView = UIView() + } + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + //承認待ち件数の表示 + Task{ + let serverList = UserDefaultsDataStore().readServerList() + let rowCount = table.numberOfRows(inSection: 0) + for row in 1.. Int { + return 1 + } + //セルの数 + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + let serverCount = UserDefaultsDataStore().readServerList().count + return serverCount + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "ServerSwitchingTableViewCell", for: indexPath) + + let serverList = UserDefaultsDataStore().readServerList() + let serverName = cell.viewWithTag(1) as! UILabel + let serverNumber = serverList[indexPath.row] + serverName.text = KeychainDataStore().readServerName(serverNumber: serverNumber) + + let badgeIcon = cell.viewWithTag(2) as! UIImageView + badgeIcon.image = UIImage(systemName: "circle.fill", withConfiguration: UIImage.SymbolConfiguration(font: .systemFont(ofSize: 25))) + let approvalCount = cell.viewWithTag(3) as! UILabel + + //ログイン中のサーバー + if indexPath.row == 0 { + //チェックマーク + badgeIcon.image = UIImage(systemName: "checkmark.circle.fill", withConfiguration: UIImage.SymbolConfiguration(font: .systemFont(ofSize: 25))) + badgeIcon.tintColor = UIColor(named: getDisplayString(key: "MainColor", comment: "")) + //承認待ち件数は取得しないため非表示 + approvalCount.isHidden = true + } + + return cell + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 50 + } + + //セル選択時の処理 + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + if indexPath.row == 0 { + self.dismiss(animated: true, completion: nil) + return + } + let serverList = UserDefaultsDataStore().readServerList() + let server = serverList[indexPath.row] + UserDefaultsDataStore().setGroupId(serverNumber: server) + UserDefaultsDataStore().changeServerList(firstServer: server) + AppDelegate.shared.rootViewController.switchToMainScreen() + self.parent!.dismiss(animated: true) + } + + private func callApprovalCount(label: UILabel) async{ + await setApprovalsCount(label: label) + } + + //承認待ち件数取得 + private func setApprovalsCount(label: UILabel) async { + let approvalsEndpoint = GetApprovalsEndpoint() + Session.send(approvalsEndpoint) { result in + var reqApprovalCount: Int = 0 + switch result { + case .success(let response): + let requestApproval = "REQUEST_APPROVAL" + for item in response.items where item.code == requestApproval { + reqApprovalCount = item.count + DispatchQueue.main.async { + label.text = String(reqApprovalCount) + } + } + case .failure(let error): + log.e(error) + DispatchQueue.main.async { + label.text = "0" + } + } + } + } +} diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift index 3ebe6b991b239771edd58acfb8032deff4c2b077..652e871aad5798aa9cf31fd09f3e65d6fbafd9fe 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift @@ -29,9 +29,9 @@ class ServerSwitchingViewController: UIViewController, UIGestureRecognizerDelega fpc.surfaceView.cornerRadius = 24.0 //下スワイプで閉じる fpc.isRemovalInteractionEnabled = true - let mordalVC = MordalViewController.fromStoryboard() + let modalVC = MordalViewController.fromStoryboard() self.view.addSubview(fpc.view) - fpc.set(contentViewController: mordalVC) + fpc.set(contentViewController: modalVC) fpc.addPanel(toParent: self) } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard index 7f04f14b0d25ac04bf00a72ab17cf67aae33a2c3..6cdbd825352059f406623a8f1618b81f3ae03149 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard +++ b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard @@ -4,6 +4,8 @@ + + @@ -22,7 +24,7 @@ - + @@ -32,25 +34,135 @@ - + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + + + + + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index 7d800c1fef1f3e5275f9938158556beb83e9d36f..dca64899897b7c8abfbf79e15045de4fd676f451 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings index 4168400356c644fd98ab2db646f41efbd9f155d0..6cc187998d895072e4236555307d0bbe64373edb 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "由通知點選的文件已經顯示了。 \n你想放棄當前的編輯並顯示一個新的文件嗎?"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index 527ffdb2642ecd62b071c7ef9615e68a7e534d1a..66bb9ee490d5c19c901df86caef0a03653522d19 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "A document by a notification tap is already displayed.\nDo you want to discard the current edits and display a new document?"; diff --git a/AgileWorks/AgileWorks/Strings/Japanese.strings b/AgileWorks/AgileWorks/Strings/Japanese.strings index 471ddc01a6d000f71367eee3a73c14ddbb5b5e57..ff87ef08c5314f520cc511abdf10702f7ef68b30 100644 --- a/AgileWorks/AgileWorks/Strings/Japanese.strings +++ b/AgileWorks/AgileWorks/Strings/Japanese.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "既に通知タップによる書類が表示されています。\n現在の編集内容を破棄し、新たな書類を表示しますか?"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index 7f2918a2e7d69ce9492609d16171ed4af02be0b4..55a7d3492b43d70446ad8c761207ca441488eceb 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "A document by a notification tap is already displayed.\nDo you want to discard the current edits and display a new document?"; diff --git a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings index 529cfff8a8d8b07de58ac75d4d247b181a69e7bd..4f6fbc8aa2835493d9dc84f010d754e2473e1345 100644 --- a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "既に通知タップによる書類が表示されています。\n現在の編集内容を破棄し、新たな書類を表示しますか?"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 19b2444df76dbd54b4aefb82dda79dc03ec5a87b..9495f6da25f1bad3b352c1661b472a080db241b0 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings index a4898c37fbfc1b4d4866d677122dd07d3852d53b..e01613e2fd3571388f61976043026d4ef69085ef 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings @@ -58,6 +58,7 @@ //server "ServerTitle" = "接続先サーバー"; +"accessPoint" = "接続先"; // Notification "DocOverrideConfirm" = "由通知點選的文件已經顯示了。 \n你想放棄當前的編輯並顯示一個新的文件嗎?"; diff --git a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift index 368a19e414ca4a79cc052aebf292e1404cde32f9..c487fbf96129b0eaefb494db23eb34299f5af7a4 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift @@ -79,7 +79,7 @@ class MenuTableViewController: UITableViewController { private func logout() { // ログアウトタップ時処理 let message = getDisplayString(key: "LogoutConfirm", comment: "") - let defaultAction = AppDelegate.shared.rootViewController.logoutDefaultAction(title: getDisplayString(key: "YES", comment: "")) + let defaultAction = AppDelegate.shared.rootViewController.logoutDefaultAction(serverRemove: true, title: getDisplayString(key: "YES", comment: "")) let cancelAction = UIAlertAction(title: getDisplayString(key: "NO", comment: ""), style: .cancel) { _ in if let indexPath = self.tableView.indexPath(for: self.logoutCell) { self.tableView.deselectRow(at: indexPath, animated: true) diff --git a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift index 07e6ba3ba31d449f8190612dbac7fdae0f4405c5..0129ea3ff158c2b45851f55b092c67bb6f47ad20 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift @@ -67,12 +67,13 @@ class MenuViewController: UIViewController { switch result { case .success(let response): let userName = response.user.name - let serverName = "サーバー識別名" //TODO response.server.name + let serverName = KeychainDataStore().readServerURL()! //TODO response.server.name let sessionId = response.sessionId DispatchQueue.main.async { self.nameLabel.text = userName self.serverLabel.text = serverName KeychainDataStore().writeSessionID(sessionID: sessionId) + KeychainDataStore().writeServerName(serverName: serverName) } case .failure: DispatchQueue.main.async { diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 4cdd571ec243eea05a935aef7b9dd9e620a045e5..eabd3610fe84c2cba2dca532a00fba7a40da398f 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -218,6 +218,7 @@ class WebViewController: UIViewController { // セッション情報取得成功 case .success(let response): KeychainDataStore().writeSessionID(sessionID: response.sessionId) + KeychainDataStore().writeServerName(serverName: "サーバー識別名") //TODO response.server.name setStringsName(language: response.user.displayLanguage) if isInit { // 画面ロード @@ -261,7 +262,7 @@ class WebViewController: UIViewController { DispatchQueue.main.async { let title = getDisplayString(key: "RefreshTokenUpdateErrorTitle", comment: "") let message = getDisplayString(key: "RefreshTokenUpdateError", comment: "") - let defaultAction = AppDelegate.shared.rootViewController.logoutDefaultAction(title: getDisplayString(key: "OK", comment: "")) + let defaultAction = AppDelegate.shared.rootViewController.logoutDefaultAction(serverRemove: true, title: getDisplayString(key: "OK", comment: "")) AppDelegate.shared.rootViewController.showAlertScreen(view: self, title: title, message: message, defaultAction: defaultAction, cancelAction: nil) } // その他エラーの場合 diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 681a27c146c33e8e13104f779fb020c1ba38129b..b3e7a6cb88bb46ef51c9eb86bd377b9346ddc077 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -12,7 +12,6 @@ import UIKit final class KeychainDataStore: DataStoreProtocol { private let service = "AgileWorks" - private let groupId = Bundle.main.object(forInfoDictionaryKey: "AppIdentifierPrefix") as! String + Configuration.shared.awShareBundleIdentifier private let kAccessToken: String = "AccessToken" private let kOAuthState: String = "OAuthState" private let kLanguage: String = "Localizable" @@ -20,6 +19,7 @@ final class KeychainDataStore: DataStoreProtocol { private let kContextPath: String = "ContextPath" private let kDeviceID: String = "DeviceID" private let kSessionID: String = "SessionID" + private let kServerName: String = "ServerName" // アクセストークンの書き込み func writeAccessToken(accessToken: String) { @@ -38,7 +38,7 @@ final class KeychainDataStore: DataStoreProtocol { // 認可ステータスの書き込み func writeOAuthState(authState: OIDAuthState) { - let keychain = Keychain(service: service, accessGroup: groupId) + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) guard let object = try? NSKeyedArchiver.archivedData(withRootObject: authState, requiringSecureCoding: true) else { return } @@ -47,7 +47,7 @@ final class KeychainDataStore: DataStoreProtocol { // 認可ステータスの読み込み func readOAuthState() -> OIDAuthState? { - let keychain = Keychain(service: service, accessGroup: groupId) + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) if let object = keychain[data: kOAuthState] { guard let authState = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(object) as? OIDAuthState else { return nil @@ -143,19 +143,39 @@ final class KeychainDataStore: DataStoreProtocol { removeKeychainValue(key: kSessionID) } + // サーバー識別名の書き込み + func writeServerName(serverName: String) { + setKeychainValue(key: kServerName, value: serverName) + } + + // サーバー識別名の読み込み + func readServerName() -> String? { + return getKeychainValue(key: kServerName) + } + func readServerName(serverNumber: Int) -> String? { + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readBaseGroupId() + String(serverNumber)) + //return keychain[kServerName] //TODO: サーバー識別名 + return keychain[kServerURL] + } + + // サーバー識別名の削除 + func removeServerName() { + removeKeychainValue(key: kServerName) + } + // KeyChain へ指定の値をセット private func setKeychainValue(key: String, value: String) { - let keychain = Keychain(service: service, accessGroup: groupId) + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) keychain[key] = value } // KeyChain から指定の値を取得 private func getKeychainValue(key: String) -> String? { - let keychain = Keychain(service: service, accessGroup: groupId) + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) return keychain[key] } // KeyChain から指定の値を削除 private func removeKeychainValue(key: String) { - let keychain = Keychain(service: service, accessGroup: groupId) + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) do { try keychain.remove(key) } catch { diff --git a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift index 1e39b583f20c109ce0f050bb374ddd37863cf1bf..7c621209efba35991177130520dce205126fd819 100644 --- a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift +++ b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift @@ -17,6 +17,11 @@ final class UserDefaultsDataStore: DataStoreProtocol { private let kFirebaseRemovalKey: String = "FirebaseRemoval" private let kLastAcceptedLicenseVersionKey: String = "LastAppceptedLicenseVersion" private let kUpdateWidgetFlgKey : String = "UpdateWidgetFlg" + private let kServerListkey: String = "ServerList" + private let kGroupIdkey: String = "GroupId" + private let baseGroupId = Bundle.main.object(forInfoDictionaryKey: "AppIdentifierPrefix") as! String + Configuration.shared.awShareBundleIdentifier + + private let severCount = 5 init() { sharedDefaults = UserDefaults() @@ -41,17 +46,87 @@ final class UserDefaultsDataStore: DataStoreProtocol { func readLastAcceptedLicenseVersion() -> Int? { return sharedDefaults.integer(forKey: kLastAcceptedLicenseVersionKey) } - + //ウィジェット更新フラグ func writeUpdateWidgetFlg(update: Bool) { sharedDefaults.set(update, forKey: kUpdateWidgetFlgKey) } - + func readUpdateWidgetFlg() -> Bool? { return sharedDefaults.bool(forKey: kUpdateWidgetFlgKey) } - + func removeUpdateWidgetFlg(update: Bool) { sharedDefaults.removeObject(forKey: kUpdateWidgetFlgKey) } + + //接続先サーバー管理 + func writeServerList(list: [Int]) { + sharedDefaults.set(list, forKey: kServerListkey) + } + + func readServerList() -> [Int] { + if let serverList = sharedDefaults.array(forKey: kServerListkey) as? [Int] { + return serverList + } + return [] + } + + func removeServer() { + var serverList = readServerList() + if !serverList.isEmpty { + //先頭(ログアウト処理を行ったサーバー)をリストから削除 + serverList.removeFirst() + writeServerList(list: serverList) + } + } + + //サーバー接続先を保存できる識別番号を探す + func serchEmptyServerData() -> Int? { + var serverList = readServerList() + if serverList.isEmpty { + return serverList.count + } + for num in 0 ..< severCount { + if !serverList.contains(num) { + return num + } + } + return nil + } + + //サーバー追加 + func addServerList() { + var serverList = readServerList() + if let serverNumber = serchEmptyServerData() { + serverList.insert(serverNumber, at: 0) + writeServerList(list: serverList) + } + } + + //サーバー並び替え + func changeServerList(firstServer: Int) { + var serverList = readServerList() + if serverList.contains(firstServer) { + //要素を削除してから先頭に追加する + serverList.removeAll(where: { $0 == firstServer }) + serverList.insert(firstServer, at: 0) + writeServerList(list: serverList) + } + } + + func setGroupId(serverNumber: Int) { + sharedDefaults.set(baseGroupId + String(serverNumber), forKey: kGroupIdkey) + } + func readGroupId() -> String? { + if let groupId = sharedDefaults.string(forKey: kGroupIdkey) as? String{ + return groupId + }else { + setGroupId(serverNumber: 0) + return sharedDefaults.string(forKey: kGroupIdkey) + } + } + func readBaseGroupId() -> String { + return baseGroupId + } }