Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
S
Sailassist
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
CpjJwWHV
Sailassist
Commits
40fa98bc
Commit
40fa98bc
authored
Mar 06, 2024
by
shigemi miura
Browse files
Options
Browse Files
Download
Plain Diff
Merge trial-chat into trial-chat2
parents
becc590d
9bbc6b0d
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
717 additions
and
254 deletions
+717
-254
project.pbxproj
Seilassist/Sailassist.xcodeproj/project.pbxproj
+0
-0
ChatView.swift
Seilassist/Sailassist/Chat/ChatView.swift
+48
-16
GetMessage.swift
Seilassist/Sailassist/Chat/GetMessage.swift
+22
-17
Imagepicker.swift
Seilassist/Sailassist/Chat/Imagepicker.swift
+50
-0
CameraView.swift
Seilassist/Sailassist/Chat/View/CameraView.swift
+27
-0
ChatInputView.swift
Seilassist/Sailassist/Chat/View/ChatInputView.swift
+100
-4
ChatMemberView.swift
Seilassist/Sailassist/Chat/View/ChatMemberView.swift
+4
-3
ChatTitleView.swift
Seilassist/Sailassist/Chat/View/ChatTitleView.swift
+10
-6
MyChatContentView.swift
Seilassist/Sailassist/Chat/View/MyChatContentView.swift
+53
-6
OtherChatContentView.swift
Seilassist/Sailassist/Chat/View/OtherChatContentView.swift
+54
-7
ReqUploadImage.swift
Seilassist/Sailassist/Json/ReqUploadImage.swift
+18
-0
ResAckMessage.swift
Seilassist/Sailassist/Json/ResAckMessage.swift
+16
-0
ResChatMessage.swift
Seilassist/Sailassist/Json/ResChatMessage.swift
+20
-0
ResChatMode.swift
Seilassist/Sailassist/Json/ResChatMode.swift
+16
-0
ResGetMessages.swift
Seilassist/Sailassist/Json/ResGetMessages.swift
+10
-2
GetManualUrl.swift
Seilassist/Sailassist/Menu/GetManualUrl.swift
+0
-1
SailassistApp.swift
Seilassist/Sailassist/SailassistApp.swift
+150
-27
ServerSession.swift
Seilassist/Sailassist/ServerSession/ServerSession.swift
+84
-0
SessionUploadImage.swift
Seilassist/Sailassist/ServerSession/SessionUploadImage.swift
+15
-14
SharingData.swift
Seilassist/Sailassist/SharingData/SharingData.swift
+5
-0
SignalRService.swift
Seilassist/Sailassist/SignalR/SignalRService.swift
+0
-142
MainTabView.swift
Seilassist/Sailassist/Tab/MainTabView.swift
+15
-9
No files found.
Seilassist/Sailassist.xcodeproj/project.pbxproj
View file @
40fa98bc
This diff is collapsed.
Click to expand it.
Seilassist/Sailassist/Chat/ChatView.swift
View file @
40fa98bc
...
@@ -11,9 +11,10 @@ struct ChatView: View {
...
@@ -11,9 +11,10 @@ struct ChatView: View {
@EnvironmentObject
private
var
selectedTabModel
:
SelectedTabModel
@EnvironmentObject
private
var
selectedTabModel
:
SelectedTabModel
@ObservedObject
var
message
=
SharingData
.
message
@ObservedObject
var
message
=
SharingData
.
message
@State
var
isShowMember
:
Bool
=
false
@State
var
isShowMember
:
Bool
=
false
@StateObject
var
scrollBottom
=
ScrollBottom
()
var
body
:
some
View
{
var
body
:
some
View
{
ZStack
{
ZStack
{
if
message
.
mode
==
1
{
if
message
.
mode
==
true
{
LinearGradient
(
gradient
:
Gradient
(
colors
:
[
.
chatEmargencyColor1
,
.
chatEmargencyColor2
]),
startPoint
:
.
top
,
endPoint
:
.
bottom
)
LinearGradient
(
gradient
:
Gradient
(
colors
:
[
.
chatEmargencyColor1
,
.
chatEmargencyColor2
]),
startPoint
:
.
top
,
endPoint
:
.
bottom
)
.
ignoresSafeArea
()
.
ignoresSafeArea
()
}
}
...
@@ -21,21 +22,41 @@ struct ChatView: View {
...
@@ -21,21 +22,41 @@ struct ChatView: View {
ChatTitleView
(
isShowMember
:
$
isShowMember
)
ChatTitleView
(
isShowMember
:
$
isShowMember
)
ZStack
{
ZStack
{
ScrollView
(
.
vertical
)
{
ScrollViewReader
{
proxy
in
Spacer
()
ScrollView
(
.
vertical
)
{
.
frame
(
height
:
20
)
VStack
{
Spacer
()
ForEach
(
message
.
messages
,
id
:
\
.
messageId
)
{
msg
in
.
frame
(
height
:
20
)
if
msg
.
fromId
!=
String
(
SharingData
.
my
.
id
){
//自分のメッセージ
ForEach
(
message
.
messages
,
id
:
\
.
messageId
)
{
msg
in
MyChatContentView
(
message
:
msg
)
// if msg.fromId == String(SharingData.my.id) {
.
padding
(
.
bottom
,
24
)
if
msg
.
from
==
Preferences
.
UserName
{
}
else
{
//自分のメッセージ
//他人のメッセージ
MyChatContentView
(
message
:
msg
)
OtherChatContentView
(
message
:
msg
)
.
padding
(
.
bottom
,
24
)
.
padding
(
.
bottom
,
24
)
}
else
{
//他人のメッセージ
OtherChatContentView
(
message
:
msg
)
.
padding
(
.
bottom
,
24
)
}
}
}
.
onAppear
{
self
.
scrollBottom
.
onAppear
()
}
}
}
}
.
onReceive
(
message
.
$
messages
)
{
(
value
)
in
withAnimation
{
guard
!
value
.
isEmpty
else
{
return
}
proxy
.
scrollTo
(
value
.
last
?
.
messageId
,
anchor
:
.
center
)
if
let
lastId
=
value
.
last
?
.
messageId
{
print
(
debug
:
"
\(
String
(
describing
:
lastId
)
)
"
)
}
}
}
.
onChange
(
of
:
scrollBottom
.
scrollID
)
{
id
in
proxy
.
scrollTo
(
id
,
anchor
:
.
center
)
}
}
}
HStack
{
HStack
{
Spacer
()
Spacer
()
...
@@ -56,14 +77,25 @@ struct ChatView: View {
...
@@ -56,14 +77,25 @@ struct ChatView: View {
ChatMemberView
()
ChatMemberView
()
}
}
}
}
ChatInputView
()
}
}
ChatInputView
()
}
}
.
background
(
ColorSet
.
BackgroundPrimary
.
color
)
.
background
(
ColorSet
.
BackgroundPrimary
.
color
)
}
}
}
}
class
ScrollBottom
:
ObservableObject
{
@Published
var
scrollID
:
String
=
""
func
onAppear
()
{
DispatchQueue
.
main
.
asyncAfter
(
deadline
:
.
now
()
+
1
)
{
if
let
id
=
SharingData
.
message
.
messages
.
last
?
.
messageId
{
self
.
scrollID
=
id
}
}
}
}
#Preview {
#Preview {
ChatView
()
ChatView
()
}
}
Seilassist/Sailassist/Chat/GetMessage.swift
View file @
40fa98bc
...
@@ -12,25 +12,30 @@ class GetMessage {
...
@@ -12,25 +12,30 @@ class GetMessage {
func
start
()
{
func
start
()
{
print
(
debug
:
"called"
)
print
(
debug
:
"called"
)
sessionGetMessage
.
RequestGetMessage
(
responseGetMessage
)
sessionGetMessage
.
RequestGetMessage
{
response
in
}
switch
response
{
case
.
success
(
let
resultData
):
private
func
responseGetMessage
(
result
:
Result
<
Data
,
APIError
>
)
{
let
serverSession
=
ServerSession
()
print
(
debug
:
"called"
)
let
resjson
=
serverSession
.
fromJSON
(
resultData
:
resultData
,
resltType
:
ResGetMessages
.
self
)
switch
result
{
if
let
res
=
resjson
{
case
.
success
(
let
resultData
):
if
res
.
mode
==
1
{
let
serverSession
=
ServerSession
()
SharingData
.
message
.
mode
=
true
let
resjson
=
serverSession
.
fromJSON
(
resultData
:
resultData
,
resltType
:
ResGetMessages
.
self
)
}
else
{
if
let
res
=
resjson
{
SharingData
.
message
.
mode
=
false
SharingData
.
message
.
mode
=
res
.
mode
}
SharingData
.
message
.
messages
=
[]
SharingData
.
message
.
messages
=
[]
if
let
msg
=
res
.
messages
{
if
let
msg
=
res
.
messages
{
SharingData
.
message
.
messages
=
msg
SharingData
.
message
.
messages
=
msg
}
SharingData
.
message
.
users
=
[]
if
let
users
=
res
.
users
{
SharingData
.
message
.
users
=
users
}
}
}
case
.
failure
(
let
errorCode
):
print
(
debug
:
errorCode
)
break
}
}
case
.
failure
(
let
errorCode
):
print
(
debug
:
errorCode
)
break
}
}
}
}
}
}
...
...
Seilassist/Sailassist/Chat/Imagepicker.swift
0 → 100644
View file @
40fa98bc
//
// Imagepicker.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/19.
//
import
SwiftUI
struct
Imagepicker
:
UIViewControllerRepresentable
{
@Binding
var
show
:
Bool
@Binding
var
image
:
Data
var
sourceType
:
UIImagePickerController
.
SourceType
func
makeCoordinator
()
->
Imagepicker
.
Coodinator
{
return
Imagepicker
.
Coordinator
(
parent
:
self
)
}
func
makeUIViewController
(
context
:
UIViewControllerRepresentableContext
<
Imagepicker
>
)
->
UIImagePickerController
{
let
controller
=
UIImagePickerController
()
controller
.
sourceType
=
sourceType
controller
.
delegate
=
context
.
coordinator
return
controller
}
func
updateUIViewController
(
_
uiViewController
:
UIImagePickerController
,
context
:
UIViewControllerRepresentableContext
<
Imagepicker
>
)
{
}
class
Coodinator
:
NSObject
,
UIImagePickerControllerDelegate
,
UINavigationControllerDelegate
{
var
parent
:
Imagepicker
init
(
parent
:
Imagepicker
){
self
.
parent
=
parent
}
//Cancel
func
imagePickerControllerDidCancel
(
_
picker
:
UIImagePickerController
)
{
self
.
parent
.
show
.
toggle
()
}
//Use Photo
func
imagePickerController
(
_
picker
:
UIImagePickerController
,
didFinishPickingMediaWithInfo
info
:
[
UIImagePickerController
.
InfoKey
:
Any
])
{
let
image
=
info
[
.
originalImage
]
as!
UIImage
let
data
=
image
.
pngData
()
self
.
parent
.
image
=
data
!
self
.
parent
.
show
.
toggle
()
}
}
}
Seilassist/Sailassist/Chat/View/CameraView.swift
0 → 100644
View file @
40fa98bc
//
// CameraView.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/19.
//
import
SwiftUI
struct
CameraView
:
View
{
@Binding
var
imageData
:
Data
@Binding
var
source
:
UIImagePickerController
.
SourceType
@Binding
var
isActionSheet
:
Bool
@Binding
var
isImagePicker
:
Bool
var
body
:
some
View
{
NavigationStack
{
List
{
}
.
navigationDestination
(
isPresented
:
$
isImagePicker
)
{
Imagepicker
(
show
:
$
isImagePicker
,
image
:
$
imageData
,
sourceType
:
source
)
}
}
.
ignoresSafeArea
(
.
all
,
edges
:
.
top
)
.
background
(
Color
.
primary
.
opacity
(
0.06
)
.
ignoresSafeArea
(
.
all
,
edges
:
.
all
))
}
}
Seilassist/Sailassist/Chat/View/ChatInputView.swift
View file @
40fa98bc
...
@@ -9,14 +9,69 @@ import SwiftUI
...
@@ -9,14 +9,69 @@ import SwiftUI
struct
ChatInputView
:
View
{
struct
ChatInputView
:
View
{
@EnvironmentObject
private
var
sceneDelegate
:
SceneDelegate
@EnvironmentObject
private
var
sceneDelegate
:
SceneDelegate
@ObservedObject
var
sessionUploadImage
:
SessionUploadImage
=
SessionUploadImage
()
@State
var
inputText
=
""
@State
var
inputText
=
""
@State
private
var
selectionValue
=
3
@State
var
isCamera
:
Bool
=
false
@State
var
isPhoto
:
Bool
=
false
@State
var
isImportFile
:
Bool
=
false
@State
var
imageData
:
Data
=
.
init
(
capacity
:
0
)
@State
var
source
:
UIImagePickerController
.
SourceType
=
.
photoLibrary
@State
var
isActionSheet
=
false
@State
var
isImagePicker
=
false
@FocusState
var
isKeyboard
:
Bool
@FocusState
var
isKeyboard
:
Bool
var
body
:
some
View
{
var
body
:
some
View
{
VStack
(
spacing
:
0
){
VStack
(
spacing
:
0
){
Spacer
()
Spacer
()
Divider
()
Divider
()
HStack
(
spacing
:
10
){
HStack
(
spacing
:
10
){
Button
{
sceneDelegate
.
tabWindow
?
.
isHidden
=
true
isCamera
=
true
source
=
.
camera
isImagePicker
.
toggle
()
}
label
:
{
Image
(
systemName
:
"camera"
)
.
resizable
()
.
frame
(
width
:
24
,
height
:
24
)
.
padding
(
10
)
}
Menu
{
Button
(
action
:
{
print
(
"Photo Library"
)
sceneDelegate
.
tabWindow
?
.
isHidden
=
true
isCamera
=
true
source
=
.
photoLibrary
isImagePicker
.
toggle
()
})
{
Label
(
"Photo Library"
,
systemImage
:
"photo.on.rectangle"
)
}
Button
(
action
:
{
print
(
"Take Photo"
)
sceneDelegate
.
tabWindow
?
.
isHidden
=
true
isImportFile
=
true
})
{
Label
(
"Take Phot"
,
systemImage
:
"camera"
)
}
Button
(
action
:
{
print
(
"Choose File"
)
sceneDelegate
.
tabWindow
?
.
isHidden
=
true
isCamera
=
true
source
=
.
photoLibrary
isImagePicker
.
toggle
()
})
{
Label
(
"Choose File"
,
systemImage
:
"folder"
)
}
}
label
:
{
Image
(
systemName
:
"photo"
)
.
resizable
()
.
frame
(
width
:
24
,
height
:
24
)
.
padding
(
10
)
}
TextField
(
""
,
text
:
$
inputText
,
onEditingChanged
:
{
isEdit
in
TextField
(
""
,
text
:
$
inputText
,
onEditingChanged
:
{
isEdit
in
sceneDelegate
.
tabWindow
?
.
isHidden
=
isEdit
sceneDelegate
.
tabWindow
?
.
isHidden
=
isEdit
})
})
...
@@ -28,10 +83,12 @@ struct ChatInputView: View {
...
@@ -28,10 +83,12 @@ struct ChatInputView: View {
.
cornerRadius
(
5
)
.
cornerRadius
(
5
)
.
padding
(
.
vertical
,
10
)
.
padding
(
.
vertical
,
10
)
.
padding
(
.
leading
,
20
)
.
padding
(
.
leading
,
20
)
Button
{
Button
{
isKeyboard
=
false
isKeyboard
=
false
let
signalRService
=
SignalR
()
signalRService
.
chatMessage
(
message
:
inputText
)
inputText
=
""
}
label
:
{
}
label
:
{
Image
(
"send"
)
Image
(
"send"
)
.
resizable
()
.
resizable
()
...
@@ -42,8 +99,47 @@ struct ChatInputView: View {
...
@@ -42,8 +99,47 @@ struct ChatInputView: View {
.
padding
(
.
trailing
,
11
)
.
padding
(
.
trailing
,
11
)
}
}
.
background
(
ColorSet
.
BackgroundSecondary
.
color
)
.
background
(
ColorSet
.
BackgroundSecondary
.
color
)
.
fullScreenCover
(
isPresented
:
.
constant
(
isImagePicker
),
onDismiss
:
{
//シートを閉じる時に実行する処理
sceneDelegate
.
tabWindow
?
.
isHidden
=
false
if
imageData
.
count
!=
0
{
let
jpegData
=
UIImage
(
data
:
imageData
)
!.
jpegData
(
compressionQuality
:
1.0
)
let
uploadImage
=
ReqUploadImage
(
shipId
:
Preferences
.
shipId
,
messageId
:
UUID
()
.
uuidString
,
location
:
2
,
from
:
Preferences
.
UserName
,
fromId
:
String
(
SharingData
.
my
.
id
),
files
:
jpegData
!
)
sessionUploadImage
.
RequestUploadImage
(
uploadImage
,
completion
:
responseUploadImage
)
}
},
content
:
{
CameraView
(
imageData
:
$
imageData
,
source
:
$
source
,
isActionSheet
:
$
isActionSheet
,
isImagePicker
:
$
isImagePicker
)
})
.
fileImporter
(
isPresented
:
$
isImportFile
,
allowedContentTypes
:
[
.
png
,
.
jpeg
,
.
pdf
])
{
result
in
switch
result
{
case
.
success
(
let
url
):
guard
let
imageData
=
try
?
Data
(
contentsOf
:
url
)
else
{
return
}
if
imageData
.
count
!=
0
{
let
jpegData
=
UIImage
(
data
:
imageData
)
!.
jpegData
(
compressionQuality
:
1.0
)
let
uploadImage
=
ReqUploadImage
(
shipId
:
Preferences
.
shipId
,
messageId
:
UUID
()
.
uuidString
,
location
:
2
,
from
:
Preferences
.
UserName
,
fromId
:
String
(
SharingData
.
my
.
id
),
files
:
jpegData
!
)
sessionUploadImage
.
RequestUploadImage
(
uploadImage
,
completion
:
responseUploadImage
)
}
case
.
failure
:
print
(
"failure"
)
}
}
}
.
frame
(
maxHeight
:
55
)
}
func
responseUploadImage
(
result
:
Result
<
Data
,
APIError
>
)
{
print
(
debug
:
"calld"
)
switch
result
{
case
.
success
(
let
resultData
):
let
serverSession
=
ServerSession
()
let
resjson
=
serverSession
.
fromJSON
(
resultData
:
resultData
,
resltType
:
ResLogin
.
self
)
case
.
failure
(
let
errorCode
):
print
(
debug
:
errorCode
)
break
}
}
}
}
}
}
...
...
Seilassist/Sailassist/Chat/View/ChatMemberView.swift
View file @
40fa98bc
...
@@ -8,12 +8,13 @@
...
@@ -8,12 +8,13 @@
import
SwiftUI
import
SwiftUI
struct
ChatMemberView
:
View
{
struct
ChatMemberView
:
View
{
var
members
=
[
"Yokoyama"
,
"Nogami"
,
"Arahira"
,
"Enokido"
]
@ObservedObject
var
message
=
SharingData
.
message
// var members = ["Yokoyama", "Nogami", "Arahira", "Enokido"]
var
body
:
some
View
{
var
body
:
some
View
{
VStack
{
VStack
{
List
{
List
{
ForEach
(
me
mbers
,
id
:
\
.
self
)
{
memb
er
in
ForEach
(
me
ssage
.
users
,
id
:
\
.
id
)
{
us
er
in
Text
(
member
)
Text
(
user
.
name
)
.
foregroundColor
(
ColorSet
.
BodyChat
.
color
)
.
foregroundColor
(
ColorSet
.
BodyChat
.
color
)
.
font
(
FontStyle
.
SupplementText
.
font
)
.
font
(
FontStyle
.
SupplementText
.
font
)
}
}
...
...
Seilassist/Sailassist/Chat/View/ChatTitleView.swift
View file @
40fa98bc
...
@@ -9,10 +9,10 @@ import SwiftUI
...
@@ -9,10 +9,10 @@ import SwiftUI
struct
ChatTitleView
:
View
{
struct
ChatTitleView
:
View
{
@Binding
var
isShowMember
:
Bool
@Binding
var
isShowMember
:
Bool
@ObservedObject
var
message
=
SharingData
.
message
var
body
:
some
View
{
var
body
:
some
View
{
VStack
{
VStack
{
HStack
{
HStack
{
Button
{
Button
{
...
@@ -25,11 +25,15 @@ struct ChatTitleView: View {
...
@@ -25,11 +25,15 @@ struct ChatTitleView: View {
Spacer
()
Spacer
()
HStack
(
spacing
:
8
)
{
HStack
(
spacing
:
8
)
{
VStack
{
VStack
{
Text
(
"JMB-Demo(0518)"
)
Text
(
SharingData
.
my
.
shipName
)
.
font
(
FontStyle
.
TitleL
.
font
)
.
font
(
FontStyle
.
TitleL
.
font
)
Text
(
"Yokoyama,Nogami,Arahira,Enokida"
)
.
font
(
FontStyle
.
TitleSBold
.
font
)
HStack
{
ForEach
(
message
.
users
,
id
:
\
.
id
)
{
user
in
Text
(
user
.
name
+
","
)
.
font
(
FontStyle
.
TitleS
.
font
)
}
}
}
}
.
foregroundColor
(
ColorSet
.
Body
.
color
)
.
foregroundColor
(
ColorSet
.
Body
.
color
)
.
frame
(
width
:
162
,
height
:
44
)
.
frame
(
width
:
162
,
height
:
44
)
...
...
Seilassist/Sailassist/Chat/View/MyChatContentView.swift
View file @
40fa98bc
...
@@ -13,12 +13,59 @@ struct MyChatContentView: View {
...
@@ -13,12 +13,59 @@ struct MyChatContentView: View {
HStack
{
HStack
{
Spacer
()
Spacer
()
VStack
(
alignment
:
.
trailing
,
spacing
:
6
)
{
VStack
(
alignment
:
.
trailing
,
spacing
:
6
)
{
Text
(
message
.
message
)
Group
{
.
font
(
FontStyle
.
DefaultText
.
font
)
if
message
.
message
.
contains
(
"https://"
)
{
//TODO: stampIdが0
.
foregroundColor
(
ColorSet
.
BodyChat
.
color
)
AsyncImage
(
url
:
URL
(
string
:
message
.
message
))
{
image
in
.
padding
(
15
)
image
.
resizable
()
.
background
(
ColorSet
.
ChatBaloon
.
color
)
.
frame
(
width
:
200
,
height
:
200
)
.
cornerRadius
(
10
,
corners
:
[
.
tl
,
.
tr
,
.
bl
])
.
contextMenu
{
Button
(
action
:
{
print
(
"fight"
)
})
{
Text
(
"Share..."
)
Image
(
systemName
:
"square.and.arrow.up"
)
}
Button
(
action
:
{
print
(
"bag"
)
})
{
Text
(
"Save to Photos"
)
Image
(
systemName
:
"square.and.arrow.down"
)
}
Button
(
action
:
{
print
(
"pokemon"
)
})
{
Text
(
"Copy"
)
Image
(
systemName
:
"doc.on.doc"
)
}
Button
(
action
:
{
print
(
"run"
)
})
{
Text
(
"Copy Subject"
)
Image
(
systemName
:
"circle.dashed.rectangle"
)
}
Button
(
action
:
{
print
(
"run"
)
})
{
Text
(
"Show Text"
)
Image
(
systemName
:
"text.viewfinder"
)
}
}
}
placeholder
:
{
ProgressView
()
}
}
else
{
Text
(
message
.
message
)
.
font
(
FontStyle
.
DefaultText
.
font
)
.
foregroundColor
(
ColorSet
.
BodyChat
.
color
)
.
padding
(
15
)
.
background
(
ColorSet
.
ChatBaloon
.
color
)
.
cornerRadius
(
10
,
corners
:
[
.
tl
,
.
tr
,
.
br
])
}
}
HStack
(
spacing
:
0
){
HStack
(
spacing
:
0
){
Text
(
DateTextLib
.
ISO86012FormatText
(
message
.
time
,
format
:
"yyyy/MM/dd hh:mm"
,
errFormat
:
""
))
Text
(
DateTextLib
.
ISO86012FormatText
(
message
.
time
,
format
:
"yyyy/MM/dd hh:mm"
,
errFormat
:
""
))
...
...
Seilassist/Sailassist/Chat/View/OtherChatContentView.swift
View file @
40fa98bc
...
@@ -16,13 +16,60 @@ struct OtherChatContentView: View {
...
@@ -16,13 +16,60 @@ struct OtherChatContentView: View {
.
font
(
FontStyle
.
EmphasisText
.
font
)
.
font
(
FontStyle
.
EmphasisText
.
font
)
.
foregroundColor
(
ColorSet
.
Body
.
color
)
.
foregroundColor
(
ColorSet
.
Body
.
color
)
VStack
(
alignment
:
.
leading
,
spacing
:
10
)
{
VStack
(
alignment
:
.
leading
,
spacing
:
10
)
{
Text
(
message
.
message
)
Group
{
.
font
(
FontStyle
.
DefaultText
.
font
)
if
message
.
message
.
contains
(
"https://"
)
{
//TODO: stampIdが0
.
foregroundColor
(
ColorSet
.
BodyChat
.
color
)
AsyncImage
(
url
:
URL
(
string
:
message
.
message
))
{
image
in
.
padding
(
15
)
image
.
resizable
()
.
background
(
ColorSet
.
ChatBaloon
.
color
)
.
frame
(
width
:
200
,
height
:
200
)
.
cornerRadius
(
10
,
corners
:
[
.
tl
,
.
tr
,
.
br
])
.
contextMenu
{
Button
(
action
:
{
print
(
"fight"
)
})
{
Text
(
"Share..."
)
Image
(
systemName
:
"square.and.arrow.up"
)
}
Button
(
action
:
{
print
(
"bag"
)
})
{
Text
(
"Save to Photos"
)
Image
(
systemName
:
"square.and.arrow.down"
)
}
Button
(
action
:
{
print
(
"pokemon"
)
})
{
Text
(
"Copy"
)
Image
(
systemName
:
"doc.on.doc"
)
}
Button
(
action
:
{
print
(
"run"
)
})
{
Text
(
"Copy Subject"
)
Image
(
systemName
:
"circle.dashed.rectangle"
)
}
Button
(
action
:
{
print
(
"run"
)
})
{
Text
(
"Show Text"
)
Image
(
systemName
:
"text.viewfinder"
)
}
}
}
placeholder
:
{
ProgressView
()
}
}
else
{
Text
(
message
.
message
)
.
font
(
FontStyle
.
DefaultText
.
font
)
.
foregroundColor
(
ColorSet
.
BodyChat
.
color
)
.
padding
(
15
)
.
background
(
ColorSet
.
ChatBaloon
.
color
)
.
cornerRadius
(
10
,
corners
:
[
.
tl
,
.
tr
,
.
br
])
}
}
HStack
(
alignment
:
.
top
){
HStack
(
alignment
:
.
top
){
Text
(
DateTextLib
.
ISO86012FormatText
(
message
.
time
,
format
:
"yyyy/MM/dd hh:mm"
,
errFormat
:
""
))
Text
(
DateTextLib
.
ISO86012FormatText
(
message
.
time
,
format
:
"yyyy/MM/dd hh:mm"
,
errFormat
:
""
))
.
font
(
FontStyle
.
DateText
.
font
)
.
font
(
FontStyle
.
DateText
.
font
)
...
...
Seilassist/Sailassist/Json/ReqUploadImage.swift
0 → 100644
View file @
40fa98bc
//
// ReqUploadImage.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/29.
//
import
Foundation
struct
ReqUploadImage
:
Codable
{
var
shipId
:
Int
var
messageId
:
String
//UUID
var
location
:
Int
//1:Shore、2:Ship
var
from
:
String
//投稿者名
var
fromId
:
String
//ユーザーID
var
files
:
Data
}
Seilassist/Sailassist/Json/ResAckMessage.swift
0 → 100644
View file @
40fa98bc
//
// ResAckMessage.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/05.
//
import
Foundation
struct
ResAckMessage
:
Codable
{
var
shipId
:
Int
var
messageId
:
Int
//UUID
var
time
:
String
//投稿日時
var
location
:
Int
//1:Shore、2:Ship
var
fromId
:
Int
//ユーザーID
}
Seilassist/Sailassist/Json/ResChatMessage.swift
0 → 100644
View file @
40fa98bc
//
// ResChatMessage.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/05.
//
import
Foundation
struct
ResChatMessage
:
Codable
{
var
shipId
:
Int
var
messageId
:
Int
//UUID
var
type
:
Int
//0:テキスト、1:スタンプ
var
time
:
String
//投稿日時
var
location
:
Int
//1:Shore、2:Ship
var
from
:
String
//投稿者名
var
fromId
:
Int
//ユーザーID
var
message
:
String
//テキスト
var
stampId
:
Int
//スタンプ番号
}
Seilassist/Sailassist/Json/ResChatMode.swift
0 → 100644
View file @
40fa98bc
//
// ResChatMode.swift
// Sailassist
//
// Created by 三浦薫巳 on 2024/01/05.
//
import
Foundation
struct
ResChatMode
:
Codable
{
var
shipId
:
Int
var
time
:
String
//投稿日時
var
location
:
Int
//1:Shore、2:Ship
var
fromId
:
Int
//ユーザーID
var
mode
:
Int
//0:通常、1:Warning中
}
Seilassist/Sailassist/Json/ResGetMessages.swift
View file @
40fa98bc
...
@@ -10,16 +10,17 @@ import Foundation
...
@@ -10,16 +10,17 @@ import Foundation
struct
ResGetMessages
:
Codable
{
struct
ResGetMessages
:
Codable
{
var
mode
:
Int
// 0:通常 , 1:Warning中
var
mode
:
Int
// 0:通常 , 1:Warning中
var
messages
:
[
ChatMessage
]?
var
messages
:
[
ChatMessage
]?
var
users
:
[
ChatUser
]?
}
}
struct
ChatMessage
:
Codable
{
struct
ChatMessage
:
Codable
{
var
shipId
:
U
Int
var
shipId
:
Int
var
messageId
:
String
//各メッセージ固有ID
var
messageId
:
String
//各メッセージ固有ID
var
type
:
Int
//0:テキスト , 1:スタンプ , 2:画像
var
type
:
Int
//0:テキスト , 1:スタンプ , 2:画像
var
time
:
String
//投稿日時
var
time
:
String
//投稿日時
var
location
:
Int
//1:Shore , 2:Ship
var
location
:
Int
//1:Shore , 2:Ship
var
from
:
String
//投稿者名
var
from
:
String
//投稿者名
var
fromId
:
String
//ユーザーID
var
fromId
:
String
?
//ユーザーID
var
message
:
String
//テキスト時:テキスト , 画像時:サムネイルのUri
var
message
:
String
//テキスト時:テキスト , 画像時:サムネイルのUri
var
stampId
:
Int
//スタンプ番号 0:Fire~
var
stampId
:
Int
//スタンプ番号 0:Fire~
var
viewer
:
[
Viewer
]
//閲覧者情報
var
viewer
:
[
Viewer
]
//閲覧者情報
...
@@ -30,3 +31,10 @@ struct Viewer: Codable {
...
@@ -30,3 +31,10 @@ struct Viewer: Codable {
var
location
:
Int
//1:Shore , 2:Ship
var
location
:
Int
//1:Shore , 2:Ship
var
id
:
String
//ユーザーID
var
id
:
String
//ユーザーID
}
}
struct
ChatUser
:
Codable
{
var
time
:
String
//最終アクセス日時
var
location
:
Int
//1:Shore , 2:Ship
var
id
:
String
//ログイン時のデバイスID
var
name
:
String
//ユーザー名
}
Seilassist/Sailassist/Menu/GetManualUrl.swift
View file @
40fa98bc
...
@@ -13,7 +13,6 @@ class GetManualUrl {
...
@@ -13,7 +13,6 @@ class GetManualUrl {
func
start
()
{
func
start
()
{
print
(
debug
:
"called"
)
print
(
debug
:
"called"
)
sessionGetManualUrl
.
getManualUrl
{
response
in
sessionGetManualUrl
.
getManualUrl
{
response
in
print
(
debug
:
"called"
)
switch
response
{
switch
response
{
case
.
success
(
let
resultData
):
case
.
success
(
let
resultData
):
print
(
debug
:
String
(
data
:
resultData
,
encoding
:
.
utf8
)
as
Any
)
print
(
debug
:
String
(
data
:
resultData
,
encoding
:
.
utf8
)
as
Any
)
...
...
Seilassist/Sailassist/SailassistApp.swift
View file @
40fa98bc
...
@@ -8,6 +8,7 @@
...
@@ -8,6 +8,7 @@
import
SwiftUI
import
SwiftUI
import
UserNotifications
import
UserNotifications
import
WindowsAzureMessaging
import
WindowsAzureMessaging
import
SwiftSignalRClient
@main
@main
struct
SailassistApp
:
App
{
struct
SailassistApp
:
App
{
...
@@ -17,6 +18,7 @@ struct SailassistApp: App {
...
@@ -17,6 +18,7 @@ struct SailassistApp: App {
let
locationViewModel
=
LocationViewModel
()
let
locationViewModel
=
LocationViewModel
()
let
signalRService
=
SignalRService
()
let
signalRService
=
SignalRService
()
var
body
:
some
Scene
{
var
body
:
some
Scene
{
WindowGroup
{
WindowGroup
{
if
!
isTermsAgree
{
if
!
isTermsAgree
{
...
@@ -66,14 +68,17 @@ class NotificationTags: NSObject {
...
@@ -66,14 +68,17 @@ class NotificationTags: NSObject {
let
bamTag
=
"bam-"
+
shipId
let
bamTag
=
"bam-"
+
shipId
let
taskAlertTag
=
"taskalert-"
+
shipId
let
taskAlertTag
=
"taskalert-"
+
shipId
let
sailassistTag
=
"sailassist-"
+
shipId
let
sailassistTag
=
"sailassist-"
+
shipId
let
chatTag
=
"chat-"
+
shipId
let
emergencyTag
=
"emergency"
+
shipId
let
emergencyTag
=
"emergency"
+
shipId
// let chatTag = "chat-" + shipId
MSNotificationHub
.
addTags
([
routeTag
,
bamTag
,
taskAlertTag
,
sailassistTag
,
emergencyTag
])
MSNotificationHub
.
addTags
([
routeTag
,
bamTag
,
taskAlertTag
,
sailassistTag
,
emergencyTag
,
chatTag
])
}
}
}
}
}
}
private
var
connection
:
HubConnection
?
class
AppDelegate
:
NSObject
,
UIApplicationDelegate
,
MSNotificationHubDelegate
,
MSInstallationLifecycleDelegate
{
class
AppDelegate
:
NSObject
,
UIApplicationDelegate
,
MSNotificationHubDelegate
,
MSInstallationLifecycleDelegate
{
private
var
hubConnectionDelegate
:
HubConnectionDelegate
?
func
application
(
_
application
:
UIApplication
,
didFinishLaunchingWithOptions
launchOptions
:
[
UIApplication
.
LaunchOptionsKey
:
Any
]?
=
nil
)
->
Bool
{
func
application
(
_
application
:
UIApplication
,
didFinishLaunchingWithOptions
launchOptions
:
[
UIApplication
.
LaunchOptionsKey
:
Any
]?
=
nil
)
->
Bool
{
print
(
debug
:
"called"
)
print
(
debug
:
"called"
)
...
@@ -100,6 +105,29 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
...
@@ -100,6 +105,29 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
Preferences
.
DeviceId
=
UUID
()
.
uuidString
Preferences
.
DeviceId
=
UUID
()
.
uuidString
}
}
//SignalR初期化
hubConnectionDelegate
=
ChatHubConnectionDelegate
(
app
:
self
)
connection
=
HubConnectionBuilder
(
url
:
URL
(
string
:
HttpRequestType
.
SignalR
.
rawValue
)
!
)
.
withHubConnectionDelegate
(
delegate
:
hubConnectionDelegate
!
)
.
withAutoReconnect
()
.
withLogging
(
minLogLevel
:
.
error
)
.
withHubConnectionOptions
(
configureHubConnectionOptions
:
{
options
in
options
.
keepAliveInterval
=
20
})
.
build
()
connection
!.
on
(
method
:
"chatMessage"
,
callback
:
{
(
message
:
ResChatMessage
)
in
self
.
handleChatMessage
(
message
:
message
)
})
connection
!.
on
(
method
:
"ackMessage"
,
callback
:
{
(
message
:
ResAckMessage
)
in
self
.
handleAckMessage
(
message
:
message
)
})
connection
!.
on
(
method
:
"chatMode"
,
callback
:
{
(
message
:
ResChatMode
)
in
self
.
handleChatMessage
(
message
:
message
)
})
connection
!.
start
()
return
true
return
true
}
}
...
@@ -122,8 +150,8 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
...
@@ -122,8 +150,8 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
// Push通知を受信した時(サイレントプッシュ)
// Push通知を受信した時(サイレントプッシュ)
func
notificationHub
(
_
notificationHub
:
MSNotificationHub
,
didReceivePushNotification
notification
:
MSNotificationHubMessage
)
{
func
notificationHub
(
_
notificationHub
:
MSNotificationHub
,
didReceivePushNotification
notification
:
MSNotificationHubMessage
)
{
// let title = notification.title ?? ""
// let title = notification.title ?? ""
// let body = notification.body ?? ""
// let body = notification.body ?? ""
let
userInfo
=
notification
.
userInfo
let
userInfo
=
notification
.
userInfo
print
(
debug
:
"called
\(
String
(
describing
:
userInfo
)
)
"
)
print
(
debug
:
"called
\(
String
(
describing
:
userInfo
)
)
"
)
...
@@ -143,6 +171,102 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
...
@@ -143,6 +171,102 @@ class AppDelegate: NSObject, UIApplicationDelegate ,MSNotificationHubDelegate, M
func
application
(
_
application
:
UIApplication
,
didFailToRegisterForRemoteNotificationsWithError
error
:
Error
)
{
func
application
(
_
application
:
UIApplication
,
didFailToRegisterForRemoteNotificationsWithError
error
:
Error
)
{
print
(
"APNs 登録に失敗しました :
\(
error
.
localizedDescription
)
"
)
print
(
"APNs 登録に失敗しました :
\(
error
.
localizedDescription
)
"
)
}
}
private
func
handleChatMessage
(
message
:
ResChatMessage
)
{
print
(
debug
:
"called"
)
}
private
func
handleAckMessage
(
message
:
ResAckMessage
)
{
print
(
debug
:
"called"
)
}
private
func
handleChatMessage
(
message
:
ResChatMode
)
{
print
(
debug
:
"called"
)
}
// func applicationWillTerminate(_ aNotification: Notification) {
// connection.stop()
// }
}
class
SignalR
:
NSObject
{
func
chatMessage
(
message
:
String
)
{
var
request
=
ReqMessage
(
shipId
:
Preferences
.
shipId
,
messageId
:
UUID
()
.
uuidString
)
request
.
type
=
0
//0:テキスト, 1:スタンプ
request
.
time
=
DateTextLib
.
Date2ISO8601Text
(
Date
())
request
.
location
=
2
//1:Shore , 2:Ship
request
.
from
=
Preferences
.
UserName
//投稿者名
request
.
fromeId
=
String
(
SharingData
.
my
.
id
)
//ユーザーID
request
.
message
=
message
//テキスト
request
.
stampId
=
0
//スタンプ番号 0:Fire~
if
message
!=
""
{
connection
!.
invoke
(
method
:
"chatMessage"
,
request
)
{
error
in
if
let
e
=
error
{
print
(
debug
:
"Error:
\(
e
)
"
)
}
}
}
}
func
ackMessage
(
messageId
:
String
)
{
var
request
=
ReqAckMessage
(
shipId
:
Preferences
.
shipId
,
messageId
:
messageId
)
request
.
time
=
DateTextLib
.
Date2ISO8601Text
(
Date
())
request
.
location
=
2
//1:Shore , 2:Ship
request
.
fromeId
=
String
(
SharingData
.
my
.
id
)
//ユーザーID
if
messageId
!=
""
{
connection
!.
invoke
(
method
:
"ackMessage"
,
request
)
{
error
in
if
let
e
=
error
{
print
(
debug
:
"Error:
\(
e
)
"
)
}
}
}
}
func
chatMode
(
mode
:
Bool
)
{
var
request
=
ReqChatModeMessage
(
shipId
:
Preferences
.
shipId
)
request
.
time
=
DateTextLib
.
Date2ISO8601Text
(
Date
())
request
.
location
=
2
//1:Shore , 2:Ship
request
.
fromeId
=
String
(
SharingData
.
my
.
id
)
//ユーザーID
if
mode
==
true
{
request
.
mode
=
1
}
else
{
request
.
mode
=
0
}
connection
!.
invoke
(
method
:
"chatMode"
,
request
)
{
error
in
if
let
e
=
error
{
print
(
debug
:
"Error:
\(
e
)
"
)
}
}
}
}
class
ChatHubConnectionDelegate
:
HubConnectionDelegate
{
weak
var
app
:
AppDelegate
?
init
(
app
:
AppDelegate
)
{
self
.
app
=
app
}
func
connectionDidOpen
(
hubConnection
:
HubConnection
)
{
// app?.connectionDidStart()
}
func
connectionDidFailToOpen
(
error
:
Error
)
{
// app?.connectionDidFailToOpen(error: error)
}
func
connectionDidClose
(
error
:
Error
?)
{
// app?.connectionDidClose(error: error)
}
func
connectionWillReconnect
(
error
:
Error
)
{
// app?.connectionWillReconnect(error: error)
}
func
connectionDidReconnect
()
{
// app?.connectionDidReconnect()
}
}
}
extension
AppDelegate
:
UNUserNotificationCenterDelegate
{
extension
AppDelegate
:
UNUserNotificationCenterDelegate
{
...
@@ -157,19 +281,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
...
@@ -157,19 +281,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
return
return
}
}
completionHandler
([[
.
banner
,
.
badge
,
.
sound
]])
let
arrCategory
=
arrAPS
[
"category"
]
as?
String
??
""
let
arrCategory
=
arrAPS
[
"category"
]
as?
String
??
""
switch
arrCategory
{
switch
arrCategory
{
// case "chat":
case
"chat"
:
// guard let arrAlert = arrAPS["alert"] as? [String: Any] else {
guard
let
arrAlert
=
arrAPS
[
"alert"
]
as?
[
String
:
Any
]
else
{
// return
completionHandler
([[
.
banner
,
.
badge
,
.
sound
]])
// }
return
// let subtitle = arrAlert["subtitle"] as? String ?? "" //送信先名称
}
// let strTitle = arrAlert["title"] as? String ?? "" //送信内容
let
subtitle
=
arrAlert
[
"subtitle"
]
as?
String
??
""
//送信先名称
// let strBody = arrAlert["body"] as? String ?? "" //船名
let
strTitle
=
arrAlert
[
"title"
]
as?
String
??
""
//送信内容
// let message = GetMessage()
let
strBody
=
arrAlert
[
"body"
]
as?
String
??
""
//船名
// message.start()
let
message
=
GetMessage
()
message
.
start
()
case
"sailassist"
:
case
"sailassist"
:
print
(
debug
:
"sailassist"
)
print
(
debug
:
"sailassist"
)
let
getPushHistory
=
GetPushHistory
()
let
getPushHistory
=
GetPushHistory
()
...
@@ -204,19 +328,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
...
@@ -204,19 +328,19 @@ extension AppDelegate: UNUserNotificationCenterDelegate {
return
return
}
}
completionHandler
()
let
arrCategory
=
arrAPS
[
"category"
]
as?
String
??
""
let
arrCategory
=
arrAPS
[
"category"
]
as?
String
??
""
switch
arrCategory
{
switch
arrCategory
{
// case "chat":
case
"chat"
:
// guard let arrAlert = arrAPS["alert"] as? [String: Any] else {
guard
let
arrAlert
=
arrAPS
[
"alert"
]
as?
[
String
:
Any
]
else
{
// return
completionHandler
()
// }
return
// let subtitle = arrAlert["subtitle"] as? String ?? "" //送信先名称
}
// let strTitle = arrAlert["title"] as? String ?? "" //送信内容
let
subtitle
=
arrAlert
[
"subtitle"
]
as?
String
??
""
//送信先名称
// let strBody = arrAlert["body"] as? String ?? "" //船名
let
strTitle
=
arrAlert
[
"title"
]
as?
String
??
""
//送信内容
// let message = GetMessage()
let
strBody
=
arrAlert
[
"body"
]
as?
String
??
""
//船名
// message.start()
let
message
=
GetMessage
()
message
.
start
()
case
"sailassist"
:
case
"sailassist"
:
print
(
debug
:
"sailassist"
)
print
(
debug
:
"sailassist"
)
let
getPushHistory
=
GetPushHistory
()
let
getPushHistory
=
GetPushHistory
()
...
@@ -269,7 +393,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, ObservableObject {
...
@@ -269,7 +393,6 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate, ObservableObject {
}
}
}
}
class
PassThroughWindow
:
UIWindow
{
class
PassThroughWindow
:
UIWindow
{
override
func
hitTest
(
_
point
:
CGPoint
,
with
event
:
UIEvent
?)
->
UIView
?
{
override
func
hitTest
(
_
point
:
CGPoint
,
with
event
:
UIEvent
?)
->
UIView
?
{
guard
let
view
=
super
.
hitTest
(
point
,
with
:
event
)
else
{
return
nil
}
guard
let
view
=
super
.
hitTest
(
point
,
with
:
event
)
else
{
return
nil
}
...
...
Seilassist/Sailassist/ServerSession/ServerSession.swift
View file @
40fa98bc
...
@@ -79,6 +79,50 @@ class ServerSession{
...
@@ -79,6 +79,50 @@ class ServerSession{
})
.
resume
()
})
.
resume
()
}
}
func
postForm
(
boundary
:
String
,
_
req_url
:
URL
,
_
postdata
:
Data
,
completion
:
@escaping
(
SessionResponse
)
->
Void
){
var
req
=
URLRequest
(
url
:
req_url
)
req
.
httpMethod
=
"POST"
req
.
setValue
(
"multipart/form-data; boundary=
\(
boundary
)
"
,
forHTTPHeaderField
:
"Content-Type"
)
req
.
setValue
(
"
\(
postdata
.
count
)
"
,
forHTTPHeaderField
:
"Content-Length"
)
req
.
httpBody
=
postdata
req
.
timeoutInterval
=
20
// タイムアウト3秒 → Amedasでタイムアウトエラー20秒に変更
// サーバー送信
let
session
=
URLSession
(
configuration
:
.
default
,
delegate
:
nil
,
delegateQueue
:
OperationQueue
.
main
)
session
.
dataTask
(
with
:
req
,
completionHandler
:
{(
data
,
response
,
error
)
in
session
.
finishTasksAndInvalidate
()
do
{
if
error
!=
nil
{
throw
APIError
.
clientError
}
guard
let
indata
=
data
,
let
inresponse
=
response
as?
HTTPURLResponse
else
{
throw
APIError
.
responseError
}
if
inresponse
.
statusCode
!=
200
{
throw
APIError
.
serverError
}
//Cookieを保存
if
let
fields
=
inresponse
.
allHeaderFields
as?
[
String
:
String
],
let
url
=
inresponse
.
url
{
for
cookie
in
HTTPCookie
.
cookies
(
withResponseHeaderFields
:
fields
,
for
:
url
)
{
HTTPCookieStorage
.
shared
.
setCookie
(
cookie
)
}
}
DispatchQueue
.
main
.
async
{
completion
(
.
success
(
indata
))
}
}
catch
{
if
error
as?
APIError
!=
nil
{
completion
(
.
failure
(
error
as!
APIError
))
}
else
{
completion
(
.
failure
(
.
unknown
))
}
}
})
.
resume
()
}
func
getJson
(
_
req_url
:
URL
,
completion
:
@escaping
(
SessionResponse
)
->
Void
){
func
getJson
(
_
req_url
:
URL
,
completion
:
@escaping
(
SessionResponse
)
->
Void
){
var
req
=
URLRequest
(
url
:
req_url
)
var
req
=
URLRequest
(
url
:
req_url
)
...
@@ -164,4 +208,44 @@ class ServerSession{
...
@@ -164,4 +208,44 @@ class ServerSession{
}
}
return
false
return
false
}
}
func
httpBody
(
boundary
:
String
,
_
uploadImage
:
ReqUploadImage
)
->
Data
!
{
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
+=
"
\(
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=\"\(uploadImage.files)\"\r\n"
httpBody1
+=
"Content-Type: image/jpeg
\r\n
"
httpBody1
+=
"
\r\n
"
var
tmp
=
httpBody1
.
data
(
using
:
.
utf8
)
!
var
httpBody
=
Data
()
httpBody
.
append
(
httpBody1
.
data
(
using
:
.
utf8
)
!
)
httpBody
.
append
(
uploadImage
.
files
)
var
httpBody2
=
"
\r\n
"
httpBody2
+=
"--
\(
boundary
)
--
\r\n
"
httpBody
.
append
(
httpBody2
.
data
(
using
:
.
utf8
)
!
)
return
httpBody
}
}
}
Seilassist/Sailassist/ServerSession/SessionUploadImage.swift
View file @
40fa98bc
...
@@ -19,7 +19,7 @@ class SessionUploadImage : ObservableObject {
...
@@ -19,7 +19,7 @@ class SessionUploadImage : ObservableObject {
/**
/**
* メッセージ
* メッセージ
*/
*/
func
Request
GetUploadImage
(
_
completion
:
@escaping
((
Result
<
Data
,
APIError
>
))
->
Void
)
{
func
Request
UploadImage
(
_
uploadImage
:
ReqUploadImage
,
completion
:
@escaping
((
Result
<
Data
,
APIError
>
))
->
Void
)
{
print
(
debug
:
"calld"
)
print
(
debug
:
"calld"
)
if
Calling
{
if
Calling
{
return
return
...
@@ -27,19 +27,20 @@ class SessionUploadImage : ObservableObject {
...
@@ -27,19 +27,20 @@ class SessionUploadImage : ObservableObject {
Calling
=
true
Calling
=
true
// リクエストURLの組み立て
// リクエストURLの組み立て
// リクエストURLの組み立て
let
url_string
:
String
=
HttpRequestType
.
UploadImage
.
rawValue
// let url_string : String = HttpRequestType.UploadImage.rawValue
guard
let
req_url
=
URL
(
string
:
url_string
)
else
{
// guard let req_url = URL(string : url_string) else {
Calling
=
false
// Calling = false
return
// return
}
// }
// if let postdata = serverSession.toJSON(login) {
// let boundary = "----------" + UUID().uuidString
// serverSession.postJson(req_url, postdata, completion: completion)
let
boundary
=
"----WebKitFormBoundaryZLdHZy8HNaBmUX0d"
// }
if
let
postdata
=
serverSession
.
httpBody
(
boundary
:
boundary
,
uploadImage
)
{
// else {
serverSession
.
postForm
(
boundary
:
boundary
,
req_url
,
postdata
,
completion
:
completion
)
// Calling = false
}
// return
else
{
// }
Calling
=
false
return
}
}
}
}
}
Seilassist/Sailassist/SharingData/SharingData.swift
View file @
40fa98bc
...
@@ -115,6 +115,11 @@ class SharingData{
...
@@ -115,6 +115,11 @@ class SharingData{
class
Message
:
ObservableObject
{
class
Message
:
ObservableObject
{
@Published
var
mode
:
Int
=
0
// 0:通常 , 1:Warning中
@Published
var
mode
:
Int
=
0
// 0:通常 , 1:Warning中
@Published
var
messages
:
[
ChatMessage
]
=
[]
@Published
var
messages
:
[
ChatMessage
]
=
[]
@Published
var
users
:
[
ChatUser
]
=
[]
func
changeMode
(){
self
.
mode
.
toggle
()
}
}
}
static
var
information
=
Information
()
static
var
information
=
Information
()
...
...
Seilassist/Sailassist/SignalR/SignalRService.swift
deleted
100644 → 0
View file @
becc590d
//
// SignalRService.swift
// Sailassist
//
// Created by 三浦薫巳 on 2023/11/17.
//
import
Foundation
import
SwiftSignalRClient
public
class
SignalRService
{
private
var
connection
:
HubConnection
private
var
hubConnectionDelegate
:
HubConnectionDelegate
?
public
init
()
{
// hubConnectionDelegate = ChatHubConnectionDelegate(app: self)
hubConnectionDelegate
=
ChatHubConnectionDelegate
()
connection
=
HubConnectionBuilder
(
url
:
URL
(
string
:
HttpRequestType
.
SignalR
.
rawValue
)
!
)
.
withHubConnectionDelegate
(
delegate
:
hubConnectionDelegate
!
)
.
withAutoReconnect
()
.
withLogging
(
minLogLevel
:
.
error
)
.
build
()
connection
.
on
(
method
:
"chatMessage"
,
callback
:
{
(
shipId
:
Int
,
messageId
:
Int
,
type
:
Int
,
time
:
String
,
location
:
Int
,
from
:
String
,
fromeId
:
Int
,
message
:
String
)
in
self
.
handleChatMessage
(
message
,
from
:
from
)
})
connection
.
on
(
method
:
"ackMessage"
,
callback
:
{
(
shipId
:
Int
,
time
:
String
,
location
:
Int
,
fromId
:
Int
,
mode
:
Int
)
in
self
.
handleAckMessage
(
time
)
})
connection
.
on
(
method
:
"chatMode"
,
callback
:
{
(
shipId
:
Int
,
time
:
String
,
location
:
Int
,
fromId
:
String
,
mode
:
Int
)
in
self
.
handleChatMessage
(
fromId
)
})
connection
.
start
()
}
private
func
handleChatMessage
(
_
message
:
String
,
from
user
:
String
)
{
print
(
debug
:
"called"
)
}
private
func
handleAckMessage
(
_
time
:
String
)
{
print
(
debug
:
"called"
)
}
private
func
handleChatMessage
(
_
fromId
:
String
)
{
print
(
debug
:
"called"
)
}
func
applicationWillTerminate
(
_
aNotification
:
Notification
)
{
connection
.
stop
()
}
//呼び出す
func
chatMessage
(
_
message
:
String
)
{
var
request
=
ReqMessage
(
shipId
:
Preferences
.
shipId
,
messageId
:
"aaaa"
)
request
.
type
=
0
//0:テキスト, 1:スタンプ
// request.time = DateTextLib.Date2ISO8601Text(date: Date())
request
.
location
=
2
//1:Shore , 2:Ship
request
.
from
=
Preferences
.
UserName
//投稿者名
// request.fromeId = SharingData.my.shipName //ユーザーID
request
.
message
=
message
//テキスト
// request.stampId = //スタンプ番号 0:Fire~
if
message
!=
""
{
connection
.
invoke
(
method
:
"ChatMessage"
,
message
)
{
error
in
if
let
e
=
error
{
print
(
debug
:
"Error:
\(
e
)
"
)
}
}
}
}
func
ackMessage
(
_
message
:
String
)
{
var
request
=
ReqAckMessage
(
shipId
:
Preferences
.
shipId
,
messageId
:
"aaaa"
)
//request.time = DateTextLib.Date2ISO8601Text(date: Date())
request
.
location
=
2
//1:Shore , 2:Ship
// request.fromeId = SharingData.my.shipName //ユーザーID
if
message
!=
""
{
connection
.
invoke
(
method
:
"AckMessage"
,
request
)
{
error
in
if
let
e
=
error
{
print
(
debug
:
"Error:
\(
e
)
"
)
}
}
}
}
func
chatMode
(
_
message
:
String
)
{
var
request
=
ReqChatModeMessage
(
shipId
:
Preferences
.
shipId
)
// request.time = DateTextLib.Date2ISO8601Text(date: Date())
request
.
location
=
2
//1:Shore , 2:Ship
// request.fromeId = SharingData.my.shipName //ユーザーID
request
.
mode
=
0
//0:通常 / 1:Warning中
if
message
!=
""
{
connection
.
invoke
(
method
:
"ChatMode"
,
message
)
{
error
in
if
let
e
=
error
{
print
(
debug
:
"Error:
\(
e
)
"
)
}
}
}
}
// func chatMode2(_ message: String) {
// connection.send(method: "Broadcast", "Playground user", "Testing send") { error in
// if let error = error {
// print("Send failed: \(error)")
// }
// }
// }
}
class
ChatHubConnectionDelegate
:
HubConnectionDelegate
{
// weak var app: AppDelegate?
//
// init(app: AppDelegate) {
// self.app = app
// }
func
connectionDidOpen
(
hubConnection
:
HubConnection
)
{
print
(
"connectionDidOpen"
)
// After connection established call registerUserInServer method
DispatchQueue
.
main
.
async
{
// self.registerUserInServer()
}
}
func
connectionDidFailToOpen
(
error
:
Error
)
{
print
(
"connectionDidFailToOpen"
)
}
func
connectionDidClose
(
error
:
Error
?)
{
print
(
"connectionDidClose"
)
}
func
connectionWillReconnect
(
error
:
Error
)
{
print
(
"connectionWillReconnect"
)
}
func
connectionDidReconnect
()
{
print
(
"connectionDidReconnect"
)
}
}
Seilassist/Sailassist/Tab/MainTabView.swift
View file @
40fa98bc
...
@@ -119,12 +119,20 @@ struct CustomTabBar: View {
...
@@ -119,12 +119,20 @@ struct CustomTabBar: View {
}
}
},
label
:
{
},
label
:
{
VStack
{
VStack
{
Image
(
selectedTabModel
.
activeTab
==
tab
?
tab
.
rawValue
+
"_selected"
:
tab
.
rawValue
)
ZStack
(
alignment
:
.
bottomTrailing
)
{
.
font
(
.
title2
)
Image
(
selectedTabModel
.
activeTab
==
tab
?
tab
.
rawValue
+
"_selected"
:
tab
.
rawValue
)
.
font
(
.
title2
)
// if tab == Tab.chat {
// Rectangle()
// .foregroundColor(.red)
// .frame(width: 12, height: 12)
// .cornerRadius(60)
// }
}
Text
(
tab
.
title
)
Text
(
tab
.
title
)
.
font
(
.
caption
)
.
font
(
.
caption
)
}
}
.
frame
(
maxWidth
:
.
infinity
,
maxHeight
:
.
infinity
)
.
frame
(
maxWidth
:
.
infinity
,
maxHeight
:
.
infinity
)
.
contentShape
(
.
rect
)
.
contentShape
(
.
rect
)
...
@@ -137,11 +145,9 @@ struct CustomTabBar: View {
...
@@ -137,11 +145,9 @@ struct CustomTabBar: View {
.
background
(
ColorSet
.
BottomNav
.
color
)
.
background
(
ColorSet
.
BottomNav
.
color
)
.
alert
(
""
,
isPresented
:
$
selectedTabModel
.
isShowChangeEmrMode
)
{
.
alert
(
""
,
isPresented
:
$
selectedTabModel
.
isShowChangeEmrMode
)
{
Button
(
"Yes"
){
Button
(
"Yes"
){
if
SharingData
.
message
.
mode
==
0
{
SharingData
.
message
.
changeMode
()
SharingData
.
message
.
mode
=
1
let
signalRService
=
SignalR
()
}
else
{
signalRService
.
chatMode
(
mode
:
SharingData
.
message
.
mode
)
SharingData
.
message
.
mode
=
0
}
}
}
Button
(
"No"
){
Button
(
"No"
){
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment