Commit dabd9d58 authored by shigemi miura's avatar shigemi miura

画像送信関連修正

parent 8af9e919
PODS: PODS:
- AzureNotificationHubs-iOS (3.1.5) - AzureNotificationHubs-iOS (3.1.5)
- SwiftSignalRClient (1.0.0) - SwiftSignalRClient (1.1.0)
DEPENDENCIES: DEPENDENCIES:
- AzureNotificationHubs-iOS - AzureNotificationHubs-iOS
...@@ -13,7 +13,7 @@ SPEC REPOS: ...@@ -13,7 +13,7 @@ SPEC REPOS:
SPEC CHECKSUMS: SPEC CHECKSUMS:
AzureNotificationHubs-iOS: e5de62f44d7915a5cc3c5194ddc57cf2ee78873e AzureNotificationHubs-iOS: e5de62f44d7915a5cc3c5194ddc57cf2ee78873e
SwiftSignalRClient: f9a23a0407d490a799cc1a3c8835b8611128d76c SwiftSignalRClient: 2fa651ea18d47c5aaa135f0c8cf959239c845999
PODFILE CHECKSUM: bbdabe3b255c91674ba1766a3ec70d307854a5a9 PODFILE CHECKSUM: bbdabe3b255c91674ba1766a3ec70d307854a5a9
......
PODS: PODS:
- AzureNotificationHubs-iOS (3.1.5) - AzureNotificationHubs-iOS (3.1.5)
- SwiftSignalRClient (1.0.0) - SwiftSignalRClient (1.1.0)
DEPENDENCIES: DEPENDENCIES:
- AzureNotificationHubs-iOS - AzureNotificationHubs-iOS
...@@ -13,7 +13,7 @@ SPEC REPOS: ...@@ -13,7 +13,7 @@ SPEC REPOS:
SPEC CHECKSUMS: SPEC CHECKSUMS:
AzureNotificationHubs-iOS: e5de62f44d7915a5cc3c5194ddc57cf2ee78873e AzureNotificationHubs-iOS: e5de62f44d7915a5cc3c5194ddc57cf2ee78873e
SwiftSignalRClient: f9a23a0407d490a799cc1a3c8835b8611128d76c SwiftSignalRClient: 2fa651ea18d47c5aaa135f0c8cf959239c845999
PODFILE CHECKSUM: bbdabe3b255c91674ba1766a3ec70d307854a5a9 PODFILE CHECKSUM: bbdabe3b255c91674ba1766a3ec70d307854a5a9
......
...@@ -116,10 +116,5 @@ There are several sample projects in the `Examples` folder. They include: ...@@ -116,10 +116,5 @@ There are several sample projects in the `Examples` folder. They include:
**"Failed to bind to address http://0.0.0.0:5000: address already in use."**. This is due to Apple now advertising an 'AirPlay Receiver' on that port. **"Failed to bind to address http://0.0.0.0:5000: address already in use."**. This is due to Apple now advertising an 'AirPlay Receiver' on that port.
This port can be freed by disabling the receiver: Navigate to _System Preferences > Sharing_ and uncheck _AirPlay Receiver_. This port can be freed by disabling the receiver: Navigate to _System Preferences > Sharing_ and uncheck _AirPlay Receiver_.
## Disclaimer
I am providing code in the repository to you under an open source license. Because this is my personal repository, the license you receive to my code is from me
and not my employer (Facebook)
## Hits ## Hits
[![HitCount](http://hits.dwyl.com/moozzyk/Signalr-Client-Swift.svg)](http://hits.dwyl.com/moozzyk/Signalr-Client-Swift) [![HitCount](http://hits.dwyl.com/moozzyk/Signalr-Client-Swift.svg)](http://hits.dwyl.com/moozzyk/Signalr-Client-Swift)
...@@ -48,6 +48,13 @@ public class HttpConnectionOptions { ...@@ -48,6 +48,13 @@ public class HttpConnectionOptions {
*/ */
public var requestTimeout: TimeInterval = 120 public var requestTimeout: TimeInterval = 120
/**
The maximum number of bytes to buffer before the receive call fails with an error.
This value includes the sum of all bytes from continuation frames. Receive calls will fail once the task reaches this limit. (URLSessionWebSocketTask)
*/
public var maximumWebsocketMessageSize: Int?
public var authenticationChallengeHandler: ((_ session: URLSession, _ challenge: URLAuthenticationChallenge, _ completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) -> Void)? public var authenticationChallengeHandler: ((_ session: URLSession, _ challenge: URLAuthenticationChallenge, _ completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) -> Void)?
/** /**
......
...@@ -171,6 +171,7 @@ public class HubConnectionBuilder { ...@@ -171,6 +171,7 @@ public class HubConnectionBuilder {
httpConnectionOptionsCopy.skipNegotiation = httpConnectionOptions.skipNegotiation httpConnectionOptionsCopy.skipNegotiation = httpConnectionOptions.skipNegotiation
} }
httpConnectionOptionsCopy.requestTimeout = httpConnectionOptions.requestTimeout httpConnectionOptionsCopy.requestTimeout = httpConnectionOptions.requestTimeout
httpConnectionOptionsCopy.maximumWebsocketMessageSize = httpConnectionOptions.maximumWebsocketMessageSize
httpConnectionOptionsCopy.callbackQueue = httpConnectionOptions.callbackQueue httpConnectionOptionsCopy.callbackQueue = httpConnectionOptions.callbackQueue
httpConnectionOptionsCopy.authenticationChallengeHandler = httpConnectionOptions.authenticationChallengeHandler httpConnectionOptionsCopy.authenticationChallengeHandler = httpConnectionOptions.authenticationChallengeHandler
return HttpConnection(url: url, options: httpConnectionOptionsCopy, transportFactory: transportFactory, logger: logger) return HttpConnection(url: url, options: httpConnectionOptionsCopy, transportFactory: transportFactory, logger: logger)
......
...@@ -35,6 +35,9 @@ public class WebsocketsTransport: NSObject, Transport, URLSessionWebSocketDelega ...@@ -35,6 +35,9 @@ public class WebsocketsTransport: NSObject, Transport, URLSessionWebSocketDelega
setAccessToken(accessTokenProvider: options.accessTokenProvider, request: &request) setAccessToken(accessTokenProvider: options.accessTokenProvider, request: &request)
urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue()) urlSession = URLSession(configuration: .default, delegate: self, delegateQueue: OperationQueue())
webSocketTask = urlSession!.webSocketTask(with: request) webSocketTask = urlSession!.webSocketTask(with: request)
if let maximumWebsocketMessageSize = options.maximumWebsocketMessageSize {
webSocketTask?.maximumMessageSize = maximumWebsocketMessageSize
}
webSocketTask!.resume() webSocketTask!.resume()
} }
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0.0</string> <string>1.1.0</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
......
...@@ -111,6 +111,8 @@ ...@@ -111,6 +111,8 @@
D59908C62B19EA70000E13DD /* ResPushHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59908C52B19EA70000E13DD /* ResPushHistory.swift */; }; D59908C62B19EA70000E13DD /* ResPushHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59908C52B19EA70000E13DD /* ResPushHistory.swift */; };
D59908C82B1ABD43000E13DD /* SessionPushHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59908C72B1ABD43000E13DD /* SessionPushHistory.swift */; }; D59908C82B1ABD43000E13DD /* SessionPushHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59908C72B1ABD43000E13DD /* SessionPushHistory.swift */; };
D59908CA2B1AC381000E13DD /* GetPushHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59908C92B1AC381000E13DD /* GetPushHistory.swift */; }; D59908CA2B1AC381000E13DD /* GetPushHistory.swift in Sources */ = {isa = PBXBuildFile; fileRef = D59908C92B1AC381000E13DD /* GetPushHistory.swift */; };
D5A4C2532E7AB48700642D7D /* SpeechRecognizer.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5A4C2522E7AB46B00642D7D /* SpeechRecognizer.swift */; };
D5AAB69D2E7A5E8F0027CD90 /* AlertModifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AAB69C2E7A5E8F0027CD90 /* AlertModifiers.swift */; };
D5AE351A2AEBA66A00059889 /* ReqLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AE35182AEBA66A00059889 /* ReqLogin.swift */; }; D5AE351A2AEBA66A00059889 /* ReqLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AE35182AEBA66A00059889 /* ReqLogin.swift */; };
D5AE351B2AEBA66A00059889 /* ResLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AE35192AEBA66A00059889 /* ResLogin.swift */; }; D5AE351B2AEBA66A00059889 /* ResLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AE35192AEBA66A00059889 /* ResLogin.swift */; };
D5AE351D2AEBA6FC00059889 /* SessionLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AE351C2AEBA6FC00059889 /* SessionLogin.swift */; }; D5AE351D2AEBA6FC00059889 /* SessionLogin.swift in Sources */ = {isa = PBXBuildFile; fileRef = D5AE351C2AEBA6FC00059889 /* SessionLogin.swift */; };
...@@ -284,6 +286,8 @@ ...@@ -284,6 +286,8 @@
D59908C52B19EA70000E13DD /* ResPushHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ResPushHistory.swift; path = Sailassist/Json/ResPushHistory.swift; sourceTree = SOURCE_ROOT; }; D59908C52B19EA70000E13DD /* ResPushHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = ResPushHistory.swift; path = Sailassist/Json/ResPushHistory.swift; sourceTree = SOURCE_ROOT; };
D59908C72B1ABD43000E13DD /* SessionPushHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionPushHistory.swift; path = Sailassist/ServerSession/SessionPushHistory.swift; sourceTree = SOURCE_ROOT; }; D59908C72B1ABD43000E13DD /* SessionPushHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = SessionPushHistory.swift; path = Sailassist/ServerSession/SessionPushHistory.swift; sourceTree = SOURCE_ROOT; };
D59908C92B1AC381000E13DD /* GetPushHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GetPushHistory.swift; path = Sailassist/Alert/GetPushHistory.swift; sourceTree = SOURCE_ROOT; }; D59908C92B1AC381000E13DD /* GetPushHistory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = GetPushHistory.swift; path = Sailassist/Alert/GetPushHistory.swift; sourceTree = SOURCE_ROOT; };
D5A4C2522E7AB46B00642D7D /* SpeechRecognizer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SpeechRecognizer.swift; sourceTree = "<group>"; };
D5AAB69C2E7A5E8F0027CD90 /* AlertModifiers.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AlertModifiers.swift; sourceTree = "<group>"; };
D5AE35182AEBA66A00059889 /* ReqLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ReqLogin.swift; path = Sailassist/Json/ReqLogin.swift; sourceTree = SOURCE_ROOT; }; D5AE35182AEBA66A00059889 /* ReqLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ReqLogin.swift; path = Sailassist/Json/ReqLogin.swift; sourceTree = SOURCE_ROOT; };
D5AE35192AEBA66A00059889 /* ResLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ResLogin.swift; path = Sailassist/Json/ResLogin.swift; sourceTree = SOURCE_ROOT; }; D5AE35192AEBA66A00059889 /* ResLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = ResLogin.swift; path = Sailassist/Json/ResLogin.swift; sourceTree = SOURCE_ROOT; };
D5AE351C2AEBA6FC00059889 /* SessionLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SessionLogin.swift; path = Sailassist/ServerSession/SessionLogin.swift; sourceTree = SOURCE_ROOT; }; D5AE351C2AEBA6FC00059889 /* SessionLogin.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = SessionLogin.swift; path = Sailassist/ServerSession/SessionLogin.swift; sourceTree = SOURCE_ROOT; };
...@@ -439,7 +443,7 @@ ...@@ -439,7 +443,7 @@
020B983E2AD8C3500029DE4C /* Tab */ = { 020B983E2AD8C3500029DE4C /* Tab */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
02C3E5CF2AFCC15700AF7837 /* View */, D5AAB69C2E7A5E8F0027CD90 /* AlertModifiers.swift */,
02CE4DC92ADF9D2E002E79BC /* ViewModel */, 02CE4DC92ADF9D2E002E79BC /* ViewModel */,
020B98582AD92A4C0029DE4C /* MainTabView.swift */, 020B98582AD92A4C0029DE4C /* MainTabView.swift */,
); );
...@@ -617,6 +621,7 @@ ...@@ -617,6 +621,7 @@
02A1DE2D2AFB497B005BCF55 /* View */ = { 02A1DE2D2AFB497B005BCF55 /* View */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
D5A4C2522E7AB46B00642D7D /* SpeechRecognizer.swift */,
02C3E5D02AFCC16800AF7837 /* ChatTitleView.swift */, 02C3E5D02AFCC16800AF7837 /* ChatTitleView.swift */,
02A1DE2E2AFB4AA0005BCF55 /* ChatInputView.swift */, 02A1DE2E2AFB4AA0005BCF55 /* ChatInputView.swift */,
02A1DE302AFB61D8005BCF55 /* MyChatContentView.swift */, 02A1DE302AFB61D8005BCF55 /* MyChatContentView.swift */,
...@@ -630,13 +635,6 @@ ...@@ -630,13 +635,6 @@
path = View; path = View;
sourceTree = "<group>"; sourceTree = "<group>";
}; };
02C3E5CF2AFCC15700AF7837 /* View */ = {
isa = PBXGroup;
children = (
);
path = View;
sourceTree = "<group>";
};
02CE4D7D2ADE4297002E79BC /* View */ = { 02CE4D7D2ADE4297002E79BC /* View */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
...@@ -1103,7 +1101,9 @@ ...@@ -1103,7 +1101,9 @@
D5258CA32B036CC500365276 /* SessionGetMessage.swift in Sources */, D5258CA32B036CC500365276 /* SessionGetMessage.swift in Sources */,
D52C2C082B9195A8003B286C /* MenuInformationView.swift in Sources */, D52C2C082B9195A8003B286C /* MenuInformationView.swift in Sources */,
D5258C992B0334BF00365276 /* SessionShipStatus.swift in Sources */, D5258C992B0334BF00365276 /* SessionShipStatus.swift in Sources */,
D5AAB69D2E7A5E8F0027CD90 /* AlertModifiers.swift in Sources */,
02CE4D872ADF62A7002E79BC /* EcaListView.swift in Sources */, 02CE4D872ADF62A7002E79BC /* EcaListView.swift in Sources */,
D5A4C2532E7AB48700642D7D /* SpeechRecognizer.swift in Sources */,
D5E008762B2ADD5900C4070A /* MenuManualRADARView.swift in Sources */, D5E008762B2ADD5900C4070A /* MenuManualRADARView.swift in Sources */,
D59908C62B19EA70000E13DD /* ResPushHistory.swift in Sources */, D59908C62B19EA70000E13DD /* ResPushHistory.swift in Sources */,
D58EF2472B9044C800FB784C /* ResInformation.swift in Sources */, D58EF2472B9044C800FB784C /* ResInformation.swift in Sources */,
...@@ -1281,7 +1281,7 @@ ...@@ -1281,7 +1281,7 @@
CODE_SIGN_ENTITLEMENTS = Sailassist/Sailassist.entitlements; CODE_SIGN_ENTITLEMENTS = Sailassist/Sailassist.entitlements;
CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_IDENTITY = "Apple Development";
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 58; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_ASSET_PATHS = "\"Sailassist/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"Sailassist/Preview Content\"";
DEVELOPMENT_TEAM = D2DC7QNNJ8; DEVELOPMENT_TEAM = D2DC7QNNJ8;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
...@@ -1330,7 +1330,7 @@ ...@@ -1330,7 +1330,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Sailassist/Sailassist.entitlements; CODE_SIGN_ENTITLEMENTS = Sailassist/Sailassist.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 58; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_ASSET_PATHS = "\"Sailassist/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"Sailassist/Preview Content\"";
DEVELOPMENT_TEAM = D2DC7QNNJ8; DEVELOPMENT_TEAM = D2DC7QNNJ8;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
...@@ -1516,7 +1516,7 @@ ...@@ -1516,7 +1516,7 @@
ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor;
CODE_SIGN_ENTITLEMENTS = Sailassist/Sailassist.entitlements; CODE_SIGN_ENTITLEMENTS = Sailassist/Sailassist.entitlements;
CODE_SIGN_STYLE = Automatic; CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 58; CURRENT_PROJECT_VERSION = 62;
DEVELOPMENT_ASSET_PATHS = "\"Sailassist/Preview Content\""; DEVELOPMENT_ASSET_PATHS = "\"Sailassist/Preview Content\"";
DEVELOPMENT_TEAM = D2DC7QNNJ8; DEVELOPMENT_TEAM = D2DC7QNNJ8;
ENABLE_PREVIEWS = YES; ENABLE_PREVIEWS = YES;
......
...@@ -15,7 +15,7 @@ struct NotificationView: View { ...@@ -15,7 +15,7 @@ struct NotificationView: View {
TitleView() TitleView()
ScrollView { ScrollView {
ForEach(pushHist.pushHistoryData.map{ $1 }.sorted{ $0.id ?? 0 > $1.id ?? 0 }, id: \.id){ data in ForEach(pushHist.pushHistoryData.map{ $1 }.filter { $0.id != nil }.sorted{ ($0.id ?? 0) > ($1.id ?? 0) }, id: \.id){ data in
NotificationContentView(pushData: data) NotificationContentView(pushData: data)
.onTapGesture { .onTapGesture {
if let position = data.position { if let position = data.position {
...@@ -38,12 +38,10 @@ struct NotificationView: View { ...@@ -38,12 +38,10 @@ struct NotificationView: View {
.onAppear { .onAppear {
let pushCount = pushHist.viewCnt let pushCount = pushHist.viewCnt
print(debug: "\(pushCount)") print(debug: "\(pushCount)")
DispatchQueue.main.async {
pushHist.viewCnt = 0 pushHist.viewCnt = 0
} }
// .onChange(of: pushHist.pushHistoryData.count) { newValue in }
// let pushCount = pushHist.viewCnt
// print(debug: "\(pushCount)")
// }
} }
struct TitleView: View { struct TitleView: View {
......
...@@ -14,7 +14,7 @@ struct NotificationContentView: View { ...@@ -14,7 +14,7 @@ struct NotificationContentView: View {
var body: some View { var body: some View {
VStack(alignment: .leading, spacing: 4){ VStack(alignment: .leading, spacing: 4){
HStack(spacing: 10) { HStack(spacing: 10) {
Text(pushData.time ?? "2023-07-13T08::17:40Z") Text(pushData.time ?? "2023-07-13T08:17:40Z")
.foregroundColor(ColorSet.BodyDescriptiion.color) .foregroundColor(ColorSet.BodyDescriptiion.color)
.font(FontStyle.SupplementText2.font) .font(FontStyle.SupplementText2.font)
......
...@@ -16,7 +16,7 @@ struct ChatView: View { ...@@ -16,7 +16,7 @@ struct ChatView: View {
var body: some View { var body: some View {
ZStack { ZStack {
if message.mode == true { if message.mode {
LinearGradient(gradient: Gradient(colors: [.chatEmargencyColor1, .chatEmargencyColor2]), startPoint: .top, endPoint: .bottom) LinearGradient(gradient: Gradient(colors: [.chatEmargencyColor1, .chatEmargencyColor2]), startPoint: .top, endPoint: .bottom)
.ignoresSafeArea() .ignoresSafeArea()
} }
...@@ -48,8 +48,10 @@ struct ChatView: View { ...@@ -48,8 +48,10 @@ struct ChatView: View {
} }
} }
.onAppear { .onAppear {
if let id = message.messages.last?.messageId { guard !message.messages.isEmpty,
let id = message.messages.last?.messageId else { return }
proxy.scrollTo(id, anchor: .bottom) proxy.scrollTo(id, anchor: .bottom)
DispatchQueue.main.async {
message.viewCnt = 0 message.viewCnt = 0
} }
} }
...@@ -118,7 +120,7 @@ struct AlertChatMessage: View { ...@@ -118,7 +120,7 @@ struct AlertChatMessage: View {
var message : ChatMessage var message : ChatMessage
var body: some View { var body: some View {
if message.mode == 1 { if message.mode == ChatMode.warningProgress.rawValue {
HStack() { HStack() {
Rectangle() Rectangle()
.fill(ColorSet.ChatDate.color) .fill(ColorSet.ChatDate.color)
......
...@@ -56,7 +56,7 @@ class GetMessage { ...@@ -56,7 +56,7 @@ class GetMessage {
} }
} }
SharingData.message.viewCnt = msgCnt - viewCnt //未読数 // SharingData.message.viewCnt = msgCnt - viewCnt //未読数
} }
/** /**
......
...@@ -69,15 +69,12 @@ struct MyChatContentView: View { ...@@ -69,15 +69,12 @@ struct MyChatContentView: View {
var shipViewer = 0 var shipViewer = 0
var companyViewr = 0 var companyViewr = 0
for viewer in message.viewer { for viewer in message.viewer {
//船のIDは全て同じ
// if viewer.id != String(SharingData.my.id) {
if viewer.location == 1 { if viewer.location == 1 {
companyViewr += 1 companyViewr += 1
} else { } else {
shipViewer += 1 shipViewer += 1
} }
} }
// }
return (shipViewer, companyViewr) return (shipViewer, companyViewr)
} }
} }
......
import Foundation
import Speech
import AVFoundation
class SpeechRecognizer: ObservableObject {
private var audioEngine = AVAudioEngine()
private var request = SFSpeechAudioBufferRecognitionRequest()
private var recognizer = SFSpeechRecognizer(locale: Locale(identifier: "ja-JP"))
private var task: SFSpeechRecognitionTask?
@Published var transcribedText = ""
func startRecording() {
SFSpeechRecognizer.requestAuthorization { authStatus in
guard authStatus == .authorized else { return }
let node = self.audioEngine.inputNode
let recordingFormat = node.outputFormat(forBus: 0)
node.removeTap(onBus: 0)
node.installTap(onBus: 0, bufferSize: 1024, format: recordingFormat) { buffer, _ in
self.request.append(buffer)
}
self.audioEngine.prepare()
try? self.audioEngine.start()
self.task = self.recognizer?.recognitionTask(with: self.request) { result, error in
if let result = result {
DispatchQueue.main.async {
self.transcribedText = result.bestTranscription.formattedString
}
}
}
}
}
func stopRecording() {
audioEngine.stop()
request.endAudio()
task?.cancel()
audioEngine.inputNode.removeTap(onBus: 0)
}
}
...@@ -2,6 +2,10 @@ ...@@ -2,6 +2,10 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSSpeechRecognitionUsageDescription</key>
<string>Uses voice recognition</string>
<key>NSMicrophoneUsageDescription</key>
<string>Use a microphone</string>
<key>MBXAccessToken</key> <key>MBXAccessToken</key>
<string>pk.eyJ1Ijoiam1hcmluZWNsb3VkIiwiYSI6ImNsbmxjbGYzZjA0dG8yaW82MDgwajQ5OTQifQ.pd8YC9qK1C4YmMUbMx6ywQ</string> <string>pk.eyJ1Ijoiam1hcmluZWNsb3VkIiwiYSI6ImNsbmxjbGYzZjA0dG8yaW82MDgwajQ5OTQifQ.pd8YC9qK1C4YmMUbMx6ywQ</string>
<key>UIBackgroundModes</key> <key>UIBackgroundModes</key>
......
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
import Foundation import Foundation
enum ChatMode: Int {
case normal = 0
case warningProgress = 1
}
struct ResGetMessages: Codable { struct ResGetMessages: Codable {
var mode: Int // 0:通常 , 1:Warning中 var mode: Int // 0:通常 , 1:Warning中
var messages: [ChatMessage]? var messages: [ChatMessage]?
......
...@@ -110,7 +110,7 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M ...@@ -110,7 +110,7 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
Preferences.DeviceId = UUID().uuidString Preferences.DeviceId = UUID().uuidString
} }
//SignalR初期化 //MARK: - SignalR初期化
hubConnectionDelegate = ChatHubConnectionDelegate(app: self) hubConnectionDelegate = ChatHubConnectionDelegate(app: self)
connection = HubConnectionBuilder(url: URL(string : HttpRequestType.SignalR.rawValue)!) connection = HubConnectionBuilder(url: URL(string : HttpRequestType.SignalR.rawValue)!)
.withHubConnectionDelegate(delegate: hubConnectionDelegate!) .withHubConnectionDelegate(delegate: hubConnectionDelegate!)
...@@ -121,10 +121,16 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M ...@@ -121,10 +121,16 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
.build() .build()
if let r_connection = connection { if let r_connection = connection {
//Chat
r_connection.on(method: "ChatMessage", callback: { (message: ResChatMessage) in r_connection.on(method: "ChatMessage", callback: { (message: ResChatMessage) in
self.handleChatMessage(message: message) self.handleChatMessage(message: message)
}) })
//Photo / Image
r_connection.on(method: "chatMessage", callback: { (message: ResChatMessage) in
self.handleChatMessage(message: message)
})
r_connection.on(method: "AckMessage", callback: { (message: ResAckMessage) in r_connection.on(method: "AckMessage", callback: { (message: ResAckMessage) in
self.handleAckMessage(message: message) self.handleAckMessage(message: message)
}) })
...@@ -158,6 +164,7 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M ...@@ -158,6 +164,7 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
// Push通知を受信した時(サイレントプッシュ) // Push通知を受信した時(サイレントプッシュ)
func notificationHub(_ notificationHub: MSNotificationHub, didReceivePushNotification notification: MSNotificationHubMessage) { func notificationHub(_ notificationHub: MSNotificationHub, didReceivePushNotification notification: MSNotificationHubMessage) {
print(debug: "called")
// let title = notification.title ?? "" // let title = notification.title ?? ""
// let body = notification.body ?? "" // let body = notification.body ?? ""
let userInfo = notification.userInfo let userInfo = notification.userInfo
...@@ -181,11 +188,13 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M ...@@ -181,11 +188,13 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
} }
private func handleChatMessage(message: ResChatMessage) { private func handleChatMessage(message: ResChatMessage) {
print(debug: "called")
let ownMsg = ChatMessage(shipId: message.shipId, messageId: message.messageId, type: message.type, time: message.time, location: message.location, from: message.from, fromId: message.fromId, mode: message.mode, message: message.message, stampId: message.stampId, viewer: []) let ownMsg = ChatMessage(shipId: message.shipId, messageId: message.messageId, type: message.type, time: message.time, location: message.location, from: message.from, fromId: message.fromId, mode: message.mode, message: message.message, stampId: message.stampId, viewer: [])
self.msg.messages.append(ownMsg) self.msg.messages.append(ownMsg)
} }
private func handleAckMessage(message: ResAckMessage) { private func handleAckMessage(message: ResAckMessage) {
print(debug: "called")
let msgIndex = self.msg.messages.firstIndex(where: {$0.messageId == message.messageId}) let msgIndex = self.msg.messages.firstIndex(where: {$0.messageId == message.messageId})
if let index = msgIndex { if let index = msgIndex {
if let fromId = message.fromId { if let fromId = message.fromId {
...@@ -199,6 +208,7 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M ...@@ -199,6 +208,7 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
} }
private func handleChatMode(message: ResChatMode) { private func handleChatMode(message: ResChatMode) {
print(debug: "called")
if message.mode == 1 { if message.mode == 1 {
self.msg.mode = true self.msg.mode = true
} else { } else {
...@@ -352,27 +362,39 @@ extension AppDelegate: UNUserNotificationCenterDelegate { ...@@ -352,27 +362,39 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
//送信先名称が同一の場合は通知を出さない //送信先名称が同一の場合は通知を出さない
if subtitle == Preferences.UserName { if subtitle == Preferences.UserName {
return return
} else {
DispatchQueue.main.async {
SharingData.message.viewCnt += 1
}
} }
case "sailassist": case "sailassist":
DispatchQueue.main.async {
print(debug: "sailassist") print(debug: "sailassist")
SharingData.pushHistory.viewCnt += 1 SharingData.pushHistory.viewCnt += 1
let getPushHistory = GetPushHistory() let getPushHistory = GetPushHistory()
getPushHistory.start() getPushHistory.start()
}
case "bam": case "bam":
DispatchQueue.main.async {
print(debug: "bam") print(debug: "bam")
SharingData.pushHistory.viewCnt += 1 SharingData.pushHistory.viewCnt += 1
let getPushHistory = GetPushHistory() let getPushHistory = GetPushHistory()
getPushHistory.start() getPushHistory.start()
}
case "route": case "route":
DispatchQueue.main.async {
print(debug: "route") print(debug: "route")
SharingData.pushHistory.viewCnt += 1 SharingData.pushHistory.viewCnt += 1
let getPushHistory = GetPushHistory() let getPushHistory = GetPushHistory()
getPushHistory.start() getPushHistory.start()
}
case "emergency": case "emergency":
DispatchQueue.main.async {
print(debug: "emergency") print(debug: "emergency")
SharingData.pushHistory.viewCnt += 1 SharingData.pushHistory.viewCnt += 1
let getPushHistory = GetPushHistory() let getPushHistory = GetPushHistory()
getPushHistory.start() getPushHistory.start()
}
default: default:
print(debug: "default") print(debug: "default")
} }
......
...@@ -14,4 +14,6 @@ enum APIError: Error{ ...@@ -14,4 +14,6 @@ enum APIError: Error{
case decodeError case decodeError
case encodeError case encodeError
case unknown case unknown
case invalidURL
case busy
} }
...@@ -51,7 +51,7 @@ class ServerSession{ ...@@ -51,7 +51,7 @@ class ServerSession{
do{ do{
if error != nil{ if error != nil{
// print(debug: "clientError: \(error)") print(debug: "clientError: \(String(describing: error))")
throw APIError.clientError throw APIError.clientError
} }
guard let indata = data, let inresponse = response as? HTTPURLResponse else { guard let indata = data, let inresponse = response as? HTTPURLResponse else {
......
...@@ -9,76 +9,107 @@ import Foundation ...@@ -9,76 +9,107 @@ import Foundation
import SwiftUI import SwiftUI
class SessionUploadImage : ObservableObject { class SessionUploadImage : ObservableObject {
@Published var status = false @Published var progress: Double = 0.0
// シングルトン宣言 @Published var isUploading: Bool = false
static let OnlyOne = SessionUploadImage() static let OnlyOne = SessionUploadImage() // シングルトン宣言
private var serverSession = ServerSession() private var serverSession = ServerSession()
private var Calling : Bool = false // 通信中 private var Calling : Bool = false // 通信中
private var uploadTask: URLSessionUploadTask?
func cancelUpload() {
uploadTask?.cancel()
isUploading = false
progress = 0.0
}
/** /**
* メッセージ * メッセージ
*/ */
func RequestUploadImage(_ uploadImage : ReqUploadImage ,completion: @escaping ((Result<Data, APIError>)) -> Void) { func requestUploadImage(_ uploadImage: ReqUploadImage) async throws -> Data {
print(debug: "calld") print(debug: "calld")
if Calling { guard !Calling else {
return throw APIError.busy
} }
Calling = true Calling = true
defer { Calling = false }
// リクエストURLの組み立て // リクエストURLの組み立て
let url_string : String = HttpRequestType.UploadImage.rawValue guard let req_url = URL(string: HttpRequestType.UploadImage.rawValue) else {
guard let req_url = URL(string : url_string) else { throw APIError.invalidURL
Calling = false
return
} }
let imageFileName = "itemp.jpg" let imageFileName = "itemp.jpg"
let boundary = "----------\(UUID().uuidString)" let boundary = "----------\(UUID().uuidString)"
var httpBody1 = "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"ShipId\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.shipId)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"MessageId\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.messageId)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"Location\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(String(uploadImage.location))\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"From\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.from)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"FromId\"\r\n"
httpBody1 += "\r\n"
httpBody1 += "\(uploadImage.fromId)\r\n"
httpBody1 += "--\(boundary)\r\n"
httpBody1 += "Content-Disposition: form-data; name=\"files\"; filename=\"\(imageFileName)\"\r\n"
httpBody1 += "Content-Type: image/jpeg\r\n"
httpBody1 += "\r\n"
var httpBody = Data() var httpBody = Data()
httpBody.append(httpBody1.data(using: .utf8)!) func appendFormField(name: String, value: String) {
httpBody.append("--\(boundary)\r\n".data(using: .utf8)!)
httpBody.append("Content-Disposition: form-data; name=\"\(name)\"\r\n\r\n".data(using: .utf8)!)
httpBody.append("\(value)\r\n".data(using: .utf8)!)
}
appendFormField(name: "ShipId", value: String(uploadImage.shipId))
appendFormField(name: "MessageId", value: uploadImage.messageId)
appendFormField(name: "Location", value: String(uploadImage.location))
appendFormField(name: "From", value: uploadImage.from)
appendFormField(name: "FromId", value: uploadImage.fromId)
httpBody.append("--\(boundary)\r\n".data(using: .utf8)!)
httpBody.append("Content-Disposition: form-data; name=\"files\"; filename=\"\(imageFileName)\"\r\n".data(using: .utf8)!)
httpBody.append("Content-Type: image/jpeg\r\n\r\n".data(using: .utf8)!)
httpBody.append(uploadImage.files) httpBody.append(uploadImage.files)
httpBody.append("\r\n--\(boundary)--\r\n".data(using: .utf8)!)
var request = URLRequest(url: req_url)
request.httpMethod = "POST"
request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
let session = URLSession(configuration: .default, delegate: UploadProgressDelegate(parent: self), delegateQueue: nil)
isUploading = true
uploadTask = session.uploadTask(with: request, from: httpBody)
uploadTask?.resume()
var httpBody2 = "\r\n" let (data, response) = try await session.upload(for: request, from: httpBody)
httpBody2 += "--\(boundary)--\r\n"
httpBody.append(httpBody2.data(using: .utf8)!) isUploading = false
// let str: String = String(decoding: httpBody, as: UTF8.self) progress = 0.0
serverSession.postForm(boundary: boundary, req_url, httpBody, completion: completion)
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
throw APIError.serverError
}
return data
}
// if let postdata = serverSession.httpBody(boundary: boundary, uploadImage) { func postFormAsync(boundary: String, url: URL, body: Data) async throws -> Data {
// serverSession.postForm(boundary: boundary, req_url, postdata, completion: completion) var request = URLRequest(url: url)
// } request.httpMethod = "POST"
// else { request.setValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// Calling = false request.httpBody = body
// return
// } let (data, response) = try await URLSession.shared.data(for: request)
guard let httpResponse = response as? HTTPURLResponse, (200...299).contains(httpResponse.statusCode) else {
throw APIError.serverError
}
return data
}
class UploadProgressDelegate: NSObject, URLSessionTaskDelegate {
weak var parent: SessionUploadImage?
init(parent: SessionUploadImage) {
self.parent = parent
}
func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64,
totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
DispatchQueue.main.async {
self.parent?.progress = Double(totalBytesSent) / Double(totalBytesExpectedToSend)
}
}
} }
} }
import SwiftUI
// MARK: - ChangeModeAlertModifier
struct ChangeModeAlertModifier: ViewModifier {
@Binding var isPresented: Bool
let currentMode: Bool
let onConfirm: () -> Void
func body(content: Content) -> some View {
content.alert("", isPresented: $isPresented) {
Button("Yes") {
onConfirm()
}
Button("No") {}
} message: {
Text("Do you change an warning mode?")
}
}
}
// MARK: - LocationAlertModifier
struct LocationAlertModifier: ViewModifier {
@Binding var isPresented: Bool
func body(content: Content) -> some View {
content.alert("Location", isPresented: $isPresented) {
Button("Cancel") {}
Button("Setting") {
guard let settingsURL = URL(string: UIApplication.openSettingsURLString) else {
return
}
UIApplication.shared.open(settingsURL, options: [:], completionHandler: nil)
}
} message: {
Text("To use ECA, set the permission to use location information to ALWAYS.")
}
}
}
// MARK: - UpdateAlertModifier
struct UpdateAlertModifier: ViewModifier {
@Binding var isPresented: Bool
let appStoreURL: URL
func body(content: Content) -> some View {
content.alert("Update", isPresented: $isPresented) {
Button("Go to app page") {
UIApplication.shared.open(appStoreURL, options: [:], completionHandler: nil)
}
} message: {
Text("A new version of this app is available.")
}
}
}
// MARK: - WarningModeAlertModifier
struct WarningModeAlertModifier: ViewModifier {
@Binding var isPresented: Bool
@Binding var isSignalrRestert: Bool
let onConfirm: () -> Void
func body(content: Content) -> some View {
content.alert("Error", isPresented: $isPresented) {
Button("OK") {
onConfirm()
isSignalrRestert = false
}
} message: {
Text("The mode did not change.")
}
}
}
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment