diff --git a/.travis.yml b/.travis.yml index 030ed58..c762139 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,29 +1,19 @@ language: swift xcode_project: Rocc.xcodeproj # path to your xcodeproj folder xcode_scheme: Rocc -osx_image: xcode10.2 +osx_image: xcode11.3 env: global: - LC_CTYPE=en_US.UTF-8 - LANG=en_US.UTF-8 - IOS_FRAMEWORK_SCHEME="Rocc" - TVOS_FRAMEWORK_SCHEME="" - - OSX_FRAMEWORK_SCHEME="RoccMac" - - IOS_SDK=iphonesimulator12.2 - - TVOS_SDK=appletvsimulator12.2 - - OSX_SDK=macosx10.14 + - OSX_FRAMEWORK_SCHEME="Rocc" + - IOS_SDK=iphonesimulator13.2 + - TVOS_SDK=appletvsimulator13.2 + - OSX_SDK=macosx10.15 matrix: - - DESTINATION="OS=11.0.1,name=iPhone 5s" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=11.0.1,name=iPhone 8 Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=11.1,name=iPhone 8" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=11.2,name=iPhone 8" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=11.1,name=iPhone 8 Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=11.2,name=iPhone 8 Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=12.0,name=iPhone 8 Plus" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=12.0,name=iPhone X" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=12.2,name=iPhone Xʀ" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="OS=12.2,name=iPhone XS Max" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" - - DESTINATION="arch=x86_64" SCHEME="$OSX_FRAMEWORK_SCHEME" SDK="$OSX_SDK" RUN_TESTS="NO" BUILD_EXAMPLE="NO" POD_LINT="NO" + - DESTINATION="OS=13.3,name=iPhone 11 Pro Max" SCHEME="$IOS_FRAMEWORK_SCHEME" SDK="$IOS_SDK" RUN_TESTS="YES" BUILD_EXAMPLE="NO" POD_LINT="NO" script: - set -o pipefail - xcodebuild -version diff --git a/README.md b/README.md index ee0a1f2..8269d8c 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,8 @@ Build Status - - Swift 5.0 + + Swift 5.0 MIT diff --git a/Rocc.xcodeproj/project.pbxproj b/Rocc.xcodeproj/project.pbxproj index 2b9ff7e..0563a93 100644 --- a/Rocc.xcodeproj/project.pbxproj +++ b/Rocc.xcodeproj/project.pbxproj @@ -22,25 +22,16 @@ B100E1C620A105D9004F7AB8 /* TVColorSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1C520A105D9004F7AB8 /* TVColorSystem.swift */; }; B100E1DE20A1A60A004F7AB8 /* RemotePlayback.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1D820A1A60A004F7AB8 /* RemotePlayback.swift */; }; B10B38F021E0F6C300FED24F /* Function.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10B38EF21E0F6C300FED24F /* Function.swift */; }; - B10B38F121E0F6C300FED24F /* Function.swift in Sources */ = {isa = PBXBuildFile; fileRef = B10B38EF21E0F6C300FED24F /* Function.swift */; }; - B115EF2421E9F26600667FB7 /* Errors.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A25F3121AE950E00D9EE81 /* Errors.swift */; }; - B115EF2A21E9F27900667FB7 /* ShutterSpeedFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A25F2021ADE6CE00D9EE81 /* ShutterSpeedFormatter.swift */; }; B115EF2F21E9FC3A00667FB7 /* SonyXMLParsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EF2E21E9FC3900667FB7 /* SonyXMLParsers.swift */; }; - B115EF3021E9FC3A00667FB7 /* SonyXMLParsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EF2E21E9FC3900667FB7 /* SonyXMLParsers.swift */; }; B115EF3721E9FDA100667FB7 /* SonyDeviceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EF3621E9FDA100667FB7 /* SonyDeviceInfo.swift */; }; - B115EF3821E9FDA100667FB7 /* SonyDeviceInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EF3621E9FDA100667FB7 /* SonyDeviceInfo.swift */; }; B115EFB721ECF88100667FB7 /* UPnPParsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EFB621ECF88100667FB7 /* UPnPParsers.swift */; }; - B115EFB821ECF88100667FB7 /* UPnPParsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EFB621ECF88100667FB7 /* UPnPParsers.swift */; }; B115EFC521ECFB4700667FB7 /* CdsDesc.xml in Resources */ = {isa = PBXBuildFile; fileRef = B115EFC321ECFB4700667FB7 /* CdsDesc.xml */; }; B115EFC621ECFB4700667FB7 /* CmsDesc.xml in Resources */ = {isa = PBXBuildFile; fileRef = B115EFC421ECFB4700667FB7 /* CmsDesc.xml */; }; B115EFD321ECFB6B00667FB7 /* ParserTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EFD221ECFB6B00667FB7 /* ParserTests.swift */; }; B115EFD421ECFBC300667FB7 /* UPnPParsers.swift in Sources */ = {isa = PBXBuildFile; fileRef = B115EFB621ECF88100667FB7 /* UPnPParsers.swift */; }; B11786F92187753F0006B72E /* SonyCamera+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11786F82187753F0006B72E /* SonyCamera+Model.swift */; }; - B11786FA2187753F0006B72E /* SonyCamera+Model.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11786F82187753F0006B72E /* SonyCamera+Model.swift */; }; B1178701218775980006B72E /* FunctionNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1178700218775980006B72E /* FunctionNames.swift */; }; - B1178702218775980006B72E /* FunctionNames.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1178700218775980006B72E /* FunctionNames.swift */; }; B11D8E7321B9300F00719019 /* SimulatedCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11D8E6D21B9300F00719019 /* SimulatedCamera.swift */; }; - B11D8E7421B9300F00719019 /* SimulatedCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B11D8E6D21B9300F00719019 /* SimulatedCamera.swift */; }; B1316A572089C08F006BD136 /* Rocc.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1316A4D2089C08F006BD136 /* Rocc.framework */; }; B1316A5C2089C08F006BD136 /* RoccTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1316A5B2089C08F006BD136 /* RoccTests.swift */; }; B1316A5E2089C08F006BD136 /* Rocc.h in Headers */ = {isa = PBXBuildFile; fileRef = B1316A502089C08F006BD136 /* Rocc.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -48,70 +39,26 @@ B1316A742089C1D6006BD136 /* UDPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1316A732089C1D6006BD136 /* UDPClient.swift */; }; B1316A7B2089C426006BD136 /* SonyConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1316A7A2089C426006BD136 /* SonyConstants.swift */; }; B154525C21EE61B800C59096 /* SOAPRequestBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154525B21EE61B800C59096 /* SOAPRequestBody.swift */; }; - B154525D21EE61B800C59096 /* SOAPRequestBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154525B21EE61B800C59096 /* SOAPRequestBody.swift */; }; B154526421EE63DB00C59096 /* SOAPRequestBody.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154525B21EE61B800C59096 /* SOAPRequestBody.swift */; }; B154535521EFDC1700C59096 /* Countable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154535421EFDC1700C59096 /* Countable.swift */; }; - B154535621EFDC1700C59096 /* Countable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154535421EFDC1700C59096 /* Countable.swift */; }; B154535E21EFE3D100C59096 /* ChildRangeTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154535D21EFE3D100C59096 /* ChildRangeTests.swift */; }; B154535F21EFE3DC00C59096 /* Countable.swift in Sources */ = {isa = PBXBuildFile; fileRef = B154535421EFDC1700C59096 /* Countable.swift */; }; B1561ED120976B850013D122 /* ShootMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1561ECB20976B850013D122 /* ShootMode.swift */; }; B1561ED420976F7B0013D122 /* Capture.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1561ED320976F7A0013D122 /* Capture.swift */; }; B16064A821E3A00A00AE3483 /* SonyTransferDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16064A221E3A00900AE3483 /* SonyTransferDevice.swift */; }; - B16064A921E3A00A00AE3483 /* SonyTransferDevice.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16064A221E3A00900AE3483 /* SonyTransferDevice.swift */; }; B163AEBF20A8D6050061D1C4 /* CameraEventNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B163AEBE20A8D6050061D1C4 /* CameraEventNotifier.swift */; }; - B163AEC020A8D6050061D1C4 /* CameraEventNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B163AEBE20A8D6050061D1C4 /* CameraEventNotifier.swift */; }; B164F02621811BD400590A05 /* SonyCameraDiscoverer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B164F02521811BD400590A05 /* SonyCameraDiscoverer.swift */; }; - B164F02721811BD400590A05 /* SonyCameraDiscoverer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B164F02521811BD400590A05 /* SonyCameraDiscoverer.swift */; }; B164F02921811C1200590A05 /* String+Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = B164F02821811C1200590A05 /* String+Regex.swift */; }; - B164F02A21811C1200590A05 /* String+Regex.swift in Sources */ = {isa = PBXBuildFile; fileRef = B164F02821811C1200590A05 /* String+Regex.swift */; }; B16BFBC820A49F92006BD081 /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16BFBC220A49F91006BD081 /* Storage.swift */; }; B16BFD1121F5F0E600AF3F24 /* SimplePing.m in Sources */ = {isa = PBXBuildFile; fileRef = B16BFD0F21F5F0E600AF3F24 /* SimplePing.m */; }; - B16BFD1221F5F0E600AF3F24 /* SimplePing.m in Sources */ = {isa = PBXBuildFile; fileRef = B16BFD0F21F5F0E600AF3F24 /* SimplePing.m */; }; B16BFD1321F5F0E600AF3F24 /* SimplePing.h in Headers */ = {isa = PBXBuildFile; fileRef = B16BFD1021F5F0E600AF3F24 /* SimplePing.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B16BFD1421F5F0E600AF3F24 /* SimplePing.h in Headers */ = {isa = PBXBuildFile; fileRef = B16BFD1021F5F0E600AF3F24 /* SimplePing.h */; settings = {ATTRIBUTES = (Public, ); }; }; B16BFD1621F5F0F100AF3F24 /* Pinger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16BFD1521F5F0F100AF3F24 /* Pinger.swift */; }; - B16BFD1721F5F0F100AF3F24 /* Pinger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16BFD1521F5F0F100AF3F24 /* Pinger.swift */; }; B1751E7920A316C2001D05F1 /* SystemClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1751E7320A316C2001D05F1 /* SystemClient.swift */; }; - B1751E7A20A316C2001D05F1 /* SystemClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1751E7320A316C2001D05F1 /* SystemClient.swift */; }; B1990A8020C3FA1D0090A2F6 /* DeviceConnectivityNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1990A7F20C3FA1D0090A2F6 /* DeviceConnectivityNotifier.swift */; }; - B1990A8120C3FA1D0090A2F6 /* DeviceConnectivityNotifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1990A7F20C3FA1D0090A2F6 /* DeviceConnectivityNotifier.swift */; }; B1990A8320C3FDAA0090A2F6 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1990A8220C3FDAA0090A2F6 /* Reachability.swift */; }; - B1990A8420C3FDAA0090A2F6 /* Reachability.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1990A8220C3FDAA0090A2F6 /* Reachability.swift */; }; B1990A8620C408C20090A2F6 /* Ping.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1990A8520C408C20090A2F6 /* Ping.swift */; }; - B1990A8720C408C20090A2F6 /* Ping.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1990A8520C408C20090A2F6 /* Ping.swift */; }; B1A1AA1A20A4E01D00FD0A4A /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A1AA1420A4E01D00FD0A4A /* Event.swift */; }; - B1A1AA1E20A4E02200FD0A4A /* Aperture.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB48722092743100C33C86 /* Aperture.swift */; }; - B1A1AA1F20A4E02200FD0A4A /* AutoPowerOff.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4C8A20A24DA100EEDE3E /* AutoPowerOff.swift */; }; - B1A1AA2020A4E02200FD0A4A /* BeepMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4CAC20A3140A00EEDE3E /* BeepMode.swift */; }; - B1A1AA2120A4E02200FD0A4A /* Capture.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1561ED320976F7A0013D122 /* Capture.swift */; }; - B1A1AA2220A4E02200FD0A4A /* ColorSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1B920A0DA92004F7AB8 /* ColorSetting.swift */; }; - B1A1AA2320A4E02200FD0A4A /* CurrentTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4CAF20A3161700EEDE3E /* CurrentTime.swift */; }; - B1A1AA2420A4E02200FD0A4A /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A1AA1420A4E01D00FD0A4A /* Event.swift */; }; - B1A1AA2520A4E02200FD0A4A /* Exposure.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E19E20A04CEF004F7AB8 /* Exposure.swift */; }; - B1A1AA2620A4E02200FD0A4A /* FileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4342920939EF500A81B9D /* FileSystem.swift */; }; - B1A1AA2720A4E02200FD0A4A /* FlipSetting.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1C220A0F90A004F7AB8 /* FlipSetting.swift */; }; - B1A1AA2820A4E02200FD0A4A /* Focus.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1A120A04EE0004F7AB8 /* Focus.swift */; }; - B1A1AA2920A4E02200FD0A4A /* InfraredRemoteControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4C8220A24B6300EEDE3E /* InfraredRemoteControl.swift */; }; - B1A1AA2A20A4E02200FD0A4A /* IntervalTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1BC20A0DE7D004F7AB8 /* IntervalTime.swift */; }; - B1A1AA2B20A4E02200FD0A4A /* ISO.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B43459209747C200A81B9D /* ISO.swift */; }; - B1A1AA2C20A4E02200FD0A4A /* LiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE24A72098FD1E0049EC87 /* LiveView.swift */; }; - B1A1AA2E20A4E02200FD0A4A /* PostViewImage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1AA20A0A42D004F7AB8 /* PostViewImage.swift */; }; - B1A1AA2F20A4E02200FD0A4A /* ProgramShift.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1A420A09986004F7AB8 /* ProgramShift.swift */; }; - B1A1AA3020A4E02200FD0A4A /* RemotePlayback.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1D820A1A60A004F7AB8 /* RemotePlayback.swift */; }; - B1A1AA3120A4E02200FD0A4A /* Scene.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1B620A0D7C7004F7AB8 /* Scene.swift */; }; - B1A1AA3220A4E02200FD0A4A /* ShootMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1561ECB20976B850013D122 /* ShootMode.swift */; }; - B1A1AA3420A4E02200FD0A4A /* Shutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE24B32099AA7D0049EC87 /* Shutter.swift */; }; - B1A1AA3520A4E02200FD0A4A /* SteadyMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1B020A0D282004F7AB8 /* SteadyMode.swift */; }; - B1A1AA3620A4E02200FD0A4A /* Storage.swift in Sources */ = {isa = PBXBuildFile; fileRef = B16BFBC220A49F91006BD081 /* Storage.swift */; }; - B1A1AA3820A4E02200FD0A4A /* TouchAF.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE444F2099B492001DB2B6 /* TouchAF.swift */; }; - B1A1AA3920A4E02200FD0A4A /* TrackingFocus.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E196209E47F8004F7AB8 /* TrackingFocus.swift */; }; - B1A1AA3A20A4E02200FD0A4A /* TVColorSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1C520A105D9004F7AB8 /* TVColorSystem.swift */; }; - B1A1AA3B20A4E02200FD0A4A /* ViewAngle.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1B320A0D59E004F7AB8 /* ViewAngle.swift */; }; - B1A1AA3C20A4E02200FD0A4A /* WhiteBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4345C2097483300A81B9D /* WhiteBalance.swift */; }; - B1A1AA3D20A4E02200FD0A4A /* WindNoiseReduction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B100E1BF20A0E8F1004F7AB8 /* WindNoiseReduction.swift */; }; - B1A1AA3E20A4E02200FD0A4A /* Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE24B12099184B0049EC87 /* Zoom.swift */; }; B1A1B67F21F8BC78008B5181 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A1B67E21F8BC78008B5181 /* Logger.swift */; }; - B1A1B68021F8BC78008B5181 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A1B67E21F8BC78008B5181 /* Logger.swift */; }; B1A25F2121ADE6CE00D9EE81 /* ShutterSpeedFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A25F2021ADE6CE00D9EE81 /* ShutterSpeedFormatter.swift */; }; B1A25F2221ADE6CE00D9EE81 /* ShutterSpeedFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A25F2021ADE6CE00D9EE81 /* ShutterSpeedFormatter.swift */; }; B1A25F2921ADEAAC00D9EE81 /* ShutterSpeedFormatterTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A25F2821ADEAAC00D9EE81 /* ShutterSpeedFormatterTests.swift */; }; @@ -120,51 +67,30 @@ B1A3EC2521F11AB700670712 /* CameraFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4344F209746B000A81B9D /* CameraFunctions.swift */; }; B1AF502A208A51D00029336B /* NetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AF5029208A51D00029336B /* NetworkInterface.swift */; }; B1AF504B208D345A0029336B /* ThunderRequest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1AF5041208D34510029336B /* ThunderRequest.framework */; }; - B1AF5091208DC3A80029336B /* RoccMac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1AF5088208DC3A80029336B /* RoccMac.framework */; }; - B1AF5096208DC3A80029336B /* RoccMacTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AF5095208DC3A80029336B /* RoccMacTests.swift */; }; - B1AF5098208DC3A80029336B /* RoccMac.h in Headers */ = {isa = PBXBuildFile; fileRef = B1AF508A208DC3A80029336B /* RoccMac.h */; settings = {ATTRIBUTES = (Public, ); }; }; - B1AF509F208DC3AF0029336B /* SonyConstants.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1316A7A2089C426006BD136 /* SonyConstants.swift */; }; - B1AF50A0208DC3B20029336B /* DeviceDiscovery.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1316A712089C0F6006BD136 /* DeviceDiscovery.swift */; }; - B1AF50A1208DC3B50029336B /* UDPClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1316A732089C1D6006BD136 /* UDPClient.swift */; }; - B1AF50A2208DC3B80029336B /* NetworkInterface.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AF5029208A51D00029336B /* NetworkInterface.swift */; }; B1B4342A20939EF500A81B9D /* FileSystem.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4342920939EF500A81B9D /* FileSystem.swift */; }; B1B43450209746B000A81B9D /* CameraFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4344F209746B000A81B9D /* CameraFunctions.swift */; }; - B1B43451209746B000A81B9D /* CameraFunctions.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4344F209746B000A81B9D /* CameraFunctions.swift */; }; B1B4345A209747C200A81B9D /* ISO.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B43459209747C200A81B9D /* ISO.swift */; }; B1B4345D2097483300A81B9D /* WhiteBalance.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1B4345C2097483300A81B9D /* WhiteBalance.swift */; }; - B1BAAC8F222583B8007F0F61 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A1B67E21F8BC78008B5181 /* Logger.swift */; }; B1BAAC96222583B9007F0F61 /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1A1B67E21F8BC78008B5181 /* Logger.swift */; }; B1CDCB8322234CAA00DD0F0E /* UPnPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CDCB8222234CAA00DD0F0E /* UPnPService.swift */; }; - B1CDCB8F2223524100DD0F0E /* ThunderRequestMac.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = B1AF5045208D34510029336B /* ThunderRequestMac.framework */; }; - B1CDCB90222352BB00DD0F0E /* UPnPService.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CDCB8222234CAA00DD0F0E /* UPnPService.swift */; }; B1CE24AD2098FD1E0049EC87 /* LiveView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE24A72098FD1E0049EC87 /* LiveView.swift */; }; B1CE24B22099184B0049EC87 /* Zoom.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE24B12099184B0049EC87 /* Zoom.swift */; }; B1CE24B42099AA7D0049EC87 /* Shutter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE24B32099AA7D0049EC87 /* Shutter.swift */; }; B1CE44552099B492001DB2B6 /* TouchAF.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1CE444F2099B492001DB2B6 /* TouchAF.swift */; }; B1D358F920AA34CF0069C698 /* LiveViewStreaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D358F820AA34CF0069C698 /* LiveViewStreaming.swift */; }; - B1D358FA20AA34CF0069C698 /* LiveViewStreaming.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D358F820AA34CF0069C698 /* LiveViewStreaming.swift */; }; B1D3591120AADC810069C698 /* Data+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D3591020AADC810069C698 /* Data+Conversion.swift */; }; - B1D3591220AADC810069C698 /* Data+Conversion.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D3591020AADC810069C698 /* Data+Conversion.swift */; }; B1D606542181225E001719EC /* UDPDeviceDiscoverer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D606532181225E001719EC /* UDPDeviceDiscoverer.swift */; }; - B1D606552181225E001719EC /* UDPDeviceDiscoverer.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1D606532181225E001719EC /* UDPDeviceDiscoverer.swift */; }; B1EF4C8820A24B6300EEDE3E /* InfraredRemoteControl.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4C8220A24B6300EEDE3E /* InfraredRemoteControl.swift */; }; B1EF4C8B20A24DA100EEDE3E /* AutoPowerOff.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4C8A20A24DA100EEDE3E /* AutoPowerOff.swift */; }; B1EF4CAD20A3140A00EEDE3E /* BeepMode.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4CAC20A3140A00EEDE3E /* BeepMode.swift */; }; B1EF4CB020A3161700EEDE3E /* CurrentTime.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1EF4CAF20A3161700EEDE3E /* CurrentTime.swift */; }; B1FB47FC209088FD00C33C86 /* SonyCameraAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB47FB209088FD00C33C86 /* SonyCameraAPIClient.swift */; }; - B1FB47FD209088FD00C33C86 /* SonyCameraAPIClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB47FB209088FD00C33C86 /* SonyCameraAPIClient.swift */; }; B1FB47FF209089CA00C33C86 /* CameraClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB47FE209089CA00C33C86 /* CameraClient.swift */; }; - B1FB4800209089CA00C33C86 /* CameraClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB47FE209089CA00C33C86 /* CameraClient.swift */; }; B1FB4802209089D800C33C86 /* AVContentClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB4801209089D800C33C86 /* AVContentClient.swift */; }; - B1FB4803209089D800C33C86 /* AVContentClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB4801209089D800C33C86 /* AVContentClient.swift */; }; B1FB48092090964100C33C86 /* BaseServiceClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB48082090964100C33C86 /* BaseServiceClient.swift */; }; - B1FB480A2090964100C33C86 /* BaseServiceClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB48082090964100C33C86 /* BaseServiceClient.swift */; }; B1FB4811209096FB00C33C86 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB4810209096FB00C33C86 /* Result.swift */; }; - B1FB4812209096FB00C33C86 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB4810209096FB00C33C86 /* Result.swift */; }; B1FB486C2092579E00C33C86 /* Camera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB486B2092579E00C33C86 /* Camera.swift */; }; - B1FB486D2092579E00C33C86 /* Camera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB486B2092579E00C33C86 /* Camera.swift */; }; B1FB486F2092585400C33C86 /* SonyCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB486E2092585400C33C86 /* SonyCamera.swift */; }; - B1FB48702092585400C33C86 /* SonyCamera.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB486E2092585400C33C86 /* SonyCamera.swift */; }; B1FB48732092743100C33C86 /* Aperture.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1FB48722092743100C33C86 /* Aperture.swift */; }; /* End PBXBuildFile section */ @@ -183,6 +109,13 @@ remoteGlobalIDString = B1316A4C2089C08F006BD136; remoteInfo = CCKit; }; + B19F94FF2413BDEC00DBBBC0 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = B1AF5038208D34510029336B /* ThunderRequest.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = B190A829228DBA3A00E44821; + remoteInfo = "ThunderRequestTests-tvOS"; + }; B1AF5040208D34510029336B /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = B1AF5038208D34510029336B /* ThunderRequest.xcodeproj */; @@ -218,13 +151,6 @@ remoteGlobalIDString = 49084FD11BD13DBD0012F636; remoteInfo = ThunderRequestTV; }; - B1AF5092208DC3A80029336B /* PBXContainerItemProxy */ = { - isa = PBXContainerItemProxy; - containerPortal = B1316A442089C08E006BD136 /* Project object */; - proxyType = 1; - remoteGlobalIDString = B1AF5087208DC3A80029336B; - remoteInfo = CCKitMac; - }; /* End PBXContainerItemProxy section */ /* Begin PBXFileReference section */ @@ -278,6 +204,8 @@ B1990A7F20C3FA1D0090A2F6 /* DeviceConnectivityNotifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeviceConnectivityNotifier.swift; sourceTree = ""; }; B1990A8220C3FDAA0090A2F6 /* Reachability.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Reachability.swift; sourceTree = ""; }; B1990A8520C408C20090A2F6 /* Ping.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ping.swift; sourceTree = ""; }; + B19F95012413BDEF00DBBBC0 /* ThunderRequestMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ThunderRequestMac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B19F95052413BE0100DBBBC0 /* ThunderRequest.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = ThunderRequest.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B1A1AA1420A4E01D00FD0A4A /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = ""; }; B1A1B67E21F8BC78008B5181 /* Logger.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = ""; }; B1A25F2021ADE6CE00D9EE81 /* ShutterSpeedFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ShutterSpeedFormatter.swift; sourceTree = ""; }; @@ -285,10 +213,8 @@ B1A25F3121AE950E00D9EE81 /* Errors.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Errors.swift; sourceTree = ""; }; B1AF5029208A51D00029336B /* NetworkInterface.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NetworkInterface.swift; sourceTree = ""; }; B1AF5038208D34510029336B /* ThunderRequest.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = ThunderRequest.xcodeproj; path = ThunderRequest/ThunderRequest.xcodeproj; sourceTree = ""; }; - B1AF5088208DC3A80029336B /* RoccMac.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = RoccMac.framework; sourceTree = BUILT_PRODUCTS_DIR; }; B1AF508A208DC3A80029336B /* RoccMac.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = RoccMac.h; sourceTree = ""; }; B1AF508B208DC3A80029336B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; - B1AF5090208DC3A80029336B /* RoccMacTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RoccMacTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; B1AF5095208DC3A80029336B /* RoccMacTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoccMacTests.swift; sourceTree = ""; }; B1AF5097208DC3A80029336B /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; B1B4342920939EF500A81B9D /* FileSystem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FileSystem.swift; sourceTree = ""; }; @@ -334,22 +260,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B1AF5084208DC3A80029336B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B1CDCB8F2223524100DD0F0E /* ThunderRequestMac.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B1AF508D208DC3A80029336B /* Frameworks */ = { - isa = PBXFrameworksBuildPhase; - buildActionMask = 2147483647; - files = ( - B1AF5091208DC3A80029336B /* RoccMac.framework in Frameworks */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ @@ -371,8 +281,6 @@ children = ( B1316A4D2089C08F006BD136 /* Rocc.framework */, B1316A562089C08F006BD136 /* RoccTests.xctest */, - B1AF5088208DC3A80029336B /* RoccMac.framework */, - B1AF5090208DC3A80029336B /* RoccMacTests.xctest */, ); name = Products; sourceTree = ""; @@ -432,10 +340,11 @@ children = ( B1AF5041208D34510029336B /* ThunderRequest.framework */, B1AF5043208D34510029336B /* ThunderRequestTests.xctest */, - B1AF5045208D34510029336B /* ThunderRequestMac.framework */, + B1AF5045208D34510029336B /* ThunderRequest.framework */, B1AF5047208D34510029336B /* ThunderRequestMacTests.xctest */, - B1AF5049208D34510029336B /* ThunderRequestTV.framework */, - B115EFC021ECF88200667FB7 /* ThunderRequestWatch.framework */, + B1AF5049208D34510029336B /* ThunderRequest.framework */, + B19F95002413BDEC00DBBBC0 /* ThunderRequestTests-tvOS.xctest */, + B115EFC021ECF88200667FB7 /* ThunderRequest.framework */, ); name = Products; sourceTree = ""; @@ -443,6 +352,8 @@ B1AF504A208D345A0029336B /* Frameworks */ = { isa = PBXGroup; children = ( + B19F95052413BE0100DBBBC0 /* ThunderRequest.framework */, + B19F95012413BDEF00DBBBC0 /* ThunderRequestMac.framework */, ); name = Frameworks; sourceTree = ""; @@ -623,15 +534,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B1AF5085208DC3A80029336B /* Headers */ = { - isa = PBXHeadersBuildPhase; - buildActionMask = 2147483647; - files = ( - B16BFD1421F5F0E600AF3F24 /* SimplePing.h in Headers */, - B1AF5098208DC3A80029336B /* RoccMac.h in Headers */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ @@ -671,42 +573,6 @@ productReference = B1316A562089C08F006BD136 /* RoccTests.xctest */; productType = "com.apple.product-type.bundle.unit-test"; }; - B1AF5087208DC3A80029336B /* RoccMac */ = { - isa = PBXNativeTarget; - buildConfigurationList = B1AF5099208DC3A80029336B /* Build configuration list for PBXNativeTarget "RoccMac" */; - buildPhases = ( - B1AF5083208DC3A80029336B /* Sources */, - B1AF5084208DC3A80029336B /* Frameworks */, - B1AF5085208DC3A80029336B /* Headers */, - B1AF5086208DC3A80029336B /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - ); - name = RoccMac; - productName = CCKitMac; - productReference = B1AF5088208DC3A80029336B /* RoccMac.framework */; - productType = "com.apple.product-type.framework"; - }; - B1AF508F208DC3A80029336B /* RoccMacTests */ = { - isa = PBXNativeTarget; - buildConfigurationList = B1AF509C208DC3A80029336B /* Build configuration list for PBXNativeTarget "RoccMacTests" */; - buildPhases = ( - B1AF508C208DC3A80029336B /* Sources */, - B1AF508D208DC3A80029336B /* Frameworks */, - B1AF508E208DC3A80029336B /* Resources */, - ); - buildRules = ( - ); - dependencies = ( - B1AF5093208DC3A80029336B /* PBXTargetDependency */, - ); - name = RoccMacTests; - productName = CCKitMacTests; - productReference = B1AF5090208DC3A80029336B /* RoccMacTests.xctest */; - productType = "com.apple.product-type.bundle.unit-test"; - }; /* End PBXNativeTarget section */ /* Begin PBXProject section */ @@ -724,13 +590,6 @@ B1316A552089C08F006BD136 = { CreatedOnToolsVersion = 9.3; }; - B1AF5087208DC3A80029336B = { - CreatedOnToolsVersion = 9.3; - LastSwiftMigration = 1010; - }; - B1AF508F208DC3A80029336B = { - CreatedOnToolsVersion = 9.3; - }; }; }; buildConfigurationList = B1316A472089C08E006BD136 /* Build configuration list for PBXProject "Rocc" */; @@ -753,20 +612,25 @@ targets = ( B1316A4C2089C08F006BD136 /* Rocc */, B1316A552089C08F006BD136 /* RoccTests */, - B1AF5087208DC3A80029336B /* RoccMac */, - B1AF508F208DC3A80029336B /* RoccMacTests */, ); }; /* End PBXProject section */ /* Begin PBXReferenceProxy section */ - B115EFC021ECF88200667FB7 /* ThunderRequestWatch.framework */ = { + B115EFC021ECF88200667FB7 /* ThunderRequest.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = ThunderRequestWatch.framework; + path = ThunderRequest.framework; remoteRef = B115EFBF21ECF88200667FB7 /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + B19F95002413BDEC00DBBBC0 /* ThunderRequestTests-tvOS.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = "ThunderRequestTests-tvOS.xctest"; + remoteRef = B19F94FF2413BDEC00DBBBC0 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; B1AF5041208D34510029336B /* ThunderRequest.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; @@ -781,10 +645,10 @@ remoteRef = B1AF5042208D34510029336B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - B1AF5045208D34510029336B /* ThunderRequestMac.framework */ = { + B1AF5045208D34510029336B /* ThunderRequest.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = ThunderRequestMac.framework; + path = ThunderRequest.framework; remoteRef = B1AF5044208D34510029336B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -795,10 +659,10 @@ remoteRef = B1AF5046208D34510029336B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; - B1AF5049208D34510029336B /* ThunderRequestTV.framework */ = { + B1AF5049208D34510029336B /* ThunderRequest.framework */ = { isa = PBXReferenceProxy; fileType = wrapper.framework; - path = ThunderRequestTV.framework; + path = ThunderRequest.framework; remoteRef = B1AF5048208D34510029336B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -821,20 +685,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B1AF5086208DC3A80029336B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B1AF508E208DC3A80029336B /* Resources */ = { - isa = PBXResourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXResourcesBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ @@ -931,90 +781,6 @@ ); runOnlyForDeploymentPostprocessing = 0; }; - B1AF5083208DC3A80029336B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B1A1AA3E20A4E02200FD0A4A /* Zoom.swift in Sources */, - B1FB4812209096FB00C33C86 /* Result.swift in Sources */, - B115EF2A21E9F27900667FB7 /* ShutterSpeedFormatter.swift in Sources */, - B1A1AA3B20A4E02200FD0A4A /* ViewAngle.swift in Sources */, - B1AF50A2208DC3B80029336B /* NetworkInterface.swift in Sources */, - B1A1AA3020A4E02200FD0A4A /* RemotePlayback.swift in Sources */, - B1A1AA3620A4E02200FD0A4A /* Storage.swift in Sources */, - B1FB4800209089CA00C33C86 /* CameraClient.swift in Sources */, - B1A1AA2A20A4E02200FD0A4A /* IntervalTime.swift in Sources */, - B16064A921E3A00A00AE3483 /* SonyTransferDevice.swift in Sources */, - B1A1AA2C20A4E02200FD0A4A /* LiveView.swift in Sources */, - B164F02A21811C1200590A05 /* String+Regex.swift in Sources */, - B1A1AA3520A4E02200FD0A4A /* SteadyMode.swift in Sources */, - B1A1AA3220A4E02200FD0A4A /* ShootMode.swift in Sources */, - B154535621EFDC1700C59096 /* Countable.swift in Sources */, - B1A1AA3920A4E02200FD0A4A /* TrackingFocus.swift in Sources */, - B1A1AA2B20A4E02200FD0A4A /* ISO.swift in Sources */, - B1A1AA2520A4E02200FD0A4A /* Exposure.swift in Sources */, - B1A1AA1E20A4E02200FD0A4A /* Aperture.swift in Sources */, - B1A1AA2420A4E02200FD0A4A /* Event.swift in Sources */, - B1A1AA2820A4E02200FD0A4A /* Focus.swift in Sources */, - B1A1AA2E20A4E02200FD0A4A /* PostViewImage.swift in Sources */, - B1FB47FD209088FD00C33C86 /* SonyCameraAPIClient.swift in Sources */, - B1FB4803209089D800C33C86 /* AVContentClient.swift in Sources */, - B1A1AA3420A4E02200FD0A4A /* Shutter.swift in Sources */, - B115EF2421E9F26600667FB7 /* Errors.swift in Sources */, - B1A1AA2920A4E02200FD0A4A /* InfraredRemoteControl.swift in Sources */, - B1A1AA2720A4E02200FD0A4A /* FlipSetting.swift in Sources */, - B115EF3821E9FDA100667FB7 /* SonyDeviceInfo.swift in Sources */, - B1D606552181225E001719EC /* UDPDeviceDiscoverer.swift in Sources */, - B1AF50A1208DC3B50029336B /* UDPClient.swift in Sources */, - B11786FA2187753F0006B72E /* SonyCamera+Model.swift in Sources */, - B1FB486D2092579E00C33C86 /* Camera.swift in Sources */, - B1A1AA3A20A4E02200FD0A4A /* TVColorSystem.swift in Sources */, - B1D358FA20AA34CF0069C698 /* LiveViewStreaming.swift in Sources */, - B16BFD1221F5F0E600AF3F24 /* SimplePing.m in Sources */, - B11D8E7421B9300F00719019 /* SimulatedCamera.swift in Sources */, - B164F02721811BD400590A05 /* SonyCameraDiscoverer.swift in Sources */, - B163AEC020A8D6050061D1C4 /* CameraEventNotifier.swift in Sources */, - B1A1AA3D20A4E02200FD0A4A /* WindNoiseReduction.swift in Sources */, - B1FB48702092585400C33C86 /* SonyCamera.swift in Sources */, - B1A1AA3C20A4E02200FD0A4A /* WhiteBalance.swift in Sources */, - B1FB480A2090964100C33C86 /* BaseServiceClient.swift in Sources */, - B1A1AA2020A4E02200FD0A4A /* BeepMode.swift in Sources */, - B1A1AA1F20A4E02200FD0A4A /* AutoPowerOff.swift in Sources */, - B1A1AA2320A4E02200FD0A4A /* CurrentTime.swift in Sources */, - B1A1AA2220A4E02200FD0A4A /* ColorSetting.swift in Sources */, - B115EF3021E9FC3A00667FB7 /* SonyXMLParsers.swift in Sources */, - B1CDCB90222352BB00DD0F0E /* UPnPService.swift in Sources */, - B154525D21EE61B800C59096 /* SOAPRequestBody.swift in Sources */, - B1A1AA2F20A4E02200FD0A4A /* ProgramShift.swift in Sources */, - B16BFD1721F5F0F100AF3F24 /* Pinger.swift in Sources */, - B1AF50A0208DC3B20029336B /* DeviceDiscovery.swift in Sources */, - B1A1AA2120A4E02200FD0A4A /* Capture.swift in Sources */, - B1A1B68021F8BC78008B5181 /* Logger.swift in Sources */, - B115EFB821ECF88100667FB7 /* UPnPParsers.swift in Sources */, - B1178702218775980006B72E /* FunctionNames.swift in Sources */, - B1A1AA3820A4E02200FD0A4A /* TouchAF.swift in Sources */, - B1A1AA2620A4E02200FD0A4A /* FileSystem.swift in Sources */, - B1D3591220AADC810069C698 /* Data+Conversion.swift in Sources */, - B10B38F121E0F6C300FED24F /* Function.swift in Sources */, - B1B43451209746B000A81B9D /* CameraFunctions.swift in Sources */, - B1990A8720C408C20090A2F6 /* Ping.swift in Sources */, - B1990A8120C3FA1D0090A2F6 /* DeviceConnectivityNotifier.swift in Sources */, - B1751E7A20A316C2001D05F1 /* SystemClient.swift in Sources */, - B1AF509F208DC3AF0029336B /* SonyConstants.swift in Sources */, - B1990A8420C3FDAA0090A2F6 /* Reachability.swift in Sources */, - B1A1AA3120A4E02200FD0A4A /* Scene.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; - B1AF508C208DC3A80029336B /* Sources */ = { - isa = PBXSourcesBuildPhase; - buildActionMask = 2147483647; - files = ( - B1AF5096208DC3A80029336B /* RoccMacTests.swift in Sources */, - B1BAAC8F222583B8007F0F61 /* Logger.swift in Sources */, - ); - runOnlyForDeploymentPostprocessing = 0; - }; /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ @@ -1023,11 +789,6 @@ target = B1316A4C2089C08F006BD136 /* Rocc */; targetProxy = B1316A582089C08F006BD136 /* PBXContainerItemProxy */; }; - B1AF5093208DC3A80029336B /* PBXTargetDependency */ = { - isa = PBXTargetDependency; - target = B1AF5087208DC3A80029336B /* RoccMac */; - targetProxy = B1AF5092208DC3A80029336B /* PBXContainerItemProxy */; - }; /* End PBXTargetDependency section */ /* Begin XCBuildConfiguration section */ @@ -1172,6 +933,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.yellowbrickbear.rocc; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; @@ -1199,6 +961,7 @@ PRODUCT_BUNDLE_IDENTIFIER = com.yellowbrickbear.rocc; PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; SKIP_INSTALL = YES; + SUPPORTS_MACCATALYST = YES; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -1240,105 +1003,6 @@ }; name = Release; }; - B1AF509A208DC3A80029336B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - INFOPLIST_FILE = RoccMac/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.13; - PRODUCT_BUNDLE_IDENTIFIER = com.yellowbrickbear.roccmac; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_OPTIMIZATION_LEVEL = "-Onone"; - SWIFT_VERSION = 4.0; - }; - name = Debug; - }; - B1AF509B208DC3A80029336B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - CLANG_ENABLE_MODULES = YES; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - DEFINES_MODULE = YES; - DYLIB_COMPATIBILITY_VERSION = 1; - DYLIB_CURRENT_VERSION = 1; - DYLIB_INSTALL_NAME_BASE = "@rpath"; - FRAMEWORK_VERSION = A; - INFOPLIST_FILE = RoccMac/Info.plist; - INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.13; - PRODUCT_BUNDLE_IDENTIFIER = com.yellowbrickbear.roccmac; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; - SDKROOT = macosx; - SKIP_INSTALL = YES; - SWIFT_VERSION = 4.0; - }; - name = Release; - }; - B1AF509D208DC3A80029336B /* Debug */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = RoccMacTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.13; - PRODUCT_BUNDLE_IDENTIFIER = com.yellowbrickbear.RoccMacTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SWIFT_VERSION = 4.0; - }; - name = Debug; - }; - B1AF509E208DC3A80029336B /* Release */ = { - isa = XCBuildConfiguration; - buildSettings = { - ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; - CODE_SIGN_IDENTITY = "-"; - CODE_SIGN_STYLE = Automatic; - COMBINE_HIDPI_IMAGES = YES; - INFOPLIST_FILE = RoccMacTests/Info.plist; - LD_RUNPATH_SEARCH_PATHS = ( - "$(inherited)", - "@executable_path/../Frameworks", - "@loader_path/../Frameworks", - ); - MACOSX_DEPLOYMENT_TARGET = 10.13; - PRODUCT_BUNDLE_IDENTIFIER = com.yellowbrickbear.RoccMacTests; - PRODUCT_NAME = "$(TARGET_NAME)"; - SDKROOT = macosx; - SWIFT_VERSION = 4.0; - }; - name = Release; - }; /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ @@ -1369,24 +1033,6 @@ defaultConfigurationIsVisible = 0; defaultConfigurationName = Release; }; - B1AF5099208DC3A80029336B /* Build configuration list for PBXNativeTarget "RoccMac" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B1AF509A208DC3A80029336B /* Debug */, - B1AF509B208DC3A80029336B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; - B1AF509C208DC3A80029336B /* Build configuration list for PBXNativeTarget "RoccMacTests" */ = { - isa = XCConfigurationList; - buildConfigurations = ( - B1AF509D208DC3A80029336B /* Debug */, - B1AF509E208DC3A80029336B /* Release */, - ); - defaultConfigurationIsVisible = 0; - defaultConfigurationName = Release; - }; /* End XCConfigurationList section */ }; rootObject = B1316A442089C08E006BD136 /* Project object */; diff --git a/Rocc/Device Discovery/DeviceDiscovery.swift b/Rocc/Device Discovery/DeviceDiscovery.swift index 784aa26..e99cbe7 100644 --- a/Rocc/Device Discovery/DeviceDiscovery.swift +++ b/Rocc/Device Discovery/DeviceDiscovery.swift @@ -7,11 +7,7 @@ // import Foundation -#if os(iOS) import ThunderRequest -#elseif os(macOS) -import ThunderRequestMac -#endif import SystemConfiguration import os @@ -33,7 +29,8 @@ protocol DeviceDiscovererDelegate { /// - Parameters: /// - discoverer: The discoverer object that discovered a device. /// - discovered: The device that it discovered. - func deviceDiscoverer(_ discoverer: T, discovered device: Camera) + /// - isCached: Whether the device was loaded from a cached xml discovery file. + func deviceDiscoverer(_ discoverer: T, discovered device: Camera, isCached: Bool) } /// A protocol to be implemented by device discovery implementations @@ -73,10 +70,13 @@ public protocol CameraDiscovererDelegate { /// Called when a camera device is discovered /// + /// - Note: if `isCached == true` you should be cautious auto-connecting to the camera (Especially if it's a transfer device) as cameras in transfer mode can advertise multiple connectivity methods and the correct one may not be returned until it's passed to you with `isCached == false`. + /// /// - Parameters: /// - discoverer: The discoverer object that discovered a device. /// - discovered: The device that it discovered. - func cameraDiscoverer(_ discoverer: CameraDiscoverer, discovered device: Camera) + /// - isCached: Whether the camera was loaded from a cached xml file url. + func cameraDiscoverer(_ discoverer: CameraDiscoverer, discovered device: Camera, isCached: Bool) } /// A class which enables the discovery of cameras @@ -85,10 +85,10 @@ public final class CameraDiscoverer { /// A delegate which will have methods called on it when cameras are discovered or an error occurs. public var delegate: CameraDiscovererDelegate? - private var discoveredCameras: [Camera] = [] + private var discoveredCameras: [(camera: Camera, isCached: Bool)] = [] /// A map of cameras by the SSID the local device was connected to when they were discovered - public var camerasBySSID: [String?: [Camera]] = [:] + public var camerasBySSID: [String?: [(camera: Camera, isCached: Bool)]] = [:] var discoverers: [DeviceDiscoverer] = [] @@ -133,20 +133,30 @@ public final class CameraDiscoverer { extension CameraDiscoverer: DeviceDiscovererDelegate { - func deviceDiscoverer(_ discoverer: T, didError error: Error) where T : DeviceDiscoverer { - delegate?.cameraDiscoverer(self, didError: error) - } - - func deviceDiscoverer(_ discoverer: T, discovered device: Camera) where T : DeviceDiscoverer { + func deviceDiscoverer(_ discoverer: T, discovered device: Camera, isCached: Bool) where T : DeviceDiscoverer { - guard !discoveredCameras.contains(where: { - $0.identifier == device.identifier - }) else { + if let previouslyDiscoveredCamera = discoveredCameras.enumerated().first(where: { + $0.element.camera.identifier == device.identifier + }) { + // If we went from non-cached, to cached, let the delegate know! + if previouslyDiscoveredCamera.element.isCached && !isCached { + discoveredCameras[previouslyDiscoveredCamera.offset] = (device, isCached) + if var camerasForSSID = camerasBySSID[Reachability.currentWiFiSSID], let indexInCamerasForSSID = camerasForSSID.firstIndex(where: { $0.camera.identifier == device.identifier }) { + camerasForSSID[indexInCamerasForSSID] = (device, isCached) + camerasBySSID[Reachability.currentWiFiSSID] = camerasForSSID + } + delegate?.cameraDiscoverer(self, discovered: device, isCached: false) + } return } - camerasBySSID[Reachability.currentWiFiSSID, default: []].append(device) - discoveredCameras.append(device) - delegate?.cameraDiscoverer(self, discovered: device) + camerasBySSID[Reachability.currentWiFiSSID, default: []].append((device, isCached)) + discoveredCameras.append((device, isCached)) + delegate?.cameraDiscoverer(self, discovered: device, isCached: isCached) + } + + + func deviceDiscoverer(_ discoverer: T, didError error: Error) where T : DeviceDiscoverer { + delegate?.cameraDiscoverer(self, didError: error) } } diff --git a/Rocc/Device Discovery/UDPDeviceDiscoverer.swift b/Rocc/Device Discovery/UDPDeviceDiscoverer.swift index 549a0c3..65a5e43 100644 --- a/Rocc/Device Discovery/UDPDeviceDiscoverer.swift +++ b/Rocc/Device Discovery/UDPDeviceDiscoverer.swift @@ -8,11 +8,7 @@ import Foundation import os -#if os(macOS) -import ThunderRequestMac -#else import ThunderRequest -#endif import SystemConfiguration extension UserDefaults { @@ -96,7 +92,7 @@ class UDPDeviceDiscoverer: DeviceDiscoverer { urls.forEach { (url) in - parseDeviceInfo(at: url) { [weak self] (error) in + parseDeviceInfo(at: url, isCached: true) { [weak self] (error) in guard let strongSelf = self else { return } @@ -170,7 +166,7 @@ class UDPDeviceDiscoverer: DeviceDiscoverer { Logger.log(message: "Did find device at \(device.ddURL.absoluteString)", category: "UDPDeviceDiscoverer") os_log("Did find device at: %{public}@", log: self.log, type: .debug, device.ddURL.absoluteString) - self.parseDeviceInfo(at: device.ddURL) + self.parseDeviceInfo(at: device.ddURL, isCached: false) } } @@ -185,7 +181,7 @@ class UDPDeviceDiscoverer: DeviceDiscoverer { udpClient.finishSearching(with: callback) } - private func parseDeviceInfo(at url: URL, callback: ((_ error: Error?) -> Void)? = nil) { + private func parseDeviceInfo(at url: URL, isCached: Bool, callback: ((_ error: Error?) -> Void)? = nil) { let lastPathComponent = url.lastPathComponent let baseURL = url.deletingLastPathComponent() @@ -210,7 +206,7 @@ class UDPDeviceDiscoverer: DeviceDiscoverer { Logger.log(message: "Parsing device info", category: "UDPDeviceDiscoverer") os_log("Parsing device info", log: strongSelf.log, type: .debug) - strongSelf.parseDevice(from: stringResponse, baseURL: baseURL, callback: { [weak strongSelf] parsed in + strongSelf.parseDevice(from: stringResponse, isCached: isCached, baseURL: baseURL, callback: { [weak strongSelf] parsed in // If we parsed a device, cache it's url! guard parsed else { return } @@ -247,7 +243,7 @@ class UDPDeviceDiscoverer: DeviceDiscoverer { } } - func parseDevice(from stringRepresentation: String, baseURL: URL, callback: @escaping (_ bool: Bool) -> Void) { + func parseDevice(from stringRepresentation: String, isCached: Bool, baseURL: URL, callback: @escaping (_ bool: Bool) -> Void) { } @@ -259,10 +255,10 @@ class UDPDeviceDiscoverer: DeviceDiscoverer { delegate?.deviceDiscoverer(self, didError: error) } - func sendDeviceToDelegate(_ camera: Camera) { + func sendDeviceToDelegate(_ camera: Camera, isCached: Bool) { Logger.log(message: "Letting delegate know about discovered device with name: \(camera.name ?? "Unknown")", category: "UDPDeviceDiscoverer") os_log("Letting delegate know about discovered device with name: %{public}@", log: log, type: .debug, camera.name ?? "Unknown") - delegate?.deviceDiscoverer(self, discovered: camera) + delegate?.deviceDiscoverer(self, discovered: camera, isCached: isCached) } } diff --git a/Rocc/Device Discovery/UPnPParsers.swift b/Rocc/Device Discovery/UPnPParsers.swift index ce877eb..5f5da46 100644 --- a/Rocc/Device Discovery/UPnPParsers.swift +++ b/Rocc/Device Discovery/UPnPParsers.swift @@ -199,9 +199,7 @@ internal final class UPnPDeviceParser: NSObject, XMLParserDelegate { guard scope.last == elementName else { return } foundCharacters = foundCharacters.trimmingCharacters(in: .whitespacesAndNewlines) - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) - + defer { currentElement = scope.removeLast() foundCharacters = "" @@ -344,9 +342,7 @@ internal final class UPnPFolderParser: NSObject, XMLParserDelegate { currentElement = elementName scope.append(elementName) - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) - + switch elementName { case "container": currentFolder = attributeDict @@ -368,7 +364,6 @@ internal final class UPnPFolderParser: NSObject, XMLParserDelegate { defer { currentElement = scope.removeLast() foundCharacters = "" - os_log("Parser did end element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } switch elementName { @@ -592,9 +587,7 @@ internal final class UPnPFileParser: NSObject, XMLParserDelegate { currentElement = elementName scope.append(elementName) - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) - + switch elementName { case "item": currentFile = attributeDict @@ -619,7 +612,6 @@ internal final class UPnPFileParser: NSObject, XMLParserDelegate { defer { currentElement = scope.removeLast() foundCharacters = "" - os_log("Parser did end element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } switch elementName { diff --git a/Rocc/Helpers/Logging/Logger.swift b/Rocc/Helpers/Logging/Logger.swift index 49e3ff5..00d2309 100644 --- a/Rocc/Helpers/Logging/Logger.swift +++ b/Rocc/Helpers/Logging/Logger.swift @@ -8,11 +8,7 @@ import Foundation import os.log -#if os(macOS) -import ThunderRequestMac -#elseif os(iOS) import ThunderRequest -#endif /// A simple class for logging to a given file url public final class Logger { @@ -67,6 +63,10 @@ public final class Logger { private func log(_ message: String, category: String) { + #if DEBUG + print("[\(category)] \(message)") + #endif + guard let fileURL = fileURL, let logQueue = logQueue else { return } logQueue.sync { diff --git a/Rocc/Helpers/Networking/SOAPRequestBody.swift b/Rocc/Helpers/Networking/SOAPRequestBody.swift index 3467db1..2c1c805 100644 --- a/Rocc/Helpers/Networking/SOAPRequestBody.swift +++ b/Rocc/Helpers/Networking/SOAPRequestBody.swift @@ -9,11 +9,8 @@ import os.log import Foundation -#if os(iOS) import ThunderRequest -#elseif os(macOS) -import ThunderRequestMac -#endif + struct SOAPRequestBody { @@ -105,8 +102,6 @@ internal final class SOAPResponseParser: NSObject, XMLParserDelegate { currentElement = elementName scope.append(elementName) - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } func parser(_ parser: XMLParser, foundCharacters string: String) { @@ -122,7 +117,6 @@ internal final class SOAPResponseParser: NSObject, XMLParserDelegate { defer { currentElement = scope.removeLast() foundCharacters = "" - os_log("Parser did end element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } // We are inside the device info object diff --git a/Rocc/Helpers/SimulatedCamera.swift b/Rocc/Helpers/SimulatedCamera.swift index eaada05..f90031e 100644 --- a/Rocc/Helpers/SimulatedCamera.swift +++ b/Rocc/Helpers/SimulatedCamera.swift @@ -49,46 +49,46 @@ extension File { static func dummy(date: Date = Date(), image: Int) -> File { let imageUrls: [String] = [ - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44045288_10205020816115765_8491817313958363136_o.jpg?_nc_cat=106&_nc_ht=scontent-lht6-1.xx&oh=aa827b2d112cf75fc080a114cc6e2111&oe=5CAD1495", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43951277_10205020817475799_1108877701613092864_o.jpg?_nc_cat=108&_nc_ht=scontent-lht6-1.xx&oh=f945dbf7d98ff96ec8b79420ccd96e8e&oe=5CA1418A", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43950872_10205020815595752_4593994433954840576_o.jpg?_nc_cat=111&_nc_ht=scontent-lht6-1.xx&oh=5e95e82f1dcfdeaf9703d92271a11876&oe=5CAE3F49", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44028187_10205020839276344_6822412080608444416_o.jpg?_nc_cat=102&_nc_ht=scontent-lht6-1.xx&oh=75b404651427be974f026d358b215561&oe=5C6721FD", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44091308_10205020826996037_485456601528926208_o.jpg?_nc_cat=106&_nc_ht=scontent-lht6-1.xx&oh=47b2e6265ba81862cc04114b51e99785&oe=5C9CEBD7", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44070700_10205020824675979_3158584147081953280_o.jpg?_nc_cat=103&_nc_ht=scontent-lht6-1.xx&oh=0bb093c82f9daf21b49d0b8b7f5f87b6&oe=5C69BD1C", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44062992_10205020823915960_5566386604706103296_o.jpg?_nc_cat=102&_nc_ht=scontent-lht6-1.xx&oh=ab2adaea6bb27b905cbd04bc88675211&oe=5CAF333C", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44023485_10205020821515900_1649964678064898048_o.jpg?_nc_cat=106&_nc_ht=scontent-lht6-1.xx&oh=2c424cf5874dad4235748e2dea06475f&oe=5C63C33C", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44023818_10205020820395872_1540489921649704960_o.jpg?_nc_cat=111&_nc_ht=scontent-lht6-1.xx&oh=64237f21cbdf98c0ad54ac8715b830a8&oe=5C9635A0", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43952978_10205020819395847_1951748682512596992_o.jpg?_nc_cat=101&_nc_ht=scontent-lht6-1.xx&oh=f78aae8489e1077df6cc3266d3c9ccc7&oe=5CA1232C", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43952276_10205020818115815_98364814186774528_o.jpg?_nc_cat=106&_nc_ht=scontent-lht6-1.xx&oh=c4dee9f352a34f1e7ad9b2deaf501784&oe=5CAFA3DB", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43950002_10205020816555776_4810511663855828992_o.jpg?_nc_cat=111&_nc_ht=scontent-lht6-1.xx&oh=f42a92648d41016b2faacdb99ed290ed&oe=5CA7D378", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44022896_10205020815995762_6125466268607709184_o.jpg?_nc_cat=105&_nc_ht=scontent-lht6-1.xx&oh=06690071f0491df3bed00404b4ed4804&oe=5C991E74", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43951941_10205020815115740_33392133775818752_o.jpg?_nc_cat=105&_nc_ht=scontent-lht6-1.xx&oh=53d47ad3ef1b90f837b48b8234ba1cfb&oe=5CA14DB2", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44037802_10205020814995737_274281400411095040_o.jpg?_nc_cat=109&_nc_ht=scontent-lht6-1.xx&oh=3210f5b051c21004aa297ec02a5169bf&oe=5C65A8E8", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44025050_10205020814195717_8521023804535734272_o.jpg?_nc_cat=107&_nc_ht=scontent-lht6-1.xx&oh=0168dbc2717a88b9e1c68476fd858144&oe=5C691255", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44166137_10205020811755656_6680655795945734144_o.jpg?_nc_cat=100&_nc_ht=scontent-lht6-1.xx&oh=49b136ec2c83b9d1d8a0e5c3b72dfaac&oe=5CA725D6", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44032459_10205020808315570_5469471131528331264_o.jpg?_nc_cat=111&_nc_ht=scontent-lht6-1.xx&oh=c3fae3b3b731fe98a36bbe09358d5e11&oe=5CA56D19", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44023944_10205020808195567_7274851361567539200_o.jpg?_nc_cat=102&_nc_ht=scontent-lht6-1.xx&oh=b6e306129912f6cf557a3c3b4beb2246&oe=5CB088B8", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44028963_10205020807875559_663651414500704256_o.jpg?_nc_cat=100&_nc_ht=scontent-lht6-1.xx&oh=491bfb2e8553f078ec3fcecb6fefd51e&oe=5CA6CF77", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44077180_10205020807475549_6486553158548979712_o.jpg?_nc_cat=101&_nc_ht=scontent-lht6-1.xx&oh=a9e9815ddd1be1ff06b17d850cf55561&oe=5C9A2DCD", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44027774_10205020806955536_5337969364752662528_o.jpg?_nc_cat=107&_nc_ht=scontent-lht6-1.xx&oh=6b63472242657e017db0ae3ccb131e39&oe=5C9FD62A", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43952377_10205020806595527_3181607508250722304_o.jpg?_nc_cat=101&_nc_ht=scontent-lht6-1.xx&oh=0dec0fb6f44a1a42349dc70fb669839d&oe=5CB03DA2", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44056825_10205020805115490_2152903248187490304_o.jpg?_nc_cat=101&_nc_ht=scontent-lht6-1.xx&oh=4cf2cdd7ee96e5931578811fe01bb4c8&oe=5C674634", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43952177_10205020804435473_1461334065226448896_o.jpg?_nc_cat=110&_nc_ht=scontent-lht6-1.xx&oh=fa88bda3a10e64da52f50b88af3d21fc&oe=5C671237", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/43950742_10205020801795407_3857080102974128128_o.jpg?_nc_cat=107&_nc_ht=scontent-lht6-1.xx&oh=5d32f7adf9c3d83ff96def1c2e15a445&oe=5C65D719", - "https://scontent-lht6-1.xx.fbcdn.net/v/t1.0-9/44063085_10205020800915385_7307852352671711232_o.jpg?_nc_cat=111&_nc_ht=scontent-lht6-1.xx&oh=cd443d54257a363973231d008b32c3c4&oe=5C65A3BF" + "https://user-images.githubusercontent.com/9033831/69366783-f0057400-0c8e-11ea-9ba6-110b184daf43.jpg", + "https://user-images.githubusercontent.com/9033831/69366786-f09e0a80-0c8e-11ea-95bb-c347c7910881.jpg", + "https://user-images.githubusercontent.com/9033831/69366787-f09e0a80-0c8e-11ea-92b1-f6e63109bde0.jpg", + "https://user-images.githubusercontent.com/9033831/69366788-f09e0a80-0c8e-11ea-8fa0-3f086154110d.jpg", + "https://user-images.githubusercontent.com/9033831/69366789-f136a100-0c8e-11ea-9190-6ea3262b5068.jpg", + "https://user-images.githubusercontent.com/9033831/69366790-f136a100-0c8e-11ea-8eca-d8b25b4ef194.jpg", + "https://user-images.githubusercontent.com/9033831/69366791-f136a100-0c8e-11ea-9592-3e234a08407e.jpg", + "https://user-images.githubusercontent.com/9033831/69366792-f136a100-0c8e-11ea-93e7-36659e4e9120.jpg", + "https://user-images.githubusercontent.com/9033831/69366794-f136a100-0c8e-11ea-9b8c-0d02bd466615.jpg", + "https://user-images.githubusercontent.com/9033831/69366795-f1cf3780-0c8e-11ea-8933-8e12d0cd507d.jpg", + "https://user-images.githubusercontent.com/9033831/69366796-f1cf3780-0c8e-11ea-866d-4157889cb9dd.jpg", + "https://user-images.githubusercontent.com/9033831/69366797-f1cf3780-0c8e-11ea-9057-88cf68158615.jpg", + "https://user-images.githubusercontent.com/9033831/69366800-f1cf3780-0c8e-11ea-9160-48f37c330641.jpg", + "https://user-images.githubusercontent.com/9033831/69366801-f1cf3780-0c8e-11ea-93c9-3b69d5b92039.jpg", + "https://user-images.githubusercontent.com/9033831/69366802-f267ce00-0c8e-11ea-86cb-7ea3facbf4f8.jpg", + "https://user-images.githubusercontent.com/9033831/69366803-f267ce00-0c8e-11ea-92ab-1b2f1aff1834.jpg", + "https://user-images.githubusercontent.com/9033831/69366805-f267ce00-0c8e-11ea-936a-9d50cc8dce21.jpg", + "https://user-images.githubusercontent.com/9033831/69366806-f267ce00-0c8e-11ea-93af-ee86d680a625.jpg", + "https://user-images.githubusercontent.com/9033831/69366807-f3006480-0c8e-11ea-8871-e89d7b890adb.jpg", + "https://user-images.githubusercontent.com/9033831/69366809-f3006480-0c8e-11ea-8f3f-8f3b9f1769e9.jpg", + "https://user-images.githubusercontent.com/9033831/69366811-f3006480-0c8e-11ea-9a9f-0d6018d9689a.jpg", + "https://user-images.githubusercontent.com/9033831/69366812-f3006480-0c8e-11ea-9896-33b82df37aa0.jpg", + "https://user-images.githubusercontent.com/9033831/69366813-f3006480-0c8e-11ea-9c9d-acf4f285c0ca.jpg", + "https://user-images.githubusercontent.com/9033831/69366814-f398fb00-0c8e-11ea-8328-6177325958c5.jpg", + "https://user-images.githubusercontent.com/9033831/69366815-f398fb00-0c8e-11ea-8313-1aed95f64171.jpg", + "https://user-images.githubusercontent.com/9033831/69366817-f398fb00-0c8e-11ea-88df-e7f6f9698366.jpg" ] let index = image % imageUrls.count let url = URL(string: imageUrls[index]) - let original = File.Content.Original(fileName: "Test", fileType: "RAW", url: url) + let original = File.Content.Original(fileName: "test.jpeg", fileType: "JPG", url: url) + let rawOriginal = File.Content.Original(fileName: "rest.ARW", fileType: "ARW", url: URL(string: "https://www.rawsamples.ch/raws/sony/RAW_SONY_ILCE-7M2.ARW")) - let content = Content(originals: [original], largeURL: url, smallURL: url, thumbnailURL: url) + let content = Content(originals: [rawOriginal, original], largeURL: url, smallURL: url, thumbnailURL: url) let file = File( content: content, created: date, - uri: imageUrls[index] + uri: imageUrls[index] + "\(image)" ) return file @@ -222,7 +222,8 @@ public final class DummyCamera: Camera { ShutterSpeed(numerator: 18, denominator: 1), ShutterSpeed(numerator: 20, denominator: 1), ShutterSpeed(numerator: 25, denominator: 1), - ShutterSpeed(numerator: 30, denominator: 1) + ShutterSpeed(numerator: 30, denominator: 1), + .bulb ] as? [T.SendType]) case .setExposureCompensation: callback(true, nil, [-3.0, -2.66, -2.33, -2.0, -1.66, -1.33, -1.0, -0.66, -0.33, 0, 0.33, 0.66, 1.0, 1.33, 1.66, 2.0, 2.33, 2.66, 3.0] as? [T.SendType]) @@ -292,8 +293,9 @@ public final class DummyCamera: Camera { ShutterSpeed(numerator: 18, denominator: 1), ShutterSpeed(numerator: 20, denominator: 1), ShutterSpeed(numerator: 25, denominator: 1), - ShutterSpeed(numerator: 30, denominator: 1) - ]), + ShutterSpeed(numerator: 30, denominator: 1), + .bulb + ]), whiteBalance: CameraEvent.WhiteBalanceInformation(shouldCheck: true, whitebalanceValue: WhiteBalance.Value(mode: "Daylight", temperature: nil)), touchAF: nil, focusStatus: nil, @@ -354,10 +356,11 @@ public final class DummyCamera: Camera { } var files: [File] = [] - var date = Date(timeIntervalSinceNow: -100) - for i in 0.. String? in + dict["postviewUrl"] as? String + }).first else { + return + } + _bulbShootingURL = URL(string: urlString) + break case "availableApiList": _apiList = dictionaryElement["names"] as? [String] case "cameraStatus": @@ -606,8 +613,7 @@ fileprivate extension CameraEvent { audioRecording = _audioRecording windNoiseReduction = _windNoiseReduction bulbCapturingTime = _bulbCapturingTime - //TODO: Add this in! - bulbShootingUrl = nil + bulbShootingUrl = _bulbShootingURL } } @@ -703,6 +709,18 @@ internal class CameraClient: ServiceClient { typealias GenericCompletion = (_ error: Error?) -> Void + var eventMethodName: String? { + guard let availableApiList = availableApiList else { + return nil + } + for eventName in ["getEvent", "receiveEvent"] { + if availableApiList.contains(eventName) { + return eventName + } + } + return nil + } + internal convenience init?(apiInfo: SonyCameraDevice.ApiDeviceInfo) { guard let cameraService = apiInfo.services.first(where: { $0.type == "camera" }) else { return nil } self.init(service: cameraService) @@ -3843,7 +3861,22 @@ internal class CameraClient: ServiceClient { func getEvent(polling: Bool, _ completion: @escaping EventCompletion) { - let body = SonyRequestBody(method: "getEvent", params: [polling], id: 1, version: versions?.last ?? "1.0") + guard let eventMethodName = eventMethodName else { + + getAvailableApiList { [weak self] (result) in + // Fallback to getEvent as more commonly used! + self?.getEvent(methodName: self?.eventMethodName ?? "getEvent", polling: polling, completion) + } + + return + } + + getEvent(methodName: eventMethodName, polling: polling, completion) + } + + private func getEvent(methodName: String, polling: Bool, _ completion: @escaping EventCompletion) { + + let body = SonyRequestBody(method: methodName, params: [polling], id: 1, version: versions?.last ?? "1.0") requestController.request(service.type, method: .POST, body: body.requestSerialised) { (response, error) in diff --git a/Rocc/Manufacturer Implementations/Sony/API/SystemClient.swift b/Rocc/Manufacturer Implementations/Sony/API/SystemClient.swift index 1b4c792..1dcdb9a 100644 --- a/Rocc/Manufacturer Implementations/Sony/API/SystemClient.swift +++ b/Rocc/Manufacturer Implementations/Sony/API/SystemClient.swift @@ -7,12 +7,7 @@ // import Foundation - -#if os(macOS) -import ThunderRequestMac -#else import ThunderRequest -#endif internal final class SystemClient: ServiceClient { diff --git a/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera+Model.swift b/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera+Model.swift index b4fd255..f975420 100644 --- a/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera+Model.swift +++ b/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera+Model.swift @@ -17,6 +17,7 @@ extension SonyCameraDevice { case a7r = "ILCE-7R" case a7rii = "ILCE-7RM2" case a7riii = "ILCE-7RM3" + case a7riv = "ILCE-7RM4" case a7s = "ILCE-7S" case a7sii = "ILCE-7SM2" case a7siii = "ILCE-7SM3" @@ -24,8 +25,13 @@ extension SonyCameraDevice { case a5000 = "ILCE-5000" case a5100 = "ILCE-5100" case a6000 = "ILCE-6000" + case a6100 = "ILCE-6100" case a6300 = "ILCE-6300" + case a6400 = "ILCE-6400" case a6500 = "ILCE-6500" + case a6600 = "ILCE-6600" + case cyberShot_HX50 = "DSC-HX50" + case cyberShot_HX50V = "DSC-HX50V" case cyberShot_HX60 = "DSC-HX60" case cyberShot_HX60V = "DSC-HX60V" case cyberShot_HX80 = "DSC-HX80" @@ -38,9 +44,11 @@ extension SonyCameraDevice { case cyberShot_RX0M2 = "DSC-RX0M2" case cyberShot_RX10M2 = "DSC-RX1RM2" case cyberShot_RX10M3 = "DSC-RX10M3" + case cyberShot_RX100M2 = "DSC-RX100M2" case cyberShot_RX100M3 = "DSC-RX100M3" case cyberShot_RX100M4 = "DSC-RX100M4" case cyberShot_RX100M5 = "DSC-RX100M5" + case cyberShot_RX100M6 = "DSC-RX100M6" case FDR_X1000V = "FDR-X1000V" case FDR_X3000 = "FDR-X3000" case HDR_AS100V = "HDR-AS100V" @@ -68,6 +76,7 @@ extension SonyCameraDevice { case .a7r: return "ɑ7R" case .a7rii: return "ɑ7R II" case .a7riii: return "ɑ7R III" + case .a7riv: return "ɑ7R IV" case .a7s: return "ɑ7S" case .a7sii: return "ɑ7S II" case .a7siii: return "ɑ7S III" @@ -75,8 +84,13 @@ extension SonyCameraDevice { case .a5000: return "ɑ5000" case .a5100: return "ɑ5100" case .a6000: return "ɑ6000" + case .a6100: return "ɑ6100" case .a6300: return "ɑ6300" + case .a6400: return "ɑ6400" case .a6500: return "ɑ6500" + case .a6600: return "ɑ6600" + case .cyberShot_HX50: return "Cyber-Shot HX50" + case .cyberShot_HX50V: return "Cyber-Shot HX50V" case .cyberShot_HX60: return "Cyber-Shot HX60" case .cyberShot_HX60V: return "Cyber-Shot HX60V" case .cyberShot_HX80: return "Cyber-Shot HX80" @@ -87,9 +101,11 @@ extension SonyCameraDevice { case .cyberShot_WX500: return "Cyber-Shot WX500" case .cyberShot_RX10M2: return "Cyber-Shot RX1 R II" case .cyberShot_RX10M3: return "Cyber-Shot RX10 III" + case .cyberShot_RX100M2: return "Cyber-Shot RX100 II" case .cyberShot_RX100M3: return "Cyber-Shot RX100 III" case .cyberShot_RX100M4: return "Cyber-Shot RX100 IV" case .cyberShot_RX100M5: return "Cyber-Shot RX100 V" + case .cyberShot_RX100M6: return "Cybter-Shot RX100 VI" case .cyberShot_RX0: return "RX0" case .cyberShot_RX0M2: return "RX0 II" case .FDR_X1000V: return "FDR-X1000V" @@ -113,6 +129,10 @@ extension SonyCameraDevice { } } + internal var usesLegacyAPI: Bool { + return [.cyberShot_RX100M2, .cyberShot_HX50V, .cyberShot_HX50].contains(self) + } + internal static func supporting(function: _CameraFunction) -> [Model] { switch function { // This isn't documented, so let's err on the side of caution! @@ -304,7 +324,7 @@ extension SonyCameraDevice { } static var cyberShotSeries: [Model] { - return [.cyberShot_HX60, .cyberShot_HX60V, .cyberShot_HX80, .cyberShot_HX90, .cyberShot_HX90V, .cyberShot_HX400, .cyberShot_HX400V, .cyberShot_WX500, .cyberShot_RX10M2, .cyberShot_RX10M3, .cyberShot_RX100M3, .cyberShot_RX100M4, .cyberShot_RX100M5, .cyberShot_RX0, .cyberShot_RX0M2] + return [.cyberShot_HX50, .cyberShot_HX50V, .cyberShot_HX60, .cyberShot_HX60V, .cyberShot_HX80, .cyberShot_HX90, .cyberShot_HX90V, .cyberShot_HX400, .cyberShot_HX400V, .cyberShot_WX500, .cyberShot_RX10M2, .cyberShot_RX10M3, .cyberShot_RX100M2, .cyberShot_RX100M3, .cyberShot_RX100M4, .cyberShot_RX100M5, .cyberShot_RX100M6, .cyberShot_RX0, .cyberShot_RX0M2] } static var fdrSeries: [Model] { @@ -333,6 +353,8 @@ extension SonyCameraDevice { return "3.00" case .a7iii, .a7riii: return "3.00" + case .a6600, .a6400: + return "2.00" case .a6300: return "2.01" case .a5000: @@ -363,7 +385,9 @@ extension SonyCameraDevice { .a7riii, .a9, .cyberShot_RX0, - .cyberShot_RX0M2 + .cyberShot_RX0M2, + .cyberShot_RX100M5, + .cyberShot_RX100M6 ] return modelsWhichRequireHalfPressToCapture.contains(self) } diff --git a/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera.swift b/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera.swift index e457cd0..0f9ea06 100644 --- a/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera.swift +++ b/Rocc/Manufacturer Implementations/Sony/Camera/SonyCamera.swift @@ -49,7 +49,7 @@ internal final class SonyCameraDevice { let accessType: String? - init?(dictionary: [AnyHashable : Any]) { + init?(dictionary: [AnyHashable : Any], model: Model?) { guard let _type = dictionary["av:X_ScalarWebAPI_ServiceType"] as? String else { return nil @@ -57,10 +57,14 @@ internal final class SonyCameraDevice { guard let urlString = dictionary["av:X_ScalarWebAPI_ActionList_URL"] as? String else { return nil } - guard let _url = URL(string: urlString) else { + guard var _url = URL(string: urlString) else { return nil } + if let model = model, model.usesLegacyAPI { + _url = _url.deletingLastPathComponent() + } + url = _url type = _type accessType = dictionary["av:X_ScalarWebAPI_AccessType"] as? String @@ -71,7 +75,7 @@ internal final class SonyCameraDevice { let services: [Service] - init?(dictionary: [AnyHashable : Any]) { + init?(dictionary: [AnyHashable : Any], model: Model?) { guard let versionString = dictionary["av:X_ScalarWebAPI_Version"] as? String else { return nil } version = versionString @@ -79,7 +83,7 @@ internal final class SonyCameraDevice { services = [] return } - services = serviceList.compactMap({ Service(dictionary: $0) }) + services = serviceList.compactMap({ Service(dictionary: $0, model: model) }) } } @@ -148,7 +152,15 @@ internal final class SonyCameraDevice { init?(dictionary: [AnyHashable : Any]) { - guard let apiDeviceInfoDict = dictionary["av:X_ScalarWebAPI_DeviceInfo"] as? [AnyHashable : Any], let apiInfo = ApiDeviceInfo(dictionary: apiDeviceInfoDict) else { + let _name = dictionary["friendlyName"] as? String + let _modelEnum: Model? + if let _name = _name { + _modelEnum = Model(rawValue: _name) + } else { + _modelEnum = nil + } + + guard let apiDeviceInfoDict = dictionary["av:X_ScalarWebAPI_DeviceInfo"] as? [AnyHashable : Any], let apiInfo = ApiDeviceInfo(dictionary: apiDeviceInfoDict, model: _modelEnum) else { return nil } @@ -156,13 +168,13 @@ internal final class SonyCameraDevice { apiClient = SonyCameraAPIClient(apiInfo: apiDeviceInfo) apiVersion = apiDeviceInfo.version - name = dictionary["friendlyName"] as? String + name = _modelEnum?.friendlyName ?? _name udn = dictionary["UDN"] as? String identifier = udn ?? NSUUID().uuidString - if let model = model { - modelEnum = Model(rawValue: model) + if let name = name { + modelEnum = Model(rawValue: name) } else { modelEnum = nil } @@ -209,89 +221,99 @@ extension SonyCameraDevice: Camera { return true } - public func connect(completion: @escaping Camera.ConnectedCompletion) { + private func getInTransferMode(callback: @escaping (Result) -> Void) { guard let cameraClient = apiClient.camera else { - completion(nil, false) + callback(Result.failure(CameraError.cameraNotReady("getVersions"))) return } - cameraClient.getVersions { (result) in - - switch result { - case .failure(let versionsError): - completion(versionsError, false) - case .success(_): + // If the camera model doesn't support getVersions then we don't need to worry! + if let modelEnum = modelEnum, modelEnum.usesLegacyAPI { + callback(Result.success(false)) + } else { + cameraClient.getVersions { (result) in + + // Ignore 404 as this just means we're a legacy camera + if case let .failure(error) = result, (error as NSError).code != 404 { + callback(Result.failure(error)) + return + } guard let avClient = self.apiClient.avContent else { + callback(Result.success(false)) + return + } + + avClient.getVersions { (avResult) in - guard self.modelEnum == nil || Model.supporting(function: .startRecordMode).contains(self.modelEnum!) else { - completion(nil, false) + // Ignore 404 as this just means we're a legacy camera + if case let .failure(error) = avResult, (error as NSError).code != 404 { + callback(Result.failure(error)) return } - cameraClient.startRecordMode() { (error) in - var _error = error - // Ignore no such method errors because in that case we simply never needed to call this method in the first place! - if let clientError = error as? CameraError, case .noSuchMethod(_) = clientError { - _error = nil - } - completion(_error, false) - } - return - } - - avClient.getVersions() { (result) in - switch result { - case .failure(let avVersionsError): - completion(avVersionsError, false) - case .success(_): + cameraClient.getCameraFunction({ (functionResult) in - let successCallback: (_ inTransferMode: Bool) -> Void = { inTransferMode in + switch functionResult { + case .failure(_): // If we can't get camera function then check what it currently + // is, and if it's "contents transfer" we know that we're in "Send to Smartphone" mode! - guard self.modelEnum == nil || Model.supporting(function: .startRecordMode).contains(self.modelEnum!) else { - completion(nil, inTransferMode) - return - } - - cameraClient.startRecordMode() { (error) in - var _error = error - // Ignore no such method errors because in that case we simply never needed to call this method in the first place! - if let clientError = error as? CameraError, case .noSuchMethod(_) = clientError { - _error = nil - } - completion(_error, inTransferMode) - } - } - - cameraClient.getCameraFunction({ (functionResult) in - - switch functionResult { - case .failure(_): // If we can't set camera function then check what it currently - // is, and if it's "contents transfer" we know that we're in "Send to Smartphone" mode! + // Get event, because getCameraFunction failed! + cameraClient.getEvent(polling: false, { (eventResult) in - // Get event, because getCameraFunction failed! - cameraClient.getEvent(polling: false, { (eventResult) in - - var isInTransferMode: Bool = false - - switch eventResult { - case .failure(_): - successCallback(false) - break - case .success(let event): - if let function = event.function?.current { - isInTransferMode = function.lowercased() == "contents transfer" - } + var isInTransferMode: Bool = false + + switch eventResult { + case .failure(_): + callback(Result.success(false)) + break + case .success(let event): + if let function = event.function?.current { + isInTransferMode = function.lowercased() == "contents transfer" } - - successCallback(isInTransferMode) - }) - case .success(_): // If we can get camera function, we're not in "Send to Smartphone" mode! - successCallback(false) - } - }) + } + + callback(Result.success(isInTransferMode)) + }) + case .success(_): // If we can get camera function, we're not in "Send to Smartphone" mode! + callback(Result.success(false)) + } + }) + } + } + } + } + + public func connect(completion: @escaping Camera.ConnectedCompletion) { + + guard let cameraClient = apiClient.camera else { + completion(nil, false) + return + } + + getInTransferMode { (result) in + + switch result { + case .failure(let error): + completion(error, false) + case .success(let inTransferMode): + + guard self.modelEnum == nil || Model.supporting(function: .startRecordMode).contains(self.modelEnum!) else { + completion(nil, inTransferMode) + return + } + + cameraClient.startRecordMode() { (error) in + var _error = error + // Ignore no such method errors because in that case we simply never needed to call this method in the first place! + if let clientError = error as? CameraError, case .noSuchMethod(_) = clientError { + _error = nil + // Also ignore 404 as this is what cameras like RX100 M2 return! + } else if (error as NSError?)?.code == 404 { + _error = nil } + completion(_error, inTransferMode) } } } @@ -312,18 +334,18 @@ extension SonyCameraDevice: Camera { return } - switchCameraToRequiredFunctionFor(function) { [weak self] (error) in + switchCameraToRequiredFunctionFor(function) { [weak self] (fnError) in - guard let this = self, error == nil else { - callback(error) + guard let this = self, fnError == nil else { + callback(fnError) return } switch function.function { case .takePicture, .startContinuousShooting, .startBulbCapture: - camera.setShootMode(.photo, completion: { [weak this] (error) in - + this.setToShootModeIfRequired(camera: camera, shootMode: .photo) { [weak this] (error) in + switch function.function { case .startContinuousShooting: this?.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { (_) in @@ -383,31 +405,23 @@ extension SonyCameraDevice: Camera { }) }) } - }) + } case .startIntervalStillRecording: - this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { (_) in - camera.setShootMode(.interval, completion: { (error) in - callback(error) - }) + this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { [weak this] (_) in + this?.setToShootModeIfRequired(camera: camera, shootMode: .interval, callback) }) case .startAudioRecording: - this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { (_) in - camera.setShootMode(.audio, completion: { (error) in - callback(error) - }) + this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { [weak this] (_) in + this?.setToShootModeIfRequired(camera: camera, shootMode: .audio, callback) }) case .startVideoRecording: - this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { (_) in - camera.setShootMode(.video, completion: { (error) in - callback(error) - }) + this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { [weak this] (_) in + this?.setToShootModeIfRequired(camera: camera, shootMode: .video, callback) }) case .startLoopRecording: - this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { (_) in - camera.setShootMode(.loop, completion: { (error) in - callback(error) - }) + this.setShutterSpeedAwayFromBulbIfRequired(camera: camera, { [weak this] (_) in + this?.setToShootModeIfRequired(camera: camera, shootMode: .loop, callback) }) default: callback(nil) @@ -415,16 +429,50 @@ extension SonyCameraDevice: Camera { } } + private func setToShootModeIfRequired(camera: CameraClient, shootMode: ShootingMode, _ completion: @escaping ((Error?) -> Void)) { + + // Last shoot mode should be up to date so do a quick check if we're already in the correct shoot mode + guard lastShootMode != shootMode else { + completion(nil) + return + } + + // Some cameras throw error if we try and set shoot mode to it's current value, so let's do a last-ditch attempt to check current shoot mode before changing + camera.getShootMode { (result) in + switch result { + case .success(let currentMode): + guard currentMode != shootMode else { + completion(nil) + return + } + camera.setShootMode(shootMode, completion: { [weak self] (error) in + completion(error) + guard error == nil else { + return + } + self?.lastShootMode = shootMode + }) + case .failure(_): + camera.setShootMode(shootMode, completion: { [weak self] (error) in + completion(error) + guard error == nil else { + return + } + self?.lastShootMode = shootMode + }) + } + } + } + private func setShutterSpeedAwayFromBulbIfRequired(camera: CameraClient, _ callback: @escaping ((Error?) -> Void)) { // We need to do this otherwise the camera can get stuck in continuous shooting mode! // If the shutter speed is BULB then we need to set it to something else! guard self.lastShutterSpeed?.isBulb == true else { - callback(nil) - return } + // Get available shutter speeds camera.getAvailableShutterSpeeds({ (shutterSpeedResults) in switch shutterSpeedResults { @@ -1755,7 +1803,7 @@ extension SonyCameraDevice: Camera { // Take picture immediately after half press has completed, two scenarios here: // 1. User is in MF, this takePicture should succeed and take the photo // 2. User is in AF, this takePicture could fail (which we ignore), and then we wait for focus change - takePicture(true, { [weak _this] success in + takePicture(false, { success in // If the take picture failed, then we'll await the focus change from `Shutter.halfPress` guard !success else { @@ -1763,15 +1811,7 @@ extension SonyCameraDevice: Camera { return } - Logger.shared.log("Take picture failed, awaiting focus change", category: "SonyCamera", level: .debug) - - // Await event letting us know the camera has finished focussing - _this?.onFocusChange({ (status) -> Bool in - guard let _status = status, _status != .focusing else { return false } - Logger.shared.log("Camera achieved focus, taking picture", category: "SonyCamera", level: .debug) - takePicture(false, nil) - return true - }) + Logger.shared.log("Take picture failed, nothing we can do...", category: "SonyCamera", level: .debug) }) }) } diff --git a/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyCameraDiscoverer.swift b/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyCameraDiscoverer.swift index 7917ae5..8e56546 100644 --- a/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyCameraDiscoverer.swift +++ b/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyCameraDiscoverer.swift @@ -7,11 +7,7 @@ // import Foundation -#if os(iOS) import ThunderRequest -#elseif os(macOS) -import ThunderRequestMac -#endif import os extension SonyCameraDevice { @@ -19,14 +15,12 @@ extension SonyCameraDevice { func update(with deviceInfo: SonyDeviceInfo?) { // Keep name if modelEnum currently nil as user has renamed camera! - self.name = modelEnum == nil ? name : (deviceInfo?.model?.friendlyName ?? name) - self.modelEnum = deviceInfo?.model ?? modelEnum - if let modelEnum = deviceInfo?.model { - self.model = modelEnum.friendlyName - } - self.lensModelName = deviceInfo?.lensModelName - self.firmwareVersion = deviceInfo?.firmwareVersion - self.remoteAppVersion = deviceInfo?.installedPlayMemoriesApps.first(where :{ $0.name == "Smart Remote Control" })?.version + name = modelEnum == nil ? name : (deviceInfo?.model?.friendlyName ?? name) + modelEnum = deviceInfo?.model ?? modelEnum + model = modelEnum?.friendlyName ?? model + lensModelName = deviceInfo?.lensModelName + firmwareVersion = deviceInfo?.firmwareVersion + remoteAppVersion = deviceInfo?.installedPlayMemoriesApps.first(where :{ $0.name == "Smart Remote Control" })?.version } } @@ -162,17 +156,17 @@ internal final class SonyCameraDiscoverer: UDPDeviceDiscoverer { self.delegate = delegate } - override func parseDevice(from stringRepresentation: String, baseURL: URL, callback: @escaping (Bool) -> Void) { - parseXML(string: stringRepresentation, baseURL: baseURL, callback: callback) + override func parseDevice(from stringRepresentation: String, isCached: Bool, baseURL: URL, callback: @escaping (Bool) -> Void) { + parseXML(string: stringRepresentation, baseURL: baseURL, isCached: isCached, callback: callback) } - public func parseXML(string: String, baseURL: URL, callback: @escaping (Bool) -> Void) { + public func parseXML(string: String, baseURL: URL, isCached: Bool, callback: @escaping (Bool) -> Void) { - parseCameraXML(string: string, baseURL: baseURL, callback: callback) - parseTransferDeviceXML(string: string, baseURL: baseURL, callback: callback) + parseCameraXML(string: string, baseURL: baseURL, isCached: isCached, callback: callback) + parseTransferDeviceXML(string: string, baseURL: baseURL, isCached: isCached, callback: callback) } - private func parseCameraXML(string: String, baseURL: URL, callback: @escaping (Bool) -> Void) { + private func parseCameraXML(string: String, baseURL: URL, isCached: Bool, callback: @escaping (Bool) -> Void) { let parser = SonyCameraParser(xmlString: string) parser.parse { [weak self] (cameraDevice, error) in @@ -189,7 +183,7 @@ internal final class SonyCameraDiscoverer: UDPDeviceDiscoverer { callback(true) guard let digitalImagingService = device.services?.first(where: { $0.type == .digitalImaging }) else { - strongSelf.sendDeviceToDelegate(device) + strongSelf.sendDeviceToDelegate(device, isCached: isCached) return } @@ -202,7 +196,7 @@ internal final class SonyCameraDiscoverer: UDPDeviceDiscoverer { } guard let string = response?.string else { - _strongSelf.sendDeviceToDelegate(device) + _strongSelf.sendDeviceToDelegate(device, isCached: isCached) return } @@ -214,7 +208,7 @@ internal final class SonyCameraDiscoverer: UDPDeviceDiscoverer { } device.update(with: deviceInfo) - __strongSelf.sendDeviceToDelegate(device) + __strongSelf.sendDeviceToDelegate(device, isCached: isCached) }) }) @@ -222,7 +216,7 @@ internal final class SonyCameraDiscoverer: UDPDeviceDiscoverer { } } - private func parseTransferDeviceXML(string: String, baseURL: URL, callback: @escaping (Bool) -> Void) { + private func parseTransferDeviceXML(string: String, baseURL: URL, isCached: Bool, callback: @escaping (Bool) -> Void) { let transferDeviceParser = SonyTransferDeviceParser(xmlString: string) transferDeviceParser.parse { [weak self] (transferDevice, error) in @@ -251,7 +245,7 @@ internal final class SonyCameraDiscoverer: UDPDeviceDiscoverer { } callback(true) - _strongSelf.sendDeviceToDelegate(_transferDevice) + _strongSelf.sendDeviceToDelegate(_transferDevice, isCached: isCached) }) } } diff --git a/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyXMLParsers.swift b/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyXMLParsers.swift index 8531610..c083979 100644 --- a/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyXMLParsers.swift +++ b/Rocc/Manufacturer Implementations/Sony/Device Discovery/SonyXMLParsers.swift @@ -84,8 +84,6 @@ final class SonyCameraParser: NSObject, XMLParserDelegate { default: break } - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } func parser(_ parser: XMLParser, foundCharacters string: String) { @@ -101,7 +99,6 @@ final class SonyCameraParser: NSObject, XMLParserDelegate { defer { currentElement = scope.removeLast() foundCharacters = "" - os_log("Parser did end element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } switch elementName { @@ -237,8 +234,6 @@ final class SonyTransferDeviceParser: NSObject, XMLParserDelegate { default: break } - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } func parser(_ parser: XMLParser, foundCharacters string: String) { @@ -254,7 +249,6 @@ final class SonyTransferDeviceParser: NSObject, XMLParserDelegate { defer { currentElement = scope.removeLast() foundCharacters = "" - os_log("Parser did end element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } switch elementName { @@ -371,8 +365,6 @@ class SonyCameraDeviceInfoParser: NSObject, XMLParserDelegate { if elementName == "X_PlayMemoriesCameraApps_App" { currentApp = [:] } - - os_log("Parser did start element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } func parser(_ parser: XMLParser, foundCharacters string: String) { @@ -388,7 +380,6 @@ class SonyCameraDeviceInfoParser: NSObject, XMLParserDelegate { defer { currentElement = scope.removeLast() foundCharacters = "" - os_log("Parser did end element: %@\nCurrent scope:%@", log: log, type: .debug, elementName, scope) } switch elementName { diff --git a/Rocc/Manufacturer Implementations/Sony/Transfer Device/SonyTransferDevice.swift b/Rocc/Manufacturer Implementations/Sony/Transfer Device/SonyTransferDevice.swift index dd3e4d6..c3546bc 100644 --- a/Rocc/Manufacturer Implementations/Sony/Transfer Device/SonyTransferDevice.swift +++ b/Rocc/Manufacturer Implementations/Sony/Transfer Device/SonyTransferDevice.swift @@ -7,11 +7,7 @@ // import Foundation -#if os(iOS) import ThunderRequest -#elseif os(macOS) -import ThunderRequestMac -#endif internal final class SonyTransferDevice { diff --git a/ThunderRequest b/ThunderRequest index 3b13c58..c9c6ad7 160000 --- a/ThunderRequest +++ b/ThunderRequest @@ -1 +1 @@ -Subproject commit 3b13c58379614661f15991de6f972e3c42fe8441 +Subproject commit c9c6ad731e5201b7f0bdb13f52f25ab45f2cc90f