mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-10-27 22:37:15 +00:00
More needed refactoring steps
This commit is contained in:
1 parent
376bcc2d34
commit
cd860fcc08
29 files changed
+819
-566
No files matched your search
@@ -9,7 +9,7 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
066B0DF652B5D2B188D4884B /* libPods-SAPTracker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B1229BB88872CD20C0AE25DE /* libPods-SAPTracker.a */; };
|
066B0DF652B5D2B188D4884B /* libPods-SAPTracker.a in Frameworks */ = {isa = PBXBuildFile; fileRef = B1229BB88872CD20C0AE25DE /* libPods-SAPTracker.a */; };
|
||||||
7F0658FD19F7D6700077FF95 /* ScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0658FC19F7D6700077FF95 /* ScanViewController.swift */; };
|
7F0658FD19F7D6700077FF95 /* ScanViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0658FC19F7D6700077FF95 /* ScanViewController.swift */; };
|
||||||
7F0658FF19F7EE910077FF95 /* CheckInData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0658FE19F7EE910077FF95 /* CheckInData.swift */; };
|
7F0658FF19F7EE910077FF95 /* RegattaData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7F0658FE19F7EE910077FF95 /* RegattaData.swift */; };
|
||||||
7F14A10A1A13B9A6001C1ECB /* _abkhazia.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0041A13B9A6001C1ECB /* _abkhazia.png */; };
|
7F14A10A1A13B9A6001C1ECB /* _abkhazia.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0041A13B9A6001C1ECB /* _abkhazia.png */; };
|
||||||
7F14A10B1A13B9A6001C1ECB /* _basque-country.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0051A13B9A6001C1ECB /* _basque-country.png */; };
|
7F14A10B1A13B9A6001C1ECB /* _basque-country.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0051A13B9A6001C1ECB /* _basque-country.png */; };
|
||||||
7F14A10C1A13B9A6001C1ECB /* _british-antarctic-territory.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0061A13B9A6001C1ECB /* _british-antarctic-territory.png */; };
|
7F14A10C1A13B9A6001C1ECB /* _british-antarctic-territory.png in Resources */ = {isa = PBXBuildFile; fileRef = 7F14A0061A13B9A6001C1ECB /* _british-antarctic-territory.png */; };
|
||||||
@@ -311,7 +311,6 @@
|
|||||||
C852BAA21CF5E1EA0093B0C5 /* RequestManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAA11CF5E1EA0093B0C5 /* RequestManager.swift */; };
|
C852BAA21CF5E1EA0093B0C5 /* RequestManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAA11CF5E1EA0093B0C5 /* RequestManager.swift */; };
|
||||||
C852BAAB1CF736680093B0C5 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAAA1CF736680093B0C5 /* Preferences.swift */; };
|
C852BAAB1CF736680093B0C5 /* Preferences.swift in Sources */ = {isa = PBXBuildFile; fileRef = C852BAAA1CF736680093B0C5 /* Preferences.swift */; };
|
||||||
C8603D511C52892A002B2F28 /* Acknowledgements.markdown in Resources */ = {isa = PBXBuildFile; fileRef = C8603D491C528832002B2F28 /* Acknowledgements.markdown */; };
|
C8603D511C52892A002B2F28 /* Acknowledgements.markdown in Resources */ = {isa = PBXBuildFile; fileRef = C8603D491C528832002B2F28 /* Acknowledgements.markdown */; };
|
||||||
C8739D8E1D23D53C00A89F3C /* SendGPSFixesController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739D8D1D23D53C00A89F3C /* SendGPSFixesController.swift */; };
|
|
||||||
C8739E041D2AA2A500A89F3C /* Regatta+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739DFA1D2AA2A500A89F3C /* Regatta+CoreDataProperties.swift */; };
|
C8739E041D2AA2A500A89F3C /* Regatta+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739DFA1D2AA2A500A89F3C /* Regatta+CoreDataProperties.swift */; };
|
||||||
C8739E051D2AA2A500A89F3C /* Regatta.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739DFB1D2AA2A500A89F3C /* Regatta.swift */; };
|
C8739E051D2AA2A500A89F3C /* Regatta.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739DFB1D2AA2A500A89F3C /* Regatta.swift */; };
|
||||||
C8739E061D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739DFC1D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift */; };
|
C8739E061D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739DFC1D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift */; };
|
||||||
@@ -322,6 +321,12 @@
|
|||||||
C8739E0B1D2AA2A500A89F3C /* Competitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E011D2AA2A500A89F3C /* Competitor.swift */; };
|
C8739E0B1D2AA2A500A89F3C /* Competitor.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E011D2AA2A500A89F3C /* Competitor.swift */; };
|
||||||
C8739E0C1D2AA2A500A89F3C /* Event+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E021D2AA2A500A89F3C /* Event+CoreDataProperties.swift */; };
|
C8739E0C1D2AA2A500A89F3C /* Event+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E021D2AA2A500A89F3C /* Event+CoreDataProperties.swift */; };
|
||||||
C8739E0D1D2AA2A500A89F3C /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E031D2AA2A500A89F3C /* Event.swift */; };
|
C8739E0D1D2AA2A500A89F3C /* Event.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E031D2AA2A500A89F3C /* Event.swift */; };
|
||||||
|
C8739E0F1D2BEE7900A89F3C /* RegattaController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E0E1D2BEE7900A89F3C /* RegattaController.swift */; };
|
||||||
|
C8739E121D2BF14F00A89F3C /* EventData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E111D2BF14F00A89F3C /* EventData.swift */; };
|
||||||
|
C8739E141D2BF16300A89F3C /* LeaderboardData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E131D2BF16300A89F3C /* LeaderboardData.swift */; };
|
||||||
|
C8739E161D2BF17900A89F3C /* CompetitorData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E151D2BF17900A89F3C /* CompetitorData.swift */; };
|
||||||
|
C8739E181D2BF2DC00A89F3C /* BaseData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E171D2BF2DC00A89F3C /* BaseData.swift */; };
|
||||||
|
C8739E1C1D2D5F1700A89F3C /* LocationData.swift in Sources */ = {isa = PBXBuildFile; fileRef = C8739E1B1D2D5F1700A89F3C /* LocationData.swift */; };
|
||||||
C89C5FC51D06A289002AAAD2 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FC41D06A289002AAAD2 /* GradientView.swift */; };
|
C89C5FC51D06A289002AAAD2 /* GradientView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FC41D06A289002AAAD2 /* GradientView.swift */; };
|
||||||
C89C5FCA1D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */; };
|
C89C5FCA1D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */; };
|
||||||
C89C5FCC1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */; };
|
C89C5FCC1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */; };
|
||||||
@@ -391,7 +396,7 @@
|
|||||||
6010190FF03AFE91478240B4 /* Pods-SAPTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SAPTrackerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SAPTrackerTests/Pods-SAPTrackerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
6010190FF03AFE91478240B4 /* Pods-SAPTrackerTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-SAPTrackerTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-SAPTrackerTests/Pods-SAPTrackerTests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||||
7F03FD3F19FA4D7400FA1327 /* bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = "<group>"; };
|
7F03FD3F19FA4D7400FA1327 /* bridge.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = bridge.h; sourceTree = "<group>"; };
|
||||||
7F0658FC19F7D6700077FF95 /* ScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ScanViewController.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
7F0658FC19F7D6700077FF95 /* ScanViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = ScanViewController.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||||
7F0658FE19F7EE910077FF95 /* CheckInData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = CheckInData.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
7F0658FE19F7EE910077FF95 /* RegattaData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; lineEnding = 0; path = RegattaData.swift; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.swift; };
|
||||||
7F14A0041A13B9A6001C1ECB /* _abkhazia.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = _abkhazia.png; sourceTree = "<group>"; };
|
7F14A0041A13B9A6001C1ECB /* _abkhazia.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = _abkhazia.png; sourceTree = "<group>"; };
|
||||||
7F14A0051A13B9A6001C1ECB /* _basque-country.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "_basque-country.png"; sourceTree = "<group>"; };
|
7F14A0051A13B9A6001C1ECB /* _basque-country.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "_basque-country.png"; sourceTree = "<group>"; };
|
||||||
7F14A0061A13B9A6001C1ECB /* _british-antarctic-territory.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "_british-antarctic-territory.png"; sourceTree = "<group>"; };
|
7F14A0061A13B9A6001C1ECB /* _british-antarctic-territory.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "_british-antarctic-territory.png"; sourceTree = "<group>"; };
|
||||||
@@ -700,7 +705,6 @@
|
|||||||
C852BAAA1CF736680093B0C5 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
C852BAAA1CF736680093B0C5 /* Preferences.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Preferences.swift; sourceTree = "<group>"; };
|
||||||
C8603D491C528832002B2F28 /* Acknowledgements.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Acknowledgements.markdown; sourceTree = "<group>"; };
|
C8603D491C528832002B2F28 /* Acknowledgements.markdown */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = Acknowledgements.markdown; sourceTree = "<group>"; };
|
||||||
C8739D891D21276B00A89F3C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = "<group>"; };
|
C8739D891D21276B00A89F3C /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Main.strings; sourceTree = "<group>"; };
|
||||||
C8739D8D1D23D53C00A89F3C /* SendGPSFixesController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SendGPSFixesController.swift; sourceTree = "<group>"; };
|
|
||||||
C8739D9A1D25317100A89F3C /* CoreData 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "CoreData 2.xcdatamodel"; sourceTree = "<group>"; };
|
C8739D9A1D25317100A89F3C /* CoreData 2.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "CoreData 2.xcdatamodel"; sourceTree = "<group>"; };
|
||||||
C8739DFA1D2AA2A500A89F3C /* Regatta+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Regatta+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
C8739DFA1D2AA2A500A89F3C /* Regatta+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Regatta+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
C8739DFB1D2AA2A500A89F3C /* Regatta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Regatta.swift; sourceTree = "<group>"; };
|
C8739DFB1D2AA2A500A89F3C /* Regatta.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Regatta.swift; sourceTree = "<group>"; };
|
||||||
@@ -712,6 +716,12 @@
|
|||||||
C8739E011D2AA2A500A89F3C /* Competitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Competitor.swift; sourceTree = "<group>"; };
|
C8739E011D2AA2A500A89F3C /* Competitor.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Competitor.swift; sourceTree = "<group>"; };
|
||||||
C8739E021D2AA2A500A89F3C /* Event+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Event+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
C8739E021D2AA2A500A89F3C /* Event+CoreDataProperties.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Event+CoreDataProperties.swift"; sourceTree = "<group>"; };
|
||||||
C8739E031D2AA2A500A89F3C /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = "<group>"; };
|
C8739E031D2AA2A500A89F3C /* Event.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Event.swift; sourceTree = "<group>"; };
|
||||||
|
C8739E0E1D2BEE7900A89F3C /* RegattaController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RegattaController.swift; sourceTree = "<group>"; };
|
||||||
|
C8739E111D2BF14F00A89F3C /* EventData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventData.swift; sourceTree = "<group>"; };
|
||||||
|
C8739E131D2BF16300A89F3C /* LeaderboardData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LeaderboardData.swift; sourceTree = "<group>"; };
|
||||||
|
C8739E151D2BF17900A89F3C /* CompetitorData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CompetitorData.swift; sourceTree = "<group>"; };
|
||||||
|
C8739E171D2BF2DC00A89F3C /* BaseData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BaseData.swift; sourceTree = "<group>"; };
|
||||||
|
C8739E1B1D2D5F1700A89F3C /* LocationData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationData.swift; sourceTree = "<group>"; };
|
||||||
C89C5FC41D06A289002AAAD2 /* GradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
|
C89C5FC41D06A289002AAAD2 /* GradientView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GradientView.swift; sourceTree = "<group>"; };
|
||||||
C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusTrackingTableViewCell.swift; sourceTree = "<group>"; };
|
C89C5FC91D06CECD002AAAD2 /* StatusTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StatusTrackingTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPSAccuracyTrackingTableViewCell.swift; sourceTree = "<group>"; };
|
C89C5FCB1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GPSAccuracyTrackingTableViewCell.swift; sourceTree = "<group>"; };
|
||||||
@@ -793,9 +803,10 @@
|
|||||||
7F06590219F7FEA40077FF95 /* DataController */ = {
|
7F06590219F7FEA40077FF95 /* DataController */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
C8739D8A1D22CCDB00A89F3C /* GPSFixes */,
|
C8739E0E1D2BEE7900A89F3C /* RegattaController.swift */,
|
||||||
|
7F23F0871A1A3DEF00F03F1C /* CheckInController.swift */,
|
||||||
|
C8739E101D2BF13200A89F3C /* Data */,
|
||||||
C852BAA61CF5E1F40093B0C5 /* CheckIn */,
|
C852BAA61CF5E1F40093B0C5 /* CheckIn */,
|
||||||
7F1B66F81A0CDCF600904A41 /* BatteryManager.swift */,
|
|
||||||
);
|
);
|
||||||
name = DataController;
|
name = DataController;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1162,8 +1173,6 @@
|
|||||||
C852BAA61CF5E1F40093B0C5 /* CheckIn */ = {
|
C852BAA61CF5E1F40093B0C5 /* CheckIn */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7F0658FE19F7EE910077FF95 /* CheckInData.swift */,
|
|
||||||
7F23F0871A1A3DEF00F03F1C /* CheckInController.swift */,
|
|
||||||
);
|
);
|
||||||
name = CheckIn;
|
name = CheckIn;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -1176,17 +1185,11 @@
|
|||||||
name = Preferences;
|
name = Preferences;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C8739D8A1D22CCDB00A89F3C /* GPSFixes */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
C8739D8D1D23D53C00A89F3C /* SendGPSFixesController.swift */,
|
|
||||||
);
|
|
||||||
name = GPSFixes;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
C8739D8B1D23C01500A89F3C /* Managers */ = {
|
C8739D8B1D23C01500A89F3C /* Managers */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
7F2C605919F160E400C32D93 /* LocationManager.swift */,
|
||||||
|
7F1B66F81A0CDCF600904A41 /* BatteryManager.swift */,
|
||||||
C852BAA11CF5E1EA0093B0C5 /* RequestManager.swift */,
|
C852BAA11CF5E1EA0093B0C5 /* RequestManager.swift */,
|
||||||
);
|
);
|
||||||
name = Managers;
|
name = Managers;
|
||||||
@@ -1200,20 +1203,11 @@
|
|||||||
name = EULA;
|
name = EULA;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
C8739DC61D2A650E00A89F3C /* Location */ = {
|
|
||||||
isa = PBXGroup;
|
|
||||||
children = (
|
|
||||||
7F2C605919F160E400C32D93 /* LocationManager.swift */,
|
|
||||||
);
|
|
||||||
name = Location;
|
|
||||||
sourceTree = "<group>";
|
|
||||||
};
|
|
||||||
C8739DC71D2A653F00A89F3C /* Classes */ = {
|
C8739DC71D2A653F00A89F3C /* Classes */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
7F06590019F7FE750077FF95 /* CoreData */,
|
7F06590019F7FE750077FF95 /* CoreData */,
|
||||||
7F06590219F7FEA40077FF95 /* DataController */,
|
7F06590219F7FEA40077FF95 /* DataController */,
|
||||||
C8739DC61D2A650E00A89F3C /* Location */,
|
|
||||||
C8739D8B1D23C01500A89F3C /* Managers */,
|
C8739D8B1D23C01500A89F3C /* Managers */,
|
||||||
C852BAA91CF736440093B0C5 /* Preferences */,
|
C852BAA91CF736440093B0C5 /* Preferences */,
|
||||||
7F06590119F7FE920077FF95 /* ViewController */,
|
7F06590119F7FE920077FF95 /* ViewController */,
|
||||||
@@ -1222,6 +1216,19 @@
|
|||||||
name = Classes;
|
name = Classes;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
};
|
};
|
||||||
|
C8739E101D2BF13200A89F3C /* Data */ = {
|
||||||
|
isa = PBXGroup;
|
||||||
|
children = (
|
||||||
|
7F0658FE19F7EE910077FF95 /* RegattaData.swift */,
|
||||||
|
C8739E111D2BF14F00A89F3C /* EventData.swift */,
|
||||||
|
C8739E131D2BF16300A89F3C /* LeaderboardData.swift */,
|
||||||
|
C8739E151D2BF17900A89F3C /* CompetitorData.swift */,
|
||||||
|
C8739E171D2BF2DC00A89F3C /* BaseData.swift */,
|
||||||
|
C8739E1B1D2D5F1700A89F3C /* LocationData.swift */,
|
||||||
|
);
|
||||||
|
name = Data;
|
||||||
|
sourceTree = "<group>";
|
||||||
|
};
|
||||||
C89C5FC31D06A269002AAAD2 /* Views */ = {
|
C89C5FC31D06A269002AAAD2 /* Views */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
@@ -1847,9 +1854,13 @@
|
|||||||
files = (
|
files = (
|
||||||
7F1875B31A10F1B800C25BE0 /* TrackingViewController.swift in Sources */,
|
7F1875B31A10F1B800C25BE0 /* TrackingViewController.swift in Sources */,
|
||||||
C8739E081D2AA2A500A89F3C /* Leaderboard+CoreDataProperties.swift in Sources */,
|
C8739E081D2AA2A500A89F3C /* Leaderboard+CoreDataProperties.swift in Sources */,
|
||||||
|
C8739E121D2BF14F00A89F3C /* EventData.swift in Sources */,
|
||||||
|
C8739E0F1D2BEE7900A89F3C /* RegattaController.swift in Sources */,
|
||||||
|
C8739E1C1D2D5F1700A89F3C /* LocationData.swift in Sources */,
|
||||||
7F83F15819F154F000C53328 /* HomeViewController.swift in Sources */,
|
7F83F15819F154F000C53328 /* HomeViewController.swift in Sources */,
|
||||||
7F8B8D431A373D4400C34B88 /* CourseViewController.swift in Sources */,
|
7F8B8D431A373D4400C34B88 /* CourseViewController.swift in Sources */,
|
||||||
7FAFA7951A126B5700D230F1 /* AboutViewController.swift in Sources */,
|
7FAFA7951A126B5700D230F1 /* AboutViewController.swift in Sources */,
|
||||||
|
C8739E161D2BF17900A89F3C /* CompetitorData.swift in Sources */,
|
||||||
C8739E0A1D2AA2A500A89F3C /* Competitor+CoreDataProperties.swift in Sources */,
|
C8739E0A1D2AA2A500A89F3C /* Competitor+CoreDataProperties.swift in Sources */,
|
||||||
C8739E0C1D2AA2A500A89F3C /* Event+CoreDataProperties.swift in Sources */,
|
C8739E0C1D2AA2A500A89F3C /* Event+CoreDataProperties.swift in Sources */,
|
||||||
C8739E071D2AA2A500A89F3C /* GPSFix.swift in Sources */,
|
C8739E071D2AA2A500A89F3C /* GPSFix.swift in Sources */,
|
||||||
@@ -1859,7 +1870,6 @@
|
|||||||
7FA6551A19F6661900A1B92D /* CoreDataManager.swift in Sources */,
|
7FA6551A19F6661900A1B92D /* CoreDataManager.swift in Sources */,
|
||||||
C852BAA21CF5E1EA0093B0C5 /* RequestManager.swift in Sources */,
|
C852BAA21CF5E1EA0093B0C5 /* RequestManager.swift in Sources */,
|
||||||
C8BBAC791C52649E004CA551 /* LicenseViewController.swift in Sources */,
|
C8BBAC791C52649E004CA551 /* LicenseViewController.swift in Sources */,
|
||||||
C8739D8E1D23D53C00A89F3C /* SendGPSFixesController.swift in Sources */,
|
|
||||||
7F23F0881A1A3DEF00F03F1C /* CheckInController.swift in Sources */,
|
7F23F0881A1A3DEF00F03F1C /* CheckInController.swift in Sources */,
|
||||||
7F2C605A19F160E400C32D93 /* LocationManager.swift in Sources */,
|
7F2C605A19F160E400C32D93 /* LocationManager.swift in Sources */,
|
||||||
C89C5FCC1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift in Sources */,
|
C89C5FCC1D06CF0C002AAAD2 /* GPSAccuracyTrackingTableViewCell.swift in Sources */,
|
||||||
@@ -1874,16 +1884,18 @@
|
|||||||
9E95C3D61C723AB30016632B /* Constants.swift in Sources */,
|
9E95C3D61C723AB30016632B /* Constants.swift in Sources */,
|
||||||
7FD9D3031A1236080058FEAD /* Extensions.swift in Sources */,
|
7FD9D3031A1236080058FEAD /* Extensions.swift in Sources */,
|
||||||
C8739E091D2AA2A500A89F3C /* Leaderboard.swift in Sources */,
|
C8739E091D2AA2A500A89F3C /* Leaderboard.swift in Sources */,
|
||||||
|
C8739E141D2BF16300A89F3C /* LeaderboardData.swift in Sources */,
|
||||||
C89C5FC51D06A289002AAAD2 /* GradientView.swift in Sources */,
|
C89C5FC51D06A289002AAAD2 /* GradientView.swift in Sources */,
|
||||||
C852BAAB1CF736680093B0C5 /* Preferences.swift in Sources */,
|
C852BAAB1CF736680093B0C5 /* Preferences.swift in Sources */,
|
||||||
7F0658FD19F7D6700077FF95 /* ScanViewController.swift in Sources */,
|
7F0658FD19F7D6700077FF95 /* ScanViewController.swift in Sources */,
|
||||||
C8739E061D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift in Sources */,
|
C8739E061D2AA2A500A89F3C /* GPSFix+CoreDataProperties.swift in Sources */,
|
||||||
7F193A8F1A39ACF500D71773 /* TimerViewController.swift in Sources */,
|
7F193A8F1A39ACF500D71773 /* TimerViewController.swift in Sources */,
|
||||||
|
C8739E181D2BF2DC00A89F3C /* BaseData.swift in Sources */,
|
||||||
7F83F15619F154F000C53328 /* AppDelegate.swift in Sources */,
|
7F83F15619F154F000C53328 /* AppDelegate.swift in Sources */,
|
||||||
7F950A911A35E967003C8C5C /* LeaderboardViewController.swift in Sources */,
|
7F950A911A35E967003C8C5C /* LeaderboardViewController.swift in Sources */,
|
||||||
C89C5FCE1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift in Sources */,
|
C89C5FCE1D06CF26002AAAD2 /* CachedFixesTrackingTableViewCell.swift in Sources */,
|
||||||
C8739E0B1D2AA2A500A89F3C /* Competitor.swift in Sources */,
|
C8739E0B1D2AA2A500A89F3C /* Competitor.swift in Sources */,
|
||||||
7F0658FF19F7EE910077FF95 /* CheckInData.swift in Sources */,
|
7F0658FF19F7EE910077FF95 /* RegattaData.swift in Sources */,
|
||||||
7F193A911A39E54600D71773 /* GPSAccuracyView.swift in Sources */,
|
7F193A911A39E54600D71773 /* GPSAccuracyView.swift in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|||||||
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// BaseData.swift
|
||||||
|
// SAPTracker
|
||||||
|
//
|
||||||
|
// Created by Raimund Wege on 05.07.16.
|
||||||
|
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class BaseData: NSObject {
|
||||||
|
|
||||||
|
let dictionary: [String: AnyObject]
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
self.dictionary = [String: AnyObject]()
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(dictionary: [String: AnyObject]?) {
|
||||||
|
self.dictionary = dictionary ?? [String: AnyObject]()
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
func doubleValue(forKey key: String) -> Double {
|
||||||
|
return dictionary[key] as? Double ?? 0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
func stringValue(forKey key: String) -> String {
|
||||||
|
return dictionary[key] as? String ?? ""
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -35,8 +35,9 @@ class CachedFixesTrackingTableViewCell: UITableViewCell {
|
|||||||
private func subscribeForNotifications() {
|
private func subscribeForNotifications() {
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
name:LocationManager.NotificationType.Updated,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unsubscribeFromNotifications() {
|
private func unsubscribeFromNotifications() {
|
||||||
|
|||||||
@@ -21,134 +21,26 @@ import AVFoundation
|
|||||||
|
|
||||||
class CheckInController : NSObject {
|
class CheckInController : NSObject {
|
||||||
|
|
||||||
private struct EventKeys {
|
|
||||||
static let EndDate = "endDate"
|
|
||||||
static let ID = "id"
|
|
||||||
static let ImageURLs = "imageURLs"
|
|
||||||
static let Name = "name"
|
|
||||||
static let StartDate = "startDate"
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct CompetitorKeys {
|
|
||||||
static let BoatClassName = "boatClassName"
|
|
||||||
static let CountryCode = "countryCode"
|
|
||||||
static let ID = "id"
|
|
||||||
static let Name = "name"
|
|
||||||
static let Nationality = "nationality"
|
|
||||||
static let SailID = "sailID"
|
|
||||||
}
|
|
||||||
|
|
||||||
private struct LeaderboardKeys {
|
|
||||||
static let Name = "name"
|
|
||||||
}
|
|
||||||
|
|
||||||
var delegate: CheckInControllerDelegate?
|
var delegate: CheckInControllerDelegate?
|
||||||
|
|
||||||
private var checkInData = CheckInData()
|
|
||||||
private var requestManager = RequestManager()
|
private var requestManager = RequestManager()
|
||||||
|
|
||||||
// Responses
|
|
||||||
private var eventDictionary: [String: AnyObject]?
|
|
||||||
private var leaderboardDictionary: [String: AnyObject]?
|
|
||||||
private var competitorDictionary: [String: AnyObject]?
|
|
||||||
private var teamImageURL: String?
|
|
||||||
|
|
||||||
// MARK: - Initialize
|
// MARK: - CheckIn
|
||||||
|
|
||||||
private func initialize(checkInData: CheckInData) {
|
func checkIn(regattaData: RegattaData) {
|
||||||
self.checkInData = checkInData
|
|
||||||
setupRequestManager()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Setups
|
|
||||||
|
|
||||||
private func setupRequestManager() {
|
|
||||||
requestManager = RequestManager(baseURLString: checkInData.serverURL)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Start check-in
|
|
||||||
|
|
||||||
func startCheckIn(checkInData: CheckInData) {
|
|
||||||
initialize(checkInData)
|
|
||||||
checkInDidStart()
|
checkInDidStart()
|
||||||
requestManager.getEvent(checkInData.eventID,
|
requestManager = RequestManager(baseURLString: regattaData.serverURL)
|
||||||
success: { (operation, responseObject) -> Void in self.eventSucceed(responseObject) },
|
requestManager.getRegattaData(regattaData,
|
||||||
failure: { (operation, error) -> Void in self.eventFailed(error) }
|
success: { (regattaData) in self.checkInSuccess(regattaData) },
|
||||||
|
failure: { (title, error) in self.checkInFailure(title, error: error) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Event
|
private func checkInSuccess(regattaData: RegattaData) {
|
||||||
|
let alertController = UIAlertController(title: regattaData.welcomeString, message: nil, preferredStyle: .Alert)
|
||||||
private func eventSucceed(eventResponseObject: AnyObject) {
|
|
||||||
eventDictionary = eventResponseObject as? [String: AnyObject]
|
|
||||||
requestManager.getLeaderboard(checkInData.leaderboardName,
|
|
||||||
success: { (operation, responseObject) -> Void in self.leaderboardSucceed(responseObject) },
|
|
||||||
failure: { (operation, error) -> Void in self.leaderboardFailed(error) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func eventFailed(error: AnyObject) {
|
|
||||||
let alertTitle = String(format: NSLocalizedString("Couldn't get event %@", comment: ""), checkInData.eventID)
|
|
||||||
let alertController = UIAlertController(title: alertTitle, message: error.localizedDescription, preferredStyle: .Alert)
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
|
||||||
self.checkInDidEnd(withSuccess: false)
|
|
||||||
}
|
|
||||||
alertController.addAction(cancelAction)
|
|
||||||
showCheckInAlert(alertController)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Leaderboard
|
|
||||||
|
|
||||||
private func leaderboardSucceed(leaderboardResponseObject: AnyObject) {
|
|
||||||
leaderboardDictionary = leaderboardResponseObject as? [String: AnyObject]
|
|
||||||
requestManager.getCompetitor(checkInData.competitorID,
|
|
||||||
success: { (operation, responseObject) in self.competitorSucceed(responseObject) },
|
|
||||||
failure: { (operation, error) in self.competitorFailed(error) }
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func leaderboardFailed(error: AnyObject) {
|
|
||||||
let alertTitle = String(format: NSLocalizedString("Couldn't get leader board %@", comment: ""), checkInData.leaderboardName)
|
|
||||||
let alertController = UIAlertController(title: alertTitle, message: error.localizedDescription, preferredStyle: .Alert)
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
|
||||||
self.checkInDidEnd(withSuccess: false)
|
|
||||||
}
|
|
||||||
alertController.addAction(cancelAction)
|
|
||||||
showCheckInAlert(alertController)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Competitor
|
|
||||||
|
|
||||||
private func competitorSucceed(competitorResponseObject: AnyObject) {
|
|
||||||
competitorDictionary = competitorResponseObject as? [String: AnyObject]
|
|
||||||
requestManager.getTeamImageURL(competitorID, result: { (imageURL) in self.teamImageURLResult(imageURL) })
|
|
||||||
}
|
|
||||||
|
|
||||||
private func competitorFailed(error: AnyObject) {
|
|
||||||
let alertTitle = String(format: NSLocalizedString("Couldn't get competitor %@", comment: ""), checkInData.competitorID)
|
|
||||||
let alertController = UIAlertController(title: alertTitle, message: error.localizedDescription, preferredStyle: .Alert)
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
|
||||||
self.checkInDidEnd(withSuccess: false)
|
|
||||||
}
|
|
||||||
alertController.addAction(cancelAction)
|
|
||||||
showCheckInAlert(alertController)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Team
|
|
||||||
|
|
||||||
private func teamImageURLResult(imageURL: String?) {
|
|
||||||
teamImageURL = imageURL
|
|
||||||
let alertTitle = String(format:NSLocalizedString("Hello %@. Welcome to %@. You are registered as %@.", comment: ""),
|
|
||||||
competitorName,
|
|
||||||
leaderboardName,
|
|
||||||
competitorSailID)
|
|
||||||
let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .Alert)
|
|
||||||
let okTitle = NSLocalizedString("OK", comment: "")
|
let okTitle = NSLocalizedString("OK", comment: "")
|
||||||
let okAction = UIAlertAction(title: okTitle, style: .Default) { (action) in
|
let okAction = UIAlertAction(title: okTitle, style: .Default) { (action) in
|
||||||
self.checkInOnServer()
|
self.postCheckIn(regattaData)
|
||||||
}
|
}
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
||||||
@@ -159,47 +51,45 @@ class CheckInController : NSObject {
|
|||||||
showCheckInAlert(alertController)
|
showCheckInAlert(alertController)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Check-in on server
|
private func checkInFailure(title: String, error: NSError) {
|
||||||
|
let alertController = UIAlertController(title: title, message: error.localizedDescription, preferredStyle: .Alert)
|
||||||
|
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
||||||
|
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
||||||
|
self.checkInDidEnd(withSuccess: false)
|
||||||
|
}
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
showCheckInAlert(alertController)
|
||||||
|
}
|
||||||
|
|
||||||
private func checkInOnServer() {
|
private func postCheckIn(regattaData: RegattaData) {
|
||||||
SVProgressHUD.show()
|
SVProgressHUD.show()
|
||||||
requestManager.postCheckIn(leaderboardName,
|
requestManager.postCheckIn(regattaData.leaderboardData.name,
|
||||||
competitorID: competitorID,
|
competitorID: regattaData.competitorData.competitorID,
|
||||||
success: { (operation, responseObject) -> Void in self.checkInOnServerSucceed() },
|
success: { (operation, responseObject) -> Void in self.postCheckInSuccess(regattaData) },
|
||||||
failure: { (operation, error) -> Void in self.checkInOnServerFailed(error) }
|
failure: { (operation, error) -> Void in self.postCheckInFailure(regattaData, error: error) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkInOnServerSucceed() {
|
private func postCheckInSuccess(regattaData: RegattaData) {
|
||||||
|
|
||||||
// Regatta
|
// Regatta
|
||||||
let regatta = CoreDataManager.sharedManager.fetchRegatta(checkInData.eventID,
|
let regatta = CoreDataManager.sharedManager.fetchRegatta(regattaData.eventID,
|
||||||
leaderboardName: checkInData.leaderboardName,
|
leaderboardName: regattaData.leaderboardName,
|
||||||
competitorID: checkInData.competitorID
|
competitorID: regattaData.competitorID
|
||||||
) ?? CoreDataManager.sharedManager.newRegatta()
|
) ?? CoreDataManager.sharedManager.newRegatta()
|
||||||
regatta.serverURL = checkInData.serverURL
|
regatta.updateWirhRegattaData(regattaData)
|
||||||
regatta.teamImageURL = teamImageURL
|
|
||||||
regatta.teamImageRetry = false
|
|
||||||
|
|
||||||
// Event
|
// Event
|
||||||
let event = regatta.event ?? CoreDataManager.sharedManager.newEvent(regatta)
|
let event = regatta.event ?? CoreDataManager.sharedManager.newEvent(regatta)
|
||||||
event.endDate = (eventEndDate / 1000)
|
event.updateWithEventData(regattaData.eventData)
|
||||||
event.eventID = eventID
|
|
||||||
event.name = eventName
|
|
||||||
event.startDate = (eventStartDate / 1000)
|
|
||||||
|
|
||||||
// Leaderboard
|
// Leaderboard
|
||||||
let leaderboard = regatta.leaderboard ?? CoreDataManager.sharedManager.newLeaderboard(regatta)
|
let leaderboard = regatta.leaderboard ?? CoreDataManager.sharedManager.newLeaderboard(regatta)
|
||||||
leaderboard.name = leaderboardName
|
leaderboard.updateWithLeaderboardData(regattaData.leaderboardData)
|
||||||
|
|
||||||
// Competitor
|
// Competitor
|
||||||
let competitor = regatta.competitor ?? CoreDataManager.sharedManager.newCompetitor(regatta)
|
let competitor = regatta.competitor ?? CoreDataManager.sharedManager.newCompetitor(regatta)
|
||||||
competitor.boatClassName = competitorBoatClassName
|
competitor.updateWithCompetitorData(regattaData.competitorData)
|
||||||
competitor.competitorID = competitorID
|
|
||||||
competitor.countryCode = competitorCountryCode
|
|
||||||
competitor.name = competitorName
|
|
||||||
competitor.nationality = competitorNationality
|
|
||||||
competitor.sailID = competitorSailID
|
|
||||||
|
|
||||||
// Save
|
// Save
|
||||||
CoreDataManager.sharedManager.saveContext()
|
CoreDataManager.sharedManager.saveContext()
|
||||||
@@ -208,8 +98,8 @@ class CheckInController : NSObject {
|
|||||||
checkInDidEnd(withSuccess: true)
|
checkInDidEnd(withSuccess: true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkInOnServerFailed(error: AnyObject) {
|
private func postCheckInFailure(regattaData: RegattaData, error: AnyObject) {
|
||||||
let alertTitle = String(format:NSLocalizedString("Couldn't check-in to %@", comment: ""), checkInData.leaderboardName)
|
let alertTitle = String(format:NSLocalizedString("Couldn't check-in to %@", comment: ""), regattaData.leaderboardName)
|
||||||
let alertController = UIAlertController(title: alertTitle, message: error.localizedDescription, preferredStyle: .Alert)
|
let alertController = UIAlertController(title: alertTitle, message: error.localizedDescription, preferredStyle: .Alert)
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel) { (action) in
|
||||||
@@ -222,67 +112,18 @@ class CheckInController : NSObject {
|
|||||||
// MARK: - Controller
|
// MARK: - Controller
|
||||||
|
|
||||||
private func checkInDidStart() {
|
private func checkInDidStart() {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
SVProgressHUD.show()
|
||||||
SVProgressHUD.show()
|
self.delegate?.checkInDidStart?(self)
|
||||||
self.delegate?.checkInDidStart?(self)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func checkInDidEnd(withSuccess succeed: Bool) {
|
private func checkInDidEnd(withSuccess succeed: Bool) {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
SVProgressHUD.popActivity()
|
||||||
SVProgressHUD.popActivity()
|
self.delegate?.checkInDidEnd?(self, withSuccess: succeed)
|
||||||
self.delegate?.checkInDidEnd?(self, withSuccess: succeed)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private func showCheckInAlert(alertController: UIAlertController) {
|
private func showCheckInAlert(alertController: UIAlertController) {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
SVProgressHUD.popActivity()
|
||||||
SVProgressHUD.popActivity()
|
self.delegate?.showCheckInAlert(self, alertController: alertController)
|
||||||
self.delegate?.showCheckInAlert(self, alertController: alertController)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Event
|
|
||||||
|
|
||||||
var eventID: String { get { return stringFromEvent(forKey: EventKeys.ID) } }
|
|
||||||
var eventName: String { get { return stringFromEvent(forKey: EventKeys.Name) } }
|
|
||||||
var eventStartDate: Double { get { return doubleFromEvent(forKey: EventKeys.StartDate) } }
|
|
||||||
var eventEndDate: Double { get { return doubleFromEvent(forKey: EventKeys.EndDate) } }
|
|
||||||
|
|
||||||
// MARK: - Leaderboard
|
|
||||||
|
|
||||||
var leaderboardName: String { get { return stringFromLeaderboard(forKey: LeaderboardKeys.Name) } }
|
|
||||||
|
|
||||||
// MARK: - Competitor
|
|
||||||
|
|
||||||
var competitorBoatClassName: String { get { return stringFromCompetitor(forKey: CompetitorKeys.BoatClassName) } }
|
|
||||||
var competitorCountryCode: String { get { return stringFromCompetitor(forKey: CompetitorKeys.CountryCode) } }
|
|
||||||
var competitorID: String { get { return stringFromCompetitor(forKey: CompetitorKeys.ID) } }
|
|
||||||
var competitorName: String { get { return stringFromCompetitor(forKey: CompetitorKeys.Name) } }
|
|
||||||
var competitorNationality: String { get { return stringFromCompetitor(forKey: CompetitorKeys.Nationality) } }
|
|
||||||
var competitorSailID: String { get { return stringFromCompetitor(forKey: CompetitorKeys.SailID) } }
|
|
||||||
|
|
||||||
// MARK: - Helper
|
|
||||||
|
|
||||||
private func doubleFromEvent(forKey key: String) -> Double { return doubleFromDictionary(eventDictionary, forKey: key) }
|
|
||||||
private func stringFromEvent(forKey key: String) -> String { return stringFromDictionary(eventDictionary, forKey: key) }
|
|
||||||
private func stringFromLeaderboard(forKey key: String) -> String { return stringFromDictionary(leaderboardDictionary, forKey: key) }
|
|
||||||
private func stringFromCompetitor(forKey key: String) -> String { return stringFromDictionary(competitorDictionary, forKey: key) }
|
|
||||||
|
|
||||||
private func doubleFromDictionary(dictionary: [String: AnyObject]?, forKey key: String) -> Double {
|
|
||||||
if let value = dictionary?[key] as? Double {
|
|
||||||
return value
|
|
||||||
} else {
|
|
||||||
return 0.0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func stringFromDictionary(dictionary: [String: AnyObject]?, forKey key: String) -> String {
|
|
||||||
if let value = dictionary?[key] as? String {
|
|
||||||
return value
|
|
||||||
} else {
|
|
||||||
return ""
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,13 @@ import CoreData
|
|||||||
@objc(Competitor)
|
@objc(Competitor)
|
||||||
class Competitor: NSManagedObject {
|
class Competitor: NSManagedObject {
|
||||||
|
|
||||||
// Insert code here to add functionality to your managed object subclass
|
func updateWithCompetitorData(competitorData: CompetitorData) {
|
||||||
|
boatClassName = competitorData.boatClassName
|
||||||
|
competitorID = competitorData.competitorID
|
||||||
|
countryCode = competitorData.countryCode
|
||||||
|
name = competitorData.name
|
||||||
|
nationality = competitorData.nationality
|
||||||
|
sailID = competitorData.sailID
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
//
|
||||||
|
// CompetitorData.swift
|
||||||
|
// SAPTracker
|
||||||
|
//
|
||||||
|
// Created by Raimund Wege on 05.07.16.
|
||||||
|
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class CompetitorData: BaseData {
|
||||||
|
|
||||||
|
private struct Keys {
|
||||||
|
static let BoatClassName = "boatClassName"
|
||||||
|
static let CountryCode = "countryCode"
|
||||||
|
static let ID = "id"
|
||||||
|
static let Name = "name"
|
||||||
|
static let Nationality = "nationality"
|
||||||
|
static let SailID = "sailID"
|
||||||
|
}
|
||||||
|
|
||||||
|
var boatClassName: String { get { return stringValue(forKey: Keys.BoatClassName) } }
|
||||||
|
var countryCode: String { get { return stringValue(forKey: Keys.CountryCode) } }
|
||||||
|
var competitorID: String { get { return stringValue(forKey: Keys.ID) } }
|
||||||
|
var name: String { get { return stringValue(forKey: Keys.Name) } }
|
||||||
|
var nationality: String { get { return stringValue(forKey: Keys.Nationality) } }
|
||||||
|
var sailID: String { get { return stringValue(forKey: Keys.SailID) } }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -35,7 +35,11 @@ class CourseViewController: UIViewController {
|
|||||||
private func subscribeForNotifications() {
|
private func subscribeForNotifications() {
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
name:LocationManager.NotificationType.Updated,
|
||||||
|
object: nil)
|
||||||
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
|
selector:#selector(locationManagerFailed(_:)),
|
||||||
|
name:LocationManager.NotificationType.Failed,
|
||||||
object: nil)
|
object: nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +49,14 @@ class CourseViewController: UIViewController {
|
|||||||
|
|
||||||
func locationManagerUpdated(notification: NSNotification) {
|
func locationManagerUpdated(notification: NSNotification) {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
self.setupCourseLabel(notification.userInfo![LocationManager.UserInfo.Course] as! Double)
|
guard let locationData = notification.userInfo?[LocationManager.UserInfo.LocationData] as? LocationData else { return }
|
||||||
|
self.setupCourseLabel(locationData.location.course)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func locationManagerFailed(notification: NSNotification) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
self.setupCourseLabel(-1.0)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,11 @@ import CoreData
|
|||||||
@objc(Event)
|
@objc(Event)
|
||||||
class Event: NSManagedObject {
|
class Event: NSManagedObject {
|
||||||
|
|
||||||
// Insert code here to add functionality to your managed object subclass
|
func updateWithEventData(eventData: EventData) {
|
||||||
|
endDate = eventData.endDate
|
||||||
|
eventID = eventData.eventID
|
||||||
|
name = eventData.name
|
||||||
|
startDate = eventData.startDate
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,26 @@
|
|||||||
|
//
|
||||||
|
// EventData.swift
|
||||||
|
// SAPTracker
|
||||||
|
//
|
||||||
|
// Created by Raimund Wege on 05.07.16.
|
||||||
|
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class EventData: BaseData {
|
||||||
|
|
||||||
|
private struct Keys {
|
||||||
|
static let EndDate = "endDate"
|
||||||
|
static let ID = "id"
|
||||||
|
static let ImageURLs = "imageURLs"
|
||||||
|
static let Name = "name"
|
||||||
|
static let StartDate = "startDate"
|
||||||
|
}
|
||||||
|
|
||||||
|
var endDate: Double { get { return doubleValue(forKey: Keys.EndDate) / 1000 } }
|
||||||
|
var eventID: String { get { return stringValue(forKey: Keys.ID) } }
|
||||||
|
var name: String { get { return stringValue(forKey: Keys.Name) } }
|
||||||
|
var startDate: Double { get { return doubleValue(forKey: Keys.StartDate) / 1000 } }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -38,12 +38,14 @@ class GPSAccuracyTrackingTableViewCell: UITableViewCell {
|
|||||||
private func subscribeForNotifications() {
|
private func subscribeForNotifications() {
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
name:LocationManager.NotificationType.Updated,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerFailed(_:)),
|
selector:#selector(locationManagerFailed(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerFailed,
|
name:LocationManager.NotificationType.Failed,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unsubscribeFromNotifications() {
|
private func unsubscribeFromNotifications() {
|
||||||
@@ -52,7 +54,8 @@ class GPSAccuracyTrackingTableViewCell: UITableViewCell {
|
|||||||
|
|
||||||
func locationManagerUpdated(notification: NSNotification) {
|
func locationManagerUpdated(notification: NSNotification) {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
self.setupGPSAccuracyLabel(notification.userInfo![LocationManager.UserInfo.HorizontalAccuracy] as! Double)
|
guard let locationData = notification.userInfo?[LocationManager.UserInfo.LocationData] as? LocationData else { return }
|
||||||
|
self.setupGPSAccuracyLabel(locationData.location.horizontalAccuracy)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -58,12 +58,14 @@ class GPSAccuracyView : UIView {
|
|||||||
private func subscribeForNotifications() {
|
private func subscribeForNotifications() {
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
name:LocationManager.NotificationType.Updated,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerFailed(_:)),
|
selector:#selector(locationManagerFailed(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerFailed,
|
name:LocationManager.NotificationType.Failed,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unsubscribeFromNotifications() {
|
private func unsubscribeFromNotifications() {
|
||||||
@@ -72,7 +74,8 @@ class GPSAccuracyView : UIView {
|
|||||||
|
|
||||||
func locationManagerUpdated(notification: NSNotification) {
|
func locationManagerUpdated(notification: NSNotification) {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
self.drawBar(notification.userInfo![LocationManager.UserInfo.HorizontalAccuracy] as! Double)
|
guard let locationData = notification.userInfo?[LocationManager.UserInfo.LocationData] as? LocationData else { return }
|
||||||
|
self.drawBar(locationData.location.horizontalAccuracy)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,12 @@ import CoreData
|
|||||||
@objc(GPSFix)
|
@objc(GPSFix)
|
||||||
class GPSFix: NSManagedObject {
|
class GPSFix: NSManagedObject {
|
||||||
|
|
||||||
// Insert code here to add functionality to your managed object subclass
|
func updateWithLocationData(locationData: LocationData) {
|
||||||
|
course = locationData.location.course
|
||||||
|
latitude = locationData.location.coordinate.latitude
|
||||||
|
longitude = locationData.location.coordinate.longitude
|
||||||
|
speed = locationData.location.speed
|
||||||
|
timestamp = round(locationData.location.timestamp.timeIntervalSince1970 * 1000)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -84,7 +84,7 @@ class HomeViewController: UIViewController {
|
|||||||
let viewTitle = NSLocalizedString("EULA_view", comment: "")
|
let viewTitle = NSLocalizedString("EULA_view", comment: "")
|
||||||
let viewAction = UIAlertAction(title: viewTitle, style: .Cancel, handler: { action in
|
let viewAction = UIAlertAction(title: viewTitle, style: .Cancel, handler: { action in
|
||||||
UIApplication.sharedApplication().openURL(URLs.EULA)
|
UIApplication.sharedApplication().openURL(URLs.EULA)
|
||||||
self.reviewEULA() // Reopen alert
|
self.reviewEULA() // Reopen alert again until user confirms
|
||||||
})
|
})
|
||||||
let confirmTitle = NSLocalizedString("EULA_confirm", comment: "")
|
let confirmTitle = NSLocalizedString("EULA_confirm", comment: "")
|
||||||
let confirmAction = UIAlertAction(title: confirmTitle, style: .Default, handler: { action in
|
let confirmAction = UIAlertAction(title: confirmTitle, style: .Default, handler: { action in
|
||||||
@@ -99,8 +99,8 @@ class HomeViewController: UIViewController {
|
|||||||
func reviewNewCheckIn() {
|
func reviewNewCheckIn() {
|
||||||
guard Preferences.termsAccepted else { return }
|
guard Preferences.termsAccepted else { return }
|
||||||
guard let urlString = Preferences.newCheckInURL else { return }
|
guard let urlString = Preferences.newCheckInURL else { return }
|
||||||
guard let checkInData = CheckInData(urlString: urlString) else { return }
|
guard let regattaData = RegattaData(urlString: urlString) else { return }
|
||||||
checkInController.startCheckIn(checkInData)
|
checkInController.checkIn(regattaData)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Notifications
|
// MARK: - Notifications
|
||||||
@@ -126,21 +126,14 @@ class HomeViewController: UIViewController {
|
|||||||
|
|
||||||
@IBAction func optionButtonTap(sender: AnyObject) {
|
@IBAction func optionButtonTap(sender: AnyObject) {
|
||||||
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
|
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
|
||||||
// FIXME: - what does this code?
|
if let popoverController = alertController.popoverPresentationController {
|
||||||
// if let popoverController = actionSheet.popoverPresentationController,
|
popoverController.barButtonItem = sender as? UIBarButtonItem
|
||||||
// let barButtonItem = sender as? UIBarButtonItem {
|
}
|
||||||
// popoverController.barButtonItem = barButtonItem
|
|
||||||
// }
|
|
||||||
// FIXME: - should be a simpler solution than dispatch with magic numbers
|
|
||||||
let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .Default) { (action) -> Void in
|
let settingsAction = UIAlertAction(title: NSLocalizedString("Settings", comment: ""), style: .Default) { (action) -> Void in
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.6 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
|
self.performSegueWithIdentifier("SettingsFromHome", sender: alertController)
|
||||||
self.performSegueWithIdentifier("SettingsFromHome", sender: alertController)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let aboutAction = UIAlertAction(title: NSLocalizedString("About", comment: ""), style: .Default) { (action) -> Void in
|
let aboutAction = UIAlertAction(title: NSLocalizedString("About", comment: ""), style: .Default) { (action) -> Void in
|
||||||
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, Int64(0.6 * Double(NSEC_PER_SEC))), dispatch_get_main_queue()) { () -> Void in
|
self.performSegueWithIdentifier("AboutFromHome", sender: alertController)
|
||||||
self.performSegueWithIdentifier("AboutFromHome", sender: alertController)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, handler: nil)
|
let cancelAction = UIAlertAction(title: NSLocalizedString("Cancel", comment: ""), style: .Cancel, handler: nil)
|
||||||
alertController.addAction(settingsAction)
|
alertController.addAction(settingsAction)
|
||||||
@@ -159,7 +152,6 @@ class HomeViewController: UIViewController {
|
|||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
|
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
|
||||||
alertController.addAction(cancelAction)
|
alertController.addAction(cancelAction)
|
||||||
presentViewController(alertController, animated: true, completion: nil)
|
presentViewController(alertController, animated: true, completion: nil)
|
||||||
return
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,10 @@ import CoreData
|
|||||||
@objc(Leaderboard)
|
@objc(Leaderboard)
|
||||||
class Leaderboard: NSManagedObject {
|
class Leaderboard: NSManagedObject {
|
||||||
|
|
||||||
|
func updateWithLeaderboardData(leaderboardData: LeaderboardData) {
|
||||||
|
name = leaderboardData.name
|
||||||
|
}
|
||||||
|
|
||||||
func nameWithQueryAllowedCharacters() -> String? {
|
func nameWithQueryAllowedCharacters() -> String? {
|
||||||
return name.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
|
return name.stringByAddingPercentEncodingWithAllowedCharacters(.URLQueryAllowedCharacterSet())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
//
|
||||||
|
// LeaderboardData.swift
|
||||||
|
// SAPTracker
|
||||||
|
//
|
||||||
|
// Created by Raimund Wege on 05.07.16.
|
||||||
|
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
class LeaderboardData: BaseData {
|
||||||
|
|
||||||
|
private struct Keys {
|
||||||
|
static let Name = "name"
|
||||||
|
}
|
||||||
|
|
||||||
|
var name: String { get { return stringValue(forKey: Keys.Name) } }
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,34 @@
|
|||||||
|
//
|
||||||
|
// LocationData.swift
|
||||||
|
// SAPTracker
|
||||||
|
//
|
||||||
|
// Created by Raimund Wege on 06.07.16.
|
||||||
|
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
import CoreLocation
|
||||||
|
|
||||||
|
class LocationData: NSObject {
|
||||||
|
|
||||||
|
struct LocationValidation {
|
||||||
|
static let requiredAccuracy: CLLocationAccuracy = 10
|
||||||
|
static let maxElapsedTime: NSTimeInterval = 10
|
||||||
|
}
|
||||||
|
|
||||||
|
var location: CLLocation
|
||||||
|
|
||||||
|
init(location: CLLocation) {
|
||||||
|
self.location = location
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
var isValid: Bool {
|
||||||
|
get {
|
||||||
|
guard location.horizontalAccuracy >= 0 && location.horizontalAccuracy <= LocationValidation.requiredAccuracy else { return false }
|
||||||
|
guard location.timestamp.timeIntervalSinceDate(NSDate()) <= LocationValidation.maxElapsedTime else { return false }
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -12,10 +12,15 @@ import CoreLocation
|
|||||||
class LocationManager: NSObject {
|
class LocationManager: NSObject {
|
||||||
|
|
||||||
struct NotificationType {
|
struct NotificationType {
|
||||||
static let LocationManagerStarted = "LocationManagerStarted"
|
static let Started = "LocationManager.Started"
|
||||||
static let LocationManagerStopped = "LocationManagerStopped"
|
static let Stopped = "LocationManager.Stopped"
|
||||||
static let LocationManagerUpdated = "LocationManagerUpdated"
|
static let Updated = "LocationManager.Updated"
|
||||||
static let LocationManagerFailed = "LocationManagerFailed"
|
static let Failed = "LocationManager.Failed"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UserInfo {
|
||||||
|
static let Error = "NSError"
|
||||||
|
static let LocationData = "LocationData"
|
||||||
}
|
}
|
||||||
|
|
||||||
enum LocationManagerError: ErrorType {
|
enum LocationManagerError: ErrorType {
|
||||||
@@ -23,8 +28,8 @@ class LocationManager: NSObject {
|
|||||||
case LocationServicesDenied
|
case LocationServicesDenied
|
||||||
var description: String {
|
var description: String {
|
||||||
switch self {
|
switch self {
|
||||||
case LocationManagerError.LocationServicesDenied: return NSLocalizedString("Please enable location services for this app.", comment: "")
|
case .LocationServicesDenied: return NSLocalizedString("Please enable location services for this app.", comment: "")
|
||||||
case LocationManagerError.LocationServicesDisabled: return NSLocalizedString("Please enable location services.", comment: "")
|
case .LocationServicesDisabled: return NSLocalizedString("Please enable location services.", comment: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -74,7 +79,7 @@ class LocationManager: NSObject {
|
|||||||
isTracking = true;
|
isTracking = true;
|
||||||
|
|
||||||
// Send notification
|
// Send notification
|
||||||
let notification = NSNotification(name: NotificationType.LocationManagerStarted, object: self)
|
let notification = NSNotification(name: NotificationType.Started, object: self)
|
||||||
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -86,7 +91,7 @@ class LocationManager: NSObject {
|
|||||||
isTracking = false;
|
isTracking = false;
|
||||||
|
|
||||||
// Send notification
|
// Send notification
|
||||||
let notification = NSNotification(name: NotificationType.LocationManagerStopped, object: self)
|
let notification = NSNotification(name: NotificationType.Stopped, object: self)
|
||||||
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -95,51 +100,19 @@ class LocationManager: NSObject {
|
|||||||
// MARK: - CLLocationManagerDelegate
|
// MARK: - CLLocationManagerDelegate
|
||||||
|
|
||||||
extension LocationManager: CLLocationManagerDelegate {
|
extension LocationManager: CLLocationManagerDelegate {
|
||||||
|
|
||||||
struct UserInfo {
|
|
||||||
static let Error = "error"
|
|
||||||
static let Course = "course"
|
|
||||||
static let HorizontalAccuracy = "horizontalAccuracy"
|
|
||||||
static let IsValid = "isValid"
|
|
||||||
static let Latitude = "latitude"
|
|
||||||
static let Longitude = "longitude"
|
|
||||||
static let Speed = "speed"
|
|
||||||
static let Timestamp = "timestamp"
|
|
||||||
}
|
|
||||||
|
|
||||||
struct LocationValidation {
|
|
||||||
static let requiredAccuracy: CLLocationAccuracy = 10
|
|
||||||
static let maxElapsedTime: NSTimeInterval = 10
|
|
||||||
}
|
|
||||||
|
|
||||||
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
|
||||||
let notification = NSNotification(name: NotificationType.LocationManagerUpdated, object: self, userInfo:dictionaryForLocation(locations.last!))
|
guard let location = locations.last else { return }
|
||||||
|
let locationData = LocationData(location: location)
|
||||||
|
let userInfo = [UserInfo.LocationData: locationData]
|
||||||
|
let notification = NSNotification(name: NotificationType.Updated, object: self, userInfo: userInfo)
|
||||||
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
||||||
}
|
}
|
||||||
|
|
||||||
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
|
func locationManager(manager: CLLocationManager, didFailWithError error: NSError) {
|
||||||
let notification = NSNotification(name: NotificationType.LocationManagerFailed, object: self, userInfo: [UserInfo.Error: error])
|
let userInfo = [UserInfo.Error: error]
|
||||||
|
let notification = NSNotification(name: NotificationType.Failed, object: self, userInfo: userInfo)
|
||||||
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
NSNotificationQueue.defaultQueue().enqueueNotification(notification, postingStyle: NSPostingStyle.PostASAP)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Helper
|
|
||||||
|
|
||||||
private func dictionaryForLocation(location: CLLocation) -> [String: AnyObject] {
|
|
||||||
return [
|
|
||||||
UserInfo.Timestamp: location.timestamp.timeIntervalSince1970,
|
|
||||||
UserInfo.Latitude : location.coordinate.latitude,
|
|
||||||
UserInfo.Longitude: location.coordinate.longitude,
|
|
||||||
UserInfo.Speed: location.speed,
|
|
||||||
UserInfo.Course: location.course,
|
|
||||||
UserInfo.HorizontalAccuracy: location.horizontalAccuracy,
|
|
||||||
UserInfo.IsValid: isLocationValid(location)
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
private func isLocationValid(location: CLLocation) -> Bool {
|
|
||||||
guard location.horizontalAccuracy >= 0 && location.horizontalAccuracy <= LocationValidation.requiredAccuracy else { return false }
|
|
||||||
guard location.timestamp.timeIntervalSinceDate(NSDate()) <= LocationValidation.maxElapsedTime else { return false }
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -14,48 +14,39 @@ class ModeTrackingTableViewCell: UITableViewCell {
|
|||||||
|
|
||||||
override func awakeFromNib() {
|
override func awakeFromNib() {
|
||||||
super.awakeFromNib()
|
super.awakeFromNib()
|
||||||
self.setupModeLabel()
|
self.setupModeLabel(RegattaController.Mode.Offline)
|
||||||
// self.subscribeForNotifications()
|
self.subscribeForNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
deinit {
|
deinit {
|
||||||
// self.unsubscribeFromNotifications()
|
self.unsubscribeFromNotifications()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Setups
|
// MARK: - Setups
|
||||||
|
|
||||||
private func setupModeLabel() {
|
private func setupModeLabel(mode: RegattaController.Mode) {
|
||||||
// FIXME: - network availability
|
modeLabel.text = mode.description
|
||||||
//if (APIManager.sharedManager.networkAvailable) {
|
|
||||||
if !BatteryManager.sharedManager.batterySaving {
|
|
||||||
modeLabel.text = NSLocalizedString("Online", comment: "")
|
|
||||||
} else {
|
|
||||||
modeLabel.text = NSLocalizedString("Battery Saving", comment: "")
|
|
||||||
}
|
|
||||||
//} else {
|
|
||||||
// modeLabel.text = NSLocalizedString("Offline", comment: "")
|
|
||||||
//}
|
|
||||||
// FIXME: - Show "API Error" in red in case of response errors
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Notifications
|
// MARK: - Notifications
|
||||||
|
|
||||||
// FIXME: - Network availability
|
private func subscribeForNotifications() {
|
||||||
// private func subscribeForNotifications() {
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
// NSNotificationCenter.defaultCenter().addObserver(self,
|
selector:#selector(regattaControllerModeChanged),
|
||||||
// selector:#selector(networkAvailabilityChanged),
|
name:RegattaController.NotificationType.ModeChanged,
|
||||||
// name:APIManager.NotificationType.networkAvailabilityChanged,
|
object: nil
|
||||||
// object: nil)
|
)
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// private func unsubscribeFromNotifications() {
|
private func unsubscribeFromNotifications() {
|
||||||
// NSNotificationCenter.defaultCenter().removeObserver(self)
|
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// func networkAvailabilityChanged(notification: NSNotification) {
|
func regattaControllerModeChanged(notification: NSNotification) {
|
||||||
// dispatch_async(dispatch_get_main_queue(), {
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
// self.setupModeLabel()
|
guard let mode = notification.userInfo?[RegattaController.UserInfo.Mode] as? RegattaController.Mode else { return }
|
||||||
// })
|
self.setupModeLabel(mode)
|
||||||
// }
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -12,6 +12,12 @@ import CoreData
|
|||||||
@objc(Regatta)
|
@objc(Regatta)
|
||||||
class Regatta: NSManagedObject {
|
class Regatta: NSManagedObject {
|
||||||
|
|
||||||
|
func updateWirhRegattaData(regattaData: RegattaData) {
|
||||||
|
serverURL = regattaData.serverURL
|
||||||
|
teamImageURL = regattaData.teamImageURL
|
||||||
|
teamImageRetry = false
|
||||||
|
}
|
||||||
|
|
||||||
func eventURL() -> NSURL? {
|
func eventURL() -> NSURL? {
|
||||||
return NSURL(string: "\(serverURL)/gwt/Home.html?navigationTab=Regattas#EventPlace:eventId=\(event.eventID)")
|
return NSURL(string: "\(serverURL)/gwt/Home.html?navigationTab=Regattas#EventPlace:eventId=\(event.eventID)")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,202 @@
|
|||||||
|
//
|
||||||
|
// RegattaController.swift
|
||||||
|
// SAPTracker
|
||||||
|
//
|
||||||
|
// Created by Raimund Wege on 05.07.16.
|
||||||
|
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
@objc protocol RegattaControllerDelegate {
|
||||||
|
|
||||||
|
func showRegattaAlert(regattaController: RegattaController, alertController: UIAlertController)
|
||||||
|
|
||||||
|
optional func regattaControllerDidUpdate(regattaController: RegattaController)
|
||||||
|
|
||||||
|
// optional func checkInDidStart(checkInController: CheckInController)
|
||||||
|
// optional func checkInDidEnd(checkInController: CheckInController, withSuccess succeed: Bool)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class RegattaController: NSObject {
|
||||||
|
|
||||||
|
struct NotificationType {
|
||||||
|
static let ModeChanged = "RegattaController.ModeChanged"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct UserInfo {
|
||||||
|
static let Mode = "Mode"
|
||||||
|
}
|
||||||
|
|
||||||
|
enum Mode: String {
|
||||||
|
case BatterySaving = "Battery Saving"
|
||||||
|
case Error = "Error"
|
||||||
|
case Online = "Online"
|
||||||
|
case Offline = "Offline"
|
||||||
|
var description: String {
|
||||||
|
switch self {
|
||||||
|
case .BatterySaving: return NSLocalizedString("Battery Saving", comment: "")
|
||||||
|
case .Error: return NSLocalizedString("Error", comment: "")
|
||||||
|
case .Offline: return NSLocalizedString("Offline", comment: "")
|
||||||
|
case .Online: return NSLocalizedString("Online", comment: "")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private struct SendingInterval {
|
||||||
|
static let Normal: NSTimeInterval = 3
|
||||||
|
static let BatterySaving: NSTimeInterval = 30
|
||||||
|
}
|
||||||
|
|
||||||
|
let regatta: Regatta
|
||||||
|
|
||||||
|
var delegate: RegattaControllerDelegate?
|
||||||
|
|
||||||
|
private (set) var isTracking: Bool = false
|
||||||
|
|
||||||
|
init(regatta: Regatta) {
|
||||||
|
self.regatta = regatta
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Notifications
|
||||||
|
|
||||||
|
private func subscribeForNotifications() {
|
||||||
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
|
name:LocationManager.NotificationType.Updated,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func unsubscribeFromNotifications() {
|
||||||
|
NSNotificationCenter.defaultCenter().removeObserver(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
func locationManagerUpdated(notification: NSNotification) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
guard self.isTracking else { return }
|
||||||
|
guard let locationData = notification.userInfo?[LocationManager.UserInfo.LocationData] as? LocationData else { return }
|
||||||
|
guard locationData.isValid else { return }
|
||||||
|
let gpsFix = CoreDataManager.sharedManager.newGPSFix(self.regatta)
|
||||||
|
gpsFix.updateWithLocationData(locationData)
|
||||||
|
CoreDataManager.sharedManager.saveContext()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Update
|
||||||
|
|
||||||
|
func update() {
|
||||||
|
SVProgressHUD.show()
|
||||||
|
let regattaData = RegattaData(serverURL: regatta.serverURL,
|
||||||
|
eventID: regatta.event.eventID,
|
||||||
|
leaderboardName: regatta.leaderboard.name,
|
||||||
|
competitorID: regatta.competitor.competitorID
|
||||||
|
)
|
||||||
|
requestManager.getRegattaData(regattaData,
|
||||||
|
success: { (regattaData) in self.updateSuccess(regattaData) },
|
||||||
|
failure: { (title, error) in self.updateFailure() }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateSuccess(regattaData: RegattaData) {
|
||||||
|
regatta.event.updateWithEventData(regattaData.eventData)
|
||||||
|
regatta.leaderboard.updateWithLeaderboardData(regattaData.leaderboardData)
|
||||||
|
regatta.competitor.updateWithCompetitorData(regattaData.competitorData)
|
||||||
|
CoreDataManager.sharedManager.saveContext()
|
||||||
|
SVProgressHUD.popActivity()
|
||||||
|
updateFinished()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateFailure() {
|
||||||
|
updateFinished()
|
||||||
|
}
|
||||||
|
|
||||||
|
func updateFinished() {
|
||||||
|
SVProgressHUD.popActivity()
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Methods
|
||||||
|
|
||||||
|
func startTracking() -> Bool {
|
||||||
|
isTracking = false
|
||||||
|
do {
|
||||||
|
try LocationManager.sharedManager.startTracking()
|
||||||
|
isTracking = true
|
||||||
|
} catch let error as LocationManager.LocationManagerError {
|
||||||
|
let alertController = UIAlertController(title: error.description, message: nil, preferredStyle: .Alert)
|
||||||
|
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
||||||
|
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
delegate?.showRegattaAlert(self, alertController: alertController)
|
||||||
|
} catch {
|
||||||
|
print("Unknown error")
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
isTracking = true
|
||||||
|
sendGPSFixes()
|
||||||
|
return isTracking
|
||||||
|
}
|
||||||
|
|
||||||
|
func stopTracking() {
|
||||||
|
isTracking = false
|
||||||
|
}
|
||||||
|
|
||||||
|
func sendGPSFixes() {
|
||||||
|
var gpsFixes = [GPSFix]()
|
||||||
|
if regatta.gpsFixes != nil {
|
||||||
|
regatta.gpsFixes!.forEach { (gpsFix) in gpsFixes.append(gpsFix as! GPSFix) }
|
||||||
|
}
|
||||||
|
if gpsFixes.count > 0 {
|
||||||
|
print("\(gpsFixes.count) GPS fixes will be sent")
|
||||||
|
requestManager.postGPSFixes(gpsFixes,
|
||||||
|
success: { (operation, responseObject) in self.sendGPSFixesSuccess(gpsFixes) },
|
||||||
|
failure: { (operation, error) in self.sendGPSFixesFailure(error) })
|
||||||
|
} else {
|
||||||
|
print("No GPS fixes available")
|
||||||
|
sendGPSFixesFinished()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private func sendGPSFixesSuccess(gpsFixes: [GPSFix]!) {
|
||||||
|
print(NSThread.isMainThread)
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
print("sending \(gpsFixes.count) GPS fixes was successful")
|
||||||
|
CoreDataManager.sharedManager.deleteGPSFixes(gpsFixes)
|
||||||
|
CoreDataManager.sharedManager.saveContext()
|
||||||
|
self.sendGPSFixesFinished()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func sendGPSFixesFailure(error: AnyObject) {
|
||||||
|
print(NSThread.isMainThread)
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
print("sending GPS fixes failed for reason: \(error)")
|
||||||
|
self.sendGPSFixesFinished()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
private func sendGPSFixesFinished() {
|
||||||
|
if isTracking {
|
||||||
|
let delay = sendingPeriod
|
||||||
|
print("sending next GPS fixes in \(delay) seconds")
|
||||||
|
performSelector(#selector(RegattaController.sendGPSFixes), withObject: nil, afterDelay: delay)
|
||||||
|
} else {
|
||||||
|
print("sending GPS fixes stopped")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Helper
|
||||||
|
|
||||||
|
var sendingPeriod: NSTimeInterval { get { return BatteryManager.sharedManager.batterySaving ? SendingInterval.BatterySaving : SendingInterval.Normal } }
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
lazy var requestManager: RequestManager = {
|
||||||
|
let requestManager = RequestManager(baseURLString: self.regatta.serverURL)
|
||||||
|
return requestManager
|
||||||
|
}()
|
||||||
|
|
||||||
|
}
|
||||||
+46
-14
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// CheckInData.swift
|
// RegattaData.swift
|
||||||
// SAPTracker
|
// SAPTracker
|
||||||
//
|
//
|
||||||
// Created by Raimund Wege on 25.05.16.
|
// Created by Raimund Wege on 25.05.16.
|
||||||
@@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
public class CheckInData: NSObject {
|
public class RegattaData: NSObject {
|
||||||
|
|
||||||
private struct ItemNames {
|
private struct ItemNames {
|
||||||
static let EventID = "event_id"
|
static let EventID = "event_id"
|
||||||
@@ -16,15 +16,28 @@ public class CheckInData: NSObject {
|
|||||||
static let CompetitorID = "competitor_id"
|
static let CompetitorID = "competitor_id"
|
||||||
}
|
}
|
||||||
|
|
||||||
public let serverURL: String
|
let serverURL: String
|
||||||
public let eventID: String
|
let eventID: String
|
||||||
public let leaderboardName: String
|
let leaderboardName: String
|
||||||
public let competitorID: String
|
let competitorID: String
|
||||||
|
|
||||||
init(serverURL: String = "",
|
var eventData = EventData()
|
||||||
eventID: String = "",
|
var leaderboardData = LeaderboardData()
|
||||||
leaderboardName: String = "",
|
var competitorData = CompetitorData()
|
||||||
competitorID: String = "")
|
var teamImageURL: String?
|
||||||
|
|
||||||
|
override init() {
|
||||||
|
serverURL = ""
|
||||||
|
eventID = ""
|
||||||
|
leaderboardName = ""
|
||||||
|
competitorID = ""
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
init(serverURL: String,
|
||||||
|
eventID: String,
|
||||||
|
leaderboardName: String,
|
||||||
|
competitorID: String)
|
||||||
{
|
{
|
||||||
self.serverURL = serverURL
|
self.serverURL = serverURL
|
||||||
self.eventID = eventID
|
self.eventID = eventID
|
||||||
@@ -33,6 +46,14 @@ public class CheckInData: NSObject {
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
init(regatta: Regatta) {
|
||||||
|
serverURL = regatta.serverURL
|
||||||
|
eventID = regatta.event.eventID
|
||||||
|
competitorID = regatta.competitor.competitorID
|
||||||
|
leaderboardName = regatta.leaderboard.name
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
convenience init?(url: NSURL) {
|
convenience init?(url: NSURL) {
|
||||||
guard let host = url.host else { return nil }
|
guard let host = url.host else { return nil }
|
||||||
guard let components = NSURLComponents(string: url.absoluteString) else { return nil }
|
guard let components = NSURLComponents(string: url.absoluteString) else { return nil }
|
||||||
@@ -45,9 +66,9 @@ public class CheckInData: NSObject {
|
|||||||
let queryItems = components.queryItems
|
let queryItems = components.queryItems
|
||||||
|
|
||||||
// Get check-in items
|
// Get check-in items
|
||||||
guard let eventID = CheckInData.queryItemValue(queryItems, itemName: CheckInData.ItemNames.EventID) else { return nil }
|
guard let eventID = RegattaData.queryItemValue(queryItems, itemName: ItemNames.EventID) else { return nil }
|
||||||
guard let leaderboardName = CheckInData.queryItemValue(queryItems, itemName: CheckInData.ItemNames.LeaderboardName) else { return nil }
|
guard let leaderboardName = RegattaData.queryItemValue(queryItems, itemName: ItemNames.LeaderboardName) else { return nil }
|
||||||
guard let competitorID = CheckInData.queryItemValue(queryItems, itemName: CheckInData.ItemNames.CompetitorID) else { return nil }
|
guard let competitorID = RegattaData.queryItemValue(queryItems, itemName: ItemNames.CompetitorID) else { return nil }
|
||||||
|
|
||||||
// Init with values
|
// Init with values
|
||||||
self.init(serverURL: serverURL,
|
self.init(serverURL: serverURL,
|
||||||
@@ -63,9 +84,20 @@ public class CheckInData: NSObject {
|
|||||||
self.init(url: url)
|
self.init(url: url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Properties
|
||||||
|
|
||||||
|
var welcomeString: String {
|
||||||
|
get {
|
||||||
|
return String(format:NSLocalizedString("Hello %@. Welcome to %@. You are registered as %@.", comment: ""),
|
||||||
|
competitorData.name,
|
||||||
|
leaderboardData.name,
|
||||||
|
competitorData.sailID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Helper
|
// MARK: - Helper
|
||||||
|
|
||||||
private class func queryItemValue(queryItems: [NSURLQueryItem]?, itemName: String) -> String? {
|
class private func queryItemValue(queryItems: [NSURLQueryItem]?, itemName: String) -> String? {
|
||||||
return queryItems?.filter({(item) -> Bool in item.name == itemName}).first?.value
|
return queryItems?.filter({(item) -> Bool in item.name == itemName}).first?.value
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -7,8 +7,6 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
import CoreLocation
|
|
||||||
import Darwin
|
|
||||||
|
|
||||||
class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
||||||
|
|
||||||
@@ -51,6 +49,9 @@ class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
|||||||
setupNavigationBar()
|
setupNavigationBar()
|
||||||
setupImageSourceTypes()
|
setupImageSourceTypes()
|
||||||
setupTeamImage()
|
setupTeamImage()
|
||||||
|
|
||||||
|
// Test
|
||||||
|
regattaController.update()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Setups
|
// MARK: - Setups
|
||||||
@@ -73,7 +74,8 @@ class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
|||||||
target: self,
|
target: self,
|
||||||
selector: #selector(RegattaViewController.refreshCountdown),
|
selector: #selector(RegattaViewController.refreshCountdown),
|
||||||
userInfo: nil,
|
userInfo: nil,
|
||||||
repeats: true)
|
repeats: true
|
||||||
|
)
|
||||||
refreshCountdown()
|
refreshCountdown()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,6 +187,9 @@ class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
|||||||
|
|
||||||
@IBAction func showMenuActionSheet(sender: AnyObject) {
|
@IBAction func showMenuActionSheet(sender: AnyObject) {
|
||||||
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
|
let alertController = UIAlertController(title: nil, message: nil, preferredStyle: .ActionSheet)
|
||||||
|
if let popoverController = alertController.popoverPresentationController {
|
||||||
|
popoverController.barButtonItem = sender as? UIBarButtonItem
|
||||||
|
}
|
||||||
let checkOutTitle = NSLocalizedString("Check-Out", comment: "")
|
let checkOutTitle = NSLocalizedString("Check-Out", comment: "")
|
||||||
let checkOutAction = UIAlertAction(title: checkOutTitle, style: .Default) { (action) in
|
let checkOutAction = UIAlertAction(title: checkOutTitle, style: .Default) { (action) in
|
||||||
self.showCheckOutAlertController()
|
self.showCheckOutAlertController()
|
||||||
@@ -207,21 +212,35 @@ class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@IBAction func startTrackingButtonTapped(sender: AnyObject) {
|
@IBAction func startTrackingButtonTapped(sender: AnyObject) {
|
||||||
do {
|
if regattaController.startTracking() {
|
||||||
try LocationManager.sharedManager.startTracking()
|
|
||||||
performSegueWithIdentifier("Tracking", sender: sender)
|
performSegueWithIdentifier("Tracking", sender: sender)
|
||||||
} catch let error as LocationManager.LocationManagerError {
|
|
||||||
let alertController = UIAlertController(title: error.description, message: nil, preferredStyle: .Alert)
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
|
|
||||||
alertController.addAction(cancelAction)
|
|
||||||
presentViewController(alertController, animated: true, completion: nil)
|
|
||||||
} catch {
|
|
||||||
print("Unknown error")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Image picker
|
// MARK: - Alerts
|
||||||
|
|
||||||
|
private func showCheckOutAlertController() {
|
||||||
|
let alertTitle = NSLocalizedString("Check-out of Regatta?", comment: "")
|
||||||
|
let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .Alert)
|
||||||
|
let okTitle = NSLocalizedString("OK", comment: "")
|
||||||
|
let okAction = UIAlertAction(title: okTitle, style: .Default) { (action) in self.preformCheckOut() }
|
||||||
|
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
||||||
|
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
|
||||||
|
alertController.addAction(okAction)
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
presentViewController(alertController, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
private func preformCheckOut() {
|
||||||
|
requestManager.postCheckOut(regatta.leaderboard.name,
|
||||||
|
competitorId: regatta.competitor.competitorID,
|
||||||
|
success: { (operation, responseObject) in },
|
||||||
|
failure: { (operation, error) in
|
||||||
|
})
|
||||||
|
CoreDataManager.sharedManager.deleteRegatta(regatta)
|
||||||
|
CoreDataManager.sharedManager.saveContext()
|
||||||
|
navigationController!.popViewControllerAnimated(true)
|
||||||
|
}
|
||||||
|
|
||||||
func showImageAlertController() {
|
func showImageAlertController() {
|
||||||
if sourceTypes.count == 1 {
|
if sourceTypes.count == 1 {
|
||||||
@@ -245,41 +264,22 @@ class RegattaViewController : UIViewController, UINavigationControllerDelegate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Check-out
|
|
||||||
|
|
||||||
func showCheckOutAlertController() {
|
|
||||||
let alertTitle = NSLocalizedString("Check-out of Regatta?", comment: "")
|
|
||||||
let alertController = UIAlertController(title: alertTitle, message: nil, preferredStyle: .Alert)
|
|
||||||
let okTitle = NSLocalizedString("OK", comment: "")
|
|
||||||
let okAction = UIAlertAction(title: okTitle, style: .Default) { (action) in self.preformCheckOut() }
|
|
||||||
let cancelTitle = NSLocalizedString("Cancel", comment: "")
|
|
||||||
let cancelAction = UIAlertAction(title: cancelTitle, style: .Cancel, handler: nil)
|
|
||||||
alertController.addAction(okAction)
|
|
||||||
alertController.addAction(cancelAction)
|
|
||||||
presentViewController(alertController, animated: true, completion: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
func preformCheckOut() {
|
|
||||||
requestManager.postCheckOut(regatta.leaderboard.name,
|
|
||||||
competitorId: regatta.competitor.competitorID,
|
|
||||||
success: { (operation, responseObject) in },
|
|
||||||
failure: { (operation, error) in
|
|
||||||
})
|
|
||||||
CoreDataManager.sharedManager.deleteRegatta(regatta!)
|
|
||||||
CoreDataManager.sharedManager.saveContext()
|
|
||||||
navigationController!.popViewControllerAnimated(true)
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Segue
|
// MARK: - Segue
|
||||||
|
|
||||||
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
|
||||||
if (segue.identifier == "Tracking") {
|
if (segue.identifier == "Tracking") {
|
||||||
let nc = segue.destinationViewController as! UINavigationController
|
let trackingNC = segue.destinationViewController as! UINavigationController
|
||||||
let vc = nc.viewControllers[0] as! TrackingViewController
|
let trackingVC = trackingNC.viewControllers[0] as! TrackingViewController
|
||||||
vc.regatta = regatta
|
trackingVC.regatta = regatta
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
lazy var regattaController: RegattaController = {
|
||||||
|
return RegattaController(regatta: self.regatta)
|
||||||
|
}()
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - UIImagePickerControllerDelegate
|
// MARK: - UIImagePickerControllerDelegate
|
||||||
@@ -344,4 +344,14 @@ extension RegattaViewController: UIImagePickerControllerDelegate {
|
|||||||
setupTeamImage()
|
setupTeamImage()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - RegattaControllerDelegate
|
||||||
|
|
||||||
|
extension RegattaViewController: RegattaControllerDelegate {
|
||||||
|
|
||||||
|
func showRegattaAlert(regattaController: RegattaController, alertController: UIAlertController) {
|
||||||
|
presentViewController(alertController, animated: true, completion: nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -10,7 +10,7 @@
|
|||||||
import UIKit
|
import UIKit
|
||||||
|
|
||||||
class RequestManager: NSObject {
|
class RequestManager: NSObject {
|
||||||
|
|
||||||
private let basePathString = "/sailingserver/api/v1"
|
private let basePathString = "/sailingserver/api/v1"
|
||||||
|
|
||||||
private enum BodyKeys {
|
private enum BodyKeys {
|
||||||
@@ -50,37 +50,142 @@ class RequestManager: NSObject {
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Regatta
|
||||||
|
|
||||||
|
func getRegattaData(regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
getEventData(regattaData, success: success, failure: failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEventData(regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
getEvent(regattaData.eventID,
|
||||||
|
success: { (data) in self.getEventDataSuccess(data, regattaData: regattaData, success: success, failure: failure) },
|
||||||
|
failure: { (title, error) in failure(title, error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEventDataSuccess(eventData: EventData,
|
||||||
|
regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
regattaData.eventData = eventData
|
||||||
|
getLeaderboardData(regattaData, success: success, failure: failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLeaderboardData(regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
getLeaderboard(regattaData.leaderboardName,
|
||||||
|
success: { (data) in self.getLeaderboardDataSuccess(data, regattaData: regattaData, success: success, failure: failure) },
|
||||||
|
failure: { (title, error) in failure(title, error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLeaderboardDataSuccess(leaderboardData: LeaderboardData,
|
||||||
|
regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
regattaData.leaderboardData = leaderboardData
|
||||||
|
getCompetitorData(regattaData, success: success, failure: failure)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCompetitorData(regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
getCompetitor(regattaData.competitorID,
|
||||||
|
success: { (data) in self.getCompetitorDataSuccess(data, regattaData: regattaData, success: success, failure: failure) },
|
||||||
|
failure: { (title, error) in failure(title, error) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCompetitorDataSuccess(competitorData: CompetitorData,
|
||||||
|
regattaData: RegattaData,
|
||||||
|
success: (RegattaData) -> Void,
|
||||||
|
failure: (String, NSError) -> Void)
|
||||||
|
{
|
||||||
|
regattaData.competitorData = competitorData
|
||||||
|
getTeamImageURL(regattaData.competitorID, result: { (imageURL) in
|
||||||
|
regattaData.teamImageURL = imageURL
|
||||||
|
success(regattaData)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: - Event
|
// MARK: - Event
|
||||||
|
|
||||||
func getEvent(eventID: String!,
|
func getEvent(eventID: String,
|
||||||
success: (AFHTTPRequestOperation!, AnyObject!) -> Void,
|
success: (EventData) -> Void,
|
||||||
failure: (AFHTTPRequestOperation!, AnyObject!) -> Void)
|
failure: (String, NSError) -> Void)
|
||||||
{
|
{
|
||||||
let encodedEventID = eventID.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) ?? ""
|
let encodedEventID = eventID.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet()) ?? ""
|
||||||
let urlString = "\(basePathString)/events/\(encodedEventID)"
|
let urlString = "\(basePathString)/events/\(encodedEventID)"
|
||||||
manager.GET(urlString, parameters: nil, success: success, failure: failure)
|
manager.GET(urlString,
|
||||||
|
parameters: nil,
|
||||||
|
success: { (requestOperation, responseObject) in self.getEventSuccess(responseObject, success: success) },
|
||||||
|
failure: { (requestOperation, error) in self.getEventFailure(eventID, error: error, failure: failure) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEventSuccess(responseObject: AnyObject, success: (EventData) -> Void) {
|
||||||
|
success(EventData(dictionary: responseObject as? [String: AnyObject]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getEventFailure(eventID: String, error: NSError, failure: (String, NSError) -> Void) -> Void {
|
||||||
|
failure(String(format: NSLocalizedString("Couldn't get event %@", comment: ""), eventID), error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Leaderboard
|
// MARK: - Leaderboard
|
||||||
|
|
||||||
func getLeaderboard(leaderboardName: String!,
|
func getLeaderboard(leaderboardName: String,
|
||||||
success: (AFHTTPRequestOperation!, AnyObject!) -> Void,
|
success: (LeaderboardData) -> Void,
|
||||||
failure: (AFHTTPRequestOperation!, AnyObject!) -> Void)
|
failure: (String, NSError) -> Void)
|
||||||
{
|
{
|
||||||
let encodedLeaderboardName = leaderboardName.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) ?? ""
|
let encodedLeaderboardName = leaderboardName.stringByAddingPercentEncodingWithAllowedCharacters(.URLPathAllowedCharacterSet()) ?? ""
|
||||||
let urlString = "\(basePathString)/leaderboards/\(encodedLeaderboardName)"
|
let urlString = "\(basePathString)/leaderboards/\(encodedLeaderboardName)"
|
||||||
manager.GET(urlString, parameters: nil, success: success, failure: failure)
|
manager.GET(urlString,
|
||||||
|
parameters: nil,
|
||||||
|
success: { (requestOperation, responseObject) in self.getLeaderboardSuccess(responseObject, success: success) },
|
||||||
|
failure: { (requestOperation, error) in self.getLeaderboardFailure(leaderboardName, error: error, failure: failure) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLeaderboardSuccess(responseObject: AnyObject, success: (LeaderboardData) -> Void) {
|
||||||
|
success(LeaderboardData(dictionary: responseObject as? [String: AnyObject]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getLeaderboardFailure(leaderboardName: String, error: NSError, failure: (String, NSError) -> Void) {
|
||||||
|
failure(String(format: NSLocalizedString("Couldn't get leader board %@", comment: ""), leaderboardName), error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Competitor
|
// MARK: - Competitor
|
||||||
|
|
||||||
func getCompetitor(competitorID: String!,
|
func getCompetitor(competitorID: String,
|
||||||
success: (AFHTTPRequestOperation!, AnyObject!) -> Void,
|
success: (CompetitorData) -> Void,
|
||||||
failure: (AFHTTPRequestOperation!, AnyObject!) -> Void)
|
failure: (String, NSError) -> Void)
|
||||||
{
|
{
|
||||||
let encodedCompetitorID = competitorID.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) ?? ""
|
let encodedCompetitorID = competitorID.stringByAddingPercentEncodingWithAllowedCharacters(NSCharacterSet.URLPathAllowedCharacterSet()) ?? ""
|
||||||
let urlString = "\(basePathString)/competitors/\(encodedCompetitorID)"
|
let urlString = "\(basePathString)/competitors/\(encodedCompetitorID)"
|
||||||
manager.GET(urlString, parameters: nil, success: success, failure: failure)
|
manager.GET(urlString,
|
||||||
|
parameters: nil,
|
||||||
|
success: { (requestOperation, responseObject) in self.getCompetitorSuccess(responseObject, success: success) },
|
||||||
|
failure: { (requestOperation, error) in self.getCompetitorFailure(competitorID, error: error, failure: failure) }
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCompetitorSuccess(responseObject: AnyObject, success: (CompetitorData) -> Void) {
|
||||||
|
success(CompetitorData(dictionary: responseObject as? [String: AnyObject]))
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCompetitorFailure(competitorID: String, error: NSError, failure: (String, NSError) -> Void) {
|
||||||
|
failure(String(format: NSLocalizedString("Couldn't get competitor %@", comment: ""), competitorID), error)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Team
|
// MARK: - Team
|
||||||
|
|||||||
@@ -14,15 +14,12 @@ class ScanViewController: UIViewController {
|
|||||||
@IBOutlet weak var previewView: UIView!
|
@IBOutlet weak var previewView: UIView!
|
||||||
@IBOutlet weak var targetImageView: UIImageView!
|
@IBOutlet weak var targetImageView: UIImageView!
|
||||||
|
|
||||||
private let checkInController = CheckInController()
|
|
||||||
|
|
||||||
private var session: AVCaptureSession!
|
private var session: AVCaptureSession!
|
||||||
private var output: AVCaptureMetadataOutput!
|
private var output: AVCaptureMetadataOutput!
|
||||||
private var previewLayer: AVCaptureVideoPreviewLayer!
|
private var previewLayer: AVCaptureVideoPreviewLayer!
|
||||||
|
|
||||||
override func viewDidLoad() {
|
override func viewDidLoad() {
|
||||||
super.viewDidLoad()
|
super.viewDidLoad()
|
||||||
setupCheckInController()
|
|
||||||
setupSession()
|
setupSession()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -31,12 +28,20 @@ class ScanViewController: UIViewController {
|
|||||||
startScanning()
|
startScanning()
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Setups
|
override func viewDidLayoutSubviews() {
|
||||||
|
super.viewDidLayoutSubviews()
|
||||||
private func setupCheckInController() {
|
layoutPreviewLayer()
|
||||||
checkInController.delegate = self
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Layouts
|
||||||
|
|
||||||
|
private func layoutPreviewLayer() {
|
||||||
|
previewLayer.frame = previewView.bounds
|
||||||
|
previewLayer.position = CGPointMake(CGRectGetMidX(previewView.bounds), CGRectGetMidY(previewView.bounds))
|
||||||
|
}
|
||||||
|
|
||||||
|
// MARK: - Setups
|
||||||
|
|
||||||
private func setupSession() {
|
private func setupSession() {
|
||||||
session = AVCaptureSession()
|
session = AVCaptureSession()
|
||||||
output = AVCaptureMetadataOutput()
|
output = AVCaptureMetadataOutput()
|
||||||
@@ -54,6 +59,7 @@ class ScanViewController: UIViewController {
|
|||||||
output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
|
output.metadataObjectTypes = [AVMetadataObjectTypeQRCode]
|
||||||
previewLayer = AVCaptureVideoPreviewLayer(session: self.session)
|
previewLayer = AVCaptureVideoPreviewLayer(session: self.session)
|
||||||
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
|
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill
|
||||||
|
previewLayer.connection.videoOrientation = videoOrientation(forInterfaceOrientation: UIApplication.sharedApplication().statusBarOrientation)
|
||||||
previewLayer.frame = previewView.bounds
|
previewLayer.frame = previewView.bounds
|
||||||
previewLayer.position = CGPointMake(CGRectGetMidX(previewView.bounds), CGRectGetMidY(previewView.bounds))
|
previewLayer.position = CGPointMake(CGRectGetMidX(previewView.bounds), CGRectGetMidY(previewView.bounds))
|
||||||
previewView.layer.addSublayer(previewLayer)
|
previewView.layer.addSublayer(previewLayer)
|
||||||
@@ -65,13 +71,7 @@ class ScanViewController: UIViewController {
|
|||||||
// MARK: - UIViewControllerDelegate
|
// MARK: - UIViewControllerDelegate
|
||||||
|
|
||||||
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
|
override func willRotateToInterfaceOrientation(toInterfaceOrientation: UIInterfaceOrientation, duration: NSTimeInterval) {
|
||||||
if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeLeft {
|
previewLayer.connection.videoOrientation = videoOrientation(forInterfaceOrientation: toInterfaceOrientation)
|
||||||
previewLayer!.connection.videoOrientation = AVCaptureVideoOrientation.LandscapeRight
|
|
||||||
} else if UIDevice.currentDevice().orientation == UIDeviceOrientation.LandscapeRight {
|
|
||||||
previewLayer!.connection.videoOrientation = AVCaptureVideoOrientation.LandscapeLeft
|
|
||||||
} else {
|
|
||||||
previewLayer!.connection.videoOrientation = AVCaptureVideoOrientation.Portrait
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Scanning
|
// MARK: - Scanning
|
||||||
@@ -90,6 +90,26 @@ class ScanViewController: UIViewController {
|
|||||||
targetImageView.image = UIImage(named: "scan_green")
|
targetImageView.image = UIImage(named: "scan_green")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - Properties
|
||||||
|
|
||||||
|
lazy var checkInController: CheckInController = {
|
||||||
|
let checkInController = CheckInController()
|
||||||
|
checkInController.delegate = self
|
||||||
|
return checkInController
|
||||||
|
}()
|
||||||
|
|
||||||
|
// MARK: - Helper
|
||||||
|
|
||||||
|
private func videoOrientation(forInterfaceOrientation orientation: UIInterfaceOrientation) -> AVCaptureVideoOrientation {
|
||||||
|
switch orientation {
|
||||||
|
case .LandscapeLeft: return .LandscapeLeft
|
||||||
|
case .LandscapeRight: return .LandscapeRight
|
||||||
|
case .Portrait: return .Portrait
|
||||||
|
case .PortraitUpsideDown: return .PortraitUpsideDown
|
||||||
|
case .Unknown: return .Portrait
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - CheckInControllerDelegate
|
// MARK: - CheckInControllerDelegate
|
||||||
@@ -120,9 +140,9 @@ extension ScanViewController: AVCaptureMetadataOutputObjectsDelegate {
|
|||||||
{
|
{
|
||||||
if metadataObjects.count > 0 {
|
if metadataObjects.count > 0 {
|
||||||
let metadataObject: AVMetadataMachineReadableCodeObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
|
let metadataObject: AVMetadataMachineReadableCodeObject = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
|
||||||
if let checkInData = CheckInData(urlString: metadataObject.stringValue) {
|
if let regattaData = RegattaData(urlString: metadataObject.stringValue) {
|
||||||
stopScanning()
|
stopScanning()
|
||||||
checkInController.startCheckIn(checkInData)
|
checkInController.checkIn(regattaData)
|
||||||
} else {
|
} else {
|
||||||
let alertTitle = NSLocalizedString("Incorrect QR Code", comment: "")
|
let alertTitle = NSLocalizedString("Incorrect QR Code", comment: "")
|
||||||
let alertController = UIAlertController(title: alertTitle, message: "", preferredStyle: .Alert)
|
let alertController = UIAlertController(title: alertTitle, message: "", preferredStyle: .Alert)
|
||||||
|
|||||||
@@ -1,129 +0,0 @@
|
|||||||
//
|
|
||||||
// SendGPSFixesController.swift
|
|
||||||
// SAPTracker
|
|
||||||
//
|
|
||||||
// Created by Raimund Wege on 29.06.16.
|
|
||||||
// Copyright © 2016 com.sap.sailing. All rights reserved.
|
|
||||||
//
|
|
||||||
|
|
||||||
import UIKit
|
|
||||||
|
|
||||||
class SendGPSFixesController: NSObject {
|
|
||||||
|
|
||||||
private struct SendingInterval {
|
|
||||||
static let Normal: NSTimeInterval = 3
|
|
||||||
static let BatterySaving: NSTimeInterval = 30
|
|
||||||
}
|
|
||||||
|
|
||||||
private let regatta: Regatta!
|
|
||||||
private let requestManager: RequestManager!
|
|
||||||
|
|
||||||
private var isRunning: Bool = false
|
|
||||||
|
|
||||||
init(regatta: Regatta) {
|
|
||||||
self.regatta = regatta
|
|
||||||
requestManager = RequestManager(baseURLString: regatta.serverURL)
|
|
||||||
super.init()
|
|
||||||
}
|
|
||||||
|
|
||||||
deinit {
|
|
||||||
unsubscribeFromNotifications()
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Notifications
|
|
||||||
|
|
||||||
private func subscribeForNotifications() {
|
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
|
||||||
object: nil)
|
|
||||||
}
|
|
||||||
|
|
||||||
private func unsubscribeFromNotifications() {
|
|
||||||
NSNotificationCenter.defaultCenter().removeObserver(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
func locationManagerUpdated(notification: NSNotification) {
|
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
|
||||||
if let userInfo = notification.userInfo {
|
|
||||||
if userInfo[LocationManager.UserInfo.IsValid] as? Bool ?? false {
|
|
||||||
let gpsFix = CoreDataManager.sharedManager.newGPSFix(self.regatta)
|
|
||||||
gpsFix.course = userInfo[LocationManager.UserInfo.Course] as! Double
|
|
||||||
gpsFix.latitude = userInfo[LocationManager.UserInfo.Latitude] as! Double
|
|
||||||
gpsFix.longitude = userInfo[LocationManager.UserInfo.Longitude] as! Double
|
|
||||||
gpsFix.speed = userInfo[LocationManager.UserInfo.Speed] as! Double
|
|
||||||
gpsFix.timestamp = round(userInfo[LocationManager.UserInfo.Timestamp] as! Double * 1000)
|
|
||||||
CoreDataManager.sharedManager.saveContext()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Methods
|
|
||||||
|
|
||||||
func startSending() {
|
|
||||||
isRunning = true
|
|
||||||
sendGPSFixes()
|
|
||||||
}
|
|
||||||
|
|
||||||
func stopSending() {
|
|
||||||
isRunning = false
|
|
||||||
}
|
|
||||||
|
|
||||||
func sendGPSFixes() {
|
|
||||||
var gpsFixes = [GPSFix]()
|
|
||||||
if regatta.gpsFixes != nil {
|
|
||||||
regatta.gpsFixes!.forEach { (gpsFix) in gpsFixes.append(gpsFix as! GPSFix) }
|
|
||||||
}
|
|
||||||
if gpsFixes.count > 0 {
|
|
||||||
log("\(gpsFixes.count) GPS fixes will be sent")
|
|
||||||
requestManager.postGPSFixes(gpsFixes,
|
|
||||||
success: { (operation, responseObject) in self.sendGPSFixesSuccess(gpsFixes) },
|
|
||||||
failure: { (operation, error) in self.sendGPSFixesFailure(error) })
|
|
||||||
} else {
|
|
||||||
log("No GPS fixes available")
|
|
||||||
sendGPSFixesFinished()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func sendGPSFixesSuccess(gpsFixes: [GPSFix]!) {
|
|
||||||
print(NSThread.isMainThread)
|
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
|
||||||
self.log("sending \(gpsFixes.count) GPS fixes was successful")
|
|
||||||
CoreDataManager.sharedManager.deleteGPSFixes(gpsFixes)
|
|
||||||
CoreDataManager.sharedManager.saveContext()
|
|
||||||
self.sendGPSFixesFinished()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private func sendGPSFixesFailure(error: AnyObject) {
|
|
||||||
print(NSThread.isMainThread)
|
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
|
||||||
self.log("sending GPS fixes failed for reason: \(error)")
|
|
||||||
self.sendGPSFixesFinished()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private func sendGPSFixesFinished() {
|
|
||||||
if isRunning {
|
|
||||||
let delay = sendingPeriod
|
|
||||||
log("sending next GPS fixes in \(delay) seconds")
|
|
||||||
performSelector(#selector(SendGPSFixesController.sendGPSFixes), withObject: nil, afterDelay: delay)
|
|
||||||
} else {
|
|
||||||
log("sending GPS fixes stopped")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MARK: - Helper
|
|
||||||
|
|
||||||
private var sendingPeriod: NSTimeInterval {
|
|
||||||
get {
|
|
||||||
return BatteryManager.sharedManager.batterySaving ? SendingInterval.BatterySaving : SendingInterval.Normal
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private func log(message: String) {
|
|
||||||
print("[GPSFixesController] \(message)")
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -40,8 +40,14 @@ class SpeedViewController: UIViewController {
|
|||||||
private func subscribeForNotifications() {
|
private func subscribeForNotifications() {
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
name:LocationManager.NotificationType.Updated,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
|
selector:#selector(locationManagerFailed(_:)),
|
||||||
|
name:LocationManager.NotificationType.Failed,
|
||||||
|
object: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unsubscribeFromNotifications() {
|
private func unsubscribeFromNotifications() {
|
||||||
@@ -50,8 +56,15 @@ class SpeedViewController: UIViewController {
|
|||||||
|
|
||||||
func locationManagerUpdated(notification: NSNotification) {
|
func locationManagerUpdated(notification: NSNotification) {
|
||||||
dispatch_async(dispatch_get_main_queue(), {
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
self.setupSpeedLabel(notification.userInfo![LocationManager.UserInfo.Speed] as! Double)
|
guard let locationData = notification.userInfo?[LocationManager.UserInfo.LocationData] as? LocationData else { return }
|
||||||
|
self.setupSpeedLabel(locationData.location.speed)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func locationManagerFailed(notification: NSNotification) {
|
||||||
|
dispatch_async(dispatch_get_main_queue(), {
|
||||||
|
self.setupSpeedLabel(-1.0)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -35,12 +35,14 @@ class StatusTrackingTableViewCell: UITableViewCell {
|
|||||||
private func subscribeForNotifications() {
|
private func subscribeForNotifications() {
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerUpdated(_:)),
|
selector:#selector(locationManagerUpdated(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerUpdated,
|
name:LocationManager.NotificationType.Updated,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
NSNotificationCenter.defaultCenter().addObserver(self,
|
NSNotificationCenter.defaultCenter().addObserver(self,
|
||||||
selector:#selector(locationManagerFailed(_:)),
|
selector:#selector(locationManagerFailed(_:)),
|
||||||
name:LocationManager.NotificationType.LocationManagerFailed,
|
name:LocationManager.NotificationType.Failed,
|
||||||
object: nil)
|
object: nil
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func unsubscribeFromNotifications() {
|
private func unsubscribeFromNotifications() {
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ class TimerViewController: UIViewController {
|
|||||||
target: self,
|
target: self,
|
||||||
selector: #selector(tick),
|
selector: #selector(tick),
|
||||||
userInfo: nil,
|
userInfo: nil,
|
||||||
repeats: true)
|
repeats: true
|
||||||
|
)
|
||||||
NSRunLoop.currentRunLoop().addTimer(timer, forMode:NSRunLoopCommonModes)
|
NSRunLoop.currentRunLoop().addTimer(timer, forMode:NSRunLoopCommonModes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import Foundation
|
|||||||
|
|
||||||
class TrackingViewController : UIViewController {
|
class TrackingViewController : UIViewController {
|
||||||
|
|
||||||
var regatta: Regatta?
|
var regatta: Regatta!
|
||||||
|
var regattaController: RegattaController!
|
||||||
|
|
||||||
@IBOutlet weak var tableView: UITableView!
|
@IBOutlet weak var tableView: UITableView!
|
||||||
@IBOutlet weak var tableViewHeight: NSLayoutConstraint!
|
@IBOutlet weak var tableViewHeight: NSLayoutConstraint!
|
||||||
|
|||||||
Reference in new issue
Block a user