From 864126642e360e97ba263b859153e751787a31ab Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Fri, 14 Apr 2023 11:12:33 +0900 Subject: [PATCH 01/36] =?UTF-8?q?=E3=83=8F=E3=83=B3=E3=83=90=E3=83=BC?= =?UTF-8?q?=E3=82=AC=E3=83=BC=E3=83=A1=E3=83=8B=E3=83=A5=E3=83=BCUI?= =?UTF-8?q?=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Strings/Chinese-Simplified.strings | 3 + .../Strings/Chinese-Traditional.strings | 3 + AgileWorks/AgileWorks/Strings/English.strings | 3 + .../AgileWorks/Strings/Japanese.strings | 3 + .../Strings/en.lproj/Localizable.strings | 3 + .../Strings/ja.lproj/Localizable.strings | 3 + .../Strings/zh-Hans.lproj/Localizable.strings | 3 + .../Strings/zh-Hant.lproj/Localizable.strings | 3 + .../View/MenuTableViewController.swift | 16 +++- .../WebView/View/MenuViewController.swift | 5 +- .../WebView/View/WebViewController.storyboard | 75 ++++++++++++++----- 11 files changed, 96 insertions(+), 24 deletions(-) diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index f39da1e..7d800c1 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "开放许可证"; +//server +"ServerTitle" = "接続先サーバー"; + // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings index de02fa7..4168400 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "開放許可證"; +//server +"ServerTitle" = "接続先サーバー"; + // Notification "DocOverrideConfirm" = "由通知點選的文件已經顯示了。 \n你想放棄當前的編輯並顯示一個新的文件嗎?"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index e4bc950..527ffdb 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "Open license"; +//server +"ServerTitle" = "接続先サーバー"; + // 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 a4fb0de..471ddc0 100644 --- a/AgileWorks/AgileWorks/Strings/Japanese.strings +++ b/AgileWorks/AgileWorks/Strings/Japanese.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "オープンソースライセンス"; +//server +"ServerTitle" = "接続先サーバー"; + // Notification "DocOverrideConfirm" = "既に通知タップによる書類が表示されています。\n現在の編集内容を破棄し、新たな書類を表示しますか?"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index e017363..7f2918a 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "Open license"; +//server +"ServerTitle" = "接続先サーバー"; + // 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 31e6319..529cfff 100644 --- a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "オープンソースライセンス"; +//server +"ServerTitle" = "接続先サーバー"; + // Notification "DocOverrideConfirm" = "既に通知タップによる書類が表示されています。\n現在の編集内容を破棄し、新たな書類を表示しますか?"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 6dc7b16..19b2444 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "开放许可证"; +//server +"ServerTitle" = "接続先サーバー"; + // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings index 6e180c6..a4898c3 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings @@ -56,6 +56,9 @@ // Open License "OpenLicenseViewTitle" = "開放許可證"; +//server +"ServerTitle" = "接続先サーバー"; + // Notification "DocOverrideConfirm" = "由通知點選的文件已經顯示了。 \n你想放棄當前的編輯並顯示一個新的文件嗎?"; diff --git a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift index 77850b6..137b310 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift @@ -16,8 +16,10 @@ class MenuTableViewController: UITableViewController { @IBOutlet private var licenseCell: UITableViewCell! @IBOutlet private var licenseLabel: UILabel! @IBOutlet private var openLicenseCell: UITableViewCell! - @IBOutlet private var openLicenseLable: UILabel! - + @IBOutlet private var openLicenseLabel: UILabel! + @IBOutlet private var serverCell: UITableViewCell! + @IBOutlet private var serverLabel: UILabel! + override func viewDidLoad() { super.viewDidLoad() self.tableView.separatorColor = UIColor(named: getDisplayString(key: "SeparatorColor", comment: "")) @@ -40,6 +42,8 @@ class MenuTableViewController: UITableViewController { self.pushToLicense() } else if let staticIndexPath = tableView.indexPath(for: self.openLicenseCell), staticIndexPath == indexPath { self.pushToOpenLicense() + } else if let staticIndecPath = tableView.indexPath(for: self.serverCell), staticIndecPath == indexPath { + self.pushToServer() } // メニュークローズ if let parent = self.parent as? MenuViewController { @@ -53,7 +57,8 @@ class MenuTableViewController: UITableViewController { self.profileLabel.text = getDisplayString(key: "ProfileTitle", comment: "") self.logoutLabel.text = getDisplayString(key: "LogoutTitle", comment: "") self.licenseLabel.text = getDisplayString(key: "LicenseTitle", comment: "") - self.openLicenseLable.text = getDisplayString(key: "OpenLicenseTitle", comment: "") + self.openLicenseLabel.text = getDisplayString(key: "OpenLicenseTitle", comment: "") + self.serverLabel.text = getDisplayString(key: "ServerTitle", comment: "") } // プロファイルセルタップ処理 private func pushToProfile() { @@ -107,4 +112,9 @@ class MenuTableViewController: UITableViewController { self.tableView.deselectRow(at: indexPath, animated: true) } } + + //接続先サーバーセルタップ処理 + private func pushToServer() { + + } } diff --git a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift index ba97475..07e6ba3 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift @@ -11,7 +11,7 @@ import UIKit class MenuViewController: UIViewController { @IBOutlet private var menuView: UIView! @IBOutlet private var nameLabel: UILabel! - + @IBOutlet private var serverLabel: UILabel! override func viewDidLoad() { super.viewDidLoad() @@ -61,14 +61,17 @@ class MenuViewController: UIViewController { // 各種セットアップ private func setup() { self.nameLabel.text = "" + self.serverLabel.text = "" // セッション情報取得 loadSessionInfo { result in switch result { case .success(let response): let userName = response.user.name + let serverName = "サーバー識別名" //TODO response.server.name let sessionId = response.sessionId DispatchQueue.main.async { self.nameLabel.text = userName + self.serverLabel.text = serverName KeychainDataStore().writeSessionID(sessionID: sessionId) } case .failure: diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.storyboard b/AgileWorks/AgileWorks/WebView/View/WebViewController.storyboard index 19d9eca..897f2d6 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.storyboard +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.storyboard @@ -1,9 +1,9 @@ - + - + @@ -20,15 +20,15 @@ - + -- GitLab From 2816ec0b782a4c4795be6fe71b96f89dcc0058a8 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 18 Apr 2023 14:09:12 +0900 Subject: [PATCH 02/36] =?UTF-8?q?=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 40 +++++++++ .../Builder/ServerSwitchingBuilder.swift | 32 +++++++ .../View/MordalViewController.swift | 23 +++++ .../View/ServerSwitchingViewController.swift | 86 +++++++++++++++++++ .../serverSwitchingViewController.storyboard | 57 ++++++++++++ .../View/MenuTableViewController.swift | 8 ++ 6 files changed, 246 insertions(+) create mode 100644 AgileWorks/AgileWorks/ServerSwitching/Builder/ServerSwitchingBuilder.swift create mode 100644 AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift create mode 100644 AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift create mode 100644 AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 10691b2..5c044bc 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -43,6 +43,10 @@ 75917FB527C371390051E201 /* StringsUtility.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75917FB227C371390051E201 /* StringsUtility.swift */; }; 75917FB627C372C80051E201 /* XCGLoggerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8D55D82420609000A667B0 /* XCGLoggerExtensions.swift */; }; 75917FB727C373060051E201 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDAB1F6C240D0D0000EA15FD /* UserDefaultsExtensions.swift */; }; + 75BC052D29ECE87500E21941 /* ServerSwitchingBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75BC052C29ECE87500E21941 /* ServerSwitchingBuilder.swift */; }; + 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 */; }; 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 */; }; @@ -244,6 +248,10 @@ 75917F9F27BDF2050051E201 /* Chinese-Simplified.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = "Chinese-Simplified.strings"; sourceTree = ""; }; 75917FA127BDF2250051E201 /* Chinese-Traditional.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = "Chinese-Traditional.strings"; sourceTree = ""; }; 75917FB227C371390051E201 /* StringsUtility.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StringsUtility.swift; sourceTree = ""; }; + 75BC052C29ECE87500E21941 /* ServerSwitchingBuilder.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerSwitchingBuilder.swift; sourceTree = ""; }; + 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 = ""; }; 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; }; @@ -481,6 +489,33 @@ path = Strings; sourceTree = ""; }; + 75BC052729ECE1FB00E21941 /* ServerSwitching */ = { + isa = PBXGroup; + children = ( + 75BC052829ECE2F500E21941 /* Builder */, + 75BC052929ECE30900E21941 /* View */, + ); + path = ServerSwitching; + sourceTree = ""; + }; + 75BC052829ECE2F500E21941 /* Builder */ = { + isa = PBXGroup; + children = ( + 75BC052C29ECE87500E21941 /* ServerSwitchingBuilder.swift */, + ); + path = Builder; + sourceTree = ""; + }; + 75BC052929ECE30900E21941 /* View */ = { + isa = PBXGroup; + children = ( + 75BC052E29ECE8AC00E21941 /* ServerSwitchingViewController.swift */, + 75BC053129ED087000E21941 /* ServerSwitchingViewController.storyboard */, + 75BC053329EDA23700E21941 /* MordalViewController.swift */, + ); + path = View; + sourceTree = ""; + }; 75EF9CB127E9E983003178A3 /* WidgetExtension */ = { isa = PBXGroup; children = ( @@ -790,6 +825,7 @@ C57DCAA727C8954B000A2ABC /* Profile */, 76AE52DB25D358D700AFA45A /* License */, C50CF78A27D86D760042C210 /* OpenLicense */, + 75BC052729ECE1FB00E21941 /* ServerSwitching */, BDEB7D8D23F5293800EFAF31 /* Podfile */, BDA1832823F406A600C9A6DD /* README.md */, 75917F9A27BDEC880051E201 /* Strings */, @@ -1181,6 +1217,7 @@ C599740F27D9E64E006F5AAC /* OpenLicenseDetailViewController.storyboard in Resources */, BDA1833123F41A4C00C9A6DD /* Images.xcassets in Resources */, BDA1831F23F3FD8000C9A6DD /* LaunchScreen.storyboard in Resources */, + 75BC053229ED087000E21941 /* ServerSwitchingViewController.storyboard in Resources */, C59C21FE282E318100DDF5CC /* License-ja.rtf in Resources */, BDA1831C23F3FD8000C9A6DD /* Assets.xcassets in Resources */, 76AE52D725D358A800AFA45A /* License.rtf in Resources */, @@ -1370,6 +1407,7 @@ BDBBF838243C9EA300EEB25D /* GetApprovalsEndpoint.swift in Sources */, BD7DC0F224C0608800C3FBED /* ErrorResponse.swift in Sources */, C52221BC27FD67EA00494390 /* SubViewStack.swift in Sources */, + 75BC052F29ECE8AC00E21941 /* ServerSwitchingViewController.swift in Sources */, BD7A8007241A16B90040B418 /* DeepLinkParser.swift in Sources */, BD7A8009241A16B90040B418 /* NotificationParser.swift in Sources */, BDEE85F82408A887006A6BF7 /* MainTabBarViewController.swift in Sources */, @@ -1389,6 +1427,8 @@ BD86A6B124067EB3007B48F1 /* APIResult.swift in Sources */, BDAB1F71240D0E5C00EA15FD /* GetSessionEndpoint.swift in Sources */, BDAABA1D24A3627B0077EC69 /* DeviceResponse.swift in Sources */, + 75BC053429EDA23700E21941 /* MordalViewController.swift in Sources */, + 75BC052D29ECE87500E21941 /* ServerSwitchingBuilder.swift in Sources */, BDA1832B23F4079400C9A6DD /* RootViewController.swift in Sources */, C57DCAAE27C89823000A2ABC /* ProfileViewController.swift in Sources */, OZPVEGK5OCQVK53RHNWXAVSG /* LoginViewController.swift in Sources */, diff --git a/AgileWorks/AgileWorks/ServerSwitching/Builder/ServerSwitchingBuilder.swift b/AgileWorks/AgileWorks/ServerSwitching/Builder/ServerSwitchingBuilder.swift new file mode 100644 index 0000000..c40d8c9 --- /dev/null +++ b/AgileWorks/AgileWorks/ServerSwitching/Builder/ServerSwitchingBuilder.swift @@ -0,0 +1,32 @@ +// +// ServerSwitchingBuilder.swift +// AgileWorks +// +// Created by Azuma Kasumi on 2023/04/17. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import UIKit + +protocol ServerSwitchingBuilder { + func build() -> UIViewController +} + +struct ServerSwitchingBuilderImpl: ServerSwitchingBuilder { + let identifier = "ServerSwitchingViewController" + + func build() -> UIViewController { + let viewController = storyboard() + + return viewController + } +} + +extension ServerSwitchingBuilderImpl { + private func storyboard() -> ServerSwitchingViewController { + let storyboard = UIStoryboard(name: identifier, bundle: Bundle.main) + let viewController = storyboard.instantiateViewController(withIdentifier: identifier) as! ServerSwitchingViewController + return viewController + } +} + diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift new file mode 100644 index 0000000..8474044 --- /dev/null +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -0,0 +1,23 @@ +// +// MordalViewController.swift +// AgileWorks +// +// Created by Azuma Kasumi on 2023/04/18. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import UIKit +import FloatingPanel + +class MordalViewController: UIViewController { + override func viewDidLoad() { + super.viewDidLoad() + + // Do any additional setup after loading the view. + } + + static func fromStoryboard(_ storyboard: UIStoryboard = UIStoryboard(name: "ServerSwitchingViewController", bundle: nil)) -> MordalViewController { + let controller = storyboard.instantiateViewController(withIdentifier: "MordalViewController") as! MordalViewController + return controller + } +} diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift new file mode 100644 index 0000000..dee57e5 --- /dev/null +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift @@ -0,0 +1,86 @@ +// +// ServerSwitchingViewController.swift +// AgileWorks +// +// Created by Azuma Kasumi on 2023/04/17. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import UIKit +import FloatingPanel + +class ServerSwitchingViewController: UIViewController, UIGestureRecognizerDelegate { + let fpc = FloatingPanelController() + + override func viewDidLoad() { + super.viewDidLoad() + + //モーダル外の背景色 + self.view.backgroundColor = UIColor.lightGray.withAlphaComponent(0.3) + + //タップ検知 + let tapGesture = UITapGestureRecognizer(target: self, action: #selector(tapped(_:))) + tapGesture.delegate = self + self.view.addGestureRecognizer(tapGesture) + + //モーダルの設定 + fpc.delegate = self + //角丸 + fpc.surfaceView.cornerRadius = 24.0 + //下スワイプで閉じる + fpc.isRemovalInteractionEnabled = true + let mordalVC = MordalViewController.fromStoryboard() + self.view.addSubview(fpc.view) + fpc.set(contentViewController: mordalVC) + fpc.addPanel(toParent: self) + } + + func closeView() { + self.dismiss(animated: true, completion: nil) + } + + //モーダル外タップで閉じる + @objc func tapped(_ sender: UITapGestureRecognizer) { + closeView() + } + + func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldReceive touch: UITouch) -> Bool { + if touch.view == self.view { + return true + } + return false + } +} + +extension ServerSwitchingViewController: FloatingPanelControllerDelegate { + // カスタマイズしたレイアウトに変更 + func floatingPanel(_ vc: FloatingPanelController, layoutFor newCollection: UITraitCollection) -> FloatingPanelLayout? { + return CustomFloatingPanelLayout() + } + //モーダルがスワイプ削除される + func floatingPanelDidEndDraggingToRemove(_ vc: FloatingPanelController, withVelocity velocity: CGPoint){ + closeView() + } +} + +class CustomFloatingPanelLayout: FloatingPanelLayout { + // 初期位置 + var initialPosition: FloatingPanelPosition { + return .half + } + + // カスタマイズした高さ + func insetFor(position: FloatingPanelPosition) -> CGFloat? { + switch position { + case .full: return 16.0 + case .half: return 350.0 + case .tip: return 44.0 + default: return nil + } + } + + // サポートする位置 + var supportedPositions: Set { + return [.full, .half] + } +} diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard new file mode 100644 index 0000000..5a74d63 --- /dev/null +++ b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift index 137b310..368a19e 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift @@ -115,6 +115,14 @@ class MenuTableViewController: UITableViewController { //接続先サーバーセルタップ処理 private func pushToServer() { + let serverSwitching = ServerSwitchingBuilderImpl().build() + serverSwitching.modalPresentationStyle = .overFullScreen + serverSwitching.modalTransitionStyle = .crossDissolve + self.present(serverSwitching, animated: false, completion: nil) + // セルの選択解除 + if let indexPath = self.tableView.indexPath(for: self.serverCell) { + self.tableView.deselectRow(at: indexPath, animated: true) + } } } -- GitLab From 441c9001b89d2c275972146d9dd14d8d2f46b6ea Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 25 Apr 2023 10:32:58 +0900 Subject: [PATCH 03/36] =?UTF-8?q?=E7=AB=AF=E6=9C=AB=E5=9B=9E=E8=BB=A2?= =?UTF-8?q?=E6=99=82=E3=81=AE=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB=E4=BD=8D?= =?UTF-8?q?=E7=BD=AE=E8=AA=BF=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ServerSwitchingViewController.swift | 52 +++++++++++++------ .../serverSwitchingViewController.storyboard | 1 + 2 files changed, 37 insertions(+), 16 deletions(-) diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift index dee57e5..3ebe6b9 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift @@ -64,23 +64,43 @@ extension ServerSwitchingViewController: FloatingPanelControllerDelegate { } class CustomFloatingPanelLayout: FloatingPanelLayout { - // 初期位置 - var initialPosition: FloatingPanelPosition { - return .half - } + // 初期位置 + var initialPosition: FloatingPanelPosition { + return .half + } // カスタマイズした高さ - func insetFor(position: FloatingPanelPosition) -> CGFloat? { - switch position { - case .full: return 16.0 - case .half: return 350.0 - case .tip: return 44.0 - default: return nil - } - } + func insetFor(position: FloatingPanelPosition) -> CGFloat? { + switch position { + case .full: return 16.0 + case .half: return 350.0 + case .tip: return 44.0 + default: return nil + } + } + + func prepareLayout(surfaceView: UIView, in view: UIView) -> [NSLayoutConstraint]{ + var screenHeight = UIScreen.main.bounds.height + var screenWidth = UIScreen.main.bounds.width + var mordalWidth = screenWidth + //iPad + if UIDevice.current.userInterfaceIdiom == .pad { + mordalWidth = 500 + } else { //iPhone + //端末が横向き + if screenWidth > screenHeight { + mordalWidth = screenHeight + } + } - // サポートする位置 - var supportedPositions: Set { - return [.full, .half] - } + return [ + surfaceView.centerXAnchor.constraint(equalTo: view.centerXAnchor), + surfaceView.widthAnchor.constraint(equalToConstant: mordalWidth), + ] + } + + // サポートするモーダルサイズ + var supportedPositions: Set { + return [.half] + } } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard index 5a74d63..7f04f14 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard +++ b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard @@ -41,6 +41,7 @@ + -- GitLab From 04e787156b6c93ae74d2227f30dc172138745e74 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 8 May 2023 15:50:19 +0900 Subject: [PATCH 04/36] =?UTF-8?q?=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB?= =?UTF-8?q?=E3=81=AE=E8=A1=A8=E7=A4=BA=E3=83=BB=E3=83=AD=E3=82=B0=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E7=94=BB=E9=9D=A2=E3=81=B8=E3=81=AE=E9=81=B7=E7=A7=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 4 + .../AgileWorks/App/RootViewController.swift | 1 + .../Login/Builder/LoginBuilder.swift | 4 + .../Login/View/LoginViewController.swift | 2 + .../View/MordalViewController.swift | 18 ++- .../ServerSwitchingTableViewController.swift | 80 +++++++++++ .../serverSwitchingViewController.storyboard | 132 ++++++++++++++++-- .../Strings/Chinese-Simplified.strings | 1 + .../Strings/Chinese-Traditional.strings | 1 + AgileWorks/AgileWorks/Strings/English.strings | 1 + .../AgileWorks/Strings/Japanese.strings | 1 + .../Strings/en.lproj/Localizable.strings | 1 + .../Strings/ja.lproj/Localizable.strings | 1 + .../Strings/zh-Hans.lproj/Localizable.strings | 1 + .../Strings/zh-Hant.lproj/Localizable.strings | 1 + .../WebView/View/MenuViewController.swift | 1 + .../WebView/View/WebViewController.swift | 1 + .../Common/DataStore/KeychainDataStore.swift | 16 +++ 18 files changed, 256 insertions(+), 11 deletions(-) create mode 100644 AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 5c044bc..64104ad 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/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index 6e82fe6..3ca5135 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -67,6 +67,7 @@ extension RootViewController { KeychainDataStore().removeOAuthState() KeychainDataStore().removeAccessToken() KeychainDataStore().removeSessionID() + KeychainDataStore().removeServerName() KeychainDataStore().removeLanguage() KeychainDataStore().removeDeviceID() diff --git a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift index 13926ad..1921dde 100644 --- a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift +++ b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift @@ -26,6 +26,10 @@ struct LoginBuilderImpl: LoginBuilder { ) return viewController } + + func loginStoryboard() -> LoginViewController { + return storyboard() + } } extension LoginBuilderImpl { diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index d12e5f1..4e9c58b 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -74,6 +74,7 @@ class LoginViewController: UIViewController { KeychainDataStore().removeOAuthState() KeychainDataStore().removeAccessToken() KeychainDataStore().removeSessionID() + KeychainDataStore().removeServerName() KeychainDataStore().removeLanguage() KeychainDataStore().removeDeviceID() @@ -209,6 +210,7 @@ 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 { //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift index 8474044..6327480 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -10,9 +10,18 @@ import UIKit import FloatingPanel class MordalViewController: UIViewController { + @IBOutlet private var accessPoint: UILabel! + @IBOutlet private var addServer: UIButton! + + let navVC = UINavigationController(rootViewController: LoginBuilderImpl().loginStoryboard()) + + @objc func cancelTapped(_ sender: UIBarButtonItem) { + navVC.dismiss(animated: true) + } + override func viewDidLoad() { super.viewDidLoad() - + accessPoint.text = getDisplayString(key: "ServerTitle", comment: "") // Do any additional setup after loading the view. } @@ -20,4 +29,11 @@ class MordalViewController: UIViewController { let controller = storyboard.instantiateViewController(withIdentifier: "MordalViewController") as! MordalViewController return controller } + @IBAction private func addServerTapped(_ sender: Any) { + //モーダルの表示 + navVC.modalPresentationStyle = .fullScreen + let leftButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped(_:))) + navVC.navigationBar.topItem!.leftBarButtonItem = leftButton + 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 0000000..54764d3 --- /dev/null +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -0,0 +1,80 @@ +// +// 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() + } + + // MARK: - Table view data source + + override func numberOfSections(in tableView: UITableView) -> Int { + // #warning Incomplete implementation, return the number of sections + return 1 + } + //セルの数 + override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + // #warning Incomplete implementation, return the number of rows + return 1 + } + + override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "ServerSwitchingTableViewCell", for: indexPath) + + let serverName = cell.viewWithTag(1) as! UILabel + serverName.text = KeychainDataStore().readServerName() + + 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 + } else {//その他サーバー + setApprovalsCount(label: approvalCount) + } + + return cell + } + + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { + return 50 + } + + //承認待ち件数取得 + private func setApprovalsCount(label: UILabel){ + 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) + label.text = "0" + } + } + } +} diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard b/AgileWorks/AgileWorks/ServerSwitching/View/serverSwitchingViewController.storyboard index 7f04f14..6cdbd82 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 7d800c1..dca6489 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 4168400..6cc1879 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 527ffdb..66bb9ee 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 471ddc0..ff87ef0 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 7f2918a..55a7d34 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 529cfff..4f6fbc8 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 19b2444..9495f6d 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 a4898c3..e01613e 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/MenuViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift index 07e6ba3..20add4e 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift @@ -73,6 +73,7 @@ class MenuViewController: UIViewController { 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 4cdd571..fe9d431 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 { // 画面ロード diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 681a27c..3529ac1 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -20,6 +20,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) { @@ -143,6 +144,21 @@ final class KeychainDataStore: DataStoreProtocol { removeKeychainValue(key: kSessionID) } + // サーバー識別名の書き込み + func writeServerName(serverName: String) { + setKeychainValue(key: kServerName, value: serverName) + } + + // サーバー識別名の読み込み + func readServerName() -> String? { + return getKeychainValue(key: kServerName) + } + + // サーバー識別名の削除 + func removeServerName() { + removeKeychainValue(key: kServerName) + } + // KeyChain へ指定の値をセット private func setKeychainValue(key: String, value: String) { let keychain = Keychain(service: service, accessGroup: groupId) -- GitLab From 91d1a6025cadbd1eaf8d9fd6bb7fba80b40964d8 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Fri, 19 May 2023 11:58:43 +0900 Subject: [PATCH 05/36] =?UTF-8?q?=E3=82=B5=E3=83=BC=E3=83=90=E3=83=BC?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=81=8B=E3=82=89=E3=83=AD=E3=82=B0=E3=82=A4?= =?UTF-8?q?=E3=83=B3=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88=EF=BC=88=E3=82=AD?= =?UTF-8?q?=E3=83=BC=E3=83=81=E3=82=A7=E3=83=B3=E5=88=87=E3=82=8A=E6=9B=BF?= =?UTF-8?q?=E3=81=88=E4=B8=8D=E5=8F=AF=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks/App/RootViewController.swift | 26 ++++++- .../Login/Builder/LoginBuilder.swift | 15 ++-- .../Login/View/LoginViewController.swift | 74 ++++++++++++------- .../View/MordalViewController.swift | 3 +- .../Common/DataStore/KeychainDataStore.swift | 8 +- .../DataStore/UserDefaultsDataStore.swift | 61 ++++++++++++++- 6 files changed, 146 insertions(+), 41 deletions(-) diff --git a/AgileWorks/AgileWorks/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index 3ca5135..0ce909d 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -40,7 +40,7 @@ class RootViewController: UIViewController { extension RootViewController { func showLoginScreen() { - let new = LoginBuilderImpl().build() + let new = LoginBuilderImpl().build(addServerloginFlg: false) addChild(new) new.view.frame = view.bounds @@ -78,6 +78,28 @@ extension RootViewController { WidgetCenter.shared.reloadAllTimelines() } } + /* + UserDefaultsDataStore().removeServer() + let serverList = UserDefaultsDataStore().readServerList() + if serverList.isEmpty { + DispatchQueue.main.async { + self.switchToLogout() + //ウィジェットの更新 + if #available(iOS 14.0, *) { + WidgetCenter.shared.reloadAllTimelines() + } + } + } else { + KeychainDataStore().setGroupId(serverNumber: serverList.first!) + DispatchQueue.main.async { + self.switchToMainScreen() + //ウィジェットの更新 + if #available(iOS 14.0, *) { + WidgetCenter.shared.reloadAllTimelines() + } + } + } + */ } } @@ -104,7 +126,7 @@ extension RootViewController { } func switchToLogout() { - let new = LoginBuilderImpl().build() + let new = LoginBuilderImpl().build(addServerloginFlg: false) animateDismissTransition(to: new) } diff --git a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift index 1921dde..42d56a5 100644 --- a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift +++ b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift @@ -9,14 +9,14 @@ import UIKit protocol LoginBuilder { - func build() -> UIViewController + func build(addServerloginFlg: Bool) -> UIViewController } struct LoginBuilderImpl: LoginBuilder { let identifier = "LoginViewController" - func build() -> UIViewController { - let viewController = storyboard() + func build(addServerloginFlg: Bool) -> UIViewController { + let viewController = storyboard(addServerloginFlg: addServerloginFlg) viewController.inject( presenter: LoginPresenterImpl( view: viewController, @@ -27,15 +27,14 @@ struct LoginBuilderImpl: LoginBuilder { return viewController } - func loginStoryboard() -> LoginViewController { - return storyboard() - } } extension LoginBuilderImpl { - private func storyboard() -> LoginViewController { + private func storyboard(addServerloginFlg: Bool) -> LoginViewController { let storyboard = mainStoryboard() - let viewController = storyboard.instantiateViewController(withIdentifier: identifier) as! LoginViewController + let viewController = storyboard.instantiateViewController(identifier: identifier){ coder in + LoginViewController(coder: coder, addServerloginFlg: addServerloginFlg) + } return viewController } diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 4e9c58b..37e45d7 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -35,11 +35,22 @@ class LoginViewController: UIViewController { @IBOutlet private var qrCodeReadView: UIView! @IBOutlet private var qrCodeStartupButton: UIButton! @IBOutlet private var scrollViewBottomConstraint: NSLayoutConstraint! + //サーバー追加画面フラグ + public var addServerloginFlg: Bool private let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) private var presenter: LoginPresenter! + init?(coder: NSCoder, addServerloginFlg: Bool){ + self.addServerloginFlg = addServerloginFlg + super.init(coder: coder) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + private var serverHost: String? { guard let server = serverTextField.text else { return nil } return server @@ -58,29 +69,30 @@ 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 !addServerloginFlg { + //ログイン画面が表示されると通知を取得しない + self.devcie { result in + switch result { + case .success: + break + case .failure(let error): + log.e(error) + } } - } - //認証情報削除 - KeychainDataStore().removeOAuthState() - KeychainDataStore().removeAccessToken() - KeychainDataStore().removeSessionID() - KeychainDataStore().removeServerName() - 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) @@ -88,10 +100,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) @@ -169,6 +183,15 @@ class LoginViewController: UIViewController { guard let context = context else { return } disableLogin() +/* + //サーバー切り替え + if let serverId = UserDefaultsDataStore().serchEmptyServerData() { + KeychainDataStore().setGroupId(serverNumber: serverId) + } else { + //TODO: サーバー追加できない場合 + } + */ + //サーバー名コンテキストパスの保存 KeychainDataStore().writeServerURL(serverURL: serverHost) KeychainDataStore().writeContextPath(contextPath: context) @@ -212,6 +235,7 @@ class LoginViewController: UIViewController { KeychainDataStore().writeSessionID(sessionID: response.sessionId) KeychainDataStore().writeServerName(serverName: "サーバー識別名") //TODO response.server.name DispatchQueue.main.async { + //UserDefaultsDataStore().addServerList() //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift index 6327480..495d92e 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -13,7 +13,7 @@ class MordalViewController: UIViewController { @IBOutlet private var accessPoint: UILabel! @IBOutlet private var addServer: UIButton! - let navVC = UINavigationController(rootViewController: LoginBuilderImpl().loginStoryboard()) + let navVC = UINavigationController(rootViewController: LoginBuilderImpl().build(addServerloginFlg: true)) @objc func cancelTapped(_ sender: UIBarButtonItem) { navVC.dismiss(animated: true) @@ -22,7 +22,6 @@ class MordalViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() accessPoint.text = getDisplayString(key: "ServerTitle", comment: "") - // Do any additional setup after loading the view. } static func fromStoryboard(_ storyboard: UIStoryboard = UIStoryboard(name: "ServerSwitchingViewController", bundle: nil)) -> MordalViewController { diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 3529ac1..e6fdd1c 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -12,7 +12,9 @@ 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 baseGroupId = Bundle.main.object(forInfoDictionaryKey: "AppIdentifierPrefix") as! String + Configuration.shared.awShareBundleIdentifier + //private var groupId: String = "" + private var groupId: String = 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" @@ -22,6 +24,10 @@ final class KeychainDataStore: DataStoreProtocol { private let kSessionID: String = "SessionID" private let kServerName: String = "ServerName" + func setGroupId(serverNumber: Int) { + groupId = baseGroupId + String(serverNumber) + } + // アクセストークンの書き込み func writeAccessToken(accessToken: String) { setKeychainValue(key: kAccessToken, value: accessToken) diff --git a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift index 1e39b58..4c53b66 100644 --- a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift +++ b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift @@ -17,6 +17,9 @@ 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 severCount = 5 init() { sharedDefaults = UserDefaults() @@ -41,17 +44,69 @@ 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() + 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) + } + } } -- GitLab From b98cbbeabdfd0bf2dd5572c16280af50db87e498 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Wed, 24 May 2023 16:06:41 +0900 Subject: [PATCH 06/36] =?UTF-8?q?=E3=82=AD=E3=83=BC=E3=83=81=E3=82=A7?= =?UTF-8?q?=E3=83=BC=E3=83=B3=E3=81=AE=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks-Production.entitlements | 6 ++- .../AgileWorks/App/RootViewController.swift | 16 +++----- .../Login/View/LoginViewController.swift | 9 ++--- .../View/MordalViewController.swift | 3 ++ .../ServerSwitchingTableViewController.swift | 39 ++++++++++++++----- .../View/MenuTableViewController.swift | 2 +- .../WebView/View/WebViewController.swift | 2 +- .../Common/DataStore/KeychainDataStore.swift | 21 +++++----- .../DataStore/UserDefaultsDataStore.swift | 22 ++++++++++- 9 files changed, 78 insertions(+), 42 deletions(-) diff --git a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements index 6f5ee78..4db9e2b 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 0ce909d..a26249a 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 { @@ -71,15 +71,10 @@ extension RootViewController { KeychainDataStore().removeLanguage() KeychainDataStore().removeDeviceID() - DispatchQueue.main.async { - self.switchToLogout() - //ウィジェットの更新 - if #available(iOS 14.0, *) { - WidgetCenter.shared.reloadAllTimelines() - } + if serverRemove { + UserDefaultsDataStore().removeServer() } - /* - UserDefaultsDataStore().removeServer() + let serverList = UserDefaultsDataStore().readServerList() if serverList.isEmpty { DispatchQueue.main.async { @@ -90,7 +85,7 @@ extension RootViewController { } } } else { - KeychainDataStore().setGroupId(serverNumber: serverList.first!) + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) DispatchQueue.main.async { self.switchToMainScreen() //ウィジェットの更新 @@ -99,7 +94,6 @@ extension RootViewController { } } } - */ } } diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 37e45d7..07e9acd 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -183,14 +183,13 @@ class LoginViewController: UIViewController { guard let context = context else { return } disableLogin() -/* + //サーバー切り替え if let serverId = UserDefaultsDataStore().serchEmptyServerData() { - KeychainDataStore().setGroupId(serverNumber: serverId) + UserDefaultsDataStore().setGroupId(serverNumber: serverId) } else { //TODO: サーバー追加できない場合 } - */ //サーバー名コンテキストパスの保存 KeychainDataStore().writeServerURL(serverURL: serverHost) @@ -235,7 +234,7 @@ class LoginViewController: UIViewController { KeychainDataStore().writeSessionID(sessionID: response.sessionId) KeychainDataStore().writeServerName(serverName: "サーバー識別名") //TODO response.server.name DispatchQueue.main.async { - //UserDefaultsDataStore().addServerList() + UserDefaultsDataStore().addServerList() //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() } @@ -326,7 +325,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 495d92e..468fa9b 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -19,6 +19,9 @@ class MordalViewController: UIViewController { navVC.dismiss(animated: true) } + func cancel() { + navVC.dismiss(animated: true) + } override func viewDidLoad() { super.viewDidLoad() accessPoint.text = getDisplayString(key: "ServerTitle", comment: "") diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift index 54764d3..f7a35d5 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -10,14 +10,32 @@ import UIKit class ServerSwitchingTableTableViewController: UITableViewController { @IBOutlet var table: UITableView! - + var serverList: [Int] = [] + override func viewDidLoad() { super.viewDidLoad() + serverList = UserDefaultsDataStore().readServerList() table.tableFooterView = UIView() } - + + override func viewWillAppear(_ animated: Bool) { + super.viewWillAppear(animated) + //承認待ち件数の表示 + Task{ + for row in 1.. Int { // #warning Incomplete implementation, return the number of sections return 1 @@ -25,14 +43,15 @@ class ServerSwitchingTableTableViewController: UITableViewController { //セルの数 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows - return 1 + return serverList.count } override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { let cell = tableView.dequeueReusableCell(withIdentifier: "ServerSwitchingTableViewCell", for: indexPath) let serverName = cell.viewWithTag(1) as! UILabel - serverName.text = KeychainDataStore().readServerName() + 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))) @@ -45,19 +64,19 @@ class ServerSwitchingTableTableViewController: UITableViewController { badgeIcon.tintColor = UIColor(named: getDisplayString(key: "MainColor", comment: "")) //承認待ち件数は取得しないため非表示 approvalCount.isHidden = true - } else {//その他サーバー - setApprovalsCount(label: approvalCount) } return cell } - + override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 50 } - + private func callApprovalCount(label: UILabel) async{ + await setApprovalsCount(label: label) + } //承認待ち件数取得 - private func setApprovalsCount(label: UILabel){ + private func setApprovalsCount(label: UILabel) async { let approvalsEndpoint = GetApprovalsEndpoint() Session.send(approvalsEndpoint) { result in diff --git a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift index 368a19e..c487fbf 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/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index fe9d431..eabd361 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -262,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 e6fdd1c..0e2a3b1 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -12,9 +12,6 @@ import UIKit final class KeychainDataStore: DataStoreProtocol { private let service = "AgileWorks" - private let baseGroupId = Bundle.main.object(forInfoDictionaryKey: "AppIdentifierPrefix") as! String + Configuration.shared.awShareBundleIdentifier - //private var groupId: String = "" - private var groupId: String = 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" @@ -24,10 +21,6 @@ final class KeychainDataStore: DataStoreProtocol { private let kSessionID: String = "SessionID" private let kServerName: String = "ServerName" - func setGroupId(serverNumber: Int) { - groupId = baseGroupId + String(serverNumber) - } - // アクセストークンの書き込み func writeAccessToken(accessToken: String) { setKeychainValue(key: kAccessToken, value: accessToken) @@ -45,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 } @@ -54,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 @@ -159,6 +152,10 @@ final class KeychainDataStore: DataStoreProtocol { 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] + } // サーバー識別名の削除 func removeServerName() { @@ -167,17 +164,17 @@ final class KeychainDataStore: DataStoreProtocol { // 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 4c53b66..7c62120 100644 --- a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift +++ b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift @@ -18,6 +18,8 @@ final class UserDefaultsDataStore: DataStoreProtocol { 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 @@ -82,8 +84,11 @@ final class UserDefaultsDataStore: DataStoreProtocol { //サーバー接続先を保存できる識別番号を探す func serchEmptyServerData() -> Int? { var serverList = readServerList() + if serverList.isEmpty { + return serverList.count + } for num in 0 ..< severCount { - if serverList.contains(num) { + if !serverList.contains(num) { return num } } @@ -109,4 +114,19 @@ final class UserDefaultsDataStore: DataStoreProtocol { 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 + } } -- GitLab From 72bc947e097a1bf0cbd06096e82739a776d78edb Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 29 May 2023 16:42:47 +0900 Subject: [PATCH 07/36] =?UTF-8?q?=E3=82=B5=E3=83=BC=E3=83=90=E3=83=BC?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=E3=83=BB=E3=83=AD=E3=82=B0=E3=82=A2=E3=82=A6?= =?UTF-8?q?=E3=83=88=20=E6=AD=A3=E5=B8=B8=E7=B3=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/Login/View/LoginViewController.swift | 2 ++ .../ServerSwitching/View/MordalViewController.swift | 2 ++ .../View/ServerSwitchingTableViewController.swift | 4 ++-- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 07e9acd..7b82f00 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -235,6 +235,8 @@ class LoginViewController: UIViewController { 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() } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift index 468fa9b..bc7b78a 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -16,6 +16,8 @@ class MordalViewController: UIViewController { let navVC = UINavigationController(rootViewController: LoginBuilderImpl().build(addServerloginFlg: true)) @objc func cancelTapped(_ sender: UIBarButtonItem) { + var serverList = UserDefaultsDataStore().readServerList() + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) navVC.dismiss(animated: true) } diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift index f7a35d5..265e158 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -23,14 +23,14 @@ class ServerSwitchingTableTableViewController: UITableViewController { //承認待ち件数の表示 Task{ for row in 1.. Date: Tue, 30 May 2023 20:27:50 +0900 Subject: [PATCH 08/36] =?UTF-8?q?navigationViewController=E3=81=AE?= =?UTF-8?q?=E8=A6=8B=E7=9B=B4=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks/App/RootViewController.swift | 4 +-- .../Login/Builder/LoginBuilder.swift | 18 +++++++------ .../Login/View/LoginViewController.swift | 25 +++++++++++-------- .../View/MordalViewController.swift | 15 +---------- .../ServerSwitchingTableViewController.swift | 9 ++++++- 5 files changed, 37 insertions(+), 34 deletions(-) diff --git a/AgileWorks/AgileWorks/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index a26249a..ace6f96 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -40,7 +40,7 @@ class RootViewController: UIViewController { extension RootViewController { func showLoginScreen() { - let new = LoginBuilderImpl().build(addServerloginFlg: false) + let new = LoginBuilderImpl().build() addChild(new) new.view.frame = view.bounds @@ -120,7 +120,7 @@ extension RootViewController { } func switchToLogout() { - let new = LoginBuilderImpl().build(addServerloginFlg: false) + let new = LoginBuilderImpl().build() animateDismissTransition(to: new) } diff --git a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift index 42d56a5..54a3c59 100644 --- a/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift +++ b/AgileWorks/AgileWorks/Login/Builder/LoginBuilder.swift @@ -9,14 +9,15 @@ import UIKit protocol LoginBuilder { - func build(addServerloginFlg: Bool) -> UIViewController + func build() -> UIViewController } struct LoginBuilderImpl: LoginBuilder { let identifier = "LoginViewController" + var navVC: UINavigationController? = nil - func build(addServerloginFlg: Bool) -> UIViewController { - let viewController = storyboard(addServerloginFlg: addServerloginFlg) + func build() -> UIViewController { + let viewController = storyboard() viewController.inject( presenter: LoginPresenterImpl( view: viewController, @@ -27,14 +28,17 @@ struct LoginBuilderImpl: LoginBuilder { return viewController } + func naviBuild() -> UINavigationController { + let navVC = UINavigationController(rootViewController: build()) + navVC.modalPresentationStyle = .fullScreen + return navVC + } } extension LoginBuilderImpl { - private func storyboard(addServerloginFlg: Bool) -> LoginViewController { + private func storyboard() -> LoginViewController { let storyboard = mainStoryboard() - let viewController = storyboard.instantiateViewController(identifier: identifier){ coder in - LoginViewController(coder: coder, addServerloginFlg: addServerloginFlg) - } + let viewController = storyboard.instantiateViewController(withIdentifier: identifier) as! LoginViewController return viewController } diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 7b82f00..3b23efb 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -36,21 +36,12 @@ class LoginViewController: UIViewController { @IBOutlet private var qrCodeStartupButton: UIButton! @IBOutlet private var scrollViewBottomConstraint: NSLayoutConstraint! //サーバー追加画面フラグ - public var addServerloginFlg: Bool + private var addServerloginFlg = false private let activityIndicator = UIActivityIndicatorView(style: .whiteLarge) private var presenter: LoginPresenter! - init?(coder: NSCoder, addServerloginFlg: Bool){ - self.addServerloginFlg = addServerloginFlg - super.init(coder: coder) - } - - required init?(coder: NSCoder) { - fatalError("init(coder:) has not been implemented") - } - private var serverHost: String? { guard let server = serverTextField.text else { return nil } return server @@ -69,6 +60,11 @@ class LoginViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() + 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 { //ログイン画面が表示されると通知を取得しない @@ -129,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.parent!.dismiss(animated: true) + } //ログイン画面の固定文言表示 private func setupFixedWording() { @@ -239,6 +241,9 @@ class LoginViewController: UIViewController { UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() + if let nc = self.parent as? UINavigationController { + nc.dismiss(animated: true) + } } // セッション情報取得失敗 case .failure(let error): diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift index bc7b78a..a67e42a 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -13,17 +13,6 @@ class MordalViewController: UIViewController { @IBOutlet private var accessPoint: UILabel! @IBOutlet private var addServer: UIButton! - let navVC = UINavigationController(rootViewController: LoginBuilderImpl().build(addServerloginFlg: true)) - - @objc func cancelTapped(_ sender: UIBarButtonItem) { - var serverList = UserDefaultsDataStore().readServerList() - UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) - navVC.dismiss(animated: true) - } - - func cancel() { - navVC.dismiss(animated: true) - } override func viewDidLoad() { super.viewDidLoad() accessPoint.text = getDisplayString(key: "ServerTitle", comment: "") @@ -35,9 +24,7 @@ class MordalViewController: UIViewController { } @IBAction private func addServerTapped(_ sender: Any) { //モーダルの表示 - navVC.modalPresentationStyle = .fullScreen - let leftButton = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: #selector(cancelTapped(_:))) - navVC.navigationBar.topItem!.leftBarButtonItem = leftButton + 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 index 265e158..b390be1 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -72,6 +72,11 @@ class ServerSwitchingTableTableViewController: UITableViewController { override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 50 } + + override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + UserDefaultsDataStore().setGroupId(serverNumber: serverList[indexPath.row]) + AppDelegate.shared.rootViewController.switchToMainScreen() + } private func callApprovalCount(label: UILabel) async{ await setApprovalsCount(label: label) } @@ -92,7 +97,9 @@ class ServerSwitchingTableTableViewController: UITableViewController { } case .failure(let error): log.e(error) - label.text = "0" + DispatchQueue.main.async { + label.text = "0" + } } } } -- GitLab From 7c362b1d067fac3f6d1bf441d81f89934021f083 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Fri, 2 Jun 2023 13:12:49 +0900 Subject: [PATCH 09/36] =?UTF-8?q?=E3=83=A2=E3=83=BC=E3=83=80=E3=83=AB?= =?UTF-8?q?=E3=82=92=E9=96=89=E3=81=98=E3=82=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Login/View/LoginViewController.swift | 4 +-- .../ServerSwitchingTableViewController.swift | 29 ++++++++++++------- .../View/ServerSwitchingViewController.swift | 4 +-- .../WebView/View/MenuViewController.swift | 2 +- .../Common/DataStore/KeychainDataStore.swift | 3 +- 5 files changed, 26 insertions(+), 16 deletions(-) diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 3b23efb..58e6da2 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -129,7 +129,7 @@ class LoginViewController: UIViewController { @objc private func cancelTapped(_ sender: UIBarButtonItem) { var serverList = UserDefaultsDataStore().readServerList() UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) - self.parent!.dismiss(animated: true) + self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) } //ログイン画面の固定文言表示 @@ -242,7 +242,7 @@ class LoginViewController: UIViewController { //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() if let nc = self.parent as? UINavigationController { - nc.dismiss(animated: true) + self.presentingViewController?.presentingViewController?.dismiss(animated: true, completion: nil) } } // セッション情報取得失敗 diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift index b390be1..f540c2b 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -10,11 +10,9 @@ import UIKit class ServerSwitchingTableTableViewController: UITableViewController { @IBOutlet var table: UITableView! - var serverList: [Int] = [] override func viewDidLoad() { super.viewDidLoad() - serverList = UserDefaultsDataStore().readServerList() table.tableFooterView = UIView() } @@ -22,14 +20,15 @@ class ServerSwitchingTableTableViewController: UITableViewController { super.viewWillAppear(animated) //承認待ち件数の表示 Task{ - for row in 1.. Int { - // #warning Incomplete implementation, return the number of sections return 1 } //セルの数 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { - // #warning Incomplete implementation, return the number of rows - return serverList.count + 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) @@ -72,18 +71,28 @@ class ServerSwitchingTableTableViewController: UITableViewController { override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return 50 } - + + //セル選択時の処理 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { - UserDefaultsDataStore().setGroupId(serverNumber: serverList[indexPath.row]) + 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 { diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingViewController.swift index 3ebe6b9..652e871 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/WebView/View/MenuViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift index 20add4e..0129ea3 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift @@ -67,7 +67,7 @@ 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 diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 0e2a3b1..b3e7a6c 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -154,7 +154,8 @@ final class KeychainDataStore: DataStoreProtocol { } func readServerName(serverNumber: Int) -> String? { let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readBaseGroupId() + String(serverNumber)) - return keychain[kServerName] + //return keychain[kServerName] //TODO: サーバー識別名 + return keychain[kServerURL] } // サーバー識別名の削除 -- GitLab From ab2a6183ea494156161f76004a26278ba2b374e2 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 5 Jun 2023 16:06:37 +0900 Subject: [PATCH 10/36] =?UTF-8?q?UI=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/Common/WidgetView.swift | 49 +++++++++++-------- .../TodayExtension-Production.entitlements | 6 ++- 2 files changed, 34 insertions(+), 21 deletions(-) diff --git a/AgileWorks/Common/WidgetView.swift b/AgileWorks/Common/WidgetView.swift index 49e429b..a22fdd3 100644 --- a/AgileWorks/Common/WidgetView.swift +++ b/AgileWorks/Common/WidgetView.swift @@ -108,6 +108,7 @@ struct ApprovalWidgetView: View { //書類状況を表示するための各BOXビュー struct StatusBoxView: View { var entry: EntryData + @State private var selection = 0 //書類状態の種類をカウント func rowCnt() -> Int { @@ -152,29 +153,37 @@ struct StatusBoxView: View { } var body: some View { - GeometryReader { geometry in - //ios13・14~状態確認ウィジェット - if geometry.size.height > kCellDefaultHight { - VStack(spacing: 5) { - ForEach(0.. kCellDefaultHight { + VStack(spacing: 5) { + ForEach(0.. 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 -- GitLab From b5b2b1b5c95edaa5d2219d269ab60aafa474cb4a Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 13 Jun 2023 11:37:51 +0900 Subject: [PATCH 11/36] =?UTF-8?q?=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=83=88=E8=A4=87=E6=95=B0=E3=82=B5=E3=83=BC=E3=83=90?= =?UTF-8?q?=E3=83=BC=E5=88=87=E3=82=8A=E6=9B=BF=E3=81=88=20widget=20Extens?= =?UTF-8?q?ion=E3=80=80UI=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 12 +- .../AgileWorks-Production.entitlements | 4 + .../AgileWorksRelease-Production.entitlements | 20 +++ AgileWorks/AgileWorks/App/AppDelegate.swift | 9 ++ .../DataStore/UserDefaultsDataStore.swift | 11 +- AgileWorks/Common/WidgetView.swift | 136 ++++++++++++++---- .../TodayExtension-Production.entitlements | 4 + ...ayExtensionRelease-Production.entitlements | 18 +++ .../View/TodayViewController.swift | 98 +++++-------- .../WidgetExtension.entitlements | 10 +- .../WidgetExtension/WidgetExtension.swift | 54 ------- ...etExtensionRelease-Production.entitlements | 18 +++ 12 files changed, 250 insertions(+), 144 deletions(-) create mode 100644 AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements create mode 100644 AgileWorks/TodayExtension/TodayExtensionRelease-Production.entitlements create mode 100644 AgileWorks/WidgetExtension/WidgetExtensionRelease-Production.entitlements diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 0ff8792..1e9166c 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -11,7 +11,6 @@ 3127EE0F241A2A9500535CC7 /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127EE0E241A2A9500535CC7 /* TodayViewController.swift */; }; 3127EE12241A2A9500535CC7 /* TodayViewController.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 3127EE10241A2A9500535CC7 /* TodayViewController.storyboard */; }; 3127EE16241A2A9500535CC7 /* TodayExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 3127EE0A241A2A9500535CC7 /* TodayExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - 3127EE1B241A2B4D00535CC7 /* TodayViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3127EE0E241A2A9500535CC7 /* TodayViewController.swift */; }; 31AA002F24347BBD000177B4 /* ApprovalResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA002E24347BBD000177B4 /* ApprovalResponse.swift */; }; 31AA003024347BD1000177B4 /* ApprovalResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA002E24347BBD000177B4 /* ApprovalResponse.swift */; }; 3AF4A84524A06A73006C0C0A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3AF4A84724A06A73006C0C0A /* Localizable.strings */; }; @@ -242,6 +241,9 @@ 3AF4A84824A06AD0006C0C0A /* ja */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = ja; path = ja.lproj/Localizable.strings; sourceTree = ""; }; 7503F77D27EAF7E00074A76E /* WidgetExtension.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = WidgetExtension.entitlements; sourceTree = ""; }; 756C7E7A282B6A5700C24F4D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7576916A2A2EFEEC00EAFCBC /* AgileWorksRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "AgileWorksRelease-Production.entitlements"; sourceTree = ""; }; + 7576916B2A2F003400EAFCBC /* TodayExtensionRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "TodayExtensionRelease-Production.entitlements"; sourceTree = ""; }; + 757691732A32E5F100EAFCBC /* WidgetExtensionRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "WidgetExtensionRelease-Production.entitlements"; sourceTree = ""; }; 75917F9227BD315A0051E201 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 75917F9627BD317E0051E201 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = ""; }; 75917F9B27BDF0F10051E201 /* Japanese.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Japanese.strings; sourceTree = ""; }; @@ -453,6 +455,7 @@ 3127EE0D241A2A9500535CC7 /* TodayExtension */ = { isa = PBXGroup; children = ( + 7576916B2A2F003400EAFCBC /* TodayExtensionRelease-Production.entitlements */, BD285CAF24D2ACA300DC712E /* View */, 3127EE13241A2A9500535CC7 /* Info.plist */, BD10D30624E38C2F00A0DFDC /* TodayExtension-Production.entitlements */, @@ -522,6 +525,7 @@ 75EF9CB127E9E983003178A3 /* WidgetExtension */ = { isa = PBXGroup; children = ( + 757691732A32E5F100EAFCBC /* WidgetExtensionRelease-Production.entitlements */, 7503F77D27EAF7E00074A76E /* WidgetExtension.entitlements */, 75EF9CB227E9E983003178A3 /* WidgetExtension.swift */, 75EF9CB427E9E984003178A3 /* Assets.xcassets */, @@ -812,6 +816,7 @@ BDA1831123F3FD7F00C9A6DD /* AgileWorks */ = { isa = PBXGroup; children = ( + 7576916A2A2EFEEC00EAFCBC /* AgileWorksRelease-Production.entitlements */, BD5061B2242865BC0014F3FA /* Configurations */, BDA6D6A42411FFAA00FA9C33 /* Settings.bundle */, BDA1831B23F3FD8000C9A6DD /* Assets.xcassets */, @@ -1442,7 +1447,6 @@ C599740B27D992E9006F5AAC /* OpenLicenseTableViewCell.swift in Sources */, 76AE533325D37B0200AFA45A /* LicenseViewPresenter.swift in Sources */, 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 */, @@ -1540,6 +1544,7 @@ isa = XCBuildConfiguration; baseConfigurationReference = BD5061AF242848560014F3FA /* Release-Production-Today.xcconfig */; buildSettings = { + CODE_SIGN_ENTITLEMENTS = "TodayExtension/TodayExtensionRelease-Production.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; @@ -1600,7 +1605,7 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - CODE_SIGN_ENTITLEMENTS = WidgetExtension/WidgetExtension.entitlements; + CODE_SIGN_ENTITLEMENTS = "WidgetExtension/WidgetExtensionRelease-Production.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; @@ -2028,6 +2033,7 @@ baseConfigurationReference = BD5061A9242846A50014F3FA /* Release-Production.xcconfig */; buildSettings = { ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; + CODE_SIGN_ENTITLEMENTS = "AgileWorks/AgileWorksRelease-Production.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CODE_SIGN_STYLE = Manual; diff --git a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements index 4db9e2b..002355e 100644 --- a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements +++ b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements @@ -4,6 +4,10 @@ aps-environment development + com.apple.security.application-groups + + group.jp.atled.agileworks + keychain-access-groups $(AppIdentifierPrefix)jp.atled.agileworks0 diff --git a/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements b/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements new file mode 100644 index 0000000..002355e --- /dev/null +++ b/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements @@ -0,0 +1,20 @@ + + + + + aps-environment + development + com.apple.security.application-groups + + group.jp.atled.agileworks + + keychain-access-groups + + $(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/AppDelegate.swift b/AgileWorks/AgileWorks/App/AppDelegate.swift index 84ff5cb..70723b2 100644 --- a/AgileWorks/AgileWorks/App/AppDelegate.swift +++ b/AgileWorks/AgileWorks/App/AppDelegate.swift @@ -72,6 +72,15 @@ class AppDelegate: UIResponder, UIApplicationDelegate { OAuthService.currentAuthorizationFlow = nil } + //タップされたサーバーに切り替える + let serverList = UserDefaultsDataStore().readServerList() + if !serverList.isEmpty { + let tapServer = UserDefaultsDataStore().readTapServer() + UserDefaultsDataStore().changeServerList(firstServer: tapServer!) + UserDefaultsDataStore().setGroupId(serverNumber: tapServer!) + } + + //ios13の場合 if url.scheme == urlSchemeName { var strUrl = url.absoluteString diff --git a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift index 7c62120..31c9173 100644 --- a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift +++ b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift @@ -19,12 +19,13 @@ final class UserDefaultsDataStore: DataStoreProtocol { private let kUpdateWidgetFlgKey : String = "UpdateWidgetFlg" private let kServerListkey: String = "ServerList" private let kGroupIdkey: String = "GroupId" + private let kTapServer: String = "TapServer" private let baseGroupId = Bundle.main.object(forInfoDictionaryKey: "AppIdentifierPrefix") as! String + Configuration.shared.awShareBundleIdentifier private let severCount = 5 init() { - sharedDefaults = UserDefaults() + sharedDefaults = UserDefaults(suiteName: "group.jp.atled.agileworks")! } func writeFirebaseRemoval(flag: Bool) { @@ -115,6 +116,14 @@ final class UserDefaultsDataStore: DataStoreProtocol { } } + func setTapServer(serverNumber: Int) { + sharedDefaults.set(serverNumber, forKey: kTapServer) + } + + func readTapServer() -> Int? { + return sharedDefaults.integer(forKey: kTapServer) + } + func setGroupId(serverNumber: Int) { sharedDefaults.set(baseGroupId + String(serverNumber), forKey: kGroupIdkey) } diff --git a/AgileWorks/Common/WidgetView.swift b/AgileWorks/Common/WidgetView.swift index a22fdd3..3bca8f6 100644 --- a/AgileWorks/Common/WidgetView.swift +++ b/AgileWorks/Common/WidgetView.swift @@ -44,6 +44,31 @@ struct EntryData { var viewController: UIViewController? } +struct TodayWidgetView: View { + var entrys: [EntryData] + @State private var selection = 0 + var serverList = UserDefaultsDataStore().readServerList() + + var body: some View { + VStack (spacing: 0) { + //未ログインの場合はサーバー切り替えボタンを表示しない + if !UserDefaultsDataStore().readServerList().isEmpty { + Picker(selection: $selection, label: Text("")) { + ForEach(0.. Int { var row = entry.approvalItems.count / 2 @@ -154,12 +179,11 @@ struct StatusBoxView: View { var body: some View { VStack (spacing: 0) { - Picker("", selection: self.$selection) { - Text("apple").tag(0) - Text("banana").tag(1) - Text("orange").tag(2) + if #available(iOS 14.0, *) { + if !serverList.isEmpty { + Text(KeychainDataStore().readServerName(serverNumber: serverList[0])!) + } } - .pickerStyle(SegmentedPickerStyle()) GeometryReader { geometry in //ios13・14~状態確認ウィジェット if geometry.size.height > kCellDefaultHight { @@ -175,7 +199,6 @@ struct StatusBoxView: View { } } .position(x: geometry.size.width / 2, y: geometry.size.height / 2) - .background(backColor()) } else { //ios13 承認待ちウィジェット if let num = findApproval() { RowView(entry: entry, boxSize: boxSize(viewSize: geometry.size), itemNum: num, oneBox: true) @@ -187,6 +210,7 @@ struct StatusBoxView: View { } } } + .background(backColor()) } } //ウィジェット1行分のビュー @@ -242,7 +266,7 @@ struct LinkView: View { var body: some View { if #available(iOS 14.0, *) { Link(destination: URL(string: getURL())!, label: { - ApprovalItemView(approvalItem: approvalItem, message: message) + ApprovalItemView(approvalItem: approvalItem, message: message, serverNameFlag: false) }) } else { ApprovalItemView(approvalItem: approvalItem, message: message) @@ -259,30 +283,41 @@ struct LinkView: View { struct ApprovalItemView: View { let approvalItem: ApprovalItem let message: String? + let serverList = UserDefaultsDataStore().readServerList() + var serverNameFlag = true var body: some View { - GeometryReader { geometry in - HStack(spacing: 0) { - Image(systemName: "folder") - .frame(width: geometry.size.width * 0.3, height: geometry.size.height) - .foregroundColor(Color.textColor) - if message == nil { - VStack(alignment: .leading) { - Text(approvalItem.name) - .frame(alignment: .leading) - .foregroundColor(Color.textColor) - Text("\(approvalItem.count)").font(.subheadline) - .frame(alignment: .leading) - .foregroundColor(Color.textColor) + VStack (spacing: 0) { + if #available(iOS 14.0, *) { + if serverNameFlag { + if !serverList.isEmpty { + Text(KeychainDataStore().readServerName(serverNumber: serverList[0])!) + } + } + } + GeometryReader { geometry in + HStack(spacing: 0) { + Image(systemName: "folder") + .frame(width: geometry.size.width * 0.3, height: geometry.size.height) + .foregroundColor(Color.textColor) + if message == nil { + VStack(alignment: .leading) { + Text(approvalItem.name) + .frame(alignment: .leading) + .foregroundColor(Color.textColor) + Text("\(approvalItem.count)").font(.subheadline) + .frame(alignment: .leading) + .foregroundColor(Color.textColor) + } + } else { //APIサーバーエラーの場合の表示 + Text(message ?? "-") } - } else { //APIサーバーエラーの場合の表示 - Text(message ?? "-") } + Spacer() } - Spacer() + .background(Color.widgetBoxColor) + .cornerRadius(20) } - .background(Color.widgetBoxColor) - .cornerRadius(20) } } @@ -305,6 +340,55 @@ func checkApprovalItems(approvalItems: [ApprovalItem]) -> [ApprovalItem] { return result } +enum WidgetAPIResult { + case success(T) + case nodate(String) + case failure(String) +} + +func fetch(completion: @escaping (WidgetAPIResult) -> Void) { + var serverList = UserDefaultsDataStore().readServerList() + if serverList.isEmpty { + completion(.failure(getDisplayString(key: "NotLogedin", comment: ""))) + return + } + + let approvalsEndpoint = GetApprovalsEndpoint() + + Session.send(approvalsEndpoint) { result in + switch result { + case .success(let response): + if !response.items.isEmpty { + completion(.success(response)) + } else { + completion(.nodate(getDisplayString(key: "NoData", comment: ""))) + } + case .failure(let error): + var errorMessage = "-" + switch error { + case .connectionError(let error): + if let message = errorMessageNSError(error: error) { + errorMessage = message + } + default: + break + } + completion(.failure(errorMessage)) + } + } +} + +func errorMessageNSError(error: Error) -> String? { + switch URLError.Code(rawValue: (error as NSError).code) { + case .notConnectedToInternet: // -1009 + return getDisplayString(key: "NotConnectNetworkError", comment: "") + case .timedOut: // -1001 + return getDisplayString(key: "TimedOutNetworkError", comment: "") + default: + return nil + } +} + //URLの末尾に設定するステータスを返す func getStatus(code: String) -> String? { var status: String? diff --git a/AgileWorks/TodayExtension/TodayExtension-Production.entitlements b/AgileWorks/TodayExtension/TodayExtension-Production.entitlements index 87bf715..df7a8b6 100644 --- a/AgileWorks/TodayExtension/TodayExtension-Production.entitlements +++ b/AgileWorks/TodayExtension/TodayExtension-Production.entitlements @@ -2,6 +2,10 @@ + com.apple.security.application-groups + + group.jp.atled.agileworks + keychain-access-groups $(AppIdentifierPrefix)jp.atled.agileworks0 diff --git a/AgileWorks/TodayExtension/TodayExtensionRelease-Production.entitlements b/AgileWorks/TodayExtension/TodayExtensionRelease-Production.entitlements new file mode 100644 index 0000000..df7a8b6 --- /dev/null +++ b/AgileWorks/TodayExtension/TodayExtensionRelease-Production.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.application-groups + + group.jp.atled.agileworks + + keychain-access-groups + + $(AppIdentifierPrefix)jp.atled.agileworks0 + $(AppIdentifierPrefix)jp.atled.agileworks1 + $(AppIdentifierPrefix)jp.atled.agileworks2 + $(AppIdentifierPrefix)jp.atled.agileworks3 + $(AppIdentifierPrefix)jp.atled.agileworks4 + + + diff --git a/AgileWorks/TodayExtension/View/TodayViewController.swift b/AgileWorks/TodayExtension/View/TodayViewController.swift index 304cc9d..e912c5c 100644 --- a/AgileWorks/TodayExtension/View/TodayViewController.swift +++ b/AgileWorks/TodayExtension/View/TodayViewController.swift @@ -25,24 +25,48 @@ class TodayViewController: UIViewController, NCWidgetProviding { } func widgetPerformUpdate(completionHandler: (@escaping (NCUpdateResult) -> Void)) { + let serverList = UserDefaultsDataStore().readServerList() + var entrys: [EntryData] = [] + var entry: EntryData = EntryData(approvalItems: previewItems(), message: getDisplayString(key: "NotLogedin", comment: ""), viewController: self) + + if serverList.isEmpty { + entrys.append(entry) + } + + //ログイン中の書類件数を全て取得する + for server in serverList { + UserDefaultsDataStore().setGroupId(serverNumber: server) + entry = resultEntry() + entrys.append(entry) + + } + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + + //描画 + var rootView = TodayWidgetView(entrys: entrys) + self.callWidgetView(vc: UIHostingController(rootView: rootView)) + completionHandler(NCUpdateResult.newData) + } + + func resultEntry() -> EntryData{ + var fetchFlag = true + var entry = EntryData(approvalItems: previewItems(), message: getDisplayString(key: "NotLogedin", comment: ""), viewController: self) fetch { result in - DispatchQueue.main.async { - var rootView: StatusCheckWidgetView - switch result { - case .success(let response): - self.approvalItems = checkApprovalItems(approvalItems: response.items) - rootView = StatusCheckWidgetView(entry: EntryData(approvalItems: self.approvalItems, message: nil, viewController: self)) - completionHandler(.newData) - case .nodate(let message): - rootView = StatusCheckWidgetView(entry: EntryData(approvalItems: [ApprovalItem](), message: message, viewController: self)) - completionHandler(.noData) - case .failure(let message): - rootView = StatusCheckWidgetView(entry: EntryData(approvalItems: previewItems(), message: message, viewController: self)) - completionHandler(.failed) - } - self.callWidgetView(vc: UIHostingController(rootView: rootView)) + switch result { + case .success(let response): + self.approvalItems = checkApprovalItems(approvalItems: response.items) + entry = EntryData(approvalItems: self.approvalItems, message: nil, viewController: self) + case .nodate(let message): + entry = EntryData(approvalItems: [ApprovalItem](), message: message, viewController: self) + case .failure(let message): + entry = EntryData(approvalItems: previewItems(), message: message, viewController: self) } + fetchFlag = false + } + while fetchFlag{ + Thread.sleep(forTimeInterval: 0.5) } + return entry } func callWidgetView(vc: UIViewController) { @@ -84,47 +108,3 @@ extension TodayViewController: UITableViewDelegate { } } */ - -extension TodayViewController { - func fetch(completion: @escaping (APIResult) -> Void) { - guard KeychainDataStore().readAccessToken() != nil else { - completion(.failure(getDisplayString(key: "NotLogedin", comment: ""))) - return - } - - let approvalsEndpoint = GetApprovalsEndpoint() - - Session.send(approvalsEndpoint) { result in - switch result { - case .success(let response): - if !response.items.isEmpty { - completion(.success(response)) - } else { - completion(.nodate(getDisplayString(key: "NoData", comment: ""))) - } - case .failure(let error): - var errorMessage = "-" - switch error { - case .connectionError(let error): - if let message = self.errorMessageNSError(error: error) { - errorMessage = message - } - default: - break - } - completion(.failure(errorMessage)) - } - } - } - - func errorMessageNSError(error: Error) -> String? { - switch URLError.Code(rawValue: (error as NSError).code) { - case .notConnectedToInternet: // -1009 - return getDisplayString(key: "NotConnectNetworkError", comment: "") - case .timedOut: // -1001 - return getDisplayString(key: "TimedOutNetworkError", comment: "") - default: - return nil - } - } -} diff --git a/AgileWorks/WidgetExtension/WidgetExtension.entitlements b/AgileWorks/WidgetExtension/WidgetExtension.entitlements index 71e202e..df7a8b6 100644 --- a/AgileWorks/WidgetExtension/WidgetExtension.entitlements +++ b/AgileWorks/WidgetExtension/WidgetExtension.entitlements @@ -2,9 +2,17 @@ + com.apple.security.application-groups + + group.jp.atled.agileworks + 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/WidgetExtension/WidgetExtension.swift b/AgileWorks/WidgetExtension/WidgetExtension.swift index cf99640..132712b 100644 --- a/AgileWorks/WidgetExtension/WidgetExtension.swift +++ b/AgileWorks/WidgetExtension/WidgetExtension.swift @@ -93,57 +93,3 @@ struct WidgetExtension_Previews: PreviewProvider { .previewContext(WidgetPreviewContext(family: .systemSmall)) } } - -enum widgetAPIResult { - case success(T) - case nodate(String) - case failure(String) -} - -func fetch(completion: @escaping (widgetAPIResult) -> Void) { - guard KeychainDataStore().readAccessToken() != nil else { - completion(.failure(getDisplayString(key: "NotLogedin", comment: ""))) - return - } - - let approvalsEndpoint = GetApprovalsEndpoint() - - while UserDefaultsDataStore().readUpdateWidgetFlg() ?? false { - //別のウィジェットが更新中の場合は待つ - } - UserDefaultsDataStore().writeUpdateWidgetFlg(update: true) - Session.send(approvalsEndpoint) { result in - UserDefaultsDataStore().writeUpdateWidgetFlg(update: false) - switch result { - case .success(let response): - if !response.items.isEmpty { - completion(.success(response)) - } else { - completion(.nodate(getDisplayString(key: "NoData", comment: ""))) - } - case .failure(let error): - var errorMessage = "-" - switch error { - case .connectionError(let error): - if let message = errorMessageNSError(error: error) { - errorMessage = message - } - default: - break - } - completion(.failure(errorMessage)) - } - } -} - -func errorMessageNSError(error: Error) -> String? { - switch URLError.Code(rawValue: (error as NSError).code) { - case .notConnectedToInternet: // -1009 - return getDisplayString(key: "NotConnectNetworkError", comment: "") - case .timedOut: // -1001 - return getDisplayString(key: "TimedOutNetworkError", comment: "") - default: - return nil - } -} - diff --git a/AgileWorks/WidgetExtension/WidgetExtensionRelease-Production.entitlements b/AgileWorks/WidgetExtension/WidgetExtensionRelease-Production.entitlements new file mode 100644 index 0000000..df7a8b6 --- /dev/null +++ b/AgileWorks/WidgetExtension/WidgetExtensionRelease-Production.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.application-groups + + group.jp.atled.agileworks + + keychain-access-groups + + $(AppIdentifierPrefix)jp.atled.agileworks0 + $(AppIdentifierPrefix)jp.atled.agileworks1 + $(AppIdentifierPrefix)jp.atled.agileworks2 + $(AppIdentifierPrefix)jp.atled.agileworks3 + $(AppIdentifierPrefix)jp.atled.agileworks4 + + + -- GitLab From 1e3e038a5e6ea97c4230967403ff538242ecd2ab Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Fri, 16 Jun 2023 13:24:38 +0900 Subject: [PATCH 12/36] =?UTF-8?q?=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=83=88=E3=81=AE=E7=B7=A8=E9=9B=86=EF=BC=88=E6=9C=AA?= =?UTF-8?q?=E8=A8=AD=E5=AE=9A=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 254 +++++++++++++++++- .../xcschemes/IntentsExtension.xcscheme | 96 +++++++ AgileWorks/AgileWorks/Info.plist | 4 + AgileWorks/IntentsExtension/Info.plist | 27 ++ .../IntentsExtension/IntentHandler.swift | 137 ++++++++++ .../WidgetConfiguration.intentdefinition | 152 +++++++++++ .../WidgetExtension/WidgetExtension.swift | 11 +- 7 files changed, 675 insertions(+), 6 deletions(-) create mode 100644 AgileWorks/AgileWorks.xcodeproj/xcshareddata/xcschemes/IntentsExtension.xcscheme create mode 100644 AgileWorks/IntentsExtension/Info.plist create mode 100644 AgileWorks/IntentsExtension/IntentHandler.swift create mode 100644 AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 1e9166c..b1f8bcc 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -47,6 +47,13 @@ 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 */; }; + 75D4EC652A3C00B00096F9D2 /* Intents.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75D4EC642A3C00B00096F9D2 /* Intents.framework */; }; + 75D4EC682A3C00B00096F9D2 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */; }; + 75D4EC6C2A3C00B00096F9D2 /* IntentsExtension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 75D4EC632A3C00B00096F9D2 /* IntentsExtension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 75D4EC712A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; + 75D4EC722A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; + 75D4EC732A3C12730096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; + 75D4EC742A3C168C0096F9D2 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC672A3C00B00096F9D2 /* IntentHandler.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 */; }; @@ -198,6 +205,13 @@ remoteGlobalIDString = 3127EE09241A2A9500535CC7; remoteInfo = TodayExtension; }; + 75D4EC6A2A3C00B00096F9D2 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = BDA1830723F3FD7F00C9A6DD /* Project object */; + proxyType = 1; + remoteGlobalIDString = 75D4EC622A3C00B00096F9D2; + remoteInfo = IntentsExtension; + }; 75EF9CB727E9E984003178A3 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = BDA1830723F3FD7F00C9A6DD /* Project object */; @@ -221,6 +235,7 @@ dstPath = ""; dstSubfolderSpec = 13; files = ( + 75D4EC6C2A3C00B00096F9D2 /* IntentsExtension.appex in Embed App Extensions */, 7672AD73257EFF500063884A /* ShareExtension.appex in Embed App Extensions */, 3127EE16241A2A9500535CC7 /* TodayExtension.appex in Embed App Extensions */, 75EF9CB927E9E985003178A3 /* WidgetExtension.appex in Embed App Extensions */, @@ -256,6 +271,11 @@ 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 = ""; }; + 75D4EC632A3C00B00096F9D2 /* IntentsExtension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = IntentsExtension.appex; sourceTree = BUILT_PRODUCTS_DIR; }; + 75D4EC642A3C00B00096F9D2 /* Intents.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Intents.framework; path = System/Library/Frameworks/Intents.framework; sourceTree = SDKROOT; }; + 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = ""; }; + 75D4EC692A3C00B00096F9D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = WidgetConfiguration.intentdefinition; 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; }; @@ -392,6 +412,14 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 75D4EC602A3C00B00096F9D2 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 75D4EC652A3C00B00096F9D2 /* Intents.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 75EF9CA927E9E983003178A3 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; @@ -429,6 +457,7 @@ CF516C40B9AA44C977664C98 /* Pods_All_AgileWorks.framework */, 75EF9CAD27E9E983003178A3 /* WidgetKit.framework */, 75EF9CAF27E9E983003178A3 /* SwiftUI.framework */, + 75D4EC642A3C00B00096F9D2 /* Intents.framework */, ); name = Frameworks; sourceTree = ""; @@ -522,6 +551,15 @@ path = View; sourceTree = ""; }; + 75D4EC662A3C00B00096F9D2 /* IntentsExtension */ = { + isa = PBXGroup; + children = ( + 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */, + 75D4EC692A3C00B00096F9D2 /* Info.plist */, + ); + path = IntentsExtension; + sourceTree = ""; + }; 75EF9CB127E9E983003178A3 /* WidgetExtension */ = { isa = PBXGroup; children = ( @@ -530,6 +568,7 @@ 75EF9CB227E9E983003178A3 /* WidgetExtension.swift */, 75EF9CB427E9E984003178A3 /* Assets.xcassets */, 75EF9CB627E9E984003178A3 /* Info.plist */, + 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */, ); path = WidgetExtension; sourceTree = ""; @@ -796,6 +835,7 @@ 3127EE0D241A2A9500535CC7 /* TodayExtension */, 7672AD6A257EFF500063884A /* ShareExtension */, 75EF9CB127E9E983003178A3 /* WidgetExtension */, + 75D4EC662A3C00B00096F9D2 /* IntentsExtension */, BDA1831023F3FD7F00C9A6DD /* Products */, 833C64FFE6F6CB735DE07EB7 /* Pods */, 07A802C56A3436654CD69C43 /* Frameworks */, @@ -809,6 +849,7 @@ 3127EE0A241A2A9500535CC7 /* TodayExtension.appex */, 7672AD69257EFF500063884A /* ShareExtension.appex */, 75EF9CAC27E9E983003178A3 /* WidgetExtension.appex */, + 75D4EC632A3C00B00096F9D2 /* IntentsExtension.appex */, ); name = Products; sourceTree = ""; @@ -1057,6 +1098,23 @@ productReference = 3127EE0A241A2A9500535CC7 /* TodayExtension.appex */; productType = "com.apple.product-type.app-extension"; }; + 75D4EC622A3C00B00096F9D2 /* IntentsExtension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 75D4EC6F2A3C00B00096F9D2 /* Build configuration list for PBXNativeTarget "IntentsExtension" */; + buildPhases = ( + 75D4EC5F2A3C00B00096F9D2 /* Sources */, + 75D4EC602A3C00B00096F9D2 /* Frameworks */, + 75D4EC612A3C00B00096F9D2 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = IntentsExtension; + productName = IntentsExtension; + productReference = 75D4EC632A3C00B00096F9D2 /* IntentsExtension.appex */; + productType = "com.apple.product-type.app-extension"; + }; 75EF9CAB27E9E983003178A3 /* WidgetExtension */ = { isa = PBXNativeTarget; buildConfigurationList = 75EF9CBC27E9E985003178A3 /* Build configuration list for PBXNativeTarget "WidgetExtension" */; @@ -1110,6 +1168,7 @@ 3127EE15241A2A9500535CC7 /* PBXTargetDependency */, 7672AD72257EFF500063884A /* PBXTargetDependency */, 75EF9CB827E9E984003178A3 /* PBXTargetDependency */, + 75D4EC6B2A3C00B00096F9D2 /* PBXTargetDependency */, ); name = AgileWorks; packageProductDependencies = ( @@ -1125,13 +1184,16 @@ BDA1830723F3FD7F00C9A6DD /* Project object */ = { isa = PBXProject; attributes = { - LastSwiftUpdateCheck = 1320; + LastSwiftUpdateCheck = 1410; LastUpgradeCheck = 1140; ORGANIZATIONNAME = "ATLED CORP"; TargetAttributes = { 3127EE09241A2A9500535CC7 = { CreatedOnToolsVersion = 11.3.1; }; + 75D4EC622A3C00B00096F9D2 = { + CreatedOnToolsVersion = 14.1; + }; 75EF9CAB27E9E983003178A3 = { CreatedOnToolsVersion = 13.2.1; }; @@ -1167,6 +1229,7 @@ 3127EE09241A2A9500535CC7 /* TodayExtension */, 7672AD68257EFF500063884A /* ShareExtension */, 75EF9CAB27E9E983003178A3 /* WidgetExtension */, + 75D4EC622A3C00B00096F9D2 /* IntentsExtension */, ); }; /* End PBXProject section */ @@ -1186,6 +1249,13 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 75D4EC612A3C00B00096F9D2 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; 75EF9CAA27E9E983003178A3 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; @@ -1354,6 +1424,15 @@ ); runOnlyForDeploymentPostprocessing = 0; }; + 75D4EC5F2A3C00B00096F9D2 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 75D4EC682A3C00B00096F9D2 /* IntentHandler.swift in Sources */, + 75D4EC732A3C12730096F9D2 /* WidgetConfiguration.intentdefinition in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; 75EF9CA827E9E983003178A3 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; @@ -1362,6 +1441,7 @@ 75EF9CD127E9ED82003178A3 /* XCGLoggerExtensions.swift in Sources */, 75EF9CD027E9ED7B003178A3 /* StringsUtility.swift in Sources */, 75EF9CCF27E9ED6D003178A3 /* ErrorResponse.swift in Sources */, + 75D4EC742A3C168C0096F9D2 /* IntentHandler.swift in Sources */, 75EF9CCE27E9ED5F003178A3 /* Log.swift in Sources */, 75EF9CCD27E9ED53003178A3 /* GetApprovalsEndpoint.swift in Sources */, 75EF9CCC27E9ED3B003178A3 /* ApprovalResponse.swift in Sources */, @@ -1373,6 +1453,7 @@ 75EF9CC727E9ECF9003178A3 /* APIEndpoint.swift in Sources */, 75EF9CC527E9ECEF003178A3 /* SessionInfo.swift in Sources */, 75EF9CC627E9ECEF003178A3 /* Session.swift in Sources */, + 75D4EC722A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition in Sources */, 75EF9CC427E9ECE5003178A3 /* URLAuthenticationUtility.swift in Sources */, 75EF9CC327E9ECDB003178A3 /* KeychainDataStore.swift in Sources */, 75EF9CC227E9ECD2003178A3 /* GetSessionEndpoint.swift in Sources */, @@ -1464,6 +1545,7 @@ BD969631240C9CD400521925 /* SessionInfo.swift in Sources */, BD928CCE2407500400ED04C2 /* UserDefaultsDataStore.swift in Sources */, BD5061B4242866780014F3FA /* Configuration.swift in Sources */, + 75D4EC712A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition in Sources */, 76AE52DD25D35CDC00AFA45A /* LicenseUtility.swift in Sources */, BDAB1F6F240D0D1400EA15FD /* APIEndpoint.swift in Sources */, C50CF79227D8708B0042C210 /* OpenLicenseViewController.swift in Sources */, @@ -1489,6 +1571,11 @@ target = 3127EE09241A2A9500535CC7 /* TodayExtension */; targetProxy = 3127EE14241A2A9500535CC7 /* PBXContainerItemProxy */; }; + 75D4EC6B2A3C00B00096F9D2 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 75D4EC622A3C00B00096F9D2 /* IntentsExtension */; + targetProxy = 75D4EC6A2A3C00B00096F9D2 /* PBXContainerItemProxy */; + }; 75EF9CB827E9E984003178A3 /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = 75EF9CAB27E9E983003178A3 /* WidgetExtension */; @@ -1569,6 +1656,162 @@ }; name = "Release-Production"; }; + 75D4EC6D2A3C00B00096F9D2 /* Release-Production */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + DEVELOPMENT_TEAM = 4TWZNUHVN6; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = IntentsExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = IntentsExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 ATLED CORP. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = jp.atled.agileworks.IntentsExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_COMPILATION_MODE = wholemodule; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = "Release-Production"; + }; + 75D4EC6E2A3C00B00096F9D2 /* Debug-Production */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_IDENTITY = "Apple Development"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = 4TWZNUHVN6; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = IntentsExtension/Info.plist; + INFOPLIST_KEY_CFBundleDisplayName = IntentsExtension; + INFOPLIST_KEY_NSHumanReadableCopyright = "Copyright © 2023 ATLED CORP. All rights reserved."; + IPHONEOS_DEPLOYMENT_TARGET = 14.0; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + "@executable_path/../../Frameworks", + ); + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + PRODUCT_BUNDLE_IDENTIFIER = jp.atled.agileworks.IntentsExtension; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = iphoneos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = "Debug-Production"; + }; 75EF9CBA27E9E985003178A3 /* Release-Production */ = { isa = XCBuildConfiguration; baseConfigurationReference = 75EF9CBF27E9EBB3003178A3 /* Release-Production-Widget.xcconfig */; @@ -2129,6 +2372,15 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = "Release-Production"; }; + 75D4EC6F2A3C00B00096F9D2 /* Build configuration list for PBXNativeTarget "IntentsExtension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 75D4EC6D2A3C00B00096F9D2 /* Release-Production */, + 75D4EC6E2A3C00B00096F9D2 /* Debug-Production */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = "Release-Production"; + }; 75EF9CBC27E9E985003178A3 /* Build configuration list for PBXNativeTarget "WidgetExtension" */ = { isa = XCConfigurationList; buildConfigurations = ( diff --git a/AgileWorks/AgileWorks.xcodeproj/xcshareddata/xcschemes/IntentsExtension.xcscheme b/AgileWorks/AgileWorks.xcodeproj/xcshareddata/xcschemes/IntentsExtension.xcscheme new file mode 100644 index 0000000..d3f03e1 --- /dev/null +++ b/AgileWorks/AgileWorks.xcodeproj/xcshareddata/xcschemes/IntentsExtension.xcscheme @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/AgileWorks/AgileWorks/Info.plist b/AgileWorks/AgileWorks/Info.plist index a511440..395e718 100644 --- a/AgileWorks/AgileWorks/Info.plist +++ b/AgileWorks/AgileWorks/Info.plist @@ -62,6 +62,10 @@ ${PRODUCT_NAME} NSPhotoLibraryUsageDescription ${PRODUCT_NAME} + NSUserActivityTypes + + WidgetConfigurationIntent + UIBackgroundModes remote-notification diff --git a/AgileWorks/IntentsExtension/Info.plist b/AgileWorks/IntentsExtension/Info.plist new file mode 100644 index 0000000..22a1714 --- /dev/null +++ b/AgileWorks/IntentsExtension/Info.plist @@ -0,0 +1,27 @@ + + + + + NSExtension + + NSExtensionAttributes + + IntentsRestrictedWhileLocked + + IntentsRestrictedWhileProtectedDataUnavailable + + IntentsSupported + + INSearchForMessagesIntent + INSendMessageIntent + INSetMessageAttributeIntent + WidgetConfigurationIntent + + + NSExtensionPointIdentifier + com.apple.intents-service + NSExtensionPrincipalClass + $(PRODUCT_MODULE_NAME).IntentHandler + + + diff --git a/AgileWorks/IntentsExtension/IntentHandler.swift b/AgileWorks/IntentsExtension/IntentHandler.swift new file mode 100644 index 0000000..819de9b --- /dev/null +++ b/AgileWorks/IntentsExtension/IntentHandler.swift @@ -0,0 +1,137 @@ +// +// IntentHandler.swift +// IntentsExtension +// +// Created by Azuma Kasumi on 2023/06/16. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import Intents + +// As an example, this class is set up to handle Message intents. +// You will want to replace this or add other intents as appropriate. +// The intents you wish to handle must be declared in the extension's Info.plist. + +// You can test your example integration by saying things to Siri like: +// "Send a message using " +// " John saying hello" +// "Search for messages in " + +class IntentHandler: INExtension, WidgetConfigurationIntentHandling{ + func provideParameterOptionsCollection(for intent: WidgetConfigurationIntent, searchTerm: String?, with completion: @escaping (INObjectCollection?, Error?) -> Void) { + var widgetTypeIdentifiers: [ServerType] = [] + //let serverList = UserDefaultsDataStore().readServerList() + for i in 0..<4 {//serverList.count { + //let serverName = KeychainDataStore().readServerName(serverNumber: serverList[i]) + let item = ServerType(identifier: String(i), display: "type" + String(i))//serverName!) + widgetTypeIdentifiers.append(item) + } + let allWidgetTypeIdentifiers = INObjectCollection(items: widgetTypeIdentifiers) + completion(allWidgetTypeIdentifiers, nil) + } + + + override func handler(for intent: INIntent) -> Any { + // This is the default implementation. If you want different objects to handle different intents, + // you can override this and return the handler you want for that particular intent. + + return self + } + + // MARK: - INSendMessageIntentHandling + + // Implement resolution methods to provide additional information about your intent (optional). + func resolveRecipients(for intent: INSendMessageIntent, with completion: @escaping ([INSendMessageRecipientResolutionResult]) -> Void) { + if let recipients = intent.recipients { + + // If no recipients were provided we'll need to prompt for a value. + if recipients.count == 0 { + completion([INSendMessageRecipientResolutionResult.needsValue()]) + return + } + + var resolutionResults = [INSendMessageRecipientResolutionResult]() + for recipient in recipients { + let matchingContacts = [recipient] // Implement your contact matching logic here to create an array of matching contacts + switch matchingContacts.count { + case 2 ... Int.max: + // We need Siri's help to ask user to pick one from the matches. + resolutionResults += [INSendMessageRecipientResolutionResult.disambiguation(with: matchingContacts)] + + case 1: + // We have exactly one matching contact + resolutionResults += [INSendMessageRecipientResolutionResult.success(with: recipient)] + + case 0: + // We have no contacts matching the description provided + resolutionResults += [INSendMessageRecipientResolutionResult.unsupported()] + + default: + break + + } + } + completion(resolutionResults) + } else { + completion([INSendMessageRecipientResolutionResult.needsValue()]) + } + } + + func resolveContent(for intent: INSendMessageIntent, with completion: @escaping (INStringResolutionResult) -> Void) { + if let text = intent.content, !text.isEmpty { + completion(INStringResolutionResult.success(with: text)) + } else { + completion(INStringResolutionResult.needsValue()) + } + } + + // Once resolution is completed, perform validation on the intent and provide confirmation (optional). + + func confirm(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { + // Verify user is authenticated and your app is ready to send a message. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) + let response = INSendMessageIntentResponse(code: .ready, userActivity: userActivity) + completion(response) + } + + // Handle the completed intent (required). + + func handle(intent: INSendMessageIntent, completion: @escaping (INSendMessageIntentResponse) -> Void) { + // Implement your application logic to send a message here. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSendMessageIntent.self)) + let response = INSendMessageIntentResponse(code: .success, userActivity: userActivity) + completion(response) + } + + // Implement handlers for each intent you wish to handle. As an example for messages, you may wish to also handle searchForMessages and setMessageAttributes. + + // MARK: - INSearchForMessagesIntentHandling + + func handle(intent: INSearchForMessagesIntent, completion: @escaping (INSearchForMessagesIntentResponse) -> Void) { + // Implement your application logic to find a message that matches the information in the intent. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSearchForMessagesIntent.self)) + let response = INSearchForMessagesIntentResponse(code: .success, userActivity: userActivity) + // Initialize with found message's attributes + response.messages = [INMessage( + identifier: "identifier", + content: "I am so excited about SiriKit!", + dateSent: Date(), + sender: INPerson(personHandle: INPersonHandle(value: "sarah@example.com", type: .emailAddress), nameComponents: nil, displayName: "Sarah", image: nil, contactIdentifier: nil, customIdentifier: nil), + recipients: [INPerson(personHandle: INPersonHandle(value: "+1-415-555-5555", type: .phoneNumber), nameComponents: nil, displayName: "John", image: nil, contactIdentifier: nil, customIdentifier: nil)] + )] + completion(response) + } + + // MARK: - INSetMessageAttributeIntentHandling + + func handle(intent: INSetMessageAttributeIntent, completion: @escaping (INSetMessageAttributeIntentResponse) -> Void) { + // Implement your application logic to set the message attribute here. + + let userActivity = NSUserActivity(activityType: NSStringFromClass(INSetMessageAttributeIntent.self)) + let response = INSetMessageAttributeIntentResponse(code: .success, userActivity: userActivity) + completion(response) + } +} diff --git a/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition b/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition new file mode 100644 index 0000000..595709d --- /dev/null +++ b/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition @@ -0,0 +1,152 @@ + + + + + INEnums + + INIntentDefinitionModelVersion + 1.2 + INIntentDefinitionNamespace + APtLEj + INIntentDefinitionSystemVersion + 21G217 + INIntentDefinitionToolsBuildVersion + 14B47b + INIntentDefinitionToolsVersion + 14.1 + INIntents + + + INIntentCategory + information + INIntentDescriptionID + AJiNw5 + INIntentEligibleForWidgets + + INIntentIneligibleForSuggestions + + INIntentLastParameterTag + 2 + INIntentName + WidgetConfiguration + INIntentParameters + + + INIntentParameterConfigurable + + INIntentParameterDisplayName + サーバー名 + INIntentParameterDisplayNameID + dpfWQr + INIntentParameterDisplayPriority + 1 + INIntentParameterName + parameter + INIntentParameterObjectType + ServerType + INIntentParameterObjectTypeNamespace + APtLEj + INIntentParameterSupportsDynamicEnumeration + + INIntentParameterSupportsSearch + + INIntentParameterTag + 2 + INIntentParameterType + Object + + + INIntentResponse + + INIntentResponseCodes + + + INIntentResponseCodeName + success + INIntentResponseCodeSuccess + + + + INIntentResponseCodeName + failure + + + + INIntentTitle + Widget Configuration + INIntentTitleID + 4UDv2R + INIntentType + Custom + INIntentVerb + View + + + INTypes + + + INTypeDisplayName + ServerType + INTypeDisplayNameID + zid8zR + INTypeLastPropertyTag + 101 + INTypeName + ServerType + INTypeProperties + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 1 + INTypePropertyName + identifier + INTypePropertyTag + 1 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 2 + INTypePropertyName + displayString + INTypePropertyTag + 2 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 3 + INTypePropertyName + pronunciationHint + INTypePropertyTag + 3 + INTypePropertyType + String + + + INTypePropertyDefault + + INTypePropertyDisplayPriority + 4 + INTypePropertyName + alternativeSpeakableMatches + INTypePropertySupportsMultipleValues + + INTypePropertyTag + 4 + INTypePropertyType + SpeakableString + + + + + + diff --git a/AgileWorks/WidgetExtension/WidgetExtension.swift b/AgileWorks/WidgetExtension/WidgetExtension.swift index 132712b..fb649c8 100644 --- a/AgileWorks/WidgetExtension/WidgetExtension.swift +++ b/AgileWorks/WidgetExtension/WidgetExtension.swift @@ -9,17 +9,17 @@ import WidgetKit import SwiftUI -struct Provider: TimelineProvider { +struct Provider: IntentTimelineProvider { func placeholder(in context: Context) -> SimpleEntry { SimpleEntry(date: Date(), approvalItems: previewItems(), message: nil) } - func getSnapshot(in context: Context, completion: @escaping (SimpleEntry) -> ()) { + func getSnapshot(for configuration: WidgetConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { let entry = SimpleEntry(date: Date(), approvalItems: previewItems(), message: nil) completion(entry) } - func getTimeline(in context: Context, completion: @escaping (Timeline) -> ()) { + func getTimeline(for configuration: WidgetConfigurationIntent, in context: Context, completion: @escaping (Timeline) -> ()) { var entries: [SimpleEntry] = [] // Generate a timeline consisting of five entries an hour apart, starting from the current date. @@ -53,7 +53,7 @@ struct StatusCheckWidget: Widget { let kind: String = "StatusCheck" var body: some WidgetConfiguration { - StaticConfiguration(kind: kind, provider: Provider()) { entry in + IntentConfiguration(kind: kind, intent: WidgetConfigurationIntent.self, provider: Provider()) { entry in StatusCheckWidgetView(entry: EntryData(approvalItems: entry.approvalItems, message: entry.message, viewController: nil)) } @@ -68,7 +68,7 @@ struct ApprovalWidget: Widget { let kind: String = "Approval" var body: some WidgetConfiguration { - StaticConfiguration(kind: kind, provider: Provider()) { entry in + IntentConfiguration(kind: kind, intent: WidgetConfigurationIntent.self, provider: Provider()) { entry in ApprovalWidgetView(entry: EntryData(approvalItems: entry.approvalItems, message: entry.message, viewController: nil)) } .configurationDisplayName(getDisplayString(key: "ApprovalWidgetName", comment: "")) @@ -93,3 +93,4 @@ struct WidgetExtension_Previews: PreviewProvider { .previewContext(WidgetPreviewContext(family: .systemSmall)) } } + -- GitLab From d82015804a9bc8e55fff3ff0e824516d3773860c Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 27 Jun 2023 10:52:43 +0900 Subject: [PATCH 13/36] =?UTF-8?q?IntenstExtesion=E3=81=AE=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0=20=E3=83=AD=E3=82=B0=E3=82=A4=E3=83=B3=E9=87=8D?= =?UTF-8?q?=E8=A4=87=E7=A2=BA=E8=AA=8D=20=E3=83=87=E3=83=90=E3=82=A4?= =?UTF-8?q?=E3=82=B9=E7=99=BB=E9=8C=B2API=E3=82=B5=E3=83=BC=E3=83=90?= =?UTF-8?q?=E3=83=BC=E6=8C=87=E5=AE=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 61 ++++++++- AgileWorks/AgileWorks/App/AppDelegate.swift | 45 +++++-- .../AgileWorks/App/RootViewController.swift | 29 +++- .../Common/Service/DeviceService.swift | 6 +- .../Login/View/LoginViewController.swift | 52 ++++--- .../Strings/Chinese-Simplified.strings | 1 + .../Strings/Chinese-Traditional.strings | 1 + AgileWorks/AgileWorks/Strings/English.strings | 1 + .../AgileWorks/Strings/Japanese.strings | 1 + .../Strings/en.lproj/Localizable.strings | 1 + .../Strings/ja.lproj/Localizable.strings | 1 + .../Strings/zh-Hans.lproj/Localizable.strings | 1 + .../Strings/zh-Hant.lproj/Localizable.strings | 1 + .../WebView/View/WebViewController.swift | 1 + .../Common/DataStore/KeychainDataStore.swift | 73 +++++++--- .../DataStore/UserDefaultsDataStore.swift | 4 + AgileWorks/Common/OAuthService.swift | 5 +- .../WebClient/DeleteDeviceEndpoint.swift | 22 +-- AgileWorks/Common/WidgetView.swift | 127 ++++++++++++------ .../Debug-Production-Intents.xcconfig | 13 ++ .../Flavor/Production-Intents.xcconfig | 17 +++ .../Release-Production-Intents.xcconfig | 13 ++ AgileWorks/IntentsExtension/Info.plist | 9 ++ .../IntentsExtension/IntentHandler.swift | 8 +- ...entsExtensionDebug-Production.entitlements | 18 +++ ...tsExtensionRelease-Production.entitlements | 18 +++ .../View/TodayViewController.swift | 7 +- .../WidgetConfiguration.intentdefinition | 2 +- .../WidgetExtension/WidgetExtension.swift | 58 ++++++-- 29 files changed, 466 insertions(+), 130 deletions(-) create mode 100644 AgileWorks/Configurations/Debug-Production-Intents.xcconfig create mode 100644 AgileWorks/Configurations/Flavor/Production-Intents.xcconfig create mode 100644 AgileWorks/Configurations/Release-Production-Intents.xcconfig create mode 100644 AgileWorks/IntentsExtension/IntentsExtensionDebug-Production.entitlements create mode 100644 AgileWorks/IntentsExtension/IntentsExtensionRelease-Production.entitlements diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index b1f8bcc..ce4ac23 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -54,6 +54,15 @@ 75D4EC722A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; 75D4EC732A3C12730096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; 75D4EC742A3C168C0096F9D2 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */; }; + 75D4EC782A3C29830096F9D2 /* UserDefaultsDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD928CCD2407500400ED04C2 /* UserDefaultsDataStore.swift */; }; + 75D4EC802A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */; }; + 75D4EC812A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 75D4EC872A3C32F10096F9D2 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD5061B3242866780014F3FA /* Configuration.swift */; }; + 75D4EC882A3C33310096F9D2 /* KeychainDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDEA2CD4246CDAEF00D3E15F /* KeychainDataStore.swift */; }; + 75D4EC892A3C33490096F9D2 /* UserDefaultsExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDAB1F6C240D0D0000EA15FD /* UserDefaultsExtensions.swift */; }; + 75D4EC8A2A3C33720096F9D2 /* XCGLoggerExtensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD8D55D82420609000A667B0 /* XCGLoggerExtensions.swift */; }; + 75D4EC8B2A3C33E70096F9D2 /* Log.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDA74C5524501917000D4351 /* Log.swift */; }; + 75D4EC8C2A413E300096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; 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 */; }; @@ -243,6 +252,17 @@ name = "Embed App Extensions"; runOnlyForDeploymentPostprocessing = 0; }; + 75D4EC822A3C2CAD0096F9D2 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 75D4EC812A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ @@ -276,6 +296,13 @@ 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IntentHandler.swift; sourceTree = ""; }; 75D4EC692A3C00B00096F9D2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */ = {isa = PBXFileReference; lastKnownFileType = file.intentdefinition; path = WidgetConfiguration.intentdefinition; sourceTree = ""; }; + 75D4EC772A3C295F0096F9D2 /* IntentsExtensionDebug-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "IntentsExtensionDebug-Production.entitlements"; sourceTree = ""; }; + 75D4EC792A3C29CB0096F9D2 /* IntentsExtensionRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "IntentsExtensionRelease-Production.entitlements"; sourceTree = ""; }; + 75D4EC7B2A3C2C760096F9D2 /* AppAuth.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = AppAuth.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Pods_All_AgileWorks.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 75D4EC832A3C2EE40096F9D2 /* Production-Intents.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Production-Intents.xcconfig"; sourceTree = ""; }; + 75D4EC852A3C308D0096F9D2 /* Debug-Production-Intents.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Debug-Production-Intents.xcconfig"; sourceTree = ""; }; + 75D4EC862A3C30B90096F9D2 /* Release-Production-Intents.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = "Release-Production-Intents.xcconfig"; 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; }; @@ -416,6 +443,7 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 75D4EC802A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Frameworks */, 75D4EC652A3C00B00096F9D2 /* Intents.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -451,6 +479,8 @@ 07A802C56A3436654CD69C43 /* Frameworks */ = { isa = PBXGroup; children = ( + 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */, + 75D4EC7B2A3C2C760096F9D2 /* AppAuth.framework */, BDA74C5824502255000D4351 /* AppAuth.framework */, BDEB7D8F23F530A400EFAF31 /* KeychainAccess.framework */, 3127EE0B241A2A9500535CC7 /* NotificationCenter.framework */, @@ -554,6 +584,8 @@ 75D4EC662A3C00B00096F9D2 /* IntentsExtension */ = { isa = PBXGroup; children = ( + 75D4EC792A3C29CB0096F9D2 /* IntentsExtensionRelease-Production.entitlements */, + 75D4EC772A3C295F0096F9D2 /* IntentsExtensionDebug-Production.entitlements */, 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */, 75D4EC692A3C00B00096F9D2 /* Info.plist */, ); @@ -741,6 +773,8 @@ 764D0E00257F603400AB6617 /* Release-Production-Share.xcconfig */, 75EF9CBE27E9EB93003178A3 /* Debug-Production-Widget.xcconfig */, 75EF9CBF27E9EBB3003178A3 /* Release-Production-Widget.xcconfig */, + 75D4EC852A3C308D0096F9D2 /* Debug-Production-Intents.xcconfig */, + 75D4EC862A3C30B90096F9D2 /* Release-Production-Intents.xcconfig */, ); path = Configurations; sourceTree = ""; @@ -753,6 +787,7 @@ BD5061A1242845750014F3FA /* Production-Today.xcconfig */, 764D0DF7257F589D00AB6617 /* Production-Share.xcconfig */, 75EF9CBD27E9EB6E003178A3 /* Production-Widget.xcconfig */, + 75D4EC832A3C2EE40096F9D2 /* Production-Intents.xcconfig */, ); path = Flavor; sourceTree = ""; @@ -1105,6 +1140,7 @@ 75D4EC5F2A3C00B00096F9D2 /* Sources */, 75D4EC602A3C00B00096F9D2 /* Frameworks */, 75D4EC612A3C00B00096F9D2 /* Resources */, + 75D4EC822A3C2CAD0096F9D2 /* Embed Frameworks */, ); buildRules = ( ); @@ -1415,6 +1451,7 @@ BDBBF83D243CAB3300EEB25D /* GetApprovalsEndpoint.swift in Sources */, BDBBF840243CAB6200EEB25D /* UserDefaultsExtensions.swift in Sources */, BDA74C5724501917000D4351 /* Log.swift in Sources */, + 75D4EC8C2A413E300096F9D2 /* WidgetConfiguration.intentdefinition in Sources */, BD7DC0F324C061EA00C3FBED /* ErrorResponse.swift in Sources */, 3127EE0F241A2A9500535CC7 /* TodayViewController.swift in Sources */, 75917FB427C371390051E201 /* StringsUtility.swift in Sources */, @@ -1429,7 +1466,13 @@ buildActionMask = 2147483647; files = ( 75D4EC682A3C00B00096F9D2 /* IntentHandler.swift in Sources */, + 75D4EC882A3C33310096F9D2 /* KeychainDataStore.swift in Sources */, + 75D4EC892A3C33490096F9D2 /* UserDefaultsExtensions.swift in Sources */, 75D4EC732A3C12730096F9D2 /* WidgetConfiguration.intentdefinition in Sources */, + 75D4EC8A2A3C33720096F9D2 /* XCGLoggerExtensions.swift in Sources */, + 75D4EC872A3C32F10096F9D2 /* Configuration.swift in Sources */, + 75D4EC8B2A3C33E70096F9D2 /* Log.swift in Sources */, + 75D4EC782A3C29830096F9D2 /* UserDefaultsDataStore.swift in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1658,6 +1701,7 @@ }; 75D4EC6D2A3C00B00096F9D2 /* Release-Production */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 75D4EC862A3C30B90096F9D2 /* Release-Production-Intents.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -1688,13 +1732,15 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = "IntentsExtension/IntentsExtensionRelease-Production.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; DEVELOPMENT_TEAM = 4TWZNUHVN6; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4TWZNUHVN6; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1715,11 +1761,13 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.0.0; MTL_ENABLE_DEBUG_INFO = NO; MTL_FAST_MATH = YES; PRODUCT_BUNDLE_IDENTIFIER = jp.atled.agileworks.IntentsExtension; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "AgileWorks App Wildcard"; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_COMPILATION_MODE = wholemodule; @@ -1733,6 +1781,7 @@ }; 75D4EC6E2A3C00B00096F9D2 /* Debug-Production */ = { isa = XCBuildConfiguration; + baseConfigurationReference = 75D4EC852A3C308D0096F9D2 /* Debug-Production-Intents.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -1763,13 +1812,15 @@ CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + CODE_SIGN_ENTITLEMENTS = "IntentsExtension/IntentsExtensionDebug-Production.entitlements"; CODE_SIGN_IDENTITY = "Apple Development"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; - CODE_SIGN_STYLE = Automatic; + CODE_SIGN_STYLE = Manual; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1; DEBUG_INFORMATION_FORMAT = dwarf; DEVELOPMENT_TEAM = 4TWZNUHVN6; + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 4TWZNUHVN6; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; GCC_C_LANGUAGE_STANDARD = gnu11; @@ -1796,12 +1847,14 @@ "@executable_path/Frameworks", "@executable_path/../../Frameworks", ); - MARKETING_VERSION = 1.0; + MARKETING_VERSION = 1.0.0; MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; MTL_FAST_MATH = YES; ONLY_ACTIVE_ARCH = YES; PRODUCT_BUNDLE_IDENTIFIER = jp.atled.agileworks.IntentsExtension; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = "AgileWorks App Wildcard"; SDKROOT = iphoneos; SKIP_INSTALL = YES; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; diff --git a/AgileWorks/AgileWorks/App/AppDelegate.swift b/AgileWorks/AgileWorks/App/AppDelegate.swift index 70723b2..468a5ca 100644 --- a/AgileWorks/AgileWorks/App/AppDelegate.swift +++ b/AgileWorks/AgileWorks/App/AppDelegate.swift @@ -63,6 +63,24 @@ class AppDelegate: UIResponder, UIApplicationDelegate { OIDURLSessionProvider.setSession(Session.shared) } + private func getTapLink(url: URL) -> String? { + var strUrl = url.absoluteString + if let index = strUrl.firstIndex(of: "?") { + strUrl = String(strUrl.prefix(upTo: index)) + return strUrl + } + return nil + } + + private func getTapServer(url: URL) -> Int? { + var strUrl = url.absoluteString + var serverNumber: Int? + if strUrl.contains("serverNumber") { + serverNumber = (Int(String(strUrl.last!))) ?? nil + } + return serverNumber + } + // MARK: DeepLinks @available(iOS 9.0, *) func application(_ application: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any]) @@ -75,18 +93,26 @@ class AppDelegate: UIResponder, UIApplicationDelegate { //タップされたサーバーに切り替える let serverList = UserDefaultsDataStore().readServerList() if !serverList.isEmpty { - let tapServer = UserDefaultsDataStore().readTapServer() - UserDefaultsDataStore().changeServerList(firstServer: tapServer!) - UserDefaultsDataStore().setGroupId(serverNumber: tapServer!) - } + var tapServer: Int? + if #available(iOS 14.0, *) { + tapServer = getTapServer(url: url) + } else { + tapServer = UserDefaultsDataStore().readTapServer() + } + if let serverNumber = tapServer { + UserDefaultsDataStore().changeServerList(firstServer: serverNumber) + UserDefaultsDataStore().setGroupId(serverNumber: serverNumber) + Thread.sleep(forTimeInterval: 1) + } + } //ios13の場合 + var resultURL = url if url.scheme == urlSchemeName { var strUrl = url.absoluteString //指定した書類状態の取得、アプリ起動のみの場合は飛ばす if strUrl.contains("/") { - let result: URL var scheme = urlScheme // 不要な"/"を取り除く let delIdx = scheme.index(scheme.endIndex, offsetBy: -1) @@ -94,11 +120,14 @@ class AppDelegate: UIResponder, UIApplicationDelegate { //scheme以降の取得 strUrl = strUrl.replacingOccurrences(of: scheme, with: "") //遷移URLの取得 - result = getStatusURL(status: strUrl) - return Linker.handleDeeplink(url: result) + resultURL = getStatusURL(status: strUrl) + } + }else { //iOS14~ + if let url = getTapLink(url: url) { + resultURL = URL(string: url)! } } - return Linker.handleDeeplink(url: url) + return Linker.handleDeeplink(url: resultURL) } func getStatusURL(status: String) -> URL { diff --git a/AgileWorks/AgileWorks/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index ace6f96..bf268dc 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -64,18 +64,15 @@ extension RootViewController { case .failure(let error): log.e(error) } - KeychainDataStore().removeOAuthState() - KeychainDataStore().removeAccessToken() - KeychainDataStore().removeSessionID() - KeychainDataStore().removeServerName() - KeychainDataStore().removeLanguage() - KeychainDataStore().removeDeviceID() + var serverList = UserDefaultsDataStore().readServerList() + let removeServer = serverList.first + self.deleteServerInfo(serverNumber: removeServer) if serverRemove { UserDefaultsDataStore().removeServer() } - let serverList = UserDefaultsDataStore().readServerList() + serverList = UserDefaultsDataStore().readServerList() if serverList.isEmpty { DispatchQueue.main.async { self.switchToLogout() @@ -100,6 +97,24 @@ extension RootViewController { return defaultAction } + func deleteServerInfo(serverNumber: Int?) { + DeviceService().deleteDevice(serverNumber: serverNumber) { result in + switch result { + case .success: + break + case .failure(let error): + log.e(error) + } + KeychainDataStore().removeOAuthState(serverNumber: serverNumber) + KeychainDataStore().removeAccessToken(serverNumber: serverNumber) + KeychainDataStore().removeDeviceID(serverNumber: serverNumber) + KeychainDataStore().removeSessionID(serverNumber: serverNumber) + } + //認証情報削除 + KeychainDataStore().removeServerName() + KeychainDataStore().removeLanguage() + } + // アラート表示 func showAlertScreen(view: UIViewController, title: String, message: String, defaultAction: UIAlertAction?, cancelAction: UIAlertAction?) { let alertController = UIAlertController(title: title, message: message, preferredStyle: .alert) diff --git a/AgileWorks/AgileWorks/Common/Service/DeviceService.swift b/AgileWorks/AgileWorks/Common/Service/DeviceService.swift index 98efebb..d2ee712 100644 --- a/AgileWorks/AgileWorks/Common/Service/DeviceService.swift +++ b/AgileWorks/AgileWorks/Common/Service/DeviceService.swift @@ -65,15 +65,15 @@ public class DeviceService { } } - func deleteDevice(completion: @escaping (APIResult) -> Void) { + func deleteDevice(serverNumber: Int? = nil, completion: @escaping (APIResult) -> Void) { let request = DeviceRequest(deleteFlag: true) - let deleteDevice = DeleteDeviceEndpoint(request: request) + let deleteDevice = DeleteDeviceEndpoint(request: request, serverNumber: serverNumber) Session.send(deleteDevice) { result in let completionArg: APIResult switch result { case .success: - KeychainDataStore().removeDeviceID() + KeychainDataStore().removeDeviceID(serverNumber: serverNumber) completionArg = .success(true) case .failure(let error): log.e(error) diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 58e6da2..7ea78a9 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -67,23 +67,17 @@ class LoginViewController: UIViewController { } //サーバー追加画面の場合は認証情報を削除しない if !addServerloginFlg { - //ログイン画面が表示されると通知を取得しない - self.devcie { result in - switch result { - case .success: - break - case .failure(let error): - log.e(error) - } + let serverList = UserDefaultsDataStore().readServerList() + + //キーチェーン情報削除 + for serverNumber in serverList { + UserDefaultsDataStore().setGroupId(serverNumber: serverNumber) + //ログイン画面が表示されると通知を取得しない + AppDelegate.shared.rootViewController.deleteServerInfo(serverNumber: serverNumber) } - //認証情報削除 - KeychainDataStore().removeOAuthState() - KeychainDataStore().removeAccessToken() - KeychainDataStore().removeSessionID() - KeychainDataStore().removeServerName() - KeychainDataStore().removeLanguage() - KeychainDataStore().removeDeviceID() + //サーバーリストの削除 + UserDefaultsDataStore().removeAllServer() //ウィジェットの更新 if #available(iOS 14.0, *) { @@ -184,6 +178,26 @@ class LoginViewController: UIViewController { guard let serverHost = serverHost else { return } guard let context = context else { return } + //サーバーの重複チェック + let serverList = UserDefaultsDataStore().readServerList() + var serverCheckFlg = false + for serverNumber in serverList { + let serverName = KeychainDataStore().readServerName(serverNumber: serverNumber)! + if serverName == serverHost { + serverCheckFlg = true + let alert = UIAlertController(title: "", message: getLocalizableStrings(key: "LoginServerAlert", comment: ""), preferredStyle: .alert) + let ok = UIAlertAction(title: "OK", style: .default) { (action) in + return + } + alert.addAction(ok) + present(alert, animated: true, completion: nil) + } + } + + if serverCheckFlg { + return + } + disableLogin() //サーバー切り替え @@ -239,6 +253,10 @@ class LoginViewController: UIViewController { UserDefaultsDataStore().addServerList() let serverList = UserDefaultsDataStore().readServerList() UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + //ウィジェットの更新 + if #available(iOS 14.0, *) { + WidgetCenter.shared.reloadAllTimelines() + } //メイン画面表示 AppDelegate.shared.rootViewController.switchToMainScreen() if let nc = self.parent as? UINavigationController { @@ -353,8 +371,8 @@ class LoginViewController: UIViewController { present(alertController, animated: true, completion: nil) } - private func devcie(completion: @escaping (APIResult) -> Void) { - DeviceService().deleteDevice { result in + private func devcie(serverNumber: Int, completion: @escaping (APIResult) -> Void) { + DeviceService().deleteDevice(serverNumber: serverNumber) { result in switch result { case .success: completion(.success(true)) diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index dca6489..f522d3b 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "取消"; "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings index 6cc1879..32cafea 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "取消"; "LoginErrorMessage" = "登錄失敗。請重新登錄。"; "CameraStartupErrorMessage" = "未能激活攝像機。"; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index 66bb9ee..91107a4 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "cancel"; "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/Japanese.strings b/AgileWorks/AgileWorks/Strings/Japanese.strings index ff87ef0..5219e3c 100644 --- a/AgileWorks/AgileWorks/Strings/Japanese.strings +++ b/AgileWorks/AgileWorks/Strings/Japanese.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "キャンセル"; "LoginErrorMessage" = "ログインに失敗しました。再度ログインしてください。"; "CameraStartupErrorMessage" = "カメラの起動に失敗しました。"; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index 55a7d34..c2874e3 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "cancel"; "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings index 4f6fbc8..2d54811 100644 --- a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "キャンセル"; "LoginErrorMessage" = "ログインに失敗しました。再度ログインしてください。"; "CameraStartupErrorMessage" = "カメラの起動に失敗しました。"; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 9495f6d..55c49a3 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "取消"; "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings index e01613e..a818da8 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings @@ -24,6 +24,7 @@ "ClientCertificateRemovalCancel" = "取消"; "LoginErrorMessage" = "登錄失敗。請重新登錄。"; "CameraStartupErrorMessage" = "未能激活攝像機。"; +"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 92720eb..008af00 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -106,6 +106,7 @@ class WebViewController: UIViewController { // WebView セットアップ private func setWebView() { + print(KeychainDataStore().readServerURL()) let userContentController = WKUserContentController() let script = "document.cookie='JSESSIONID=\(KeychainDataStore().readSessionID() ?? "")'" let cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false) diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index b3e7a6c..cd7b89e 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -27,12 +27,18 @@ final class KeychainDataStore: DataStoreProtocol { } // アクセストークンの読み込み - func readAccessToken() -> String? { + func readAccessToken(serverNumber: Int? = nil) -> String? { + if let serverNumber = serverNumber { + return getKeychainValue(key: kAccessToken, serverNumber: serverNumber) + } return getKeychainValue(key: kAccessToken) } // アクセストークンの削除 - func removeAccessToken() { + func removeAccessToken(serverNumber: Int? = nil) { + if let serverNumber = serverNumber { + removeKeychainValue(key: kAccessToken, serverNumber: serverNumber) + } removeKeychainValue(key: kAccessToken) } @@ -58,7 +64,10 @@ final class KeychainDataStore: DataStoreProtocol { } // 認可ステータスの削除 - func removeOAuthState() { + func removeOAuthState(serverNumber: Int? = nil) { + if let serverNumber = serverNumber { + removeKeychainValue(key: kOAuthState, serverNumber: serverNumber) + } removeKeychainValue(key: kOAuthState) } @@ -98,7 +107,10 @@ final class KeychainDataStore: DataStoreProtocol { } // コンテキストパスの読み込み - func readContextPath() -> String? { + func readContextPath(serverNumber: Int? = nil) -> String? { + if let serverNumber = serverNumber { + return getKeychainValue(key: kContextPath, serverNumber: serverNumber) + } return getKeychainValue(key: kContextPath) } @@ -113,8 +125,15 @@ final class KeychainDataStore: DataStoreProtocol { } // デバイスIDの読み込み - func readDeviceID() -> Int? { - guard let deviceIDString = getKeychainValue(key: kDeviceID) else { + func readDeviceID(serverNumber: Int? = nil) -> Int? { + var deviceIDString: String? + if let serverNumber = serverNumber { + deviceIDString = getKeychainValue(key: kDeviceID, serverNumber: serverNumber) + } else { + deviceIDString = getKeychainValue(key: kDeviceID) + } + + guard let deviceIDString = deviceIDString else { return nil } guard let deviceID = Int(deviceIDString) else { @@ -124,7 +143,10 @@ final class KeychainDataStore: DataStoreProtocol { } // デバイスIDの削除 - func removeDeviceID() { + func removeDeviceID(serverNumber: Int? = nil) { + if let serverNumber = serverNumber { + removeKeychainValue(key: kDeviceID, serverNumber: serverNumber) + } removeKeychainValue(key: kDeviceID) } @@ -139,8 +161,11 @@ final class KeychainDataStore: DataStoreProtocol { } // セッションIDの削除 - func removeSessionID() { - removeKeychainValue(key: kSessionID) + func removeSessionID(serverNumber: Int? = nil) { + if let serverNumber = serverNumber { + return removeKeychainValue(key: kSessionID, serverNumber: serverNumber) + } + return removeKeychainValue(key: kSessionID) } // サーバー識別名の書き込み @@ -149,13 +174,11 @@ final class KeychainDataStore: DataStoreProtocol { } // サーバー識別名の読み込み - 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 readServerName(serverNumber: Int? = nil) -> String? { + if let serverNumber = serverNumber { + return getKeychainValue(key: kServerURL, serverNumber: serverNumber) + } + return getKeychainValue(key: kServerURL) } // サーバー識別名の削除 @@ -168,11 +191,21 @@ final class KeychainDataStore: DataStoreProtocol { let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) keychain[key] = value } + private func setKeychainValue(key: String, value: String, serverNumber: Int) { + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readBaseGroupId() + String(serverNumber)) + keychain[key] = value + } + // KeyChain から指定の値を取得 private func getKeychainValue(key: String) -> String? { let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) return keychain[key] } + private func getKeychainValue(key: String, serverNumber: Int) -> String? { + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readBaseGroupId() + String(serverNumber)) + return keychain[key] + } + // KeyChain から指定の値を削除 private func removeKeychainValue(key: String) { let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) @@ -182,4 +215,12 @@ final class KeychainDataStore: DataStoreProtocol { log.e(error) } } + private func removeKeychainValue(key: String, serverNumber: Int) { + let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readBaseGroupId() + String(serverNumber)) + do { + try keychain.remove(key) + } catch { + log.e(error) + } + } } diff --git a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift index 31c9173..aaa5091 100644 --- a/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift +++ b/AgileWorks/Common/DataStore/UserDefaultsDataStore.swift @@ -81,6 +81,10 @@ final class UserDefaultsDataStore: DataStoreProtocol { writeServerList(list: serverList) } } + + func removeAllServer() { + writeServerList(list: []) + } //サーバー接続先を保存できる識別番号を探す func serchEmptyServerData() -> Int? { diff --git a/AgileWorks/Common/OAuthService.swift b/AgileWorks/Common/OAuthService.swift index 0786799..1a62912 100644 --- a/AgileWorks/Common/OAuthService.swift +++ b/AgileWorks/Common/OAuthService.swift @@ -53,10 +53,7 @@ public class OAuthService: NSObject { } KeychainDataStore().writeAccessToken(accessToken: accessToken) - //ウィジェットの更新 - if #available(iOS 14.0, *) { - WidgetCenter.shared.reloadAllTimelines() - } + completion(.success(())) } else { self.setAuthState(nil) diff --git a/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift b/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift index 3dae7ca..d6433cc 100644 --- a/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift +++ b/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift @@ -12,21 +12,16 @@ struct DeleteDeviceEndpoint: APIEndpoint { typealias Response = DeviceResponse let method: HttpMethod = .POST - let path = "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/MobileAppApi/Device" + + let path: String var requestBody: Data? - var headerFields: [String: String]? { - return ["Authorization": "Bearer \(KeychainDataStore().readAccessToken() ?? "")", - "X-ATLED-AW-Device-Id": KeychainDataStore().readDeviceID()?.description ?? "", - "Content-Type": "application/json"] - } + var headerFields: [String: String]? - var pathParameters: [String]? { - return [KeychainDataStore().readDeviceID()?.description ?? ""] - } + var pathParameters: [String]? - init(request: DeviceRequest) { + init(request: DeviceRequest, serverNumber: Int?) { let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase @@ -35,6 +30,13 @@ struct DeleteDeviceEndpoint: APIEndpoint { } catch { log.e(error.localizedDescription) } + self.path = "/" + (KeychainDataStore().readContextPath(serverNumber: serverNumber) ?? "") + "/Broker/MobileAppApi/Device" + + self.headerFields = ["Authorization": "Bearer \(KeychainDataStore().readAccessToken(serverNumber: serverNumber) ?? "")", + "X-ATLED-AW-Device-Id": KeychainDataStore().readDeviceID(serverNumber: serverNumber)?.description ?? "", + "Content-Type": "application/json"] + + self.pathParameters = [KeychainDataStore().readDeviceID(serverNumber: serverNumber)?.description ?? ""] } } diff --git a/AgileWorks/Common/WidgetView.swift b/AgileWorks/Common/WidgetView.swift index 3bca8f6..90517e9 100644 --- a/AgileWorks/Common/WidgetView.swift +++ b/AgileWorks/Common/WidgetView.swift @@ -39,6 +39,7 @@ func previewItems() -> [ApprovalItem] { } struct EntryData { + var serverNumber: Int? var approvalItems: [ApprovalItem] var message: String? var viewController: UIViewController? @@ -82,8 +83,11 @@ struct StatusCheckWidgetView: View { StatusBoxView(entry: entry) } else { //ログイン・コネクションエラー if #available(iOS 14.0, *) { - FailureWidgetView(entry: entry) - }else { + let url = getWorkURL(serverNumber: entry.serverNumber) + Link(destination: URL(string: url)!, label: { + FailureWidgetView(entry: entry) + }) + } else { FailureWidgetView(entry: entry) .onTapGesture { if entry.viewController != nil { @@ -108,23 +112,35 @@ struct ApprovalWidgetView: View { return nil } + func errorEntry() -> EntryData { + var errorEntry = entry + errorEntry.message = "-" + return errorEntry + } + var body: some View { //API取得成功 if entry.message == nil { if let num = findApproval() { //「承認依頼」項目あり if #available(iOS 14.0, *) { - ApprovalItemView(approvalItem: entry.approvalItems[num], message: entry.message) - .widgetURL(URL(string: Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#docList_" + "RequestApproval")) + let url = getURL(approvalItem: entry.approvalItems[num], serverNumber: entry.serverNumber) + ApprovalItemView(itemNum: num, entry: entry) + .widgetURL(URL(string: url)) } } else { //「承認依頼」項目なし - ApprovalItemView(approvalItem: ApprovalItem(code: "", name: "", count: 0), message: "-") + ApprovalItemView(itemNum: 0, entry: errorEntry()) } } else { //APIサーバーエラー if entry.message == "-" { - ApprovalItemView(approvalItem: ApprovalItem(code: "", name: "", count: 0), message: "-") + ApprovalItemView(itemNum: 0, entry: errorEntry()) } else {//ログイン・コネクションエラー - FailureWidgetView(entry: entry) + if #available(iOS 14.0, *) { + let url = getWorkURL(serverNumber: entry.serverNumber) + Link(destination: URL(string: url)!, label: { + FailureWidgetView(entry: entry) + }) + } } } } @@ -180,8 +196,8 @@ struct StatusBoxView: View { var body: some View { VStack (spacing: 0) { if #available(iOS 14.0, *) { - if !serverList.isEmpty { - Text(KeychainDataStore().readServerName(serverNumber: serverList[0])!) + if let serverNumber = entry.serverNumber { + Text(KeychainDataStore().readServerName(serverNumber: serverNumber)!) } } GeometryReader { geometry in @@ -223,11 +239,11 @@ struct RowView: View { var body: some View { HStack(spacing: 10) { //BOX左側 - LinkView(approvalItem: entry.approvalItems[itemNum], message: entry.message, viewController: entry.viewController) + LinkView(itemNum: itemNum, entry: entry) .frame(width: boxSize.width, height: boxSize.height) //BOX右側 if !oneBox { - LinkView(approvalItem: entry.approvalItems[itemNum + 1], message: entry.message, viewController: entry.viewController) + LinkView(itemNum: itemNum + 1, entry: entry) .frame(width: boxSize.width, height: boxSize.height) } else { HStack { @@ -241,22 +257,17 @@ struct RowView: View { //ウィジェットからアプリへ遷移するためのリンクview struct LinkView: View { - let approvalItem: ApprovalItem - let message: String? - let viewController: UIViewController? + let itemNum: Int + let entry: EntryData - //遷移先URLの取得(iOS14以降) - func getURL() -> String { - if let status = getStatus(code: approvalItem.code) { - return Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#docList_" + status - } else { - return Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#work" - } + func getApprovalItem() -> ApprovalItem { + return entry.approvalItems[itemNum] } //遷移先URLはアプリ側で設定するためURL末尾のステータスのみ設定(iOS13) func getStatusURL() -> String { //スキーム+ステータスで設定 + let approvalItem = getApprovalItem() if let status = getStatus(code: approvalItem.code) { return urlScheme + status } @@ -265,33 +276,33 @@ struct LinkView: View { var body: some View { if #available(iOS 14.0, *) { - Link(destination: URL(string: getURL())!, label: { - ApprovalItemView(approvalItem: approvalItem, message: message, serverNameFlag: false) + let url = getURL(approvalItem: getApprovalItem(), serverNumber: entry.serverNumber) + Link(destination: URL(string: url)!, label: { + ApprovalItemView(itemNum: itemNum, entry: entry, serverNameFlag: false) }) } else { - ApprovalItemView(approvalItem: approvalItem, message: message) - .onTapGesture { - if viewController != nil { - viewController!.extensionContext?.open(NSURL(fileURLWithPath: getStatusURL())as URL, completionHandler: nil) - } - } + ApprovalItemView(itemNum: itemNum, entry: entry) } } } //書類状況の内容を表示するビュー struct ApprovalItemView: View { - let approvalItem: ApprovalItem - let message: String? + let itemNum: Int + let entry: EntryData let serverList = UserDefaultsDataStore().readServerList() var serverNameFlag = true + + func getApprovalItem() -> ApprovalItem { + return entry.approvalItems[itemNum] + } var body: some View { VStack (spacing: 0) { if #available(iOS 14.0, *) { if serverNameFlag { - if !serverList.isEmpty { - Text(KeychainDataStore().readServerName(serverNumber: serverList[0])!) + if let serverNumber = entry.serverNumber { + Text(KeychainDataStore().readServerName(serverNumber: serverNumber)!) } } } @@ -300,17 +311,17 @@ struct ApprovalItemView: View { Image(systemName: "folder") .frame(width: geometry.size.width * 0.3, height: geometry.size.height) .foregroundColor(Color.textColor) - if message == nil { + if entry.message == nil { VStack(alignment: .leading) { - Text(approvalItem.name) + Text(getApprovalItem().name) .frame(alignment: .leading) .foregroundColor(Color.textColor) - Text("\(approvalItem.count)").font(.subheadline) + Text("\(getApprovalItem().count)").font(.subheadline) .frame(alignment: .leading) .foregroundColor(Color.textColor) } } else { //APIサーバーエラーの場合の表示 - Text(message ?? "-") + Text(entry.message ?? "-") } } Spacer() @@ -323,13 +334,42 @@ struct ApprovalItemView: View { //エラー文言を表示するビュー struct FailureWidgetView: View { - var entry: EntryData + let entry: EntryData + let serverList = UserDefaultsDataStore().readServerList() var body: some View { - Text(entry.message ?? "") - .foregroundColor(Color.textColor) + if !serverList.isEmpty { + if let serverNumber = entry.serverNumber { + Text(KeychainDataStore().readServerName(serverNumber: serverNumber)!) + } + } + Text(entry.message ?? "") + .frame(maxWidth: .infinity, maxHeight: .infinity) + .foregroundColor(Color.textColor) + } +} + +func getWorkURL(serverNumber: Int?) -> String { + var url = Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#work" + if let serverNumber = serverNumber { + url += "?serverNumber=" + String(serverNumber) + } + return url +} + +//遷移先URLの取得(iOS14以降) +func getURL(approvalItem: ApprovalItem, serverNumber: Int?) -> String { + if let status = getStatus(code: approvalItem.code) { + var url = Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#docList_" + status + if let serverNumber = serverNumber { + return url + "?serverNumber=" + String(serverNumber) + } + return url + } else { + return getWorkURL(serverNumber: serverNumber) } } + func checkApprovalItems(approvalItems: [ApprovalItem]) -> [ApprovalItem] { var result = [ApprovalItem]() for item in approvalItems { @@ -355,7 +395,14 @@ func fetch(completion: @escaping (WidgetAPIResult let approvalsEndpoint = GetApprovalsEndpoint() + while UserDefaultsDataStore().readUpdateWidgetFlg() ?? false { + //別のウィジェットが更新中の場合は待つ + } + UserDefaultsDataStore().writeUpdateWidgetFlg(update: true) + Session.send(approvalsEndpoint) { result in + UserDefaultsDataStore().writeUpdateWidgetFlg(update: false) + switch result { case .success(let response): if !response.items.isEmpty { diff --git a/AgileWorks/Configurations/Debug-Production-Intents.xcconfig b/AgileWorks/Configurations/Debug-Production-Intents.xcconfig new file mode 100644 index 0000000..26d7762 --- /dev/null +++ b/AgileWorks/Configurations/Debug-Production-Intents.xcconfig @@ -0,0 +1,13 @@ +// +// Debug-Production-Intents.xcconfig +// AgileWorks +// +// Created by Azuma Kasumi on 2023/06/16. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 +#include "../Pods/Target Support Files/Pods-All-AgileWorks/Pods-All-AgileWorks.debug-production.xcconfig" +#include "Build/Debug.xcconfig" +#include "Flavor/Production-Intents.xcconfig" diff --git a/AgileWorks/Configurations/Flavor/Production-Intents.xcconfig b/AgileWorks/Configurations/Flavor/Production-Intents.xcconfig new file mode 100644 index 0000000..61a9968 --- /dev/null +++ b/AgileWorks/Configurations/Flavor/Production-Intents.xcconfig @@ -0,0 +1,17 @@ +// +// Production-Intents.xcconfig +// AgileWorks +// +// Created by Azuma Kasumi on 2023/06/16. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 +#include "Base-Production.xcconfig" + +DISPLAY_NAME = AgileWorks + +PRODUCT_BUNDLE_IDENTIFIER = $(AGILE_WORKS_SHARE_BUNDLE_IDENTIFIER).IntentsExtension + +CODE_SIGN_ENTITLEMENTS = IntentsExtension/IntentsExtension.entitlements diff --git a/AgileWorks/Configurations/Release-Production-Intents.xcconfig b/AgileWorks/Configurations/Release-Production-Intents.xcconfig new file mode 100644 index 0000000..22583ba --- /dev/null +++ b/AgileWorks/Configurations/Release-Production-Intents.xcconfig @@ -0,0 +1,13 @@ +// +// Release-Production-Intents.xcconfig +// AgileWorks +// +// Created by Azuma Kasumi on 2023/06/16. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 +#include "../Pods/Target Support Files/Pods-All-AgileWorks/Pods-All-AgileWorks.release-production.xcconfig" +#include "Build/Release.xcconfig" +#include "Flavor/Production-Intents.xcconfig" diff --git a/AgileWorks/IntentsExtension/Info.plist b/AgileWorks/IntentsExtension/Info.plist index 22a1714..5b98bb3 100644 --- a/AgileWorks/IntentsExtension/Info.plist +++ b/AgileWorks/IntentsExtension/Info.plist @@ -2,6 +2,15 @@ + AppConfig + + AGILE_WORKS_SHARE_BUNDLE_IDENTIFIER + $(AGILE_WORKS_SHARE_BUNDLE_IDENTIFIER) + OAUTH_CLIENTID + $(OAUTH_CLIENTID) + + AppIdentifierPrefix + $(AppIdentifierPrefix) NSExtension NSExtensionAttributes diff --git a/AgileWorks/IntentsExtension/IntentHandler.swift b/AgileWorks/IntentsExtension/IntentHandler.swift index 819de9b..5fbafd8 100644 --- a/AgileWorks/IntentsExtension/IntentHandler.swift +++ b/AgileWorks/IntentsExtension/IntentHandler.swift @@ -20,10 +20,10 @@ import Intents class IntentHandler: INExtension, WidgetConfigurationIntentHandling{ func provideParameterOptionsCollection(for intent: WidgetConfigurationIntent, searchTerm: String?, with completion: @escaping (INObjectCollection?, Error?) -> Void) { var widgetTypeIdentifiers: [ServerType] = [] - //let serverList = UserDefaultsDataStore().readServerList() - for i in 0..<4 {//serverList.count { - //let serverName = KeychainDataStore().readServerName(serverNumber: serverList[i]) - let item = ServerType(identifier: String(i), display: "type" + String(i))//serverName!) + let serverList = UserDefaultsDataStore().readServerList() + for i in 0.. + + + + com.apple.security.application-groups + + group.jp.atled.agileworks + + keychain-access-groups + + $(AppIdentifierPrefix)jp.atled.agileworks0 + $(AppIdentifierPrefix)jp.atled.agileworks1 + $(AppIdentifierPrefix)jp.atled.agileworks2 + $(AppIdentifierPrefix)jp.atled.agileworks3 + $(AppIdentifierPrefix)jp.atled.agileworks4 + + + diff --git a/AgileWorks/IntentsExtension/IntentsExtensionRelease-Production.entitlements b/AgileWorks/IntentsExtension/IntentsExtensionRelease-Production.entitlements new file mode 100644 index 0000000..df7a8b6 --- /dev/null +++ b/AgileWorks/IntentsExtension/IntentsExtensionRelease-Production.entitlements @@ -0,0 +1,18 @@ + + + + + com.apple.security.application-groups + + group.jp.atled.agileworks + + keychain-access-groups + + $(AppIdentifierPrefix)jp.atled.agileworks0 + $(AppIdentifierPrefix)jp.atled.agileworks1 + $(AppIdentifierPrefix)jp.atled.agileworks2 + $(AppIdentifierPrefix)jp.atled.agileworks3 + $(AppIdentifierPrefix)jp.atled.agileworks4 + + + diff --git a/AgileWorks/TodayExtension/View/TodayViewController.swift b/AgileWorks/TodayExtension/View/TodayViewController.swift index e912c5c..fd075a2 100644 --- a/AgileWorks/TodayExtension/View/TodayViewController.swift +++ b/AgileWorks/TodayExtension/View/TodayViewController.swift @@ -28,7 +28,7 @@ class TodayViewController: UIViewController, NCWidgetProviding { let serverList = UserDefaultsDataStore().readServerList() var entrys: [EntryData] = [] var entry: EntryData = EntryData(approvalItems: previewItems(), message: getDisplayString(key: "NotLogedin", comment: ""), viewController: self) - + if serverList.isEmpty { entrys.append(entry) } @@ -38,7 +38,7 @@ class TodayViewController: UIViewController, NCWidgetProviding { UserDefaultsDataStore().setGroupId(serverNumber: server) entry = resultEntry() entrys.append(entry) - + } UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) @@ -55,7 +55,8 @@ class TodayViewController: UIViewController, NCWidgetProviding { switch result { case .success(let response): self.approvalItems = checkApprovalItems(approvalItems: response.items) - entry = EntryData(approvalItems: self.approvalItems, message: nil, viewController: self) + + entry = EntryData(approvalItems: self.approvalItems, viewController: self) case .nodate(let message): entry = EntryData(approvalItems: [ApprovalItem](), message: message, viewController: self) case .failure(let message): diff --git a/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition b/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition index 595709d..459916a 100644 --- a/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition +++ b/AgileWorks/WidgetExtension/WidgetConfiguration.intentdefinition @@ -90,7 +90,7 @@ INTypeDisplayNameID zid8zR INTypeLastPropertyTag - 101 + 103 INTypeName ServerType INTypeProperties diff --git a/AgileWorks/WidgetExtension/WidgetExtension.swift b/AgileWorks/WidgetExtension/WidgetExtension.swift index fb649c8..7f9b269 100644 --- a/AgileWorks/WidgetExtension/WidgetExtension.swift +++ b/AgileWorks/WidgetExtension/WidgetExtension.swift @@ -11,11 +11,13 @@ import SwiftUI struct Provider: IntentTimelineProvider { func placeholder(in context: Context) -> SimpleEntry { - SimpleEntry(date: Date(), approvalItems: previewItems(), message: nil) + let entryData = EntryData(approvalItems: previewItems()) + return SimpleEntry(date: Date(), entryData: entryData) } func getSnapshot(for configuration: WidgetConfigurationIntent, in context: Context, completion: @escaping (SimpleEntry) -> ()) { - let entry = SimpleEntry(date: Date(), approvalItems: previewItems(), message: nil) + let entryData = EntryData(approvalItems: previewItems()) + let entry = SimpleEntry(date: Date(), entryData: entryData) completion(entry) } @@ -23,29 +25,60 @@ struct Provider: IntentTimelineProvider { var entries: [SimpleEntry] = [] // Generate a timeline consisting of five entries an hour apart, starting from the current date. - let entryDate = Calendar.current.date(byAdding: .minute, value: 15, to: Date()) ?? Date() - + let updateTime = Calendar.current.date(byAdding: .minute, value: 15, to: Date()) ?? Date() + let serverNumber = getServerNumber(configuration: configuration) + if serverNumber != nil { + UserDefaultsDataStore().setGroupId(serverNumber: serverNumber!) + } + fetch { result in DispatchQueue.main.async { switch result { case .success(let response): - entries.append(SimpleEntry(date: entryDate, approvalItems: checkApprovalItems(approvalItems: response.items), message: nil)) + let approvalItems = checkApprovalItems(approvalItems: response.items) + let entryData = EntryData(serverNumber: getServerNumber(configuration: configuration), approvalItems: approvalItems) + entries.append(SimpleEntry(date: updateTime, entryData: entryData)) case .nodate(let message): - entries.append(SimpleEntry(date: entryDate, approvalItems: [ApprovalItem](), message: message)) + let entryData = EntryData(serverNumber: getServerNumber(configuration: configuration), approvalItems: [ApprovalItem](), message: message) + entries.append(SimpleEntry(date: updateTime, entryData: entryData)) case .failure(let message): - entries.append(SimpleEntry(date: entryDate, approvalItems: previewItems(), message: message)) + let entryData = EntryData(serverNumber: getServerNumber(configuration: configuration), approvalItems: previewItems(), message: message) + entries.append(SimpleEntry(date: updateTime, entryData: entryData)) } - let timeline = Timeline(entries: entries, policy: .after(entryDate)) + let timeline = Timeline(entries: entries, policy: .after(updateTime)) completion(timeline) } } + let serverList = UserDefaultsDataStore().readServerList() + if !serverList.isEmpty { + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + } + } + + func getServerNumber(configuration: WidgetConfigurationIntent) -> Int? { + var serverNumber: Int? + + let serverList = UserDefaultsDataStore().readServerList() + if serverList.isEmpty { + return nil + } + // ウィジェット構成 + if configuration.parameter == nil { + serverNumber = serverList.first! + } else { + serverNumber = Int((configuration.parameter?.identifier!)!)! + //ウィジェットの構成が古い(ログアウトされたサーバーが選択されている)場合 + if !serverList.contains(serverNumber!) { + serverNumber = serverList.first! + } + } + return serverNumber } } struct SimpleEntry: TimelineEntry { let date: Date - var approvalItems: [ApprovalItem] - var message: String? + var entryData: EntryData } //状況確認ウィジェット @@ -54,8 +87,7 @@ struct StatusCheckWidget: Widget { var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: WidgetConfigurationIntent.self, provider: Provider()) { entry in - - StatusCheckWidgetView(entry: EntryData(approvalItems: entry.approvalItems, message: entry.message, viewController: nil)) + StatusCheckWidgetView(entry: entry.entryData) } .configurationDisplayName(getDisplayString(key: "StatusCheckWidgetName", comment: "")) .description(getDisplayString(key: "StatusCheckWidgetDescription", comment: "")) @@ -69,7 +101,7 @@ struct ApprovalWidget: Widget { var body: some WidgetConfiguration { IntentConfiguration(kind: kind, intent: WidgetConfigurationIntent.self, provider: Provider()) { entry in - ApprovalWidgetView(entry: EntryData(approvalItems: entry.approvalItems, message: entry.message, viewController: nil)) + ApprovalWidgetView(entry: entry.entryData) } .configurationDisplayName(getDisplayString(key: "ApprovalWidgetName", comment: "")) .description(getDisplayString(key: "ApprovalWidgetDescription", comment: "")) -- GitLab From 4be0992fbeb2d152bedff6c939802c125dbb105c Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Thu, 29 Jun 2023 17:10:51 +0900 Subject: [PATCH 14/36] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E3=82=B5=E3=83=BC?= =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=A2=E3=83=A9=E3=83=BC=E3=83=88=EF=BC=88?= =?UTF-8?q?=E5=8B=95=E4=BD=9C=E6=9C=AA=E7=A2=BA=E8=AA=8D=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Main/View/MainTabBarViewController.swift | 19 ++++++- .../Wireframe/MainTabBarViewWireframe.swift | 49 ++++++++++++++----- .../WebView/View/WebViewController.swift | 35 +++++++++++-- 3 files changed, 87 insertions(+), 16 deletions(-) diff --git a/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift b/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift index a9a9227..47b8549 100644 --- a/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift +++ b/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift @@ -105,6 +105,13 @@ class MainTabBarViewController: UITabBarController { } } +//通知モーダルが閉じられたのを検知 +extension MainTabBarViewController: UIAdaptivePresentationControllerDelegate { + func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { + wireframe.reloadWebview() + } +} + extension MainTabBarViewController: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { if let navigationController = tabBarController.selectedViewController as? UINavigationController { @@ -135,8 +142,16 @@ extension MainTabBarViewController: UITabBarControllerDelegate { } } webView.loadViewIfNeeded() - webView.reloadWebView(sameTab: selectedTabIndex == tabBarController.selectedIndex) - selectedTabIndex = tabBarController.selectedIndex + + let serverList = UserDefaultsDataStore().readServerList() + let serverNumber = serverList.first + if webView.displayedServerNumber != serverNumber { + webView.loadURL = wireframe.createLoadUrl(urlPath: ViewURL.home.rawValue) + webView.remakeWebView(url: webView.loadURL) + } else { + webView.reloadWebView(sameTab: selectedTabIndex == tabBarController.selectedIndex) + selectedTabIndex = tabBarController.selectedIndex + } } } } diff --git a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift index 1ee5b97..90d16a8 100644 --- a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift +++ b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift @@ -11,6 +11,8 @@ import UIKit protocol MainTabBarViewWireframe: AnyObject { func showApprovalDetail(url: String) func showDocForm(notificationData: NotificationData) + func reloadWebview() + func createLoadUrl(urlPath: String) -> String } class MainTabBarViewWireframeImpl { @@ -32,6 +34,21 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { } return false } + + func openViewController(tabNumber: Int) -> WebViewController { + // モーダルでViewが表示されているか。 + if let presentNavi = self.viewController.presentedViewController as? UINavigationController { + // 表示されている場合、閉じる + presentNavi.dismiss(animated: true, completion: nil) + } + + viewController.selectedIndex = tabNumber + + let view = viewController.children[tabNumber] as! UINavigationController + let VC = view.viewControllers[view.viewControllers.count - 1] as! WebViewController + return VC + } + //ウィジェットからの起動 func showApprovalDetail(url: String) { //アプリ起動のみ @@ -42,23 +59,15 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { if alertCheck() { return } - // モーダルでViewが表示されているか。 - if let presentNavi = self.viewController.presentedViewController as? UINavigationController { - // 表示されている場合、閉じる - presentNavi.dismiss(animated: true, completion: nil) - } - let workNum = 1 - viewController.selectedIndex = workNum - - let view = viewController.children[workNum] as! UINavigationController - let workVC = view.viewControllers[view.viewControllers.count - 1] as! WebViewController + let workTabNumber = 1 + let workVC = openViewController(tabNumber: workTabNumber) //ウィジェットから起動する workVC.openByWidget = true //viewの読み込み workVC.loadViewIfNeeded() - workVC.widgetLoadWebView(url: url) + workVC.remakeWebView(url: url) } // 通知から書類表示 func showDocForm(notificationData: NotificationData) { @@ -73,6 +82,8 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { modalWebVC.showNotification = true let nav = UINavigationController(rootViewController: modalWebVC) nav.modalPresentationStyle = .fullScreen + nav.presentationController?.delegate = viewController as? any UIAdaptivePresentationControllerDelegate + // 既にモーダルでViewが表示されているか。 if let presentNavi = self.viewController.presentedViewController as? UINavigationController { // されている場合、開き直しの確認 @@ -100,4 +111,20 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { // アラート表示 AppDelegate.shared.rootViewController.showAlertScreen(view: oldNavi, title: "", message: message, defaultAction: defaultAction, cancelAction: cancelAction) } + + func reloadWebview() { + let homeNumber = 0 + let homeVC = openViewController(tabNumber: homeNumber) + + //viewの読み込み + homeVC.loadViewIfNeeded() + homeVC.loadURL = createLoadUrl(urlPath: ViewURL.home.rawValue) + homeVC.remakeWebView(url: homeVC.loadURL) + } + + // WebView でロードするURL生成 + func createLoadUrl(urlPath: String) -> String { + return Configuration.shared.awURL + "/" + Configuration.shared.awContextPath + urlPath + } + } diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 008af00..12601ce 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -38,6 +38,8 @@ class WebViewController: UIViewController { var tabTitleKey: String! // 現在表示中のURL var nowURL: String! + //表示中のサーバー + var displayedServerNumber: Int = 0 // 描画完了フラグ var drawingComp = false @@ -106,7 +108,9 @@ class WebViewController: UIViewController { // WebView セットアップ private func setWebView() { - print(KeychainDataStore().readServerURL()) + let serverList = UserDefaultsDataStore().readServerList() + displayedServerNumber = serverList.first! + let userContentController = WKUserContentController() let script = "document.cookie='JSESSIONID=\(KeychainDataStore().readSessionID() ?? "")'" let cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false) @@ -177,7 +181,7 @@ class WebViewController: UIViewController { } // WidgetからWebView ロード処理 - func widgetLoadWebView(url: String) { + func remakeWebView(url: String) { //webviewの生成 self.setWebView() loadWebView(url: url) @@ -362,11 +366,36 @@ class WebViewController: UIViewController { @IBAction private func closeTapped() { if subViewStack.pop() == nil { if self.showNotification { - self.dismiss(animated: true, completion: nil) + //ログイン中のサーバーと表示中の書類サーバーの差異チェック + let serverList = UserDefaultsDataStore().readServerList() + let documentServer = serverList.first + if displayedServerNumber != documentServer { + showServerSwichAlert() + } else { + self.dismiss(animated: true, completion: nil) + } } } } + //サーバー切り替え確認アラート + func showServerSwichAlert() { + let message = "現在別のサーバーでログイン中です。表示中の書類のサーバーに切り替えますか?" + // OK アクション設定 + let defaultAction = UIAlertAction(title: getDisplayString(key: "YES", comment: ""), style: .default) { _ in + let documentServer = UserDefaultsDataStore().readSetServerNumber() + UserDefaultsDataStore().changeServerList(firstServer: documentServer) + self.dismiss(animated: true, completion: nil) + } + // キャンセルアクション設定 + let cancelAction = UIAlertAction(title: getDisplayString(key: "NO", comment: ""), style: .cancel) { _ in + UserDefaultsDataStore().setGroupId(serverNumber: self.displayedServerNumber) + self.dismiss(animated: true, completion: nil) + } + // アラート表示 + AppDelegate.shared.rootViewController.showAlertScreen(view:self, title: "", message: message, defaultAction: defaultAction, cancelAction: cancelAction) + } + // 接続確認ボタンタップ処理 @IBAction private func checkConnectTapped() { // 2重タップ防止 -- GitLab From aa5cbb4ef3631edc3960d4cae730e4c93fc585ed Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 3 Jul 2023 17:23:21 +0900 Subject: [PATCH 15/36] =?UTF-8?q?=E5=8B=95=E4=BD=9C=E7=A2=BA=E8=AA=8D?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3=E7=89=88=EF=BC=88=E9=80=9A=E7=9F=A5=E6=9B=B8?= =?UTF-8?q?=E9=A1=9E=E9=96=89=E3=81=98=E3=81=9F=E5=BE=8C=E3=81=AE=E5=86=8D?= =?UTF-8?q?=E8=AA=AD=E3=81=BF=E8=BE=BC=E3=81=BF=E3=81=8C=E3=81=BE=E3=81=A0?= =?UTF-8?q?=EF=BC=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Wireframe/MainTabBarViewWireframe.swift | 30 +++++++++++++++--- .../Splash/View/SplashViewController.swift | 5 +++ .../WebView/View/WebViewController.swift | 31 +++++++++++++------ 3 files changed, 53 insertions(+), 13 deletions(-) diff --git a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift index 90d16a8..407ada0 100644 --- a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift +++ b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift @@ -16,9 +16,9 @@ protocol MainTabBarViewWireframe: AnyObject { } class MainTabBarViewWireframeImpl { - weak var viewController: UITabBarController! + weak var viewController: MainTabBarViewController! - required init(viewController: UITabBarController) { + required init(viewController: MainTabBarViewController) { self.viewController = viewController } } @@ -75,15 +75,21 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { if alertCheck() { return } + + if notificationData.url.isEmpty { + return + } + let modalWebVC = WebViewBuilderImpl().buildVC() // URL , タイトル設定 modalWebVC.loadURL = notificationData.url modalWebVC.navigationItem.title = notificationData.title modalWebVC.showNotification = true + modalWebVC.displayedServerNumber = getDocumentServerNumber(url: URL(string: notificationData.url)) let nav = UINavigationController(rootViewController: modalWebVC) nav.modalPresentationStyle = .fullScreen - nav.presentationController?.delegate = viewController as? any UIAdaptivePresentationControllerDelegate - + nav.presentationController?.delegate = viewController + print(nav.presentationController?.delegate) // 既にモーダルでViewが表示されているか。 if let presentNavi = self.viewController.presentedViewController as? UINavigationController { // されている場合、開き直しの確認 @@ -94,6 +100,22 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { } } + func getDocumentServerNumber(url: URL?) -> Int? { + guard let _ = url else { + return nil + } + let serverList = UserDefaultsDataStore().readServerList() + for serverNumber in serverList { + UserDefaultsDataStore().setGroupId(serverNumber: serverNumber) + let serverURL = KeychainDataStore().readServerURL() + if serverURL == url?.host { + return serverNumber + } + } + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + return nil + } + // 書類上書き確認アラート表示 func showOverrideAlter(oldNavi: UINavigationController, newNavi: UINavigationController) { // 開き直し確認 diff --git a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift index fea0064..efa76c5 100644 --- a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift +++ b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift @@ -47,6 +47,11 @@ class SplashViewController: UIViewController { private func makeServiceCall() { activityIndicator.startAnimating() + let serverList = UserDefaultsDataStore().readServerList() + if !serverList.isEmpty { + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + } + guard KeychainDataStore().readOAuthState() != nil else { self.switchToLogoutOrLicenseView() return diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 12601ce..6ac6f6a 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -39,7 +39,7 @@ class WebViewController: UIViewController { // 現在表示中のURL var nowURL: String! //表示中のサーバー - var displayedServerNumber: Int = 0 + var displayedServerNumber: Int? = nil // 描画完了フラグ var drawingComp = false @@ -108,9 +108,11 @@ class WebViewController: UIViewController { // WebView セットアップ private func setWebView() { - let serverList = UserDefaultsDataStore().readServerList() - displayedServerNumber = serverList.first! - + //表示中のサーバー番号 + if displayedServerNumber == nil { + let serverList = UserDefaultsDataStore().readServerList() + displayedServerNumber = serverList.first + } let userContentController = WKUserContentController() let script = "document.cookie='JSESSIONID=\(KeychainDataStore().readSessionID() ?? "")'" let cookieScript = WKUserScript(source: script, injectionTime: .atDocumentStart, forMainFrameOnly: false) @@ -368,8 +370,8 @@ class WebViewController: UIViewController { if self.showNotification { //ログイン中のサーバーと表示中の書類サーバーの差異チェック let serverList = UserDefaultsDataStore().readServerList() - let documentServer = serverList.first - if displayedServerNumber != documentServer { + let firstServerNumver = serverList.first + if displayedServerNumber != firstServerNumver { showServerSwichAlert() } else { self.dismiss(animated: true, completion: nil) @@ -383,13 +385,14 @@ class WebViewController: UIViewController { let message = "現在別のサーバーでログイン中です。表示中の書類のサーバーに切り替えますか?" // OK アクション設定 let defaultAction = UIAlertAction(title: getDisplayString(key: "YES", comment: ""), style: .default) { _ in - let documentServer = UserDefaultsDataStore().readSetServerNumber() - UserDefaultsDataStore().changeServerList(firstServer: documentServer) + UserDefaultsDataStore().changeServerList(firstServer: self.displayedServerNumber!) self.dismiss(animated: true, completion: nil) } // キャンセルアクション設定 let cancelAction = UIAlertAction(title: getDisplayString(key: "NO", comment: ""), style: .cancel) { _ in - UserDefaultsDataStore().setGroupId(serverNumber: self.displayedServerNumber) + let serverList = UserDefaultsDataStore().readServerList() + let firstServerNumver = serverList.first + UserDefaultsDataStore().setGroupId(serverNumber: firstServerNumver!) self.dismiss(animated: true, completion: nil) } // アラート表示 @@ -745,3 +748,13 @@ extension WebViewController: UIScrollViewDelegate { scrollView.pinchGestureRecognizer?.isEnabled = false } } + +extension WebViewController { + override func dismiss(animated flag: Bool, completion: (() -> Void)? = nil) { + super.dismiss(animated: flag, completion: completion) + guard let presentationController = presentationController else { + return + } + presentationController.delegate?.presentationControllerDidDismiss?(presentationController) + } +} -- GitLab From dea1b96c49868d95161038ec3d29e225c1a09075 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 3 Jul 2023 17:24:27 +0900 Subject: [PATCH 16/36] =?UTF-8?q?=E3=82=B3=E3=83=9F=E3=83=83=E3=83=88?= =?UTF-8?q?=E5=BF=98=E3=82=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks/Main/View/MainTabBarViewController.swift | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift b/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift index 47b8549..7d85471 100644 --- a/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift +++ b/AgileWorks/AgileWorks/Main/View/MainTabBarViewController.swift @@ -8,7 +8,7 @@ import UIKit -class MainTabBarViewController: UITabBarController { +class MainTabBarViewController: UITabBarController , UIAdaptivePresentationControllerDelegate { private var wireframe: MainTabBarViewWireframe! var screenPath: String? { @@ -103,14 +103,19 @@ class MainTabBarViewController: UITabBarController { } } } + func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { + wireframe.reloadWebview() + } } +/* //通知モーダルが閉じられたのを検知 extension MainTabBarViewController: UIAdaptivePresentationControllerDelegate { func presentationControllerDidDismiss(_ presentationController: UIPresentationController) { wireframe.reloadWebview() } } + */ extension MainTabBarViewController: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { -- GitLab From 1cb36ee385e95d25ee3d67bc611c30629fd7281c Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 4 Jul 2023 12:39:33 +0900 Subject: [PATCH 17/36] =?UTF-8?q?=E3=82=AF=E3=83=A9=E3=82=A4=E3=82=A2?= =?UTF-8?q?=E3=83=B3=E3=83=88=E8=A8=BC=E6=98=8E=E6=9B=B8=20=E6=9B=B8?= =?UTF-8?q?=E3=81=8D=E8=BE=BC=E3=81=BF/=E8=AA=AD=E3=81=BF=E8=BE=BC?= =?UTF-8?q?=E3=81=BF/=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/App/AppDelegate.swift | 2 +- .../Common/Service/DeviceService.swift | 2 +- .../Login/View/LoginViewController.swift | 4 +- .../WebView/View/WebViewController.swift | 2 +- .../DataStore/CertificateDataStore.swift | 79 ++++++++++++++++--- .../Common/DataStore/KeychainDataStore.swift | 15 ++++ .../Utility/URLAuthenticationUtility.swift | 5 +- AgileWorks/Common/WebClient/Session.swift | 16 ++-- .../View/ShareViewController.swift | 2 +- 9 files changed, 104 insertions(+), 23 deletions(-) diff --git a/AgileWorks/AgileWorks/App/AppDelegate.swift b/AgileWorks/AgileWorks/App/AppDelegate.swift index 468a5ca..90cefab 100644 --- a/AgileWorks/AgileWorks/App/AppDelegate.swift +++ b/AgileWorks/AgileWorks/App/AppDelegate.swift @@ -60,7 +60,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate { } private func setupAppAuth() { - OIDURLSessionProvider.setSession(Session.shared) + OIDURLSessionProvider.setSession(Session.shared(serverNumber: nil)) } private func getTapLink(url: URL) -> String? { diff --git a/AgileWorks/AgileWorks/Common/Service/DeviceService.swift b/AgileWorks/AgileWorks/Common/Service/DeviceService.swift index d2ee712..fda7423 100644 --- a/AgileWorks/AgileWorks/Common/Service/DeviceService.swift +++ b/AgileWorks/AgileWorks/Common/Service/DeviceService.swift @@ -69,7 +69,7 @@ public class DeviceService { let request = DeviceRequest(deleteFlag: true) let deleteDevice = DeleteDeviceEndpoint(request: request, serverNumber: serverNumber) - Session.send(deleteDevice) { result in + Session.send(serverNumber: serverNumber, deleteDevice) { result in let completionArg: APIResult switch result { case .success: diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 7ea78a9..99ffad2 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -85,7 +85,7 @@ class LoginViewController: UIViewController { } } - clientCertificateSettingView.isHidden = (CertificateDataStore().readClientCertificate() == nil) + clientCertificateSettingView.isHidden = (CertificateDataStore().readClientCertificate(label: nil) == nil) //固定文言表示 setupFixedWording() @@ -362,7 +362,7 @@ class LoginViewController: UIViewController { @IBAction private func clientCertificateRemovalTapped(_ sender: Any) { let alertController = UIAlertController(title: "", message: getLocalizableStrings(key: "ClientCertificateRemovalConfirmation", comment: ""), preferredStyle: .alert) let okAction = UIAlertAction(title: getLocalizableStrings(key: "ClientCertificateRemovalOK", comment: ""), style: .default) { _ in - CertificateDataStore().removeClientCertificate() + CertificateDataStore().removeClientCertificate(label: "") self.clientCertificateSettingView.isHidden = true } let cancelAction = UIAlertAction(title: getLocalizableStrings(key: "ClientCertificateRemovalCancel", comment: ""), style: .cancel, handler: nil) diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 008af00..6fdb282 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -603,7 +603,7 @@ extension WebViewController: WKNavigationDelegate { private func download(url: URL, saveAs fileName: String) { var request = downloadRequest(url: url) var tempPath: URL = FileManager.default.temporaryDirectory.appendingPathComponent(fileName) - Session.shared.dataTask(with: request) { data, res, err in + Session.shared(serverNumber: nil).dataTask(with: request) { data, res, err in guard let data = data, err == nil else { log.e(err) return diff --git a/AgileWorks/Common/DataStore/CertificateDataStore.swift b/AgileWorks/Common/DataStore/CertificateDataStore.swift index 45f08c4..8bf677c 100644 --- a/AgileWorks/Common/DataStore/CertificateDataStore.swift +++ b/AgileWorks/Common/DataStore/CertificateDataStore.swift @@ -17,27 +17,34 @@ let kClientCertLabel = "ClientCert" /// その実装に用いている `Keychain` は `kSecIdentity` の読み書きに対応していないため別途定義。 class CertificateDataStore { /// クライアント証明書を読み込む。取得できなければ `nil` 。 - func readClientCertificate() -> SecIdentity? { - return readIdentity(label: kClientCertLabel) + func readClientCertificate(label: String?) -> SecIdentity? { + guard let label else { + return nil + } + return readIdentity(label: label) + } + func readAllClientCertificate() -> [NSDictionary]? { + return readAllIdentity() } /// クライアント証明書を利用した `URLCredential` (セッション内で有効) を取得する。取得できなければ `nil`。 - func getClientCertificateSessionCredential() -> URLCredential? { - if let identity = readClientCertificate() { + func getClientCertificateSessionCredential(label: String?) -> URLCredential? { + if let identity = readClientCertificate(label: label) { return sessionCredential(identity: identity) } else { return nil } } - /// クライアント証明書を書き込む。 - func writeClientCertificate(identity: SecIdentity) { - writeIdentity(label: kClientCertLabel, identity: identity) + //証明書の書き込み + func writeNewClientCertificate(identity: SecIdentity) { + var newLabel = kClientCertLabel + serchLabelID() + writeIdentity(label: newLabel, identity: identity) } /// クライアント証明書を削除する。 - func removeClientCertificate() { - removeIdentity(label: kClientCertLabel) + func removeClientCertificate(label: String) { + removeIdentity(label: label) } private func readIdentity(label: String) -> SecIdentity? { @@ -69,6 +76,36 @@ class CertificateDataStore { } } + //証明書リスト呼び出し + private func readAllIdentity() -> [NSDictionary]? { + let query: [String: Any] = [ + kSecClass as String: kSecClassIdentity, + //kSecAttrLabel as String: label, + kSecReturnRef as String: true, + kSecReturnPersistentRef as String: true, + kSecMatchLimit as String: kSecMatchLimitAll + ] + var result: CFTypeRef? = nil + let status = SecItemCopyMatching(query as CFDictionary, &result) + switch status { + case errSecSuccess: + if let result = result { + let array = (result as? NSArray) as? [NSDictionary] + return array + } else { + log.error("unexpected nil result") + return nil + } + + case errSecItemNotFound: + return nil + + default: + log.error("keychain reading error: OSStatus = \(status)") + return nil + } + } + private func writeIdentity(label: String, identity: SecIdentity) { let query: [String: Any] = [ kSecValueRef as String: identity, @@ -80,6 +117,29 @@ class CertificateDataStore { } } + private func serchLabelID() -> String { + var labelID = 0 + var flg = true + while flg { + let label = kClientCertLabel + String(labelID) + let query: [String: Any] = [ + kSecClass as String: kSecClassIdentity, + kSecAttrLabel as String: label, + kSecReturnRef as String: true, + kSecReturnPersistentRef as String: true + ] + var result: CFTypeRef? = nil + let status = SecItemCopyMatching(query as CFDictionary, &result) + switch status { + case errSecItemNotFound: + flg = false + default: + labelID += 1 + } + } + return String(labelID) + } + private func removeIdentity(label: String) { let query: [String: Any] = [ kSecClass as String: kSecClassIdentity, @@ -95,3 +155,4 @@ class CertificateDataStore { return URLCredential(identity: identity, certificates: nil, persistence: .forSession) } } + diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index cd7b89e..ae48cb1 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -20,6 +20,7 @@ final class KeychainDataStore: DataStoreProtocol { private let kDeviceID: String = "DeviceID" private let kSessionID: String = "SessionID" private let kServerName: String = "ServerName" + private let kCertificateLabel: String = "CertificateLabel" // アクセストークンの書き込み func writeAccessToken(accessToken: String) { @@ -186,6 +187,20 @@ final class KeychainDataStore: DataStoreProtocol { removeKeychainValue(key: kServerName) } + func writeCertificateLabel(label: String) { + setKeychainValue(key: kCertificateLabel, value: label) + } + + func readCertificateLabel(serverNumber: Int?) -> String? { + if let serverNumber = serverNumber { + return getKeychainValue(key: kCertificateLabel, serverNumber: serverNumber) + } + return getKeychainValue(key: kCertificateLabel) + } + + func removeCertificateLabel() { + removeKeychainValue(key: kCertificateLabel) + } // KeyChain へ指定の値をセット private func setKeychainValue(key: String, value: String) { let keychain = Keychain(service: service, accessGroup: UserDefaultsDataStore().readGroupId()!) diff --git a/AgileWorks/Common/Utility/URLAuthenticationUtility.swift b/AgileWorks/Common/Utility/URLAuthenticationUtility.swift index cd151b6..3eadaec 100644 --- a/AgileWorks/Common/Utility/URLAuthenticationUtility.swift +++ b/AgileWorks/Common/Utility/URLAuthenticationUtility.swift @@ -8,12 +8,13 @@ import Foundation -func handleURLAuthenticationChallenge(_ challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { +func handleURLAuthenticationChallenge(_ challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void, serverNumber: Int? = nil) { var handled = false switch challenge.protectionSpace.authenticationMethod { case NSURLAuthenticationMethodClientCertificate: - if let credential = CertificateDataStore().getClientCertificateSessionCredential() { + var certificateLabel = KeychainDataStore().readCertificateLabel(serverNumber: serverNumber) + if let credential = CertificateDataStore().getClientCertificateSessionCredential(label: certificateLabel) { completionHandler(.useCredential, credential) handled = true } diff --git a/AgileWorks/Common/WebClient/Session.swift b/AgileWorks/Common/WebClient/Session.swift index da0f712..bb3886b 100644 --- a/AgileWorks/Common/WebClient/Session.swift +++ b/AgileWorks/Common/WebClient/Session.swift @@ -17,25 +17,29 @@ enum SessionError: Error { class Session { private static let kRetryCount = 3 - private static let privateShared = URLSession(configuration: .default, delegate: SessionDelegate(), delegateQueue: nil) + //private static let privateShared = URLSession(configuration: .default, delegate: SessionDelegate(), delegateQueue: nil) private static var retryCount = kRetryCount - class var shared: URLSession { + class func shared(serverNumber: Int? = nil) -> URLSession { + var sessionDelegate = SessionDelegate() + + sessionDelegate.serverNumber = serverNumber + let privateShared = URLSession(configuration: .default, delegate: sessionDelegate, delegateQueue: nil) return privateShared } private class SessionDelegate: NSObject, URLSessionDelegate { + var serverNumber: Int? = nil func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { - handleURLAuthenticationChallenge(challenge, completionHandler: completionHandler) + handleURLAuthenticationChallenge(challenge, completionHandler: completionHandler, serverNumber: serverNumber) } } @discardableResult - class func send(_ request: T, completion: @escaping (Result) -> Void) -> URLSessionTask? { + class func send(serverNumber: Int? = nil, _ request: T, completion: @escaping (Result) -> Void) -> URLSessionTask? { let req = request.request log.debug("Session Request: \(String(describing: req.url))\nHTTPMethod: \(String(describing: req.httpMethod) )\nHeaders: \(String(describing: req.allHTTPHeaderFields))\nHTTPBody: \(String(data: req.httpBody ?? Data(), encoding: .utf8)!)") - - let task = shared.dataTask(with: req) { data, response, error in + let task = shared(serverNumber: serverNumber).dataTask(with: req) { data, response, error in let result: Result let res = response as? HTTPURLResponse diff --git a/AgileWorks/ShareExtension/View/ShareViewController.swift b/AgileWorks/ShareExtension/View/ShareViewController.swift index b0be7d8..7d7a2d5 100644 --- a/AgileWorks/ShareExtension/View/ShareViewController.swift +++ b/AgileWorks/ShareExtension/View/ShareViewController.swift @@ -47,7 +47,7 @@ class ShareViewController: UITableViewController { @IBAction func onImportButtonTapped(_ sender: UIBarButtonItem) { importCertificateFromContext() { identity, error in if let identity = identity { - CertificateDataStore().writeClientCertificate(identity: identity) + CertificateDataStore().writeNewClientCertificate(identity: identity) self.alertInUiThread(message: getDisplayString(key: "CertificateImportSuccess", comment: "")) { self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) } -- GitLab From fcdfe19d958612487667f236df02f4168b30f51a Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 4 Jul 2023 13:01:53 +0900 Subject: [PATCH 18/36] =?UTF-8?q?today=E3=82=BF=E3=83=83=E3=83=97=E5=8B=95?= =?UTF-8?q?=E4=BD=9C=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/Common/WidgetView.swift | 5 +++++ AgileWorks/TodayExtension/View/TodayViewController.swift | 5 ++++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/AgileWorks/Common/WidgetView.swift b/AgileWorks/Common/WidgetView.swift index 90517e9..6b32306 100644 --- a/AgileWorks/Common/WidgetView.swift +++ b/AgileWorks/Common/WidgetView.swift @@ -282,6 +282,11 @@ struct LinkView: View { }) } else { ApprovalItemView(itemNum: itemNum, entry: entry) + .onTapGesture { + if entry.viewController != nil { + entry.viewController!.extensionContext?.open(NSURL(fileURLWithPath: getStatusURL())as URL, completionHandler: nil) + } + } } } } diff --git a/AgileWorks/TodayExtension/View/TodayViewController.swift b/AgileWorks/TodayExtension/View/TodayViewController.swift index fd075a2..7633422 100644 --- a/AgileWorks/TodayExtension/View/TodayViewController.swift +++ b/AgileWorks/TodayExtension/View/TodayViewController.swift @@ -40,7 +40,10 @@ class TodayViewController: UIViewController, NCWidgetProviding { entrys.append(entry) } - UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + + if !serverList.isEmpty { + UserDefaultsDataStore().setGroupId(serverNumber: serverList.first!) + } //描画 var rootView = TodayWidgetView(entrys: entrys) -- GitLab From 6837c3f94006fb1be43d604a6f999349c2afb49b Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Wed, 5 Jul 2023 13:14:59 +0900 Subject: [PATCH 19/36] =?UTF-8?q?=E8=A8=BC=E6=98=8E=E6=9B=B8=E3=81=AE?= =?UTF-8?q?=E6=9B=B8=E3=81=8D=E8=BE=BC=E3=81=BF=E3=83=BB=E8=AA=AD=E3=81=BF?= =?UTF-8?q?=E8=BE=BC=E3=81=BF=E3=83=BB=E5=89=8A=E9=99=A4=20UI=E9=80=A3?= =?UTF-8?q?=E6=90=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 4 + .../ClientCertificateViewController.swift | 96 +++++++++++++++++++ .../Login/View/LoginViewController.storyboard | 85 +++++++++++----- .../Login/View/LoginViewController.swift | 33 ++++++- .../Strings/Chinese-Simplified.strings | 1 + .../Strings/Chinese-Traditional.strings | 1 + AgileWorks/AgileWorks/Strings/English.strings | 1 + .../AgileWorks/Strings/Japanese.strings | 1 + .../Strings/en.lproj/Localizable.strings | 1 + .../Strings/ja.lproj/Localizable.strings | 1 + .../Strings/zh-Hans.lproj/Localizable.strings | 1 + .../Strings/zh-Hant.lproj/Localizable.strings | 1 + .../DataStore/CertificateDataStore.swift | 21 ++-- .../Common/DataStore/KeychainDataStore.swift | 2 +- .../View/ShareViewController.swift | 16 +++- 15 files changed, 227 insertions(+), 38 deletions(-) create mode 100644 AgileWorks/AgileWorks/Login/View/ClientCertificateViewController.swift diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index ce4ac23..db10737 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -22,6 +22,7 @@ 7549FC9227EAF42C00FF9E0C /* Chinese-Simplified.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75917F9F27BDF2050051E201 /* Chinese-Simplified.strings */; }; 7549FC9327EAF42C00FF9E0C /* Chinese-Traditional.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75917FA127BDF2250051E201 /* Chinese-Traditional.strings */; }; 756C7E7B282B6A5700C24F4D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 756C7E7A282B6A5700C24F4D /* Assets.xcassets */; }; + 758F1BC02A5408D400DDEBC5 /* ClientCertificateViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 758F1BBF2A5408D400DDEBC5 /* ClientCertificateViewController.swift */; }; 75917F9C27BDF0F10051E201 /* Japanese.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75917F9B27BDF0F10051E201 /* Japanese.strings */; }; 75917F9E27BDF1C30051E201 /* English.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75917F9D27BDF1C30051E201 /* English.strings */; }; 75917FA027BDF2050051E201 /* Chinese-Simplified.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75917F9F27BDF2050051E201 /* Chinese-Simplified.strings */; }; @@ -279,6 +280,7 @@ 7576916A2A2EFEEC00EAFCBC /* AgileWorksRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "AgileWorksRelease-Production.entitlements"; sourceTree = ""; }; 7576916B2A2F003400EAFCBC /* TodayExtensionRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "TodayExtensionRelease-Production.entitlements"; sourceTree = ""; }; 757691732A32E5F100EAFCBC /* WidgetExtensionRelease-Production.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "WidgetExtensionRelease-Production.entitlements"; sourceTree = ""; }; + 758F1BBF2A5408D400DDEBC5 /* ClientCertificateViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientCertificateViewController.swift; sourceTree = ""; }; 75917F9227BD315A0051E201 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; 75917F9627BD317E0051E201 /* zh-Hant */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hant"; path = "zh-Hant.lproj/Localizable.strings"; sourceTree = ""; }; 75917F9B27BDF0F10051E201 /* Japanese.strings */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; path = Japanese.strings; sourceTree = ""; }; @@ -680,6 +682,7 @@ children = ( VRZQMTKT1ZML0OSDGAKBK8ID /* LoginViewController.storyboard */, TXU9U01HBM9MEYSGQITWCSE9 /* LoginViewController.swift */, + 758F1BBF2A5408D400DDEBC5 /* ClientCertificateViewController.swift */, ); path = View; sourceTree = ""; @@ -1583,6 +1586,7 @@ UMOPI6WFDHHR8CWFUZDQE9U2 /* LoginUseCase.swift in Sources */, BD6C1AED24A480C70057756F /* DeviceService.swift in Sources */, 76AE530025D3626800AFA45A /* LicenseViewController.swift in Sources */, + 758F1BC02A5408D400DDEBC5 /* ClientCertificateViewController.swift in Sources */, BDAB1F6D240D0D0000EA15FD /* UserDefaultsExtensions.swift in Sources */, C50CF78E27D86DC90042C210 /* OpenLicenseBuilder.swift in Sources */, BD969631240C9CD400521925 /* SessionInfo.swift in Sources */, diff --git a/AgileWorks/AgileWorks/Login/View/ClientCertificateViewController.swift b/AgileWorks/AgileWorks/Login/View/ClientCertificateViewController.swift new file mode 100644 index 0000000..c80a688 --- /dev/null +++ b/AgileWorks/AgileWorks/Login/View/ClientCertificateViewController.swift @@ -0,0 +1,96 @@ +// +// ClientCertificateTableViewController.swift +// AgileWorks +// +// Created by Azuma Kasumi on 2023/07/04. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import UIKit + +class ClientCertificateViewController: UIViewController, UITableViewDataSource, UITableViewDelegate { + @IBOutlet weak var tableView: UITableView! + //インポート済みの証明書リスト + var certificates = CertificateDataStore().readAllClientCertificate() + override func viewDidLoad() { + super.viewDidLoad() + tableView.register(UITableViewCell.self, forCellReuseIdentifier: "Cell") + + tableView.dataSource = self + tableView.delegate = self + + tableView.allowsMultipleSelection = false + } + + func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { + let cell = tableView.dequeueReusableCell(withIdentifier: "Cell", for: indexPath) + + cell.selectionStyle = UITableViewCell.SelectionStyle.none + + //ラベル名取得 + let dic = certificates![indexPath.row] + let label = dic[kSecAttrLabel as String] as! String + cell.textLabel?.text = label + + //選択中のラベルの場合はチェックマークをつける + let selectedLabel = KeychainDataStore().readCertificateLabel() + if selectedLabel == label { + cell.accessoryType = .checkmark + self.tableView.selectRow(at: indexPath, animated: false, scrollPosition: .none) + } + return cell + } + + //セルの数 + func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { + if certificates == nil { + return 0 + } + return certificates!.count + } + + // セルが選択された時に呼び出される + func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { + let cell = tableView.cellForRow(at: indexPath) + // チェックマークを入れる + cell!.accessoryType = .checkmark + + let dic = certificates![indexPath.row] + let label = dic[kSecAttrLabel as String] as! String + + let selectedLabel = KeychainDataStore().readCertificateLabel() + if selectedLabel != label { + //キーチェーンにラベル名を保存 + KeychainDataStore().writeCertificateLabel(label: label) + } else { + //設定済みの場合は解除 + cell!.accessoryType = .none + KeychainDataStore().removeCertificateLabel() + } + } + + // セルの選択が外れた時に呼び出される + func tableView(_ tableView: UITableView, didDeselectRowAt indexPath: IndexPath) { + let cell = tableView.cellForRow(at: indexPath) + // チェックマークを外す + cell!.accessoryType = .none + } + + //クライアント証明書をスワイプ削除 + func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) { + if editingStyle == .delete { + let dic = certificates![indexPath.row] + let label = dic[kSecAttrLabel as String] as! String + CertificateDataStore().removeClientCertificate(label: label) + + //選択中の証明書が削除された場合 + let selectedLabel = KeychainDataStore().readCertificateLabel() + if selectedLabel == label { + KeychainDataStore().removeCertificateLabel() + } + certificates = CertificateDataStore().readAllClientCertificate() + + tableView.deleteRows(at: [indexPath], with: .automatic) + } + } +} diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.storyboard b/AgileWorks/AgileWorks/Login/View/LoginViewController.storyboard index ae4f5c3..422edd7 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.storyboard +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.storyboard @@ -1,9 +1,9 @@ - + - + @@ -19,17 +19,17 @@ - + - + - + - + @@ -95,21 +95,31 @@ - + @@ -208,7 +218,7 @@ - + @@ -227,11 +237,42 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - @@ -245,7 +286,7 @@ - + diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 99ffad2..e96cf0a 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -30,7 +30,7 @@ class LoginViewController: UIViewController { @IBOutlet private var disablingView: UIView! @IBOutlet private var clientCertificateLabel: UILabel! @IBOutlet private var clientCertificateSettingView: UIView! - @IBOutlet private var clientCertificateRemovalButton: UIButton! + @IBOutlet weak var clientCertificateSelectButton: UIButton! @IBOutlet private var qrCodeReadLabel: UILabel! @IBOutlet private var qrCodeReadView: UIView! @IBOutlet private var qrCodeStartupButton: UIButton! @@ -52,6 +52,8 @@ class LoginViewController: UIViewController { return context } + private var navVC: UINavigationController? = nil + let qrCodeReader = QRCodeReader() func inject(presenter: LoginPresenter) { @@ -85,7 +87,9 @@ class LoginViewController: UIViewController { } } - clientCertificateSettingView.isHidden = (CertificateDataStore().readClientCertificate(label: nil) == nil) + let certificates = CertificateDataStore().readAllClientCertificate() + clientCertificateSettingView.isHidden = certificates?.isEmpty ?? true + //固定文言表示 setupFixedWording() @@ -174,6 +178,26 @@ class LoginViewController: UIViewController { self.view.endEditing(true) } + @IBAction func clientCertificateSelectButtonTapped(_ sender: Any) { + let csVC = clientCertificateSelectView() + navVC = UINavigationController(rootViewController: csVC) + //navVC.setNavigationBarHidden(false, animated: true) + let chevronLeftImage: UIImage? = UIImage(systemName: "chevron.left") + let backButton = UIBarButtonItem(image: chevronLeftImage, style: .plain, target: self, action: #selector(onTapBackButton(_:))) + navVC!.navigationBar.topItem!.leftBarButtonItem = backButton + navVC!.modalPresentationStyle = .fullScreen + self.present(navVC!, animated: true) + } + @objc func onTapBackButton(_ sender: UIBarButtonItem) { + navVC?.dismiss(animated: true) + } + + private func clientCertificateSelectView() -> UIViewController { + let storyboard = UIStoryboard(name: "LoginViewController", bundle: nil) + let vc = storyboard.instantiateViewController(withIdentifier: "ClientCertificateTableViewController") + return vc + } + @IBAction private func loginTapped() { guard let serverHost = serverHost else { return } guard let context = context else { return } @@ -339,7 +363,7 @@ class LoginViewController: UIViewController { private func setLoginControlesEnabled(_ enabled: Bool) { disablingView.isHidden = enabled - let controls: [UIControl] = [serverTextField, contextTextField, loginButton, clientCertificateRemovalButton, qrCodeStartupButton] + let controls: [UIControl] = [serverTextField, contextTextField, loginButton, clientCertificateSelectButton, qrCodeStartupButton] for view in controls { view.isEnabled = enabled } @@ -359,6 +383,7 @@ class LoginViewController: UIViewController { } } + @IBAction private func clientCertificateRemovalTapped(_ sender: Any) { let alertController = UIAlertController(title: "", message: getLocalizableStrings(key: "ClientCertificateRemovalConfirmation", comment: ""), preferredStyle: .alert) let okAction = UIAlertAction(title: getLocalizableStrings(key: "ClientCertificateRemovalOK", comment: ""), style: .default) { _ in @@ -370,7 +395,7 @@ class LoginViewController: UIViewController { alertController.addAction(cancelAction) present(alertController, animated: true, completion: nil) } - + private func devcie(serverNumber: Int, completion: @escaping (APIResult) -> Void) { DeviceService().deleteDevice(serverNumber: serverNumber) { result in switch result { diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index f522d3b..a3ae55f 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "输入的客户证书。"; "IncorrectPassphrase" = "通行证短语是不同的。"; "CertificateImportError" = "在证书导入过程中发生了一个错误。"; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "草稿"; diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings index 32cafea..583c9aa 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "輸入的客戶證書。"; "IncorrectPassphrase" = "通行證短語是不同的。"; "CertificateImportError" = "在證書導入過程中發生了一個錯誤。"; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "草稿"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index 91107a4..1aa6030 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "Client certificate imported."; "IncorrectPassphrase" = "The passphrase is different."; "CertificateImportError" = "An error occurred during certificate import."; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "Draft"; diff --git a/AgileWorks/AgileWorks/Strings/Japanese.strings b/AgileWorks/AgileWorks/Strings/Japanese.strings index 5219e3c..9a7dbfc 100644 --- a/AgileWorks/AgileWorks/Strings/Japanese.strings +++ b/AgileWorks/AgileWorks/Strings/Japanese.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "クライアント証明書をインポートしました。"; "IncorrectPassphrase" = "パスフレーズが違います。"; "CertificateImportError" = "証明書のインポート中にエラーが発生しました。"; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "下書き"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index c2874e3..eced434 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "Client certificate imported."; "IncorrectPassphrase" = "The passphrase is different."; "CertificateImportError" = "An error occurred during certificate import."; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "Draft"; diff --git a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings index 2d54811..0575be7 100644 --- a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "クライアント証明書をインポートしました。"; "IncorrectPassphrase" = "パスフレーズが違います。"; "CertificateImportError" = "証明書のインポート中にエラーが発生しました。"; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "下書き"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 55c49a3..8861234 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "输入的客户证书。"; "IncorrectPassphrase" = "通行证短语是不同的。"; "CertificateImportError" = "在证书导入过程中发生了一个错误。"; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "草稿"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings index a818da8..3568da2 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings @@ -104,6 +104,7 @@ "CertificateImportSuccess" = "輸入的客戶證書。"; "IncorrectPassphrase" = "通行證短語是不同的。"; "CertificateImportError" = "在證書導入過程中發生了一個錯誤。"; +"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; // Widget Status "Draft" = "草稿"; diff --git a/AgileWorks/Common/DataStore/CertificateDataStore.swift b/AgileWorks/Common/DataStore/CertificateDataStore.swift index 8bf677c..19f4f3b 100644 --- a/AgileWorks/Common/DataStore/CertificateDataStore.swift +++ b/AgileWorks/Common/DataStore/CertificateDataStore.swift @@ -37,9 +37,15 @@ class CertificateDataStore { } //証明書の書き込み - func writeNewClientCertificate(identity: SecIdentity) { - var newLabel = kClientCertLabel + serchLabelID() - writeIdentity(label: newLabel, identity: identity) + func writeNewClientCertificate(identity: SecIdentity) -> String? { + let labelID = serchLabelID() + if let labelID = labelID { + var newLabel = kClientCertLabel + labelID + writeIdentity(label: newLabel, identity: identity) + } else { + log.error("Certificate storage limit exceeded") + } + return labelID } /// クライアント証明書を削除する。 @@ -117,10 +123,9 @@ class CertificateDataStore { } } - private func serchLabelID() -> String { + private func serchLabelID() -> String? { var labelID = 0 - var flg = true - while flg { + while labelID < 20 { let label = kClientCertLabel + String(labelID) let query: [String: Any] = [ kSecClass as String: kSecClassIdentity, @@ -132,12 +137,12 @@ class CertificateDataStore { let status = SecItemCopyMatching(query as CFDictionary, &result) switch status { case errSecItemNotFound: - flg = false + return String(labelID) default: labelID += 1 } } - return String(labelID) + return nil } private func removeIdentity(label: String) { diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index ae48cb1..dd6a43e 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -191,7 +191,7 @@ final class KeychainDataStore: DataStoreProtocol { setKeychainValue(key: kCertificateLabel, value: label) } - func readCertificateLabel(serverNumber: Int?) -> String? { + func readCertificateLabel(serverNumber: Int? = nil) -> String? { if let serverNumber = serverNumber { return getKeychainValue(key: kCertificateLabel, serverNumber: serverNumber) } diff --git a/AgileWorks/ShareExtension/View/ShareViewController.swift b/AgileWorks/ShareExtension/View/ShareViewController.swift index 7d7a2d5..e0086a8 100644 --- a/AgileWorks/ShareExtension/View/ShareViewController.swift +++ b/AgileWorks/ShareExtension/View/ShareViewController.swift @@ -47,9 +47,19 @@ class ShareViewController: UITableViewController { @IBAction func onImportButtonTapped(_ sender: UIBarButtonItem) { importCertificateFromContext() { identity, error in if let identity = identity { - CertificateDataStore().writeNewClientCertificate(identity: identity) - self.alertInUiThread(message: getDisplayString(key: "CertificateImportSuccess", comment: "")) { - self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) + //書き込み + let result = CertificateDataStore().writeNewClientCertificate(identity: identity) + + if let _ = result { + //成功 + self.alertInUiThread(message: getDisplayString(key: "CertificateImportSuccess", comment: "")) { + self.extensionContext?.completeRequest(returningItems: nil, completionHandler: nil) + } + } else { + //保存上限オーバー + self.alertInUiThread(message: getDisplayString(key: "CertificateStorageLimit", comment: "")) { + self.extensionContext?.cancelRequest(withError: error ?? ShareExtensionError.genericError) + } } } else { if let error = error as NSError?, -- GitLab From a85865d93a2b3c32e4043f0c4df3220c46f066b9 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 10 Jul 2023 14:30:08 +0900 Subject: [PATCH 20/36] =?UTF-8?q?=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=83=88=E3=82=BF=E3=83=83=E3=83=97URL=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/Common/DataStore/KeychainDataStore.swift | 5 ++++- AgileWorks/Common/WidgetView.swift | 8 ++++++-- 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index cd7b89e..0766a7e 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -92,7 +92,10 @@ final class KeychainDataStore: DataStoreProtocol { } // サーバーURLの読み込み - func readServerURL() -> String? { + func readServerURL(serverNumber: Int? = nil) -> String? { + if let serverNumber = serverNumber { + return getKeychainValue(key: kServerURL, serverNumber: serverNumber) + } return getKeychainValue(key: kServerURL) } diff --git a/AgileWorks/Common/WidgetView.swift b/AgileWorks/Common/WidgetView.swift index 6b32306..ed1a4f5 100644 --- a/AgileWorks/Common/WidgetView.swift +++ b/AgileWorks/Common/WidgetView.swift @@ -355,7 +355,9 @@ struct FailureWidgetView: View { } func getWorkURL(serverNumber: Int?) -> String { - var url = Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#work" + let serverURL = KeychainDataStore().readServerURL(serverNumber: serverNumber) ?? "" + let contextPath = KeychainDataStore().readContextPath(serverNumber: serverNumber) ?? "" + var url = "https://" + serverURL + "/" + contextPath + "/Broker/Mobile#work" if let serverNumber = serverNumber { url += "?serverNumber=" + String(serverNumber) } @@ -365,7 +367,9 @@ func getWorkURL(serverNumber: Int?) -> String { //遷移先URLの取得(iOS14以降) func getURL(approvalItem: ApprovalItem, serverNumber: Int?) -> String { if let status = getStatus(code: approvalItem.code) { - var url = Configuration.shared.awURL + "/" + (KeychainDataStore().readContextPath() ?? "") + "/Broker/Mobile#docList_" + status + let serverURL = KeychainDataStore().readServerURL(serverNumber: serverNumber) ?? "" + let contextPath = KeychainDataStore().readContextPath(serverNumber: serverNumber) ?? "" + let url: String = "https://" + serverURL + "/" + contextPath + "/Broker/Mobile#docList_" + status if let serverNumber = serverNumber { return url + "?serverNumber=" + String(serverNumber) } -- GitLab From 882e0fd3a31b529fb86bf7fce92b1a174a9d359c Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Mon, 31 Jul 2023 11:35:18 +0900 Subject: [PATCH 21/36] =?UTF-8?q?=E6=89=BF=E8=AA=8D=E5=BE=85=E3=81=A1?= =?UTF-8?q?=E4=BB=B6=E6=95=B0=E5=8F=96=E5=BE=97=E3=81=AE=E3=83=93=E3=83=AB?= =?UTF-8?q?=E3=83=89=E3=82=A8=E3=83=A9=E3=83=BC=E5=9B=9E=E9=81=BF=E3=83=BB?= =?UTF-8?q?=E3=83=AD=E3=82=B0=E3=82=A2=E3=82=A6=E3=83=88=E6=99=82=E3=81=AE?= =?UTF-8?q?=E8=AA=8D=E8=A8=BC=E6=83=85=E5=A0=B1=E5=89=8A=E9=99=A4=E5=87=A6?= =?UTF-8?q?=E7=90=86=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../View/ServerSwitchingTableViewController.swift | 9 ++++----- .../Common/DataStore/KeychainDataStore.swift | 14 +++++++++----- .../Common/WebClient/DeleteDeviceEndpoint.swift | 5 +++++ 3 files changed, 18 insertions(+), 10 deletions(-) diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift index f540c2b..b788826 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -94,19 +94,18 @@ class ServerSwitchingTableTableViewController: UITableViewController { 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) + let approvalCountLabel = String(item.count) + DispatchQueue.main.async{ + label.text = approvalCountLabel } } case .failure(let error): log.e(error) - DispatchQueue.main.async { + DispatchQueue.main.async{ label.text = "0" } } diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 0766a7e..aeda469 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -38,8 +38,9 @@ final class KeychainDataStore: DataStoreProtocol { func removeAccessToken(serverNumber: Int? = nil) { if let serverNumber = serverNumber { removeKeychainValue(key: kAccessToken, serverNumber: serverNumber) + }else { + removeKeychainValue(key: kAccessToken) } - removeKeychainValue(key: kAccessToken) } // 認可ステータスの書き込み @@ -67,8 +68,9 @@ final class KeychainDataStore: DataStoreProtocol { func removeOAuthState(serverNumber: Int? = nil) { if let serverNumber = serverNumber { removeKeychainValue(key: kOAuthState, serverNumber: serverNumber) + }else { + removeKeychainValue(key: kOAuthState) } - removeKeychainValue(key: kOAuthState) } // 言語設定の書き込み @@ -149,8 +151,9 @@ final class KeychainDataStore: DataStoreProtocol { func removeDeviceID(serverNumber: Int? = nil) { if let serverNumber = serverNumber { removeKeychainValue(key: kDeviceID, serverNumber: serverNumber) + } else { + removeKeychainValue(key: kDeviceID) } - removeKeychainValue(key: kDeviceID) } // セッションIDの書き込み @@ -166,9 +169,10 @@ final class KeychainDataStore: DataStoreProtocol { // セッションIDの削除 func removeSessionID(serverNumber: Int? = nil) { if let serverNumber = serverNumber { - return removeKeychainValue(key: kSessionID, serverNumber: serverNumber) + removeKeychainValue(key: kSessionID, serverNumber: serverNumber) + } else { + removeKeychainValue(key: kSessionID) } - return removeKeychainValue(key: kSessionID) } // サーバー識別名の書き込み diff --git a/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift b/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift index d6433cc..7d5506f 100644 --- a/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift +++ b/AgileWorks/Common/WebClient/DeleteDeviceEndpoint.swift @@ -21,6 +21,8 @@ struct DeleteDeviceEndpoint: APIEndpoint { var pathParameters: [String]? + var baseURL: URL + init(request: DeviceRequest, serverNumber: Int?) { let encoder = JSONEncoder() encoder.keyEncodingStrategy = .convertToSnakeCase @@ -37,6 +39,9 @@ struct DeleteDeviceEndpoint: APIEndpoint { "Content-Type": "application/json"] self.pathParameters = [KeychainDataStore().readDeviceID(serverNumber: serverNumber)?.description ?? ""] + + let serverURL = KeychainDataStore().readServerURL(serverNumber: serverNumber) ?? "" + self.baseURL = URL(string: "https://" + serverURL)! } } -- GitLab From 09a573f57b621747dff995199ca9a8d143e12f18 Mon Sep 17 00:00:00 2001 From: Koda Tomomi Date: Fri, 8 Sep 2023 15:54:12 +0900 Subject: [PATCH 22/36] =?UTF-8?q?systenName=E3=81=AE=E8=A1=A8=E7=A4=BA?= =?UTF-8?q?=E5=87=A6=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 10 ++++----- .../AgileWorks/App/RootViewController.swift | 1 - .../Login/View/LoginViewController.swift | 8 +++---- .../ServerSwitchingTableViewController.swift | 4 ++-- .../WebView/View/MenuViewController.swift | 9 ++++---- .../WebView/View/WebViewController.swift | 4 ++-- .../Common/DataStore/KeychainDataStore.swift | 21 ++++++++++++------- AgileWorks/Common/Entity/SessionInfo.swift | 1 + AgileWorks/Common/WidgetView.swift | 8 +++---- .../IntentsExtension/IntentHandler.swift | 4 ++-- AgileWorks/Podfile.lock | 2 +- 11 files changed, 39 insertions(+), 33 deletions(-) diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 5c364a5..12a7cb6 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -15,6 +15,7 @@ 31AA003024347BD1000177B4 /* ApprovalResponse.swift in Sources */ = {isa = PBXBuildFile; fileRef = 31AA002E24347BBD000177B4 /* ApprovalResponse.swift */; }; 3AF4A84524A06A73006C0C0A /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3AF4A84724A06A73006C0C0A /* Localizable.strings */; }; 430C967B2E966FC047726763 /* Pods_All_AgileWorks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CF516C40B9AA44C977664C98 /* Pods_All_AgileWorks.framework */; }; + 5B3C0583429101EF000E5B66 /* Pods_All_AgileWorks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */; }; 752FE4D02966B9C2004922AD /* ISO8859 in Frameworks */ = {isa = PBXBuildFile; productRef = 752FE4CF2966B9C2004922AD /* ISO8859 */; }; 7549FC8F27EAF42C00FF9E0C /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3AF4A84724A06A73006C0C0A /* Localizable.strings */; }; 7549FC9027EAF42C00FF9E0C /* English.strings in Resources */ = {isa = PBXBuildFile; fileRef = 75917F9D27BDF1C30051E201 /* English.strings */; }; @@ -56,7 +57,6 @@ 75D4EC732A3C12730096F9D2 /* WidgetConfiguration.intentdefinition in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC702A3C01D90096F9D2 /* WidgetConfiguration.intentdefinition */; }; 75D4EC742A3C168C0096F9D2 /* IntentHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75D4EC672A3C00B00096F9D2 /* IntentHandler.swift */; }; 75D4EC782A3C29830096F9D2 /* UserDefaultsDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD928CCD2407500400ED04C2 /* UserDefaultsDataStore.swift */; }; - 75D4EC802A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */; }; 75D4EC812A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 75D4EC7F2A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 75D4EC872A3C32F10096F9D2 /* Configuration.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD5061B3242866780014F3FA /* Configuration.swift */; }; 75D4EC882A3C33310096F9D2 /* KeychainDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = BDEA2CD4246CDAEF00D3E15F /* KeychainDataStore.swift */; }; @@ -445,7 +445,6 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 75D4EC802A3C2CAD0096F9D2 /* Pods_All_AgileWorks.framework in Frameworks */, 75D4EC652A3C00B00096F9D2 /* Intents.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -472,6 +471,7 @@ files = ( 752FE4D02966B9C2004922AD /* ISO8859 in Frameworks */, 430C967B2E966FC047726763 /* Pods_All_AgileWorks.framework in Frameworks */, + 5B3C0583429101EF000E5B66 /* Pods_All_AgileWorks.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1258,7 +1258,7 @@ ); mainGroup = BDA1830623F3FD7F00C9A6DD; packageReferences = ( - 752FE4CE2966B9C1004922AD /* XCRemoteSwiftPackageReference "ISO8859" */, + 752FE4CE2966B9C1004922AD /* XCRemoteSwiftPackageReference "ISO8859.git" */, ); productRefGroup = BDA1831023F3FD7F00C9A6DD /* Products */; projectDirPath = ""; @@ -2477,7 +2477,7 @@ /* End XCConfigurationList section */ /* Begin XCRemoteSwiftPackageReference section */ - 752FE4CE2966B9C1004922AD /* XCRemoteSwiftPackageReference "ISO8859" */ = { + 752FE4CE2966B9C1004922AD /* XCRemoteSwiftPackageReference "ISO8859.git" */ = { isa = XCRemoteSwiftPackageReference; repositoryURL = "https://github.com/Cosmo/ISO8859.git"; requirement = { @@ -2490,7 +2490,7 @@ /* Begin XCSwiftPackageProductDependency section */ 752FE4CF2966B9C2004922AD /* ISO8859 */ = { isa = XCSwiftPackageProductDependency; - package = 752FE4CE2966B9C1004922AD /* XCRemoteSwiftPackageReference "ISO8859" */; + package = 752FE4CE2966B9C1004922AD /* XCRemoteSwiftPackageReference "ISO8859.git" */; productName = ISO8859; }; /* End XCSwiftPackageProductDependency section */ diff --git a/AgileWorks/AgileWorks/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index bf268dc..42b925b 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -111,7 +111,6 @@ extension RootViewController { KeychainDataStore().removeSessionID(serverNumber: serverNumber) } //認証情報削除 - KeychainDataStore().removeServerName() KeychainDataStore().removeLanguage() } diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index e96cf0a..04c7c1e 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -206,8 +206,8 @@ class LoginViewController: UIViewController { let serverList = UserDefaultsDataStore().readServerList() var serverCheckFlg = false for serverNumber in serverList { - let serverName = KeychainDataStore().readServerName(serverNumber: serverNumber)! - if serverName == serverHost { + let systemName = KeychainDataStore().readSystemName(serverNumber: serverNumber) + if systemName == serverHost { serverCheckFlg = true let alert = UIAlertController(title: "", message: getLocalizableStrings(key: "LoginServerAlert", comment: ""), preferredStyle: .alert) let ok = UIAlertAction(title: "OK", style: .default) { (action) in @@ -269,10 +269,10 @@ class LoginViewController: UIViewController { Session.send(sessionEndpoint) { result in switch result { // セッション情報取得成功 - case .success(let response): + case .success(var response): setStringsName(language: response.user.displayLanguage) KeychainDataStore().writeSessionID(sessionID: response.sessionId) - KeychainDataStore().writeServerName(serverName: "サーバー識別名") //TODO response.server.name + KeychainDataStore().writeSystemName(systemName: response.systemName) DispatchQueue.main.async { UserDefaultsDataStore().addServerList() let serverList = UserDefaultsDataStore().readServerList() diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift index b788826..6520864 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/ServerSwitchingTableViewController.swift @@ -48,9 +48,9 @@ class ServerSwitchingTableTableViewController: UITableViewController { let cell = tableView.dequeueReusableCell(withIdentifier: "ServerSwitchingTableViewCell", for: indexPath) let serverList = UserDefaultsDataStore().readServerList() - let serverName = cell.viewWithTag(1) as! UILabel + let systemName = cell.viewWithTag(1) as! UILabel let serverNumber = serverList[indexPath.row] - serverName.text = KeychainDataStore().readServerName(serverNumber: serverNumber) + systemName.text = KeychainDataStore().readSystemName(serverNumber: serverNumber) let badgeIcon = cell.viewWithTag(2) as! UIImageView badgeIcon.image = UIImage(systemName: "circle.fill", withConfiguration: UIImage.SymbolConfiguration(font: .systemFont(ofSize: 25))) diff --git a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift index 0129ea3..ef7008d 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift @@ -65,15 +65,16 @@ class MenuViewController: UIViewController { // セッション情報取得 loadSessionInfo { result in switch result { - case .success(let response): + case .success(var response): let userName = response.user.name - let serverName = KeychainDataStore().readServerURL()! //TODO response.server.name let sessionId = response.sessionId + let systemName = response.systemName DispatchQueue.main.async { self.nameLabel.text = userName - self.serverLabel.text = serverName + self.serverLabel.text = systemName KeychainDataStore().writeSessionID(sessionID: sessionId) - KeychainDataStore().writeServerName(serverName: serverName) + KeychainDataStore().writeSystemName(systemName: systemName) + self.serverLabel.text = KeychainDataStore().readSystemName() } case .failure: DispatchQueue.main.async { diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 823cf88..6e41436 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -224,9 +224,9 @@ class WebViewController: UIViewController { Session.send(sessionEndpoint) { result in switch result { // セッション情報取得成功 - case .success(let response): + case .success(var response): KeychainDataStore().writeSessionID(sessionID: response.sessionId) - KeychainDataStore().writeServerName(serverName: "サーバー識別名") //TODO response.server.name + KeychainDataStore().writeSystemName(systemName: response.systemName) setStringsName(language: response.user.displayLanguage) if isInit { // 画面ロード diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 7d7c600..1b3e8b1 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -19,7 +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" + private let kSystemName: String = "SystemName" private let kCertificateLabel: String = "CertificateLabel" // アクセストークンの書き込み @@ -177,21 +177,26 @@ final class KeychainDataStore: DataStoreProtocol { } // サーバー識別名の書き込み - func writeServerName(serverName: String) { - setKeychainValue(key: kServerName, value: serverName) + func writeSystemName(systemName: String?) { + if systemName != nil { + setKeychainValue(key: kSystemName, value: systemName!) + } else { + let systemName = readServerURL() + setKeychainValue(key: kSystemName, value: systemName!) + } } // サーバー識別名の読み込み - func readServerName(serverNumber: Int? = nil) -> String? { + func readSystemName(serverNumber: Int? = nil) -> String? { if let serverNumber = serverNumber { - return getKeychainValue(key: kServerURL, serverNumber: serverNumber) + return getKeychainValue(key: kSystemName, serverNumber: serverNumber) } - return getKeychainValue(key: kServerURL) + return getKeychainValue(key: kSystemName) } // サーバー識別名の削除 - func removeServerName() { - removeKeychainValue(key: kServerName) + func removeSystemName() { + removeKeychainValue(key: kSystemName) } func writeCertificateLabel(label: String) { diff --git a/AgileWorks/Common/Entity/SessionInfo.swift b/AgileWorks/Common/Entity/SessionInfo.swift index 695a4e8..a9a3e60 100644 --- a/AgileWorks/Common/Entity/SessionInfo.swift +++ b/AgileWorks/Common/Entity/SessionInfo.swift @@ -34,4 +34,5 @@ struct SessionInfo: Codable { let unit: [Unit] let role: [Role] let sessionId: String + var systemName: String? } diff --git a/AgileWorks/Common/WidgetView.swift b/AgileWorks/Common/WidgetView.swift index ed1a4f5..7120725 100644 --- a/AgileWorks/Common/WidgetView.swift +++ b/AgileWorks/Common/WidgetView.swift @@ -56,7 +56,7 @@ struct TodayWidgetView: View { if !UserDefaultsDataStore().readServerList().isEmpty { Picker(selection: $selection, label: Text("")) { ForEach(0.. Date: Mon, 11 Sep 2023 13:21:49 +0900 Subject: [PATCH 23/36] =?UTF-8?q?systemName=E3=81=AE=E5=89=8A=E9=99=A4?= =?UTF-8?q?=E5=87=A6=E7=90=86=E8=BF=BD=E5=8A=A0=E3=83=BB=E4=B8=8D=E8=A6=81?= =?UTF-8?q?=E3=81=AA=E4=BB=A3=E5=85=A5=E5=89=8A=E9=99=A4=E3=83=BBsystemNam?= =?UTF-8?q?e=E3=81=AE=E4=BB=95=E6=A7=98=E3=81=AB=E3=81=A4=E3=81=84?= =?UTF-8?q?=E3=81=A6=E3=81=AE=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E8=BF=BD?= =?UTF-8?q?=E8=A8=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/App/RootViewController.swift | 1 + AgileWorks/AgileWorks/WebView/View/MenuViewController.swift | 1 - AgileWorks/Common/DataStore/KeychainDataStore.swift | 1 + AgileWorks/Podfile.lock | 2 +- 4 files changed, 3 insertions(+), 2 deletions(-) diff --git a/AgileWorks/AgileWorks/App/RootViewController.swift b/AgileWorks/AgileWorks/App/RootViewController.swift index 42b925b..7710298 100644 --- a/AgileWorks/AgileWorks/App/RootViewController.swift +++ b/AgileWorks/AgileWorks/App/RootViewController.swift @@ -111,6 +111,7 @@ extension RootViewController { KeychainDataStore().removeSessionID(serverNumber: serverNumber) } //認証情報削除 + KeychainDataStore().removeSystemName() KeychainDataStore().removeLanguage() } diff --git a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift index ef7008d..1700e93 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuViewController.swift @@ -71,7 +71,6 @@ class MenuViewController: UIViewController { let systemName = response.systemName DispatchQueue.main.async { self.nameLabel.text = userName - self.serverLabel.text = systemName KeychainDataStore().writeSessionID(sessionID: sessionId) KeychainDataStore().writeSystemName(systemName: systemName) self.serverLabel.text = KeychainDataStore().readSystemName() diff --git a/AgileWorks/Common/DataStore/KeychainDataStore.swift b/AgileWorks/Common/DataStore/KeychainDataStore.swift index 1b3e8b1..03de57d 100644 --- a/AgileWorks/Common/DataStore/KeychainDataStore.swift +++ b/AgileWorks/Common/DataStore/KeychainDataStore.swift @@ -181,6 +181,7 @@ final class KeychainDataStore: DataStoreProtocol { if systemName != nil { setKeychainValue(key: kSystemName, value: systemName!) } else { + //systemNameがレスポンスに無い場合、serverURLをsystemNameとして設定 let systemName = readServerURL() setKeychainValue(key: kSystemName, value: systemName!) } diff --git a/AgileWorks/Podfile.lock b/AgileWorks/Podfile.lock index 2e036b5..796da82 100644 --- a/AgileWorks/Podfile.lock +++ b/AgileWorks/Podfile.lock @@ -177,4 +177,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 098b08dfc02bcc011514548f1c9cd491768400be -COCOAPODS: 1.12.1 +COCOAPODS: 1.11.2 -- GitLab From 21fb075c690b97076b301a1edfa6936d9a6b6b30 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Wed, 13 Sep 2023 10:57:15 +0900 Subject: [PATCH 24/36] =?UTF-8?q?=E7=BF=BB=E8=A8=B3=E5=89=8D=E3=81=AE?= =?UTF-8?q?=E3=83=99=E3=83=BC=E3=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../ServerSwitching/View/MordalViewController.swift | 3 ++- AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings | 4 +++- AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings | 4 +++- AgileWorks/AgileWorks/Strings/English.strings | 4 +++- AgileWorks/AgileWorks/Strings/Japanese.strings | 4 +++- AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings | 4 +++- AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings | 4 +++- .../AgileWorks/Strings/zh-Hans.lproj/Localizable.strings | 4 +++- .../AgileWorks/Strings/zh-Hant.lproj/Localizable.strings | 4 +++- .../AgileWorks/WebView/View/MenuTableViewController.swift | 2 +- AgileWorks/AgileWorks/WebView/View/WebViewController.swift | 2 +- 11 files changed, 28 insertions(+), 11 deletions(-) diff --git a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift index a67e42a..0ca1c7c 100644 --- a/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift +++ b/AgileWorks/AgileWorks/ServerSwitching/View/MordalViewController.swift @@ -15,7 +15,8 @@ class MordalViewController: UIViewController { override func viewDidLoad() { super.viewDidLoad() - accessPoint.text = getDisplayString(key: "ServerTitle", comment: "") + accessPoint.text = getDisplayString(key: "accessPoint", comment: "") + addServer.setTitle(getDisplayString(key: "AddConnection", comment: ""), for: .normal) } static func fromStoryboard(_ storyboard: UIStoryboard = UIStoryboard(name: "ServerSwitchingViewController", bundle: nil)) -> MordalViewController { diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index a3ae55f..30925a3 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "开放许可证"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "访问令牌更新错误"; diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings index 583c9aa..3da1ee5 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "開放許可證"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "由通知點選的文件已經顯示了。 \n你想放棄當前的編輯並顯示一個新的文件嗎?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "訪問令牌更新錯誤"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index 1aa6030..d9ec952 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "Open license"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "A document by a notification tap is already displayed.\nDo you want to discard the current edits and display a new document?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "Access token update error"; diff --git a/AgileWorks/AgileWorks/Strings/Japanese.strings b/AgileWorks/AgileWorks/Strings/Japanese.strings index 9a7dbfc..df9efa6 100644 --- a/AgileWorks/AgileWorks/Strings/Japanese.strings +++ b/AgileWorks/AgileWorks/Strings/Japanese.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "オープンソースライセンス"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "既に通知タップによる書類が表示されています。\n現在の編集内容を破棄し、新たな書類を表示しますか?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "アクセストークン更新エラー"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index eced434..ab10d58 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "Open license"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "A document by a notification tap is already displayed.\nDo you want to discard the current edits and display a new document?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "Access token update error"; diff --git a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings index 0575be7..7b9d21c 100644 --- a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "オープンソースライセンス"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "既に通知タップによる書類が表示されています。\n現在の編集内容を破棄し、新たな書類を表示しますか?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "アクセストークン更新エラー"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 8861234..28633e5 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "开放许可证"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "访问令牌更新错误"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings index 3568da2..3a1903a 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings @@ -58,11 +58,13 @@ "OpenLicenseViewTitle" = "開放許可證"; //server -"ServerTitle" = "接続先サーバー"; "accessPoint" = "接続先"; +"AddConnection" = "+接続先を追加"; +"ConnectionName" = "接続先名"; // Notification "DocOverrideConfirm" = "由通知點選的文件已經顯示了。 \n你想放棄當前的編輯並顯示一個新的文件嗎?"; +"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "訪問令牌更新錯誤"; diff --git a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift index c487fbf..f6f1f22 100644 --- a/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/MenuTableViewController.swift @@ -58,7 +58,7 @@ class MenuTableViewController: UITableViewController { self.logoutLabel.text = getDisplayString(key: "LogoutTitle", comment: "") self.licenseLabel.text = getDisplayString(key: "LicenseTitle", comment: "") self.openLicenseLabel.text = getDisplayString(key: "OpenLicenseTitle", comment: "") - self.serverLabel.text = getDisplayString(key: "ServerTitle", comment: "") + self.serverLabel.text = getDisplayString(key: "accessPoint", comment: "") } // プロファイルセルタップ処理 private func pushToProfile() { diff --git a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift index 6e41436..edee032 100644 --- a/AgileWorks/AgileWorks/WebView/View/WebViewController.swift +++ b/AgileWorks/AgileWorks/WebView/View/WebViewController.swift @@ -382,7 +382,7 @@ class WebViewController: UIViewController { //サーバー切り替え確認アラート func showServerSwichAlert() { - let message = "現在別のサーバーでログイン中です。表示中の書類のサーバーに切り替えますか?" + let message = getDisplayString(key: "DocDifferentServer", comment: "") // OK アクション設定 let defaultAction = UIAlertAction(title: getDisplayString(key: "YES", comment: ""), style: .default) { _ in UserDefaultsDataStore().changeServerList(firstServer: self.displayedServerNumber!) -- GitLab From ceb79f2b34cb77ef5133ef7c95afcfe23bc935c5 Mon Sep 17 00:00:00 2001 From: Koda Tomomi Date: Wed, 13 Sep 2023 11:22:06 +0900 Subject: [PATCH 25/36] =?UTF-8?q?=E3=83=AD=E3=82=B0=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E5=8F=AF=E8=83=BD=E3=81=AA=E6=8E=A5=E7=B6=9A=E6=95=B0=E3=82=92?= =?UTF-8?q?=E8=B6=85=E3=81=88=E3=81=9F=E5=A0=B4=E5=90=88=E3=81=AE=E3=82=A2?= =?UTF-8?q?=E3=83=A9=E3=83=BC=E3=83=88=E8=BF=BD=E5=8A=A0=E3=83=BB=E9=87=8D?= =?UTF-8?q?=E8=A4=87=E3=83=81=E3=82=A7=E3=83=83=E3=82=AF=E3=81=AE=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Login/View/LoginViewController.swift | 27 +++++++++++-------- .../Strings/Chinese-Simplified.strings | 1 + .../Strings/Chinese-Traditional.strings | 1 + AgileWorks/AgileWorks/Strings/English.strings | 1 + .../AgileWorks/Strings/Japanese.strings | 1 + .../Strings/en.lproj/Localizable.strings | 1 + .../Strings/ja.lproj/Localizable.strings | 1 + .../Strings/zh-Hans.lproj/Localizable.strings | 1 + .../Strings/zh-Hant.lproj/Localizable.strings | 1 + 9 files changed, 24 insertions(+), 11 deletions(-) diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 04c7c1e..79808b3 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -206,15 +206,10 @@ class LoginViewController: UIViewController { let serverList = UserDefaultsDataStore().readServerList() var serverCheckFlg = false for serverNumber in serverList { - let systemName = KeychainDataStore().readSystemName(serverNumber: serverNumber) - if systemName == serverHost { + let serverCheck = KeychainDataStore().readServerURL(serverNumber: serverNumber) + if serverCheck == serverHost { serverCheckFlg = true - let alert = UIAlertController(title: "", message: getLocalizableStrings(key: "LoginServerAlert", comment: ""), preferredStyle: .alert) - let ok = UIAlertAction(title: "OK", style: .default) { (action) in - return - } - alert.addAction(ok) - present(alert, animated: true, completion: nil) + alertDialog(alertMessage :"LoginServerAlert") } } @@ -222,14 +217,16 @@ class LoginViewController: UIViewController { return } - disableLogin() - //サーバー切り替え if let serverId = UserDefaultsDataStore().serchEmptyServerData() { UserDefaultsDataStore().setGroupId(serverNumber: serverId) } else { - //TODO: サーバー追加できない場合 + //ログインできる接続先が上限数に達している場合 + alertDialog(alertMessage :"LoginServerOver") + return } + + disableLogin() //サーバー名コンテキストパスの保存 KeychainDataStore().writeServerURL(serverURL: serverHost) @@ -249,6 +246,14 @@ class LoginViewController: UIViewController { } } } + + private func alertDialog(alertMessage :String) { + let alert = UIAlertController(title: "", message: getLocalizableStrings(key: alertMessage, comment: ""), preferredStyle: .alert) + let ok = UIAlertAction(title: "OK", style: .default) + alert.addAction(ok) + present(alert, animated: true, completion: nil) + + } private func registDevice() { // デバイス登録 diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index a3ae55f..e287253 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings index 583c9aa..881c9f2 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Traditional.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "登錄失敗。請重新登錄。"; "CameraStartupErrorMessage" = "未能激活攝像機。"; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index 1aa6030..f312efc 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/Japanese.strings b/AgileWorks/AgileWorks/Strings/Japanese.strings index 9a7dbfc..77e484e 100644 --- a/AgileWorks/AgileWorks/Strings/Japanese.strings +++ b/AgileWorks/AgileWorks/Strings/Japanese.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "ログインに失敗しました。再度ログインしてください。"; "CameraStartupErrorMessage" = "カメラの起動に失敗しました。"; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index eced434..e19a41b 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings index 0575be7..abe990b 100644 --- a/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/ja.lproj/Localizable.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "ログインに失敗しました。再度ログインしてください。"; "CameraStartupErrorMessage" = "カメラの起動に失敗しました。"; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 8861234..0265c05 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings index 3568da2..6a97f8c 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hant.lproj/Localizable.strings @@ -25,6 +25,7 @@ "LoginErrorMessage" = "登錄失敗。請重新登錄。"; "CameraStartupErrorMessage" = "未能激活攝像機。"; "LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; // WebView "HomeTitle" = "家"; -- GitLab From 3e81f8ad4d4edb7f3a396b58dbc21bdfe6b5db9a Mon Sep 17 00:00:00 2001 From: Koda Tomomi Date: Thu, 14 Sep 2023 10:36:27 +0900 Subject: [PATCH 26/36] =?UTF-8?q?=E9=87=8D=E8=A4=87=E3=83=81=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=82=AF=E3=81=A7=E9=87=8D=E8=A4=87=E3=81=97=E3=81=9F?= =?UTF-8?q?=E5=A0=B4=E5=90=88for=E6=96=87=E3=82=92=E6=8A=9C=E3=81=91?= =?UTF-8?q?=E3=82=8B=E5=87=A6=E7=90=86=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/Login/View/LoginViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift index 79808b3..ffb1dd3 100644 --- a/AgileWorks/AgileWorks/Login/View/LoginViewController.swift +++ b/AgileWorks/AgileWorks/Login/View/LoginViewController.swift @@ -210,6 +210,7 @@ class LoginViewController: UIViewController { if serverCheck == serverHost { serverCheckFlg = true alertDialog(alertMessage :"LoginServerAlert") + break } } -- GitLab From 30f60b0ee79442f1b1c48c3bd66ba44f9332b986 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Wed, 27 Sep 2023 15:21:32 +0900 Subject: [PATCH 27/36] =?UTF-8?q?=E9=80=9A=E7=9F=A5=E9=87=8D=E8=A4=87?= =?UTF-8?q?=E8=A1=A8=E7=A4=BA=E7=A2=BA=E8=AA=8D=E3=82=A2=E3=83=A9=E3=83=BC?= =?UTF-8?q?=E3=83=88=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift index c733522..d9c2ee8 100644 --- a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift +++ b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift @@ -90,7 +90,10 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { nav.modalPresentationStyle = .fullScreen let homeTabNumber = 0 - let homeVC = openViewController(tabNumber: homeTabNumber) + viewController.selectedIndex = homeTabNumber + + let view = viewController.children[homeTabNumber] as! UINavigationController + let homeVC = view.viewControllers[view.viewControllers.count - 1] as! WebViewController modalWebVC.presentationController?.delegate = homeVC // 既にモーダルでViewが表示されているか。 -- GitLab From 09a961df3c376d69cc1413785abab1e2946034e3 Mon Sep 17 00:00:00 2001 From: Koda Tomomi Date: Wed, 4 Oct 2023 12:40:24 +0900 Subject: [PATCH 28/36] =?UTF-8?q?=E3=82=A6=E3=82=A3=E3=82=B8=E3=82=A7?= =?UTF-8?q?=E3=83=83=E3=83=88=E8=B5=B7=E5=8B=95=E6=99=82=E3=81=AB=E3=83=A2?= =?UTF-8?q?=E3=83=BC=E3=83=80=E3=83=AB=E9=9D=9E=E8=A1=A8=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Main/Wireframe/MainTabBarViewWireframe.swift | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift index c733522..8c74a85 100644 --- a/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift +++ b/AgileWorks/AgileWorks/Main/Wireframe/MainTabBarViewWireframe.swift @@ -51,6 +51,13 @@ extension MainTabBarViewWireframeImpl: MainTabBarViewWireframe { //ウィジェットからの起動 func showApprovalDetail(url: String) { + //接続先モーダルが表示されていたら閉じる + if let modal = self.viewController.presentedViewController as? ServerSwitchingViewController { + if modal != nil { + modal.dismiss(animated: true, completion: nil) + } + } + //アプリ起動のみ if url.contains(urlSchemeName) { return -- GitLab From ef8bc5d1e2c372d986421848147bdc043a544b58 Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 10 Oct 2023 19:03:58 +0900 Subject: [PATCH 29/36] =?UTF-8?q?=E8=8B=B1=E8=AA=9E=E3=83=BB=E7=B0=A1?= =?UTF-8?q?=E4=BD=93=E8=AA=9E=E3=81=AE=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks/Strings/Chinese-Simplified.strings | 12 ++++++------ AgileWorks/AgileWorks/Strings/English.strings | 12 ++++++------ .../AgileWorks/Strings/en.lproj/Localizable.strings | 12 ++++++------ .../Strings/zh-Hans.lproj/Localizable.strings | 12 ++++++------ 4 files changed, 24 insertions(+), 24 deletions(-) diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index 30925a3..e72795f 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -24,7 +24,7 @@ "ClientCertificateRemovalCancel" = "取消"; "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; -"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerAlert" = "您已登录连接。 请注销后重试。"; // WebView "HomeTitle" = "家"; @@ -58,13 +58,13 @@ "OpenLicenseViewTitle" = "开放许可证"; //server -"accessPoint" = "接続先"; -"AddConnection" = "+接続先を追加"; -"ConnectionName" = "接続先名"; +"accessPoint" = "接入点"; +"AddConnection" = "+添加连接点"; +"ConnectionName" = "连接名称"; // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; -"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; +"DocDifferentServer" = "您目前使用的是其他连接登录。\n您想切换到正在查看的文档的连接点吗?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "访问令牌更新错误"; @@ -106,7 +106,7 @@ "CertificateImportSuccess" = "输入的客户证书。"; "IncorrectPassphrase" = "通行证短语是不同的。"; "CertificateImportError" = "在证书导入过程中发生了一个错误。"; -"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; +"CertificateStorageLimit" = "超过证书存储限制。\n请从登录界面删除。"; // Widget Status "Draft" = "草稿"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index d9ec952..69014b8 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -24,7 +24,7 @@ "ClientCertificateRemovalCancel" = "cancel"; "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; -"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerAlert" = "You are already logged in to the connection.\nPlease log out and try again."; // WebView "HomeTitle" = "HOME"; @@ -58,13 +58,13 @@ "OpenLicenseViewTitle" = "Open license"; //server -"accessPoint" = "接続先"; -"AddConnection" = "+接続先を追加"; -"ConnectionName" = "接続先名"; +"accessPoint" = "Access point"; +"AddConnection" = "+Add a connection"; +"ConnectionName" = "Connection name"; // Notification "DocOverrideConfirm" = "A document by a notification tap is already displayed.\nDo you want to discard the current edits and display a new document?"; -"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; +"DocDifferentServer" = "You are currently logged in with a different connection.\nWould you like to switch to the connection of the document you are viewing?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "Access token update error"; @@ -106,7 +106,7 @@ "CertificateImportSuccess" = "Client certificate imported."; "IncorrectPassphrase" = "The passphrase is different."; "CertificateImportError" = "An error occurred during certificate import."; -"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; +"CertificateStorageLimit" = "Certificate storage limit has been exceeded.\nPlease delete it from the login screen."; // Widget Status "Draft" = "Draft"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index ab10d58..b6a590d 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -24,7 +24,7 @@ "ClientCertificateRemovalCancel" = "cancel"; "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; -"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerAlert" = "You are already logged in to the connection.\nPlease log out and try again."; // WebView "HomeTitle" = "HOME"; @@ -58,13 +58,13 @@ "OpenLicenseViewTitle" = "Open license"; //server -"accessPoint" = "接続先"; -"AddConnection" = "+接続先を追加"; -"ConnectionName" = "接続先名"; +"accessPoint" = "Access point"; +"AddConnection" = "+Add a connection"; +"ConnectionName" = "Connection name"; // Notification "DocOverrideConfirm" = "A document by a notification tap is already displayed.\nDo you want to discard the current edits and display a new document?"; -"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; +"DocDifferentServer" = "You are currently logged in with a different connection.\nWould you like to switch to the connection of the document you are viewing?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "Access token update error"; @@ -106,7 +106,7 @@ "CertificateImportSuccess" = "Client certificate imported."; "IncorrectPassphrase" = "The passphrase is different."; "CertificateImportError" = "An error occurred during certificate import."; -"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; +"CertificateStorageLimit" = "Certificate storage limit has been exceeded.\nPlease delete it from the login screen."; // Widget Status "Draft" = "Draft"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index 28633e5..a396ae0 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -24,7 +24,7 @@ "ClientCertificateRemovalCancel" = "取消"; "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; -"LoginServerAlert" = "ログイン済のサーバーです。ログアウトを行ってから再度お試しください。"; +"LoginServerAlert" = "您已登录连接。 请注销后重试。"; // WebView "HomeTitle" = "家"; @@ -58,13 +58,13 @@ "OpenLicenseViewTitle" = "开放许可证"; //server -"accessPoint" = "接続先"; -"AddConnection" = "+接続先を追加"; -"ConnectionName" = "接続先名"; +"accessPoint" = "接入点"; +"AddConnection" = "+添加连接点"; +"ConnectionName" = "连接名称"; // Notification "DocOverrideConfirm" = "由通知点选的文件已经显示了。\n你想放弃当前的编辑并显示一个新的文件吗?"; -"DocDifferentServer" = "現在別の接続先でログイン中です。\n表示中の書類の接続先に切り替えますか?"; +"DocDifferentServer" = "您目前使用的是其他连接登录。\n您想切换到正在查看的文档的连接点吗?"; // Refresh Token Error "RefreshTokenUpdateErrorTitle" = "访问令牌更新错误"; @@ -106,7 +106,7 @@ "CertificateImportSuccess" = "输入的客户证书。"; "IncorrectPassphrase" = "通行证短语是不同的。"; "CertificateImportError" = "在证书导入过程中发生了一个错误。"; -"CertificateStorageLimit" = "証明書の保存上限を超えました。ログイン画面から削除してください。"; +"CertificateStorageLimit" = "超过证书存储限制。\n请从登录界面删除。"; // Widget Status "Draft" = "草稿"; -- GitLab From 9cab74a8390fa6ec0945cd3004cd4e3bb7ef0d6b Mon Sep 17 00:00:00 2001 From: Azuma Kasumi Date: Tue, 10 Oct 2023 19:14:36 +0900 Subject: [PATCH 30/36] =?UTF-8?q?=E3=83=AD=E3=82=B0=E3=82=A4=E3=83=B3?= =?UTF-8?q?=E4=B8=8A=E9=99=90=E6=95=B0=E3=82=A2=E3=83=A9=E3=83=BC=E3=83=88?= =?UTF-8?q?=20=E8=8B=B1=E8=AA=9E=E3=83=BB=E7=B0=A1=E4=BD=93=E8=AA=9E=20?= =?UTF-8?q?=E7=BF=BB=E8=A8=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings | 2 +- AgileWorks/AgileWorks/Strings/English.strings | 2 +- AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings | 2 +- AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings index 8cfb241..4436813 100644 --- a/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings +++ b/AgileWorks/AgileWorks/Strings/Chinese-Simplified.strings @@ -25,7 +25,7 @@ "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; "LoginServerAlert" = "您已登录连接。 请注销后重试。"; -"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "已超过您可以登录的最大连接数。\n请退出并重试。"; // WebView "HomeTitle" = "家"; diff --git a/AgileWorks/AgileWorks/Strings/English.strings b/AgileWorks/AgileWorks/Strings/English.strings index 4fababf..fe0c439 100644 --- a/AgileWorks/AgileWorks/Strings/English.strings +++ b/AgileWorks/AgileWorks/Strings/English.strings @@ -25,7 +25,7 @@ "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; "LoginServerAlert" = "You are already logged in to the connection.\nPlease log out and try again."; -"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "The maximum number of connections you can log in to has been exceeded.\nPlease log out and try again."; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings index 7cc59aa..40821af 100644 --- a/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/en.lproj/Localizable.strings @@ -25,7 +25,7 @@ "LoginErrorMessage" = "Login failed. Please login again."; "CameraStartupErrorMessage" = "Camera failed to start."; "LoginServerAlert" = "You are already logged in to the connection.\nPlease log out and try again."; -"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "The maximum number of connections you can log in to has been exceeded.\nPlease log out and try again."; // WebView "HomeTitle" = "HOME"; diff --git a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings index eab3455..2867ee6 100644 --- a/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings +++ b/AgileWorks/AgileWorks/Strings/zh-Hans.lproj/Localizable.strings @@ -25,7 +25,7 @@ "LoginErrorMessage" = "登录失败。 请重新登录。"; "CameraStartupErrorMessage" = "未能激活摄像机。"; "LoginServerAlert" = "您已登录连接。 请注销后重试。"; -"LoginServerOver" = "ログインできる接続先の上限数を超えました。ログアウトを行ってから再度お試しください。"; +"LoginServerOver" = "已超过您可以登录的最大连接数。\n请退出并重试。"; // WebView "HomeTitle" = "家"; -- GitLab From a5fd9b6108e15addea6b55a841a46d242e3923b0 Mon Sep 17 00:00:00 2001 From: Gk40002148 Date: Mon, 11 Dec 2023 19:21:32 +0900 Subject: [PATCH 31/36] =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=83=87=E3=83=BC=E3=83=88=E5=AF=BE=E5=BF=9C?= =?UTF-8?q?=20=E6=97=A7=E3=82=A2=E3=83=97=E3=83=AA=E6=83=85=E5=A0=B1?= =?UTF-8?q?=E5=BC=95=E3=81=8D=E7=B6=99=E3=81=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../OldServerCertificateDataStore.swift | 97 ++++++++++ .../OldServerKeychainDataStore.swift | 165 ++++++++++++++++++ 2 files changed, 262 insertions(+) create mode 100644 AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift create mode 100644 AgileWorks/Common/DataStore/OldServerKeychainDataStore.swift diff --git a/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift b/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift new file mode 100644 index 0000000..970a625 --- /dev/null +++ b/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift @@ -0,0 +1,97 @@ +// +// OldServerCertificateDataStore.swift +// AgileWorks +// +// Created by Gk40002148 on 2023/12/06. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import Foundation + +// クライアント証明書格納用ラベル +let kClientCertLabel = "ClientCert" + +/// 証明書情報のデータストア。 +/// +/// `KeychainDataStore` と同様にキーチェーンへのアクセスを行うが、`KeychainDataStore` が +/// その実装に用いている `Keychain` は `kSecIdentity` の読み書きに対応していないため別途定義。 +class OldServerCertificateDataStore { + /// クライアント証明書を読み込む。取得できなければ `nil` 。 + func readClientCertificate() -> SecIdentity? { + return readIdentity(label: kClientCertLabel) + } + + /// クライアント証明書を利用した `URLCredential` (セッション内で有効) を取得する。取得できなければ `nil`。 + func getClientCertificateSessionCredential() -> URLCredential? { + if let identity = readClientCertificate() { + return sessionCredential(identity: identity) + } else { + return nil + } + } + + /// クライアント証明書を書き込む。 + func writeClientCertificate(identity: SecIdentity) { + writeIdentity(label: kClientCertLabel, identity: identity) + } + + /// クライアント証明書を削除する。 + func removeClientCertificate() { + removeIdentity(label: kClientCertLabel) + } + + private func readIdentity(label: String) -> SecIdentity? { + let query: [String: Any] = [ + kSecClass as String: kSecClassIdentity, + kSecAttrLabel as String: label, + kSecReturnRef as String: true, + kSecReturnPersistentRef as String: true + ] + var result: CFTypeRef? = nil + let status = SecItemCopyMatching(query as CFDictionary, &result) + switch status { + case errSecSuccess: + if let result = result { + let dic = result as! [String: Any] + let identity = dic[kSecValueRef as String] as! SecIdentity + return identity + } else { + log.error("unexpected nil result") + return nil + } + + case errSecItemNotFound: + return nil + + default: + log.error("keychain reading error: OSStatus = \(status)") + return nil + } + } + + private func writeIdentity(label: String, identity: SecIdentity) { + let query: [String: Any] = [ + kSecValueRef as String: identity, + kSecAttrLabel as String: label, + ] + let status = SecItemAdd(query as CFDictionary, nil) + if status != errSecSuccess { + log.error("keychain writing error: OSStatus = \(status)") + } + } + + private func removeIdentity(label: String) { + let query: [String: Any] = [ + kSecClass as String: kSecClassIdentity, + kSecAttrLabel as String: label + ] + let status = SecItemDelete(query as CFDictionary) + if status != errSecSuccess { + log.error("keychain writing error: OSStatus = \(status)") + } + } + + private func sessionCredential(identity: SecIdentity) -> URLCredential { + return URLCredential(identity: identity, certificates: nil, persistence: .forSession) + } +} diff --git a/AgileWorks/Common/DataStore/OldServerKeychainDataStore.swift b/AgileWorks/Common/DataStore/OldServerKeychainDataStore.swift new file mode 100644 index 0000000..a6e3446 --- /dev/null +++ b/AgileWorks/Common/DataStore/OldServerKeychainDataStore.swift @@ -0,0 +1,165 @@ +// +// OldServerKeychainDataStore.swift +// AgileWorks +// +// Created by Gk40002148 on 2023/12/06. +// Copyright © 2023 ATLED CORP. All rights reserved. +// + +import AppAuth +import KeychainAccess +import UIKit + +final class OldServerKeychainDataStore: 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" + private let kServerURL: String = "ServerURL" + private let kContextPath: String = "ContextPath" + private let kDeviceID: String = "DeviceID" + private let kSessionID: String = "SessionID" + + // アクセストークンの書き込み + func writeAccessToken(accessToken: String) { + setKeychainValue(key: kAccessToken, value: accessToken) + } + + // アクセストークンの読み込み + func readAccessToken() -> String? { + return getKeychainValue(key: kAccessToken) + } + + // アクセストークンの削除 + func removeAccessToken() { + removeKeychainValue(key: kAccessToken) + } + + // 認可ステータスの書き込み + func writeOAuthState(authState: OIDAuthState) { + let keychain = Keychain(service: service, accessGroup: groupId) + guard let object = try? NSKeyedArchiver.archivedData(withRootObject: authState, requiringSecureCoding: true) else { + return + } + keychain[data: kOAuthState] = object + } + + // 認可ステータスの読み込み + func readOAuthState() -> OIDAuthState? { + let keychain = Keychain(service: service, accessGroup: groupId) + if let object = keychain[data: kOAuthState] { + guard let authState = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(object) as? OIDAuthState else { + return nil + } + return authState + } + return nil + } + + // 認可ステータスの削除 + func removeOAuthState() { + removeKeychainValue(key: kOAuthState) + } + + // 言語設定の書き込み + func writeLanguage(language: String) { + setKeychainValue(key: kLanguage, value: language) + } + + // 言語設定の読み込み + func readLanguage() -> String? { + return getKeychainValue(key: kLanguage) + } + + // 言語設定の削除 + func removeLanguage() { + removeKeychainValue(key: kLanguage) + } + + // サーバーURLの書き込み + func writeServerURL(serverURL: String) { + setKeychainValue(key: kServerURL, value: serverURL) + } + + // サーバーURLの読み込み + func readServerURL() -> String? { + return getKeychainValue(key: kServerURL) + } + + // サーバーURLの削除 + func removeServerURL() { + removeKeychainValue(key: kServerURL) + } + + // コンテキストパスの書き込み + func writeContextPath(contextPath: String) { + setKeychainValue(key: kContextPath, value: contextPath) + } + + // コンテキストパスの読み込み + func readContextPath() -> String? { + return getKeychainValue(key: kContextPath) + } + + // コンテキストパスの削除 + func removeContextPath() { + removeKeychainValue(key: kContextPath) + } + + // デバイスIDの書き込み + func writeDeviceID(deviceID: Int) { + setKeychainValue(key: kDeviceID, value: deviceID.description) + } + + // デバイスIDの読み込み + func readDeviceID() -> Int? { + guard let deviceIDString = getKeychainValue(key: kDeviceID) else { + return nil + } + guard let deviceID = Int(deviceIDString) else { + return nil + } + return deviceID + } + + // デバイスIDの削除 + func removeDeviceID() { + removeKeychainValue(key: kDeviceID) + } + + // セッションIDの書き込み + func writeSessionID(sessionID: String) { + setKeychainValue(key: kSessionID, value: sessionID) + } + + // セッションIDの読み込み + func readSessionID() -> String? { + return getKeychainValue(key: kSessionID) + } + + // セッションIDの削除 + func removeSessionID() { + removeKeychainValue(key: kSessionID) + } + + // KeyChain へ指定の値をセット + private func setKeychainValue(key: String, value: String) { + let keychain = Keychain(service: service, accessGroup: groupId) + keychain[key] = value + } + // KeyChain から指定の値を取得 + private func getKeychainValue(key: String) -> String? { + let keychain = Keychain(service: service, accessGroup: groupId) + return keychain[key] + } + // KeyChain から指定の値を削除 + private func removeKeychainValue(key: String) { + let keychain = Keychain(service: service, accessGroup: groupId) + do { + try keychain.remove(key) + } catch { + log.e(error) + } + } +} -- GitLab From 22ed1cbd2af0f15f31662385df758f84433ab49a Mon Sep 17 00:00:00 2001 From: Gk40002148 Date: Mon, 11 Dec 2023 21:12:56 +0900 Subject: [PATCH 32/36] =?UTF-8?q?=E3=82=A2=E3=83=97=E3=83=AA=E3=82=A2?= =?UTF-8?q?=E3=83=83=E3=83=97=E3=83=87=E3=83=BC=E3=83=88=E5=AF=BE=E5=BF=9C?= =?UTF-8?q?=20=E6=97=A7=E3=82=A2=E3=83=97=E3=83=AA=E6=83=85=E5=A0=B1?= =?UTF-8?q?=E5=BC=95=E3=81=8D=E7=B6=99=E3=81=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks.xcodeproj/project.pbxproj | 10 ++++- .../AgileWorks-Production.entitlements | 1 + .../AgileWorksRelease-Production.entitlements | 1 + .../Splash/View/SplashViewController.swift | 41 +++++++++++++++++++ 4 files changed, 52 insertions(+), 1 deletion(-) diff --git a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj index 12a7cb6..27e433d 100644 --- a/AgileWorks/AgileWorks.xcodeproj/project.pbxproj +++ b/AgileWorks/AgileWorks.xcodeproj/project.pbxproj @@ -3,7 +3,7 @@ archiveVersion = 1; classes = { }; - objectVersion = 52; + objectVersion = 54; objects = { /* Begin PBXBuildFile section */ @@ -185,6 +185,8 @@ C57DCAB027C8AEFC000A2ABC /* ProfileTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C57DCAAF27C8AEFC000A2ABC /* ProfileTableViewController.swift */; }; C5848EB827BC8EBC00AA796D /* MenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5848EB727BC8EBB00AA796D /* MenuViewController.swift */; }; C5848EBA27BCE0F100AA796D /* MenuTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C5848EB927BCE0F100AA796D /* MenuTableViewController.swift */; }; + C58DE59F2B2717B40004C4E6 /* OldServerCertificateDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C58DE59D2B2717B40004C4E6 /* OldServerCertificateDataStore.swift */; }; + C58DE5A02B2717B40004C4E6 /* OldServerKeychainDataStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = C58DE59E2B2717B40004C4E6 /* OldServerKeychainDataStore.swift */; }; C599740827D992A5006F5AAC /* OpenLicenseTableViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C599740727D992A5006F5AAC /* OpenLicenseTableViewController.swift */; }; C599740B27D992E9006F5AAC /* OpenLicenseTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C599740A27D992E9006F5AAC /* OpenLicenseTableViewCell.swift */; }; C599740D27D9E634006F5AAC /* OpenLicenseDetailViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C599740C27D9E633006F5AAC /* OpenLicenseDetailViewController.swift */; }; @@ -409,6 +411,8 @@ C57DCAAF27C8AEFC000A2ABC /* ProfileTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileTableViewController.swift; sourceTree = ""; }; C5848EB727BC8EBB00AA796D /* MenuViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuViewController.swift; sourceTree = ""; }; C5848EB927BCE0F100AA796D /* MenuTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuTableViewController.swift; sourceTree = ""; }; + C58DE59D2B2717B40004C4E6 /* OldServerCertificateDataStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OldServerCertificateDataStore.swift; sourceTree = ""; }; + C58DE59E2B2717B40004C4E6 /* OldServerKeychainDataStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OldServerKeychainDataStore.swift; sourceTree = ""; }; C599740727D992A5006F5AAC /* OpenLicenseTableViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenLicenseTableViewController.swift; sourceTree = ""; }; C599740A27D992E9006F5AAC /* OpenLicenseTableViewCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenLicenseTableViewCell.swift; sourceTree = ""; }; C599740C27D9E633006F5AAC /* OpenLicenseDetailViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OpenLicenseDetailViewController.swift; sourceTree = ""; }; @@ -716,6 +720,8 @@ BD0231F2242B6E06000A95BB /* DataStore */ = { isa = PBXGroup; children = ( + C58DE59D2B2717B40004C4E6 /* OldServerCertificateDataStore.swift */, + C58DE59E2B2717B40004C4E6 /* OldServerKeychainDataStore.swift */, BD5061B3242866780014F3FA /* Configuration.swift */, BD928CCD2407500400ED04C2 /* UserDefaultsDataStore.swift */, BDEA2CD4246CDAEF00D3E15F /* KeychainDataStore.swift */, @@ -1532,11 +1538,13 @@ files = ( 764D0DB5257F450500AB6617 /* CertificateDataStore.swift in Sources */, C5E5A4C827853BEF00668C7D /* QRCodeReader.swift in Sources */, + C58DE59F2B2717B40004C4E6 /* OldServerCertificateDataStore.swift in Sources */, BD6C1AE424A471070057756F /* PutDeviceEndpoint.swift in Sources */, BDA1831323F3FD7F00C9A6DD /* AppDelegate.swift in Sources */, BD3E90862474F50B00B449A7 /* IntExtensions.swift in Sources */, C5848EB827BC8EBC00AA796D /* MenuViewController.swift in Sources */, BDA74C5624501917000D4351 /* Log.swift in Sources */, + C58DE5A02B2717B40004C4E6 /* OldServerKeychainDataStore.swift in Sources */, 85X3ZXEG18PWU7J17GNGF3UG /* SplashPresenter.swift in Sources */, KQWCT9WOHFNQBPP7I7C3OL6Q /* SplashViewController.swift in Sources */, BDBBF838243C9EA300EEB25D /* GetApprovalsEndpoint.swift in Sources */, diff --git a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements index 002355e..f691bfa 100644 --- a/AgileWorks/AgileWorks/AgileWorks-Production.entitlements +++ b/AgileWorks/AgileWorks/AgileWorks-Production.entitlements @@ -15,6 +15,7 @@ $(AppIdentifierPrefix)jp.atled.agileworks2 $(AppIdentifierPrefix)jp.atled.agileworks3 $(AppIdentifierPrefix)jp.atled.agileworks4 + $(AppIdentifierPrefix)jp.atled.agileworks diff --git a/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements b/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements index 002355e..f691bfa 100644 --- a/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements +++ b/AgileWorks/AgileWorks/AgileWorksRelease-Production.entitlements @@ -15,6 +15,7 @@ $(AppIdentifierPrefix)jp.atled.agileworks2 $(AppIdentifierPrefix)jp.atled.agileworks3 $(AppIdentifierPrefix)jp.atled.agileworks4 + $(AppIdentifierPrefix)jp.atled.agileworks diff --git a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift index efa76c5..a0189f5 100644 --- a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift +++ b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift @@ -46,6 +46,9 @@ class SplashViewController: UIViewController { private func makeServiceCall() { activityIndicator.startAnimating() + + // サーバ情報引き継ぎ + updateServerSettings() let serverList = UserDefaultsDataStore().readServerList() if !serverList.isEmpty { @@ -104,6 +107,44 @@ class SplashViewController: UIViewController { } } } + + // サーバ切り替え対応前アプリのサーバ情報引き継ぎ + private func updateServerSettings() { + // 旧バージョン時のログイン情報を引き継ぐ + guard OldServerKeychainDataStore().readOAuthState() != nil { + // 旧Keychainに保存されてる内容を、0番目のKeychainにコピーして、旧Keychain情報をクリアする + let keychain = KeychainDataStore() + let oldKeychain = OldServerKeychainDataStore() + keychain.writeAccessToken(accessToken: oldKeychain.readAccessToken()) + keychain.writeOAuthState(authState: oldKeychain.readOAuthState()) + keychain.writeLanguage(language: oldKeychain.readLanguage()) + keychain.writeServerURL(serverURL: oldKeychain.readServerURL()) + keychain.writeContextPath(contextPath: oldKeychain.readContextPath()) + keychain.writeDeviceID(deviceID: oldKeychain.readDeviceID()) + keychain.writeSessionID(sessionID: oldKeychain.readSessionID()) + // 旧情報クリア + oldKeychain.removeAccessToken() + oldKeychain.removeOAuthState() + oldKeychain.removeLanguage() + oldKeychain.removeServerURL() + oldKeychain.removeContextPath() + oldKeychain.removeDeviceID() + oldKeychain.removeSessionID() + // サーバリストの追加 + UserDefaultsDataStore().addServerList() + } + + // クライアント証明書の引き継ぎ + guard OldServerCertificateDataStore().readClientCertificate() != nil { + let label = CertificateDataStore().writeNewClientCertificate(identity: OldServerCertificateDataStore().readClientCertificate()!) + // 旧バージョンでクライアント証明書が設定されている=クライアント証明書を使用しての通信を実施しているので + // その情報も引き継ぐ + KeychainDataStore().writeCertificateLabel(label: "ClientCert" + label) + // 証明書情報削除 + OldServerCertificateDataStore().removeClientCertificate() + } + } + } extension SplashViewController: SplashView { -- GitLab From 8eaddf86aebfe81651cace28982f2ea4607d556a Mon Sep 17 00:00:00 2001 From: sbc Date: Mon, 11 Dec 2023 21:27:24 +0900 Subject: [PATCH 33/36] =?UTF-8?q?=E3=82=A8=E3=83=A9=E3=83=BC=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Splash/View/SplashViewController.swift | 59 ++++++++++--------- .../OldServerCertificateDataStore.swift | 2 +- 2 files changed, 32 insertions(+), 29 deletions(-) diff --git a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift index a0189f5..16d2b12 100644 --- a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift +++ b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift @@ -111,38 +111,41 @@ class SplashViewController: UIViewController { // サーバ切り替え対応前アプリのサーバ情報引き継ぎ private func updateServerSettings() { // 旧バージョン時のログイン情報を引き継ぐ - guard OldServerKeychainDataStore().readOAuthState() != nil { - // 旧Keychainに保存されてる内容を、0番目のKeychainにコピーして、旧Keychain情報をクリアする - let keychain = KeychainDataStore() - let oldKeychain = OldServerKeychainDataStore() - keychain.writeAccessToken(accessToken: oldKeychain.readAccessToken()) - keychain.writeOAuthState(authState: oldKeychain.readOAuthState()) - keychain.writeLanguage(language: oldKeychain.readLanguage()) - keychain.writeServerURL(serverURL: oldKeychain.readServerURL()) - keychain.writeContextPath(contextPath: oldKeychain.readContextPath()) - keychain.writeDeviceID(deviceID: oldKeychain.readDeviceID()) - keychain.writeSessionID(sessionID: oldKeychain.readSessionID()) - // 旧情報クリア - oldKeychain.removeAccessToken() - oldKeychain.removeOAuthState() - oldKeychain.removeLanguage() - oldKeychain.removeServerURL() - oldKeychain.removeContextPath() - oldKeychain.removeDeviceID() - oldKeychain.removeSessionID() - // サーバリストの追加 - UserDefaultsDataStore().addServerList() + guard OldServerKeychainDataStore().readOAuthState() != nil else { + return } + // 旧Keychainに保存されてる内容を、0番目のKeychainにコピーして、旧Keychain情報をクリアする + let keychain = KeychainDataStore() + let oldKeychain = OldServerKeychainDataStore() + + keychain.writeAccessToken(accessToken: oldKeychain.readAccessToken()!) + keychain.writeOAuthState(authState: oldKeychain.readOAuthState()!) + keychain.writeLanguage(language: oldKeychain.readLanguage()!) + keychain.writeServerURL(serverURL: oldKeychain.readServerURL()!) + keychain.writeContextPath(contextPath: oldKeychain.readContextPath()!) + keychain.writeDeviceID(deviceID: oldKeychain.readDeviceID()!) + keychain.writeSessionID(sessionID: oldKeychain.readSessionID()!) + // 旧情報クリア + oldKeychain.removeAccessToken() + oldKeychain.removeOAuthState() + oldKeychain.removeLanguage() + oldKeychain.removeServerURL() + oldKeychain.removeContextPath() + oldKeychain.removeDeviceID() + oldKeychain.removeSessionID() + // サーバリストの追加 + UserDefaultsDataStore().addServerList() // クライアント証明書の引き継ぎ - guard OldServerCertificateDataStore().readClientCertificate() != nil { - let label = CertificateDataStore().writeNewClientCertificate(identity: OldServerCertificateDataStore().readClientCertificate()!) - // 旧バージョンでクライアント証明書が設定されている=クライアント証明書を使用しての通信を実施しているので - // その情報も引き継ぐ - KeychainDataStore().writeCertificateLabel(label: "ClientCert" + label) - // 証明書情報削除 - OldServerCertificateDataStore().removeClientCertificate() + guard OldServerCertificateDataStore().readClientCertificate() != nil else { + return } + let label = CertificateDataStore().writeNewClientCertificate(identity: OldServerCertificateDataStore().readClientCertificate()!) + // 旧バージョンでクライアント証明書が設定されている=クライアント証明書を使用しての通信を実施しているので + // その情報も引き継ぐ + KeychainDataStore().writeCertificateLabel(label: "ClientCert" + label!) + // 証明書情報削除 + OldServerCertificateDataStore().removeClientCertificate() } } diff --git a/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift b/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift index 970a625..6b4ce7c 100644 --- a/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift +++ b/AgileWorks/Common/DataStore/OldServerCertificateDataStore.swift @@ -9,7 +9,7 @@ import Foundation // クライアント証明書格納用ラベル -let kClientCertLabel = "ClientCert" +//let clientCertLabel = "ClientCert" /// 証明書情報のデータストア。 /// -- GitLab From a1b9246cd208e010d8fd011a9cd412b52d7e41c5 Mon Sep 17 00:00:00 2001 From: sbc Date: Mon, 11 Dec 2023 21:35:52 +0900 Subject: [PATCH 34/36] =?UTF-8?q?=E3=83=A9=E3=82=A4=E3=82=BB=E3=83=B3?= =?UTF-8?q?=E3=82=B9=E3=81=AE=E5=90=8C=E6=84=8F=E7=8A=B6=E6=85=8B=E5=BC=95?= =?UTF-8?q?=E3=81=8D=E7=B6=99=E3=81=8E?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/Splash/View/SplashViewController.swift | 3 +++ 1 file changed, 3 insertions(+) diff --git a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift index 16d2b12..2469937 100644 --- a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift +++ b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift @@ -135,6 +135,9 @@ class SplashViewController: UIViewController { oldKeychain.removeSessionID() // サーバリストの追加 UserDefaultsDataStore().addServerList() + + // ライセンス情報は同意済みのため、現バージョンをセット + writeAcceptedLicenseVersionToCurrentVersion() // クライアント証明書の引き継ぎ guard OldServerCertificateDataStore().readClientCertificate() != nil else { -- GitLab From c1b8088924488e4b6c79bff8790d47c01946ed17 Mon Sep 17 00:00:00 2001 From: sbc Date: Tue, 12 Dec 2023 20:25:22 +0900 Subject: [PATCH 35/36] =?UTF-8?q?=E8=AD=A6=E5=91=8A=E9=99=A4=E5=8E=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AgileWorks/Splash/View/SplashViewController.swift | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift index 2469937..994f0f4 100644 --- a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift +++ b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift @@ -45,8 +45,7 @@ class SplashViewController: UIViewController { } private func makeServiceCall() { - activityIndicator.startAnimating() - + // サーバ情報引き継ぎ updateServerSettings() @@ -107,7 +106,7 @@ class SplashViewController: UIViewController { } } } - + // サーバ切り替え対応前アプリのサーバ情報引き継ぎ private func updateServerSettings() { // 旧バージョン時のログイン情報を引き継ぐ @@ -117,7 +116,6 @@ class SplashViewController: UIViewController { // 旧Keychainに保存されてる内容を、0番目のKeychainにコピーして、旧Keychain情報をクリアする let keychain = KeychainDataStore() let oldKeychain = OldServerKeychainDataStore() - keychain.writeAccessToken(accessToken: oldKeychain.readAccessToken()!) keychain.writeOAuthState(authState: oldKeychain.readOAuthState()!) keychain.writeLanguage(language: oldKeychain.readLanguage()!) @@ -135,10 +133,8 @@ class SplashViewController: UIViewController { oldKeychain.removeSessionID() // サーバリストの追加 UserDefaultsDataStore().addServerList() - // ライセンス情報は同意済みのため、現バージョンをセット writeAcceptedLicenseVersionToCurrentVersion() - // クライアント証明書の引き継ぎ guard OldServerCertificateDataStore().readClientCertificate() != nil else { return @@ -150,7 +146,6 @@ class SplashViewController: UIViewController { // 証明書情報削除 OldServerCertificateDataStore().removeClientCertificate() } - } extension SplashViewController: SplashView { -- GitLab From da769f564d6a7f6d2fedb551d3965c7bb7523e57 Mon Sep 17 00:00:00 2001 From: sbc Date: Tue, 12 Dec 2023 22:09:17 +0900 Subject: [PATCH 36/36] =?UTF-8?q?=E5=89=8A=E9=99=A4=E3=81=97=E3=81=99?= =?UTF-8?q?=E3=81=8E=E3=81=9F=E3=82=B3=E3=83=BC=E3=83=89=E5=BE=A9=E6=B4=BB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- AgileWorks/AgileWorks/Splash/View/SplashViewController.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift index 994f0f4..de7daea 100644 --- a/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift +++ b/AgileWorks/AgileWorks/Splash/View/SplashViewController.swift @@ -45,6 +45,7 @@ class SplashViewController: UIViewController { } private func makeServiceCall() { + activityIndicator.startAnimating() // サーバ情報引き継ぎ updateServerSettings() -- GitLab