diff --git a/Podfile b/Podfile index 0e787b0..33f1e79 100644 --- a/Podfile +++ b/Podfile @@ -1,13 +1,22 @@ inhibit_all_warnings! use_frameworks! -platform :osx, '10.10' -inhibit_all_warnings! -use_frameworks! -abstract_target :VBBPods do - pod 'Realm', '~> 3.0' - target "VBBFramework" - target "VBBNow" - target "VBB" -end \ No newline at end of file +abstract_target :VBBFrameworkPods do + pod 'Realm' + + target :'VBB' do + end + + target :'VBBNow' do + end + + target :'VBBWatch Extension' do + end + + target :'VBBFramework-macOS' do + end + + target :'VBBFramework-WatchOS' do + end +end diff --git a/Podfile.lock b/Podfile.lock index f8d9fc2..ee85d02 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -1,18 +1,18 @@ PODS: - - Realm (3.13.0): - - Realm/Headers (= 3.13.0) - - Realm/Headers (3.13.0) + - Realm (4.3.1): + - Realm/Headers (= 4.3.1) + - Realm/Headers (4.3.1) DEPENDENCIES: - - Realm (~> 3.0) + - Realm SPEC REPOS: https://github.com/cocoapods/specs.git: - Realm SPEC CHECKSUMS: - Realm: 5edd2ee65406aef591a4f9895de5a3440e51b3d8 + Realm: 31dc40934081ef740f60feedc46d88473cbfeb40 -PODFILE CHECKSUM: f19745799be5bdfb8c29ddec6fd1423907c59999 +PODFILE CHECKSUM: 6e2f38ddafeab222e67edf494ab5a420080186cf -COCOAPODS: 1.5.3 +COCOAPODS: 1.7.5 diff --git a/Sketch/AppIcon.sketch b/Sketch/AppIcon.sketch deleted file mode 100644 index d048ab6..0000000 Binary files a/Sketch/AppIcon.sketch and /dev/null differ diff --git a/Sketch/Bus.sketch b/Sketch/Bus.sketch deleted file mode 100644 index 9d3632e..0000000 Binary files a/Sketch/Bus.sketch and /dev/null differ diff --git a/Sketch/Ferry.sketch b/Sketch/Ferry.sketch deleted file mode 100644 index 868703f..0000000 Binary files a/Sketch/Ferry.sketch and /dev/null differ diff --git a/Sketch/Icons.sketch b/Sketch/Icons.sketch new file mode 100644 index 0000000..1e37973 Binary files /dev/null and b/Sketch/Icons.sketch differ diff --git a/Sketch/MetroBus.sketch b/Sketch/MetroBus.sketch deleted file mode 100644 index 0c4d9e5..0000000 Binary files a/Sketch/MetroBus.sketch and /dev/null differ diff --git a/Sketch/Ubahn.sketch b/Sketch/Ubahn.sketch deleted file mode 100644 index 52c4ba8..0000000 Binary files a/Sketch/Ubahn.sketch and /dev/null differ diff --git a/Sketch/local.sketch b/Sketch/local.sketch deleted file mode 100644 index 9a01599..0000000 Binary files a/Sketch/local.sketch and /dev/null differ diff --git a/Sketch/tram.sketch b/Sketch/tram.sketch deleted file mode 100644 index 08f6b8e..0000000 Binary files a/Sketch/tram.sketch and /dev/null differ diff --git a/VBB.xcodeproj/project.pbxproj b/VBB.xcodeproj/project.pbxproj index 67f3301..bc07f9a 100644 --- a/VBB.xcodeproj/project.pbxproj +++ b/VBB.xcodeproj/project.pbxproj @@ -7,11 +7,84 @@ objects = { /* Begin PBXBuildFile section */ - 41CECF18E34FE366E3303421 /* Pods_VBBPods_VBBNow.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9E218DF1D9207421C3487148 /* Pods_VBBPods_VBBNow.framework */; }; + 0F4BD038674E6ECDF4E53CA9 /* Pods_VBBFrameworkPods_VBB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 285021482A6ED538287500DD /* Pods_VBBFrameworkPods_VBB.framework */; }; + 790388C022F4C993002326D9 /* NSBundle+VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 790388BE22F4C993002326D9 /* NSBundle+VBB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 790388C122F4C993002326D9 /* NSBundle+VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 790388BE22F4C993002326D9 /* NSBundle+VBB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 790388C222F4C993002326D9 /* NSBundle+VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 790388BF22F4C993002326D9 /* NSBundle+VBB.m */; }; + 790388C322F4C993002326D9 /* NSBundle+VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 790388BF22F4C993002326D9 /* NSBundle+VBB.m */; }; + 79051D6022B57B3B00694592 /* DepartureListPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79051D5F22B57B3B00694592 /* DepartureListPresenter.swift */; }; + 791EDCDE22F37BF9006F6113 /* DeparturePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 791EDCDD22F37BF9006F6113 /* DeparturePresenter.swift */; }; + 79290564233558C8001D6737 /* OnboardingPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79290563233558C8001D6737 /* OnboardingPresenter.swift */; }; + 794A506D2337AFDE00AFA228 /* VBBNetworkStatus-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 794A506C2337AFDE00AFA228 /* VBBNetworkStatus-Extension.swift */; }; + 7951B06B22F4085800FBA206 /* View-Gradient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7951B06A22F4085800FBA206 /* View-Gradient.swift */; }; + 7951B06D22F4129400FBA206 /* VBBDeparture-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7951B06C22F4129400FBA206 /* VBBDeparture-Extension.swift */; }; + 7951B07022F4B69800FBA206 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7951B06E22F4B69200FBA206 /* Assets.xcassets */; }; + 7951B07122F4B69800FBA206 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7951B06E22F4B69200FBA206 /* Assets.xcassets */; }; + 7962705E234126E20076EB39 /* TimeInterval-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7962705D234126E20076EB39 /* TimeInterval-Extension.swift */; }; + 79653F5022BABAA60040A51F /* NSString+VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 79653F4E22BABAA60040A51F /* NSString+VBB.h */; }; + 79653F5122BABAA60040A51F /* NSString+VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 79653F4F22BABAA60040A51F /* NSString+VBB.m */; }; + 79653F5222BABEA60040A51F /* NSDateComponentsFormatter+VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 7967A74D22B6715D004FA671 /* NSDateComponentsFormatter+VBB.m */; }; + 79653F5322BABEA60040A51F /* NSString+VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 79653F4F22BABAA60040A51F /* NSString+VBB.m */; }; + 7967A74822B66AF3004FA671 /* VBBLine-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7967A74722B66AF3004FA671 /* VBBLine-Extension.swift */; }; + 7967A74E22B6715D004FA671 /* NSDateComponentsFormatter+VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967A74C22B6715D004FA671 /* NSDateComponentsFormatter+VBB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7967A74F22B6715D004FA671 /* NSDateComponentsFormatter+VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 7967A74D22B6715D004FA671 /* NSDateComponentsFormatter+VBB.m */; }; + 7967A75022B671F3004FA671 /* NSDateComponentsFormatter+VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 7967A74C22B6715D004FA671 /* NSDateComponentsFormatter+VBB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 7967A75422B679EB004FA671 /* VBBStation-Extension.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7967A75322B679EA004FA671 /* VBBStation-Extension.swift */; }; + 7968953E22B5574E002EAF84 /* VBBWatch App.app in Embed Watch Content */ = {isa = PBXBuildFile; fileRef = 7968953D22B5574E002EAF84 /* VBBWatch App.app */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 7968954422B5574E002EAF84 /* Interface.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 7968954222B5574E002EAF84 /* Interface.storyboard */; }; + 7968954622B5574F002EAF84 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7968954522B5574F002EAF84 /* Assets.xcassets */; }; + 7968954D22B5574F002EAF84 /* VBBWatch Extension.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = 7968954C22B5574F002EAF84 /* VBBWatch Extension.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; + 7968955222B5574F002EAF84 /* DepartureListView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7968955122B5574F002EAF84 /* DepartureListView.swift */; }; + 7968955422B5574F002EAF84 /* HostingController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7968955322B5574F002EAF84 /* HostingController.swift */; }; + 7968955622B5574F002EAF84 /* ExtensionDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7968955522B5574F002EAF84 /* ExtensionDelegate.swift */; }; + 7968955822B5574F002EAF84 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7968955722B5574F002EAF84 /* Assets.xcassets */; }; + 7968955B22B5574F002EAF84 /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7968955A22B5574F002EAF84 /* Preview Assets.xcassets */; }; + 7968956822B55762002EAF84 /* VBBFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79A8682C22B54CA40002F85D /* VBBFramework.framework */; }; + 7968956922B55762002EAF84 /* VBBFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 79A8682C22B54CA40002F85D /* VBBFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 7970D99822F3636400D96BEB /* VBBNetworkManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E19086EF1A79886400364EA2 /* VBBNetworkManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 797DF3AF233FF4CE00764404 /* NSNotification-Extensions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 797DF3AE233FF4CE00764404 /* NSNotification-Extensions.swift */; }; + 79A32CF022E4CB2F0030A481 /* Pods_VBBFrameworkPods_VBBFramework_macOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BDCCB7D0C262E7F2817D7DE4 /* Pods_VBBFrameworkPods_VBBFramework_macOS.framework */; }; + 79A32CF322E4CB490030A481 /* VBBFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E157C33A2099CC2400C0CD60 /* VBBFramework.framework */; }; + 79A32CF422E4CB490030A481 /* VBBFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E157C33A2099CC2400C0CD60 /* VBBFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; + 79A867DD22B54B160002F85D /* VBBFramework-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A867DC22B54B160002F85D /* VBBFramework-umbrella.h */; }; + 79A8681122B54CA40002F85D /* VBBLine.m in Sources */ = {isa = PBXBuildFile; fileRef = E14CDF0B1A7EB911007B1C46 /* VBBLine.m */; }; + 79A8681222B54CA40002F85D /* VBBStationParser.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A5689E1A7990C500C2EA16 /* VBBStationParser.m */; }; + 79A8681322B54CA40002F85D /* VBBLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = E1FA45AA1D4F7F1800D6F33D /* VBBLocation.m */; }; + 79A8681422B54CA40002F85D /* VBBDepature.m in Sources */ = {isa = PBXBuildFile; fileRef = E1948A9E1A7A46F1005C9D97 /* VBBDepature.m */; }; + 79A8681522B54CA40002F85D /* VBBPersistanceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A5689A1A79893100C2EA16 /* VBBPersistanceManager.m */; }; + 79A8681622B54CA40002F85D /* VBBDepatureParser.m in Sources */ = {isa = PBXBuildFile; fileRef = E1948A9B1A7A46DB005C9D97 /* VBBDepatureParser.m */; }; + 79A8681722B54CA40002F85D /* VBBNetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E19086F01A79886400364EA2 /* VBBNetworkManager.m */; }; + 79A8681822B54CA40002F85D /* VBBaseParser.m in Sources */ = {isa = PBXBuildFile; fileRef = E1948A961A7A3EB0005C9D97 /* VBBaseParser.m */; }; + 79A8681922B54CA40002F85D /* VBBStation.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A568A11A7991CE00C2EA16 /* VBBStation.m */; }; + 79A8681D22B54CA40002F85D /* VBBFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = E157C33C2099CC2400C0CD60 /* VBBFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8681E22B54CA40002F85D /* VBBNetworkManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E19086EF1A79886400364EA2 /* VBBNetworkManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8681F22B54CA40002F85D /* VBBPersistanceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A568991A79893100C2EA16 /* VBBPersistanceManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8682022B54CA40002F85D /* VBBStation.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A568A01A7991CE00C2EA16 /* VBBStation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8682122B54CA40002F85D /* VBBDepature.h in Headers */ = {isa = PBXBuildFile; fileRef = E1948A9D1A7A46F1005C9D97 /* VBBDepature.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8682222B54CA40002F85D /* VBBLine.h in Headers */ = {isa = PBXBuildFile; fileRef = E14CDF0A1A7EB911007B1C46 /* VBBLine.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8682322B54CA40002F85D /* VBBLocation.h in Headers */ = {isa = PBXBuildFile; fileRef = E1FA45A91D4F7F1800D6F33D /* VBBLocation.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79A8682422B54CA40002F85D /* VBBaseParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E1948A951A7A3EB0005C9D97 /* VBBaseParser.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 79A8682522B54CA40002F85D /* VBBStationParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A5689D1A7990C500C2EA16 /* VBBStationParser.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 79A8682722B54CA40002F85D /* VBBDepatureParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E1948A9A1A7A46DB005C9D97 /* VBBDepatureParser.h */; settings = {ATTRIBUTES = (Private, ); }; }; + 79A8683E22B5518E0002F85D /* VBBFramework-umbrella.h in Headers */ = {isa = PBXBuildFile; fileRef = 79A867DC22B54B160002F85D /* VBBFramework-umbrella.h */; }; + 79A8C61A22BEB842002BE5D6 /* ParentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79A8C61922BEB842002BE5D6 /* ParentView.swift */; }; + 79AF31BD22F59AEA006F7881 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 7951B07222F4BC1600FBA206 /* Icons.xcassets */; }; + 79AF31C122F6157A006F7881 /* LinePresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79AF31C022F6157A006F7881 /* LinePresenter.swift */; }; + 79AF31C322F61609006F7881 /* LineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79AF31C222F61609006F7881 /* LineView.swift */; }; + 79AF31C822F61A8F006F7881 /* Realm-VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 79AF31C522F61A7B006F7881 /* Realm-VBB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79AF31C922F61A8F006F7881 /* Realm-VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 79AF31C622F61A7B006F7881 /* Realm-VBB.m */; }; + 79AF31CA22F61A90006F7881 /* Realm-VBB.h in Headers */ = {isa = PBXBuildFile; fileRef = 79AF31C522F61A7B006F7881 /* Realm-VBB.h */; settings = {ATTRIBUTES = (Public, ); }; }; + 79AF31CB22F61A90006F7881 /* Realm-VBB.m in Sources */ = {isa = PBXBuildFile; fileRef = 79AF31C622F61A7B006F7881 /* Realm-VBB.m */; }; 79B1495A21DCB3A4001E5FEB /* VBBTodayViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 791C44FA21DBDB8F00269E47 /* VBBTodayViewController.xib */; }; 79B1495B21DCB3A7001E5FEB /* VBBListRowViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 791C44FC21DBDC0F00269E47 /* VBBListRowViewController.xib */; }; - 8CD4F290FE6C1AB8362E5EA6 /* Pods_VBBPods_VBBFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 46BFD4E2F68B97E4359A32B4 /* Pods_VBBPods_VBBFramework.framework */; }; - ACFB3B0EA651E6F34979F4CE /* Pods_VBBPods_VBB.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 667BF803F6EC46231455275D /* Pods_VBBPods_VBB.framework */; }; + 79B2591522F6E526005224E2 /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 79B2591722F6E526005224E2 /* Localizable.strings */; }; + 79C3AA4422B9689E00EACD7A /* OnboardingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79C3AA4322B9689E00EACD7A /* OnboardingView.swift */; }; + 79C5648822B55BD000039D3C /* DepartureView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79C5648722B55BD000039D3C /* DepartureView.swift */; }; + 79C6FB9422B832E000ABF0F4 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 79C6FB9322B832E000ABF0F4 /* MapKit.framework */; }; + 79EA57D222FA0279009A2D15 /* LoadingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79EA57D122FA0279009A2D15 /* LoadingView.swift */; }; + 79ED02A222B96CE00089AB45 /* ParentPresenter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 79ED02A122B96CE00089AB45 /* ParentPresenter.swift */; }; + B0FA7E675B626B64CA9E295A /* Pods_VBBFrameworkPods_VBBNow.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AFEE9A1EECB9500388A2A98A /* Pods_VBBFrameworkPods_VBBNow.framework */; }; + B11114E7D32C0C2D70604DC9 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7968953522B554F3002EAF84 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework */; }; E157C33E2099CC2400C0CD60 /* VBBFramework.h in Headers */ = {isa = PBXBuildFile; fileRef = E157C33C2099CC2400C0CD60 /* VBBFramework.h */; settings = {ATTRIBUTES = (Public, ); }; }; E157C3412099CC2400C0CD60 /* VBBFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E157C33A2099CC2400C0CD60 /* VBBFramework.framework */; }; E157C3422099CC2400C0CD60 /* VBBFramework.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = E157C33A2099CC2400C0CD60 /* VBBFramework.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; @@ -26,8 +99,6 @@ E157C37E2099CD9A00C0CD60 /* VBBLocation.m in Sources */ = {isa = PBXBuildFile; fileRef = E1FA45AA1D4F7F1800D6F33D /* VBBLocation.m */; }; E157C37F2099CD9E00C0CD60 /* VBBNetworkManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E19086F01A79886400364EA2 /* VBBNetworkManager.m */; }; E157C3802099CD9E00C0CD60 /* VBBPersistanceManager.m in Sources */ = {isa = PBXBuildFile; fileRef = E1A5689A1A79893100C2EA16 /* VBBPersistanceManager.m */; }; - E157C3812099CDAB00C0CD60 /* VBBFramework.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E157C33A2099CC2400C0CD60 /* VBBFramework.framework */; }; - E157C3822099D06A00C0CD60 /* VBBNetworkManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E19086EF1A79886400364EA2 /* VBBNetworkManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; E157C3832099D06A00C0CD60 /* VBBPersistanceManager.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A568991A79893100C2EA16 /* VBBPersistanceManager.h */; settings = {ATTRIBUTES = (Public, ); }; }; E157C3842099D06A00C0CD60 /* VBBStation.h in Headers */ = {isa = PBXBuildFile; fileRef = E1A568A01A7991CE00C2EA16 /* VBBStation.h */; settings = {ATTRIBUTES = (Public, ); }; }; E157C3852099D06A00C0CD60 /* VBBDepature.h in Headers */ = {isa = PBXBuildFile; fileRef = E1948A9D1A7A46F1005C9D97 /* VBBDepature.h */; settings = {ATTRIBUTES = (Public, ); }; }; @@ -38,16 +109,36 @@ E157C38A2099D06A00C0CD60 /* VBBDepatureParser.h in Headers */ = {isa = PBXBuildFile; fileRef = E1948A9A1A7A46DB005C9D97 /* VBBDepatureParser.h */; settings = {ATTRIBUTES = (Private, ); }; }; E15C8B6B1A7C0F3C0080EE8B /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = E19086D61A79870300364EA2 /* MainMenu.xib */; }; E17F97A51A7C0E4800623FB2 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = E17F97A01A7C0E4800623FB2 /* InfoPlist.strings */; }; - E17F97A61A7C0E4800623FB2 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E17F97A21A7C0E4800623FB2 /* Icons.xcassets */; }; E17F97A81A7C0E4800623FB2 /* vbbnow.entitlements in Resources */ = {isa = PBXBuildFile; fileRef = E17F97A41A7C0E4800623FB2 /* vbbnow.entitlements */; }; E19086D11A79870300364EA2 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = E19086D01A79870300364EA2 /* AppDelegate.m */; }; E19086D31A79870300364EA2 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = E19086D21A79870300364EA2 /* main.m */; }; E1AEBBE81A7B701D00196F97 /* NotificationCenter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E1948A7E1A7A3DEB005C9D97 /* NotificationCenter.framework */; }; E1AEBBFC1A7B701D00196F97 /* VBBNow.appex in Embed App Extensions */ = {isa = PBXBuildFile; fileRef = E1AEBBE71A7B701D00196F97 /* VBBNow.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; }; - E1F6153B1A7D407F00EEA639 /* Icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = E17F97A21A7C0E4800623FB2 /* Icons.xcassets */; }; + EE6B87726DE4BF0128458003 /* Pods_VBBFrameworkPods_VBBWatch_Extension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3421FA8B2C099BFC93F860C2 /* Pods_VBBFrameworkPods_VBBWatch_Extension.framework */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ + 7968953F22B5574E002EAF84 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E19086C21A79870300364EA2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7968953C22B5574E002EAF84; + remoteInfo = "VBBWatch WatchKit App"; + }; + 7968954E22B5574F002EAF84 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E19086C21A79870300364EA2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 7968954B22B5574F002EAF84; + remoteInfo = "VBBWatch WatchKit Extension"; + }; + 7968956A22B55762002EAF84 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = E19086C21A79870300364EA2 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 79A8680E22B54CA40002F85D; + remoteInfo = "VBBFramework-WatchOS"; + }; 79B1496221DCB5A2001E5FEB /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = E19086C21A79870300364EA2 /* Project object */; @@ -72,6 +163,50 @@ /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ + 7968956022B5574F002EAF84 /* Embed App Extensions */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 13; + files = ( + 7968954D22B5574F002EAF84 /* VBBWatch Extension.appex in Embed App Extensions */, + ); + name = "Embed App Extensions"; + runOnlyForDeploymentPostprocessing = 0; + }; + 7968956422B5574F002EAF84 /* Embed Watch Content */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = "$(CONTENTS_FOLDER_PATH)/Watch"; + dstSubfolderSpec = 16; + files = ( + 7968953E22B5574E002EAF84 /* VBBWatch App.app in Embed Watch Content */, + ); + name = "Embed Watch Content"; + runOnlyForDeploymentPostprocessing = 0; + }; + 7968956C22B55762002EAF84 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 7968956922B55762002EAF84 /* VBBFramework.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; + 79A32CF522E4CB490030A481 /* Embed Frameworks */ = { + isa = PBXCopyFilesBuildPhase; + buildActionMask = 2147483647; + dstPath = ""; + dstSubfolderSpec = 10; + files = ( + 79A32CF422E4CB490030A481 /* VBBFramework.framework in Embed Frameworks */, + ); + name = "Embed Frameworks"; + runOnlyForDeploymentPostprocessing = 0; + }; E157C3462099CC2400C0CD60 /* Embed Frameworks */ = { isa = PBXCopyFilesBuildPhase; buildActionMask = 2147483647; @@ -97,22 +232,86 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0167B0997B867BBF926B3FB2 /* Pods-VBBFrameworkPods-VBBWatch Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBWatch Extension.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBWatch Extension/Pods-VBBFrameworkPods-VBBWatch Extension.release.xcconfig"; sourceTree = ""; }; + 0ADE7AED1B652065D933F38B /* Pods-VBBFrameworkPods-VBBFramework.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBFramework.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBFramework/Pods-VBBFrameworkPods-VBBFramework.release.xcconfig"; sourceTree = ""; }; 0B61806681AAA7E29F1AA122 /* Pods-VBBPods-VBBFramework.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBPods-VBBFramework.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBPods-VBBFramework/Pods-VBBPods-VBBFramework.debug.xcconfig"; sourceTree = ""; }; 0C26A8B1F7DEF56ACD31B606 /* Pods_VBBFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 12191626B6A522251DF25AA0 /* Pods-VBBFramework.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFramework.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFramework/Pods-VBBFramework.release.xcconfig"; sourceTree = ""; }; - 16AAB8987028C777D0FBCE02 /* Pods-VBBPods-VBBNow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBPods-VBBNow.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBPods-VBBNow/Pods-VBBPods-VBBNow.debug.xcconfig"; sourceTree = ""; }; - 46BFD4E2F68B97E4359A32B4 /* Pods_VBBPods_VBBFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBPods_VBBFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 16D192B187425E69B9B2A938 /* Pods-VBBFrameworkPods-VBBFramework-WatchOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBFramework-WatchOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBFramework-WatchOS/Pods-VBBFrameworkPods-VBBFramework-WatchOS.release.xcconfig"; sourceTree = ""; }; + 17869F29851E0C35950B3E0A /* Pods-VBBWatch Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBWatch Extension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBWatch Extension/Pods-VBBWatch Extension.debug.xcconfig"; sourceTree = ""; }; + 20973B06F87F036D3A4110F2 /* Pods-VBBFrameworkPods-VBBFramework-macOS.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBFramework-macOS.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBFramework-macOS/Pods-VBBFrameworkPods-VBBFramework-macOS.release.xcconfig"; sourceTree = ""; }; + 285021482A6ED538287500DD /* Pods_VBBFrameworkPods_VBB.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBFrameworkPods_VBB.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 28E87E95EDA4B923462F4D83 /* Pods-VBBFrameworkPods-VBBFramework-WatchOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBFramework-WatchOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBFramework-WatchOS/Pods-VBBFrameworkPods-VBBFramework-WatchOS.debug.xcconfig"; sourceTree = ""; }; + 2BC934B59A728B7BEA0636B3 /* Pods-VBBFrameworkPods-VBBNow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBNow.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBNow/Pods-VBBFrameworkPods-VBBNow.debug.xcconfig"; sourceTree = ""; }; + 3421FA8B2C099BFC93F860C2 /* Pods_VBBFrameworkPods_VBBWatch_Extension.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBFrameworkPods_VBBWatch_Extension.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 3C7FF169CB98E57F7920091C /* Pods-VBBFrameworkPods-VBBFramework-macOS.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBFramework-macOS.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBFramework-macOS/Pods-VBBFrameworkPods-VBBFramework-macOS.debug.xcconfig"; sourceTree = ""; }; + 4EA4D3DCA40C5D292659654B /* Pods-VBB.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBB.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBB/Pods-VBB.release.xcconfig"; sourceTree = ""; }; + 4F4E06631C481A8587DE5947 /* Pods-VBBWatch WatchKit Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBWatch WatchKit Extension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBWatch WatchKit Extension/Pods-VBBWatch WatchKit Extension.debug.xcconfig"; sourceTree = ""; }; + 54086035F2CBD9CEEAE40458 /* Pods-VBBNow.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBNow.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBNow/Pods-VBBNow.debug.xcconfig"; sourceTree = ""; }; + 5D7324615ABC71518CDB615F /* Pods-VBBFrameworkPods-VBBFramework.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBFramework.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBFramework/Pods-VBBFrameworkPods-VBBFramework.debug.xcconfig"; sourceTree = ""; }; 667BF803F6EC46231455275D /* Pods_VBBPods_VBB.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBPods_VBB.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - 67F15DD87868EF68F4B521BF /* Pods-VBBPods-VBBNow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBPods-VBBNow.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBPods-VBBNow/Pods-VBBPods-VBBNow.release.xcconfig"; sourceTree = ""; }; + 69955D582DA31771816542E1 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 7891A1221A1C1E755E21A434 /* Pods-VBBFramework.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFramework.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFramework/Pods-VBBFramework.debug.xcconfig"; sourceTree = ""; }; + 790388BE22F4C993002326D9 /* NSBundle+VBB.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSBundle+VBB.h"; sourceTree = ""; }; + 790388BF22F4C993002326D9 /* NSBundle+VBB.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSBundle+VBB.m"; sourceTree = ""; }; + 79051D5F22B57B3B00694592 /* DepartureListPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DepartureListPresenter.swift; sourceTree = ""; }; 791C44FA21DBDB8F00269E47 /* VBBTodayViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VBBTodayViewController.xib; sourceTree = ""; }; 791C44FC21DBDC0F00269E47 /* VBBListRowViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = VBBListRowViewController.xib; sourceTree = ""; }; - 90DAD5A44B2AE01CFEFFBCA4 /* Pods_VBBNow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBNow.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 791EDCDD22F37BF9006F6113 /* DeparturePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DeparturePresenter.swift; sourceTree = ""; }; + 79290563233558C8001D6737 /* OnboardingPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingPresenter.swift; sourceTree = ""; }; + 7929056523356C1C001D6737 /* de */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = de; path = de.lproj/Localizable.strings; sourceTree = ""; }; + 794A506C2337AFDE00AFA228 /* VBBNetworkStatus-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VBBNetworkStatus-Extension.swift"; sourceTree = ""; }; + 7951B06A22F4085800FBA206 /* View-Gradient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "View-Gradient.swift"; sourceTree = ""; }; + 7951B06C22F4129400FBA206 /* VBBDeparture-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VBBDeparture-Extension.swift"; sourceTree = ""; }; + 7951B06E22F4B69200FBA206 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7951B07222F4BC1600FBA206 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Icons.xcassets; path = VBB/Icons.xcassets; sourceTree = SOURCE_ROOT; }; + 7962705D234126E20076EB39 /* TimeInterval-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "TimeInterval-Extension.swift"; sourceTree = ""; }; + 79653F4E22BABAA60040A51F /* NSString+VBB.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSString+VBB.h"; sourceTree = ""; }; + 79653F4F22BABAA60040A51F /* NSString+VBB.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSString+VBB.m"; sourceTree = ""; }; + 7967A74722B66AF3004FA671 /* VBBLine-Extension.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "VBBLine-Extension.swift"; sourceTree = ""; }; + 7967A74C22B6715D004FA671 /* NSDateComponentsFormatter+VBB.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSDateComponentsFormatter+VBB.h"; sourceTree = ""; }; + 7967A74D22B6715D004FA671 /* NSDateComponentsFormatter+VBB.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSDateComponentsFormatter+VBB.m"; sourceTree = ""; }; + 7967A75322B679EA004FA671 /* VBBStation-Extension.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "VBBStation-Extension.swift"; sourceTree = ""; }; + 7968953522B554F3002EAF84 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; path = Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 7968953A22B5574E002EAF84 /* VBBWatch.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VBBWatch.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 7968953D22B5574E002EAF84 /* VBBWatch App.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "VBBWatch App.app"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7968954322B5574E002EAF84 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Interface.storyboard; sourceTree = ""; }; + 7968954522B5574F002EAF84 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7968954722B5574F002EAF84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 7968954C22B5574F002EAF84 /* VBBWatch Extension.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = "VBBWatch Extension.appex"; sourceTree = BUILT_PRODUCTS_DIR; }; + 7968955122B5574F002EAF84 /* DepartureListView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DepartureListView.swift; sourceTree = ""; }; + 7968955322B5574F002EAF84 /* HostingController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HostingController.swift; sourceTree = ""; }; + 7968955522B5574F002EAF84 /* ExtensionDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionDelegate.swift; sourceTree = ""; }; + 7968955722B5574F002EAF84 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 7968955A22B5574F002EAF84 /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; }; + 7968955C22B5574F002EAF84 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 797DF3AE233FF4CE00764404 /* NSNotification-Extensions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NSNotification-Extensions.swift"; sourceTree = ""; }; + 79A867DB22B54B160002F85D /* VBBFramework.modulemap */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = "sourcecode.module-map"; path = VBBFramework.modulemap; sourceTree = ""; }; + 79A867DC22B54B160002F85D /* VBBFramework-umbrella.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "VBBFramework-umbrella.h"; sourceTree = ""; }; + 79A8682C22B54CA40002F85D /* VBBFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = VBBFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 79A8C61922BEB842002BE5D6 /* ParentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentView.swift; sourceTree = ""; }; + 79AF31C022F6157A006F7881 /* LinePresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LinePresenter.swift; sourceTree = ""; }; + 79AF31C222F61609006F7881 /* LineView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LineView.swift; sourceTree = ""; }; + 79AF31C522F61A7B006F7881 /* Realm-VBB.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "Realm-VBB.h"; sourceTree = ""; }; + 79AF31C622F61A7B006F7881 /* Realm-VBB.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "Realm-VBB.m"; sourceTree = ""; }; + 79B2591622F6E526005224E2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 79C3AA4322B9689E00EACD7A /* OnboardingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OnboardingView.swift; sourceTree = ""; }; + 79C5648722B55BD000039D3C /* DepartureView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DepartureView.swift; sourceTree = ""; }; + 79C6FB9322B832E000ABF0F4 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = Platforms/WatchOS.platform/Developer/SDKs/WatchOS6.0.sdk/System/Library/Frameworks/MapKit.framework; sourceTree = DEVELOPER_DIR; }; + 79EA57D122FA0279009A2D15 /* LoadingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoadingView.swift; sourceTree = ""; }; + 79ED02A122B96CE00089AB45 /* ParentPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ParentPresenter.swift; sourceTree = ""; }; + 7AA5C8D3A5AC7FE7FFE62ACD /* Pods-VBBFrameworkPods-VBB.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBB.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBB/Pods-VBBFrameworkPods-VBB.debug.xcconfig"; sourceTree = ""; }; + 89322760E49051FD19D10F36 /* Pods-VBBWatch.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBWatch.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBWatch/Pods-VBBWatch.release.xcconfig"; sourceTree = ""; }; + 93E3B5B9C59E98CA7CFD6885 /* Pods-VBBWatch WatchKit Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBWatch WatchKit Extension.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBWatch WatchKit Extension/Pods-VBBWatch WatchKit Extension.release.xcconfig"; sourceTree = ""; }; 9E218DF1D9207421C3487148 /* Pods_VBBPods_VBBNow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBPods_VBBNow.framework; sourceTree = BUILT_PRODUCTS_DIR; }; - B0957EF3840658A2EB7B3B1A /* Pods-VBBPods-VBB.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBPods-VBB.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBPods-VBB/Pods-VBBPods-VBB.debug.xcconfig"; sourceTree = ""; }; - B4EDD8701BB4D2A7152E0253 /* Pods-VBBPods-VBB.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBPods-VBB.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBPods-VBB/Pods-VBBPods-VBB.release.xcconfig"; sourceTree = ""; }; - C3D0945F3F45278CE0C206A7 /* Pods_VBB.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBB.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + 9F15AF78642C8708D51A0C35 /* Pods-VBBFrameworkPods-VBBNow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBNow.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBNow/Pods-VBBFrameworkPods-VBBNow.release.xcconfig"; sourceTree = ""; }; + 9F580EADBF13D1ED2D28A965 /* Pods-VBBWatch Extension.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBWatch Extension.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBWatch Extension/Pods-VBBWatch Extension.release.xcconfig"; sourceTree = ""; }; + AFEE9A1EECB9500388A2A98A /* Pods_VBBFrameworkPods_VBBNow.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBFrameworkPods_VBBNow.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + B2968187C6C527FD730FFB01 /* Pods-VBB.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBB.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBB/Pods-VBB.debug.xcconfig"; sourceTree = ""; }; + BDCCB7D0C262E7F2817D7DE4 /* Pods_VBBFrameworkPods_VBBFramework_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBFrameworkPods_VBBFramework_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + CB625DCF924575090FED786C /* Pods-VBBFrameworkPods-VBBWatch Extension.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBBWatch Extension.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBBWatch Extension/Pods-VBBFrameworkPods-VBBWatch Extension.debug.xcconfig"; sourceTree = ""; }; DA14C1F48BCDD3F011F7DA68 /* Pods-VBBPods-VBBFramework.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBPods-VBBFramework.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBPods-VBBFramework/Pods-VBBPods-VBBFramework.release.xcconfig"; sourceTree = ""; }; + DBC5C40767773931E189155B /* Pods-VBBNow.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBNow.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBNow/Pods-VBBNow.release.xcconfig"; sourceTree = ""; }; E14CDF0A1A7EB911007B1C46 /* VBBLine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VBBLine.h; sourceTree = ""; }; E14CDF0B1A7EB911007B1C46 /* VBBLine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VBBLine.m; sourceTree = ""; }; E157C33A2099CC2400C0CD60 /* VBBFramework.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = VBBFramework.framework; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -125,10 +324,9 @@ E16440861A7AAB890008ECA3 /* libPods.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; name = libPods.a; path = Pods/build/Debug/libPods.a; sourceTree = ""; }; E17A6ABA1C770CF900506B8A /* VBB.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = VBB.entitlements; sourceTree = ""; }; E17F97A11A7C0E4800623FB2 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = InfoPlist.strings; sourceTree = ""; }; - E17F97A21A7C0E4800623FB2 /* Icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Icons.xcassets; path = VBBNow/Icons.xcassets; sourceTree = SOURCE_ROOT; }; E17F97A31A7C0E4800623FB2 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = "VBBNow/Supporting Files/Info.plist"; sourceTree = SOURCE_ROOT; }; E17F97A41A7C0E4800623FB2 /* vbbnow.entitlements */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.entitlements; name = vbbnow.entitlements; path = "VBBNow/Supporting Files/vbbnow.entitlements"; sourceTree = SOURCE_ROOT; }; - E19086CA1A79870300364EA2 /* VBB.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VBB.app; sourceTree = BUILT_PRODUCTS_DIR; }; + E19086CA1A79870300364EA2 /* VBBNow.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = VBBNow.app; sourceTree = BUILT_PRODUCTS_DIR; }; E19086CE1A79870300364EA2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; E19086CF1A79870300364EA2 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; E19086D01A79870300364EA2 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -152,14 +350,49 @@ E1AEBBE71A7B701D00196F97 /* VBBNow.appex */ = {isa = PBXFileReference; explicitFileType = "wrapper.app-extension"; includeInIndex = 0; path = VBBNow.appex; sourceTree = BUILT_PRODUCTS_DIR; }; E1FA45A91D4F7F1800D6F33D /* VBBLocation.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VBBLocation.h; sourceTree = ""; }; E1FA45AA1D4F7F1800D6F33D /* VBBLocation.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VBBLocation.m; sourceTree = ""; }; + E8708C61D9B673753DA164E6 /* Pods_VBBWatch.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_VBBWatch.framework; sourceTree = BUILT_PRODUCTS_DIR; }; + F0B41255AA6C835D0479A7B6 /* Pods-VBBFrameworkPods-VBB.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBFrameworkPods-VBB.release.xcconfig"; path = "Pods/Target Support Files/Pods-VBBFrameworkPods-VBB/Pods-VBBFrameworkPods-VBB.release.xcconfig"; sourceTree = ""; }; + F4CA7E39BC970F70DF84E2A1 /* Pods-VBBWatch.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-VBBWatch.debug.xcconfig"; path = "Pods/Target Support Files/Pods-VBBWatch/Pods-VBBWatch.debug.xcconfig"; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ + 389B04799A1AAFD2E3F38482 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7968954922B5574F002EAF84 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 79C6FB9422B832E000ABF0F4 /* MapKit.framework in Frameworks */, + 7968956822B55762002EAF84 /* VBBFramework.framework in Frameworks */, + EE6B87726DE4BF0128458003 /* Pods_VBBFrameworkPods_VBBWatch_Extension.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79A8681A22B54CA40002F85D /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + B11114E7D32C0C2D70604DC9 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + B62765DEBCD442FD0EF7E12B /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; E157C3362099CC2400C0CD60 /* Frameworks */ = { isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - 8CD4F290FE6C1AB8362E5EA6 /* Pods_VBBPods_VBBFramework.framework in Frameworks */, + 79A32CF022E4CB2F0030A481 /* Pods_VBBFrameworkPods_VBBFramework_macOS.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -168,7 +401,7 @@ buildActionMask = 2147483647; files = ( E157C3412099CC2400C0CD60 /* VBBFramework.framework in Frameworks */, - ACFB3B0EA651E6F34979F4CE /* Pods_VBBPods_VBB.framework in Frameworks */, + 0F4BD038674E6ECDF4E53CA9 /* Pods_VBBFrameworkPods_VBB.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -176,15 +409,130 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( - E157C3812099CDAB00C0CD60 /* VBBFramework.framework in Frameworks */, E1AEBBE81A7B701D00196F97 /* NotificationCenter.framework in Frameworks */, - 41CECF18E34FE366E3303421 /* Pods_VBBPods_VBBNow.framework in Frameworks */, + 79A32CF322E4CB490030A481 /* VBBFramework.framework in Frameworks */, + B0FA7E675B626B64CA9E295A /* Pods_VBBFrameworkPods_VBBNow.framework in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; /* End PBXFrameworksBuildPhase section */ /* Begin PBXGroup section */ + 790E9CC322B5710100DBC9C4 /* Extensions */ = { + isa = PBXGroup; + children = ( + 797DF3AE233FF4CE00764404 /* NSNotification-Extensions.swift */, + 7962705D234126E20076EB39 /* TimeInterval-Extension.swift */, + 7951B06C22F4129400FBA206 /* VBBDeparture-Extension.swift */, + 7967A74722B66AF3004FA671 /* VBBLine-Extension.swift */, + 794A506C2337AFDE00AFA228 /* VBBNetworkStatus-Extension.swift */, + 7967A75322B679EA004FA671 /* VBBStation-Extension.swift */, + 7951B06A22F4085800FBA206 /* View-Gradient.swift */, + ); + path = Extensions; + sourceTree = ""; + }; + 7967A74922B67108004FA671 /* Miscellaneous */ = { + isa = PBXGroup; + children = ( + 79AF31C522F61A7B006F7881 /* Realm-VBB.h */, + 79AF31C622F61A7B006F7881 /* Realm-VBB.m */, + 7967A74C22B6715D004FA671 /* NSDateComponentsFormatter+VBB.h */, + 7967A74D22B6715D004FA671 /* NSDateComponentsFormatter+VBB.m */, + 79653F4E22BABAA60040A51F /* NSString+VBB.h */, + 79653F4F22BABAA60040A51F /* NSString+VBB.m */, + 790388BE22F4C993002326D9 /* NSBundle+VBB.h */, + 790388BF22F4C993002326D9 /* NSBundle+VBB.m */, + ); + path = Miscellaneous; + sourceTree = ""; + }; + 7968954122B5574E002EAF84 /* VBBWatch App */ = { + isa = PBXGroup; + children = ( + 7968954222B5574E002EAF84 /* Interface.storyboard */, + 7968954522B5574F002EAF84 /* Assets.xcassets */, + 7968954722B5574F002EAF84 /* Info.plist */, + ); + path = "VBBWatch App"; + sourceTree = ""; + }; + 7968955022B5574F002EAF84 /* VBBWatch Extension */ = { + isa = PBXGroup; + children = ( + 79C5648622B5599600039D3C /* Controller */, + 7968955522B5574F002EAF84 /* ExtensionDelegate.swift */, + 790E9CC322B5710100DBC9C4 /* Extensions */, + 79C3AA4222B95A9E00EACD7A /* Presenter */, + 79C5648522B5598900039D3C /* Support Files */, + 79C5648422B5598000039D3C /* Views */, + ); + path = "VBBWatch Extension"; + sourceTree = ""; + }; + 7968955922B5574F002EAF84 /* Preview Content */ = { + isa = PBXGroup; + children = ( + 7968955A22B5574F002EAF84 /* Preview Assets.xcassets */, + ); + path = "Preview Content"; + sourceTree = ""; + }; + 79A867DA22B54B040002F85D /* Support Files */ = { + isa = PBXGroup; + children = ( + E157C33C2099CC2400C0CD60 /* VBBFramework.h */, + 79A867DC22B54B160002F85D /* VBBFramework-umbrella.h */, + 79A867DB22B54B160002F85D /* VBBFramework.modulemap */, + 7951B06E22F4B69200FBA206 /* Assets.xcassets */, + ); + path = "Support Files"; + sourceTree = ""; + }; + 79C3AA4222B95A9E00EACD7A /* Presenter */ = { + isa = PBXGroup; + children = ( + 79051D5F22B57B3B00694592 /* DepartureListPresenter.swift */, + 791EDCDD22F37BF9006F6113 /* DeparturePresenter.swift */, + 79AF31C022F6157A006F7881 /* LinePresenter.swift */, + 79290563233558C8001D6737 /* OnboardingPresenter.swift */, + 79ED02A122B96CE00089AB45 /* ParentPresenter.swift */, + ); + path = Presenter; + sourceTree = ""; + }; + 79C5648422B5598000039D3C /* Views */ = { + isa = PBXGroup; + children = ( + 7968955122B5574F002EAF84 /* DepartureListView.swift */, + 79C5648722B55BD000039D3C /* DepartureView.swift */, + 79C3AA4322B9689E00EACD7A /* OnboardingView.swift */, + 79A8C61922BEB842002BE5D6 /* ParentView.swift */, + 79AF31C222F61609006F7881 /* LineView.swift */, + 79EA57D122FA0279009A2D15 /* LoadingView.swift */, + ); + path = Views; + sourceTree = ""; + }; + 79C5648522B5598900039D3C /* Support Files */ = { + isa = PBXGroup; + children = ( + 7968955722B5574F002EAF84 /* Assets.xcassets */, + 7968955C22B5574F002EAF84 /* Info.plist */, + 7968955922B5574F002EAF84 /* Preview Content */, + 79B2591722F6E526005224E2 /* Localizable.strings */, + ); + path = "Support Files"; + sourceTree = ""; + }; + 79C5648622B5599600039D3C /* Controller */ = { + isa = PBXGroup; + children = ( + 7968955322B5574F002EAF84 /* HostingController.swift */, + ); + path = Controller; + sourceTree = ""; + }; 8D27E6BEE4206BC56C37BDCD /* Pods */ = { isa = PBXGroup; children = ( @@ -192,10 +540,28 @@ 12191626B6A522251DF25AA0 /* Pods-VBBFramework.release.xcconfig */, 0B61806681AAA7E29F1AA122 /* Pods-VBBPods-VBBFramework.debug.xcconfig */, DA14C1F48BCDD3F011F7DA68 /* Pods-VBBPods-VBBFramework.release.xcconfig */, - B0957EF3840658A2EB7B3B1A /* Pods-VBBPods-VBB.debug.xcconfig */, - B4EDD8701BB4D2A7152E0253 /* Pods-VBBPods-VBB.release.xcconfig */, - 16AAB8987028C777D0FBCE02 /* Pods-VBBPods-VBBNow.debug.xcconfig */, - 67F15DD87868EF68F4B521BF /* Pods-VBBPods-VBBNow.release.xcconfig */, + 5D7324615ABC71518CDB615F /* Pods-VBBFrameworkPods-VBBFramework.debug.xcconfig */, + 28E87E95EDA4B923462F4D83 /* Pods-VBBFrameworkPods-VBBFramework-WatchOS.debug.xcconfig */, + 16D192B187425E69B9B2A938 /* Pods-VBBFrameworkPods-VBBFramework-WatchOS.release.xcconfig */, + 0ADE7AED1B652065D933F38B /* Pods-VBBFrameworkPods-VBBFramework.release.xcconfig */, + F4CA7E39BC970F70DF84E2A1 /* Pods-VBBWatch.debug.xcconfig */, + 89322760E49051FD19D10F36 /* Pods-VBBWatch.release.xcconfig */, + 4F4E06631C481A8587DE5947 /* Pods-VBBWatch WatchKit Extension.debug.xcconfig */, + 93E3B5B9C59E98CA7CFD6885 /* Pods-VBBWatch WatchKit Extension.release.xcconfig */, + 3C7FF169CB98E57F7920091C /* Pods-VBBFrameworkPods-VBBFramework-macOS.debug.xcconfig */, + 20973B06F87F036D3A4110F2 /* Pods-VBBFrameworkPods-VBBFramework-macOS.release.xcconfig */, + B2968187C6C527FD730FFB01 /* Pods-VBB.debug.xcconfig */, + 4EA4D3DCA40C5D292659654B /* Pods-VBB.release.xcconfig */, + 17869F29851E0C35950B3E0A /* Pods-VBBWatch Extension.debug.xcconfig */, + 9F580EADBF13D1ED2D28A965 /* Pods-VBBWatch Extension.release.xcconfig */, + 54086035F2CBD9CEEAE40458 /* Pods-VBBNow.debug.xcconfig */, + DBC5C40767773931E189155B /* Pods-VBBNow.release.xcconfig */, + 7AA5C8D3A5AC7FE7FFE62ACD /* Pods-VBBFrameworkPods-VBB.debug.xcconfig */, + F0B41255AA6C835D0479A7B6 /* Pods-VBBFrameworkPods-VBB.release.xcconfig */, + 2BC934B59A728B7BEA0636B3 /* Pods-VBBFrameworkPods-VBBNow.debug.xcconfig */, + 9F15AF78642C8708D51A0C35 /* Pods-VBBFrameworkPods-VBBNow.release.xcconfig */, + CB625DCF924575090FED786C /* Pods-VBBFrameworkPods-VBBWatch Extension.debug.xcconfig */, + 0167B0997B867BBF926B3FB2 /* Pods-VBBFrameworkPods-VBBWatch Extension.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -203,14 +569,19 @@ E114AB8D017F74B47967DFA8 /* Frameworks */ = { isa = PBXGroup; children = ( + 79C6FB9322B832E000ABF0F4 /* MapKit.framework */, + 7968953522B554F3002EAF84 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework */, E16440861A7AAB890008ECA3 /* libPods.a */, E1948A7E1A7A3DEB005C9D97 /* NotificationCenter.framework */, - C3D0945F3F45278CE0C206A7 /* Pods_VBB.framework */, - 90DAD5A44B2AE01CFEFFBCA4 /* Pods_VBBNow.framework */, 0C26A8B1F7DEF56ACD31B606 /* Pods_VBBFramework.framework */, 667BF803F6EC46231455275D /* Pods_VBBPods_VBB.framework */, - 46BFD4E2F68B97E4359A32B4 /* Pods_VBBPods_VBBFramework.framework */, 9E218DF1D9207421C3487148 /* Pods_VBBPods_VBBNow.framework */, + 69955D582DA31771816542E1 /* Pods_VBBFrameworkPods_VBBFramework_WatchOS.framework */, + E8708C61D9B673753DA164E6 /* Pods_VBBWatch.framework */, + BDCCB7D0C262E7F2817D7DE4 /* Pods_VBBFrameworkPods_VBBFramework_macOS.framework */, + 285021482A6ED538287500DD /* Pods_VBBFrameworkPods_VBB.framework */, + AFEE9A1EECB9500388A2A98A /* Pods_VBBFrameworkPods_VBBNow.framework */, + 3421FA8B2C099BFC93F860C2 /* Pods_VBBFrameworkPods_VBBWatch_Extension.framework */, ); name = Frameworks; sourceTree = ""; @@ -220,9 +591,10 @@ children = ( E157C33D2099CC2400C0CD60 /* Info.plist */, E157C3492099CC3800C0CD60 /* Manager */, + 7967A74922B67108004FA671 /* Miscellaneous */, E157C3482099CC3000C0CD60 /* Model */, E157C3472099CC2A00C0CD60 /* Parser */, - E157C33C2099CC2400C0CD60 /* VBBFramework.h */, + 79A867DA22B54B040002F85D /* Support Files */, ); path = VBBFramework; sourceTree = ""; @@ -303,6 +675,8 @@ children = ( E19086CC1A79870300364EA2 /* VBB */, E1AEBBE91A7B701D00196F97 /* VBBNow */, + 7968954122B5574E002EAF84 /* VBBWatch App */, + 7968955022B5574F002EAF84 /* VBBWatch Extension */, E157C33B2099CC2400C0CD60 /* VBBFramework */, E19086CB1A79870300364EA2 /* Products */, E114AB8D017F74B47967DFA8 /* Frameworks */, @@ -313,9 +687,13 @@ E19086CB1A79870300364EA2 /* Products */ = { isa = PBXGroup; children = ( - E19086CA1A79870300364EA2 /* VBB.app */, + E19086CA1A79870300364EA2 /* VBBNow.app */, E1AEBBE71A7B701D00196F97 /* VBBNow.appex */, E157C33A2099CC2400C0CD60 /* VBBFramework.framework */, + 79A8682C22B54CA40002F85D /* VBBFramework.framework */, + 7968953A22B5574E002EAF84 /* VBBWatch.app */, + 7968953D22B5574E002EAF84 /* VBBWatch App.app */, + 7968954C22B5574F002EAF84 /* VBBWatch Extension.appex */, ); name = Products; sourceTree = ""; @@ -326,7 +704,6 @@ E17A6ABA1C770CF900506B8A /* VBB.entitlements */, E19086CF1A79870300364EA2 /* AppDelegate.h */, E19086D01A79870300364EA2 /* AppDelegate.m */, - E17F97A21A7C0E4800623FB2 /* Icons.xcassets */, E19086D61A79870300364EA2 /* MainMenu.xib */, E19086CD1A79870300364EA2 /* Supporting Files */, ); @@ -337,6 +714,7 @@ E19086CD1A79870300364EA2 /* Supporting Files */ = { isa = PBXGroup; children = ( + 7951B07222F4BC1600FBA206 /* Icons.xcassets */, E19086CE1A79870300364EA2 /* Info.plist */, E19086D21A79870300364EA2 /* main.m */, ); @@ -355,19 +733,45 @@ /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ + 79A8681C22B54CA40002F85D /* Headers */ = { + isa = PBXHeadersBuildPhase; + buildActionMask = 2147483647; + files = ( + 79A8681D22B54CA40002F85D /* VBBFramework.h in Headers */, + 79A8681E22B54CA40002F85D /* VBBNetworkManager.h in Headers */, + 79A8681F22B54CA40002F85D /* VBBPersistanceManager.h in Headers */, + 7967A75022B671F3004FA671 /* NSDateComponentsFormatter+VBB.h in Headers */, + 79A8682022B54CA40002F85D /* VBBStation.h in Headers */, + 79A8682122B54CA40002F85D /* VBBDepature.h in Headers */, + 79A8682222B54CA40002F85D /* VBBLine.h in Headers */, + 79A8682322B54CA40002F85D /* VBBLocation.h in Headers */, + 79A8683E22B5518E0002F85D /* VBBFramework-umbrella.h in Headers */, + 790388C122F4C993002326D9 /* NSBundle+VBB.h in Headers */, + 79AF31CA22F61A90006F7881 /* Realm-VBB.h in Headers */, + 79A8682422B54CA40002F85D /* VBBaseParser.h in Headers */, + 79A8682522B54CA40002F85D /* VBBStationParser.h in Headers */, + 79A8682722B54CA40002F85D /* VBBDepatureParser.h in Headers */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; E157C3372099CC2400C0CD60 /* Headers */ = { isa = PBXHeadersBuildPhase; buildActionMask = 2147483647; files = ( E157C33E2099CC2400C0CD60 /* VBBFramework.h in Headers */, - E157C3822099D06A00C0CD60 /* VBBNetworkManager.h in Headers */, E157C3832099D06A00C0CD60 /* VBBPersistanceManager.h in Headers */, E157C3842099D06A00C0CD60 /* VBBStation.h in Headers */, + 790388C022F4C993002326D9 /* NSBundle+VBB.h in Headers */, E157C3852099D06A00C0CD60 /* VBBDepature.h in Headers */, E157C3862099D06A00C0CD60 /* VBBLine.h in Headers */, + 7967A74E22B6715D004FA671 /* NSDateComponentsFormatter+VBB.h in Headers */, E157C3872099D06A00C0CD60 /* VBBLocation.h in Headers */, + 7970D99822F3636400D96BEB /* VBBNetworkManager.h in Headers */, E157C3882099D06A00C0CD60 /* VBBaseParser.h in Headers */, E157C3892099D06A00C0CD60 /* VBBStationParser.h in Headers */, + 79653F5022BABAA60040A51F /* NSString+VBB.h in Headers */, + 79A867DD22B54B160002F85D /* VBBFramework-umbrella.h in Headers */, + 79AF31C822F61A8F006F7881 /* Realm-VBB.h in Headers */, E157C38A2099D06A00C0CD60 /* VBBDepatureParser.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; @@ -375,9 +779,85 @@ /* End PBXHeadersBuildPhase section */ /* Begin PBXNativeTarget section */ - E157C3392099CC2400C0CD60 /* VBBFramework */ = { + 7968953922B5574E002EAF84 /* VBBWatch */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7968956522B5574F002EAF84 /* Build configuration list for PBXNativeTarget "VBBWatch" */; + buildPhases = ( + 7968953822B5574E002EAF84 /* Resources */, + 7968956422B5574F002EAF84 /* Embed Watch Content */, + B62765DEBCD442FD0EF7E12B /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7968954022B5574E002EAF84 /* PBXTargetDependency */, + ); + name = VBBWatch; + productName = VBBWatch; + productReference = 7968953A22B5574E002EAF84 /* VBBWatch.app */; + productType = "com.apple.product-type.application.watchapp2-container"; + }; + 7968953C22B5574E002EAF84 /* VBBWatch App */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7968956122B5574F002EAF84 /* Build configuration list for PBXNativeTarget "VBBWatch App" */; + buildPhases = ( + 7968953B22B5574E002EAF84 /* Resources */, + 7968956022B5574F002EAF84 /* Embed App Extensions */, + 389B04799A1AAFD2E3F38482 /* Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7968954F22B5574F002EAF84 /* PBXTargetDependency */, + ); + name = "VBBWatch App"; + productName = "VBBWatch WatchKit App"; + productReference = 7968953D22B5574E002EAF84 /* VBBWatch App.app */; + productType = "com.apple.product-type.application.watchapp2"; + }; + 7968954B22B5574F002EAF84 /* VBBWatch Extension */ = { + isa = PBXNativeTarget; + buildConfigurationList = 7968955D22B5574F002EAF84 /* Build configuration list for PBXNativeTarget "VBBWatch Extension" */; + buildPhases = ( + 3924C1B2F8F28EC4FF923B99 /* [CP] Check Pods Manifest.lock */, + 7968954822B5574F002EAF84 /* Sources */, + 7968954922B5574F002EAF84 /* Frameworks */, + 7968954A22B5574F002EAF84 /* Resources */, + 7968956C22B55762002EAF84 /* Embed Frameworks */, + FF51DDE7E25771F1B1424D93 /* [CP] Embed Pods Frameworks */, + ); + buildRules = ( + ); + dependencies = ( + 7968956B22B55762002EAF84 /* PBXTargetDependency */, + ); + name = "VBBWatch Extension"; + productName = "VBBWatch WatchKit Extension"; + productReference = 7968954C22B5574F002EAF84 /* VBBWatch Extension.appex */; + productType = "com.apple.product-type.watchkit2-extension"; + }; + 79A8680E22B54CA40002F85D /* VBBFramework-WatchOS */ = { isa = PBXNativeTarget; - buildConfigurationList = E157C3452099CC2400C0CD60 /* Build configuration list for PBXNativeTarget "VBBFramework" */; + buildConfigurationList = 79A8682922B54CA40002F85D /* Build configuration list for PBXNativeTarget "VBBFramework-WatchOS" */; + buildPhases = ( + 79A8680F22B54CA40002F85D /* [CP] Check Pods Manifest.lock */, + 79A8681022B54CA40002F85D /* Sources */, + 79A8681A22B54CA40002F85D /* Frameworks */, + 79A8681C22B54CA40002F85D /* Headers */, + 79A8682822B54CA40002F85D /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = "VBBFramework-WatchOS"; + productName = VBBFramework; + productReference = 79A8682C22B54CA40002F85D /* VBBFramework.framework */; + productType = "com.apple.product-type.framework"; + }; + E157C3392099CC2400C0CD60 /* VBBFramework-macOS */ = { + isa = PBXNativeTarget; + buildConfigurationList = E157C3452099CC2400C0CD60 /* Build configuration list for PBXNativeTarget "VBBFramework-macOS" */; buildPhases = ( 264B07C77728EA84BC85CA4F /* [CP] Check Pods Manifest.lock */, E157C3352099CC2400C0CD60 /* Sources */, @@ -389,7 +869,7 @@ ); dependencies = ( ); - name = VBBFramework; + name = "VBBFramework-macOS"; productName = VBBFramework; productReference = E157C33A2099CC2400C0CD60 /* VBBFramework.framework */; productType = "com.apple.product-type.framework"; @@ -398,13 +878,13 @@ isa = PBXNativeTarget; buildConfigurationList = E19086E71A79870300364EA2 /* Build configuration list for PBXNativeTarget "VBB" */; buildPhases = ( - 614ACA198863A10FF6843720 /* [CP] Check Pods Manifest.lock */, + 3F1BB7193E36977CE2FF86E6 /* [CP] Check Pods Manifest.lock */, E19086C61A79870300364EA2 /* Sources */, E19086C71A79870300364EA2 /* Frameworks */, E19086C81A79870300364EA2 /* Resources */, E1948A921A7A3DEB005C9D97 /* Embed App Extensions */, E157C3462099CC2400C0CD60 /* Embed Frameworks */, - 86541FE9AA960EC91AE11AC2 /* [CP] Embed Pods Frameworks */, + 1770E394FD22251233F49B16 /* [CP] Embed Pods Frameworks */, ); buildRules = ( ); @@ -414,17 +894,18 @@ ); name = VBB; productName = VBB/; - productReference = E19086CA1A79870300364EA2 /* VBB.app */; + productReference = E19086CA1A79870300364EA2 /* VBBNow.app */; productType = "com.apple.product-type.application"; }; E1AEBBE61A7B701D00196F97 /* VBBNow */ = { isa = PBXNativeTarget; buildConfigurationList = E1AEBBFD1A7B701D00196F97 /* Build configuration list for PBXNativeTarget "VBBNow" */; buildPhases = ( - 9284CEDE3076668EC2ECA92D /* [CP] Check Pods Manifest.lock */, + 8861021FDE16031313BF649E /* [CP] Check Pods Manifest.lock */, E1AEBBE31A7B701D00196F97 /* Sources */, E1AEBBE41A7B701D00196F97 /* Frameworks */, E1AEBBE51A7B701D00196F97 /* Resources */, + 79A32CF522E4CB490030A481 /* Embed Frameworks */, ); buildRules = ( ); @@ -443,9 +924,29 @@ isa = PBXProject; attributes = { CLASSPREFIX = VBB; - LastUpgradeCheck = 1010; + LastSwiftUpdateCheck = 1100; + LastUpgradeCheck = 1100; ORGANIZATIONNAME = "Dennis Oberhoff"; TargetAttributes = { + 7968953922B5574E002EAF84 = { + CreatedOnToolsVersion = 11.0; + DevelopmentTeam = YE33ZK7Z99; + ProvisioningStyle = Automatic; + }; + 7968953C22B5574E002EAF84 = { + CreatedOnToolsVersion = 11.0; + DevelopmentTeam = YE33ZK7Z99; + ProvisioningStyle = Automatic; + }; + 7968954B22B5574F002EAF84 = { + CreatedOnToolsVersion = 11.0; + DevelopmentTeam = YE33ZK7Z99; + ProvisioningStyle = Automatic; + }; + 79A8680E22B54CA40002F85D = { + DevelopmentTeam = YE33ZK7Z99; + ProvisioningStyle = Automatic; + }; E157C3392099CC2400C0CD60 = { CreatedOnToolsVersion = 9.3; DevelopmentTeam = YE33ZK7Z99; @@ -477,11 +978,12 @@ }; buildConfigurationList = E19086C51A79870300364EA2 /* Build configuration list for PBXProject "VBB" */; compatibilityVersion = "Xcode 3.2"; - developmentRegion = English; + developmentRegion = en; hasScannedForEncodings = 0; knownRegions = ( en, Base, + de, ); mainGroup = E19086C11A79870300364EA2; productRefGroup = E19086CB1A79870300364EA2 /* Products */; @@ -490,16 +992,55 @@ targets = ( E19086C91A79870300364EA2 /* VBB */, E1AEBBE61A7B701D00196F97 /* VBBNow */, - E157C3392099CC2400C0CD60 /* VBBFramework */, + 7968953922B5574E002EAF84 /* VBBWatch */, + 7968953C22B5574E002EAF84 /* VBBWatch App */, + 7968954B22B5574F002EAF84 /* VBBWatch Extension */, + E157C3392099CC2400C0CD60 /* VBBFramework-macOS */, + 79A8680E22B54CA40002F85D /* VBBFramework-WatchOS */, ); }; /* End PBXProject section */ /* Begin PBXResourcesBuildPhase section */ + 7968953822B5574E002EAF84 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7968953B22B5574E002EAF84 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7968954622B5574F002EAF84 /* Assets.xcassets in Resources */, + 7968954422B5574E002EAF84 /* Interface.storyboard in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 7968954A22B5574F002EAF84 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7968955B22B5574F002EAF84 /* Preview Assets.xcassets in Resources */, + 79B2591522F6E526005224E2 /* Localizable.strings in Resources */, + 7968955822B5574F002EAF84 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79A8682822B54CA40002F85D /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 7951B07122F4B69800FBA206 /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; E157C3382099CC2400C0CD60 /* Resources */ = { isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( + 7951B07022F4B69800FBA206 /* Assets.xcassets in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -507,7 +1048,7 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - E1F6153B1A7D407F00EEA639 /* Icons.xcassets in Resources */, + 79AF31BD22F59AEA006F7881 /* Icons.xcassets in Resources */, E15C8B6B1A7C0F3C0080EE8B /* MainMenu.xib in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -519,7 +1060,6 @@ E17F97A81A7C0E4800623FB2 /* vbbnow.entitlements in Resources */, 79B1495B21DCB3A7001E5FEB /* VBBListRowViewController.xib in Resources */, 79B1495A21DCB3A4001E5FEB /* VBBTodayViewController.xib in Resources */, - E17F97A61A7C0E4800623FB2 /* Icons.xcassets in Resources */, E17F97A51A7C0E4800623FB2 /* InfoPlist.strings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -527,6 +1067,24 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ + 1770E394FD22251233F49B16 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-VBBFrameworkPods-VBB/Pods-VBBFrameworkPods-VBB-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Realm-macOS/Realm.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VBBFrameworkPods-VBB/Pods-VBBFrameworkPods-VBB-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; 264B07C77728EA84BC85CA4F /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; @@ -538,50 +1096,58 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-VBBPods-VBBFramework-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-VBBFrameworkPods-VBBFramework-macOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 614ACA198863A10FF6843720 /* [CP] Check Pods Manifest.lock */ = { + 3924C1B2F8F28EC4FF923B99 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( "${PODS_PODFILE_DIR_PATH}/Podfile.lock", "${PODS_ROOT}/Manifest.lock", ); name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-VBBPods-VBB-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-VBBFrameworkPods-VBBWatch Extension-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 86541FE9AA960EC91AE11AC2 /* [CP] Embed Pods Frameworks */ = { + 3F1BB7193E36977CE2FF86E6 /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); + inputFileListPaths = ( + ); inputPaths = ( - "${SRCROOT}/Pods/Target Support Files/Pods-VBBPods-VBB/Pods-VBBPods-VBB-frameworks.sh", - "${BUILT_PRODUCTS_DIR}/Realm/Realm.framework", + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( ); - name = "[CP] Embed Pods Frameworks"; outputPaths = ( - "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + "$(DERIVED_FILE_DIR)/Pods-VBBFrameworkPods-VBB-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-VBBPods-VBB/Pods-VBBPods-VBB-frameworks.sh\"\n"; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; - 9284CEDE3076668EC2ECA92D /* [CP] Check Pods Manifest.lock */ = { + 79A8680F22B54CA40002F85D /* [CP] Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( @@ -592,20 +1158,108 @@ ); name = "[CP] Check Pods Manifest.lock"; outputPaths = ( - "$(DERIVED_FILE_DIR)/Pods-VBBPods-VBBNow-checkManifestLockResult.txt", + "$(DERIVED_FILE_DIR)/Pods-VBBFrameworkPods-VBBFramework-WatchOS-checkManifestLockResult.txt", ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; showEnvVarsInLog = 0; }; + 8861021FDE16031313BF649E /* [CP] Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputFileListPaths = ( + ); + inputPaths = ( + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", + "${PODS_ROOT}/Manifest.lock", + ); + name = "[CP] Check Pods Manifest.lock"; + outputFileListPaths = ( + ); + outputPaths = ( + "$(DERIVED_FILE_DIR)/Pods-VBBFrameworkPods-VBBNow-checkManifestLockResult.txt", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; + showEnvVarsInLog = 0; + }; + FF51DDE7E25771F1B1424D93 /* [CP] Embed Pods Frameworks */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + "${PODS_ROOT}/Target Support Files/Pods-VBBFrameworkPods-VBBWatch Extension/Pods-VBBFrameworkPods-VBBWatch Extension-frameworks.sh", + "${BUILT_PRODUCTS_DIR}/Realm-watchOS/Realm.framework", + ); + name = "[CP] Embed Pods Frameworks"; + outputPaths = ( + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Realm.framework", + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-VBBFrameworkPods-VBBWatch Extension/Pods-VBBFrameworkPods-VBBWatch Extension-frameworks.sh\"\n"; + showEnvVarsInLog = 0; + }; /* End PBXShellScriptBuildPhase section */ /* Begin PBXSourcesBuildPhase section */ + 7968954822B5574F002EAF84 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 79290564233558C8001D6737 /* OnboardingPresenter.swift in Sources */, + 7968955422B5574F002EAF84 /* HostingController.swift in Sources */, + 79C3AA4422B9689E00EACD7A /* OnboardingView.swift in Sources */, + 79ED02A222B96CE00089AB45 /* ParentPresenter.swift in Sources */, + 7968955222B5574F002EAF84 /* DepartureListView.swift in Sources */, + 7962705E234126E20076EB39 /* TimeInterval-Extension.swift in Sources */, + 797DF3AF233FF4CE00764404 /* NSNotification-Extensions.swift in Sources */, + 7951B06B22F4085800FBA206 /* View-Gradient.swift in Sources */, + 79A8C61A22BEB842002BE5D6 /* ParentView.swift in Sources */, + 7967A74822B66AF3004FA671 /* VBBLine-Extension.swift in Sources */, + 791EDCDE22F37BF9006F6113 /* DeparturePresenter.swift in Sources */, + 794A506D2337AFDE00AFA228 /* VBBNetworkStatus-Extension.swift in Sources */, + 79AF31C122F6157A006F7881 /* LinePresenter.swift in Sources */, + 7951B06D22F4129400FBA206 /* VBBDeparture-Extension.swift in Sources */, + 7968955622B5574F002EAF84 /* ExtensionDelegate.swift in Sources */, + 79AF31C322F61609006F7881 /* LineView.swift in Sources */, + 79051D6022B57B3B00694592 /* DepartureListPresenter.swift in Sources */, + 79C5648822B55BD000039D3C /* DepartureView.swift in Sources */, + 7967A75422B679EB004FA671 /* VBBStation-Extension.swift in Sources */, + 79EA57D222FA0279009A2D15 /* LoadingView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 79A8681022B54CA40002F85D /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 790388C322F4C993002326D9 /* NSBundle+VBB.m in Sources */, + 79A8681122B54CA40002F85D /* VBBLine.m in Sources */, + 79A8681222B54CA40002F85D /* VBBStationParser.m in Sources */, + 79A8681322B54CA40002F85D /* VBBLocation.m in Sources */, + 79A8681422B54CA40002F85D /* VBBDepature.m in Sources */, + 79653F5222BABEA60040A51F /* NSDateComponentsFormatter+VBB.m in Sources */, + 79A8681522B54CA40002F85D /* VBBPersistanceManager.m in Sources */, + 79A8681622B54CA40002F85D /* VBBDepatureParser.m in Sources */, + 79A8681722B54CA40002F85D /* VBBNetworkManager.m in Sources */, + 79653F5322BABEA60040A51F /* NSString+VBB.m in Sources */, + 79A8681822B54CA40002F85D /* VBBaseParser.m in Sources */, + 79AF31CB22F61A90006F7881 /* Realm-VBB.m in Sources */, + 79A8681922B54CA40002F85D /* VBBStation.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; E157C3352099CC2400C0CD60 /* Sources */ = { isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( + 790388C222F4C993002326D9 /* NSBundle+VBB.m in Sources */, E157C37D2099CD9A00C0CD60 /* VBBLine.m in Sources */, E157C3792099CD9400C0CD60 /* VBBStationParser.m in Sources */, E157C37E2099CD9A00C0CD60 /* VBBLocation.m in Sources */, @@ -613,7 +1267,10 @@ E157C3802099CD9E00C0CD60 /* VBBPersistanceManager.m in Sources */, E157C37A2099CD9400C0CD60 /* VBBDepatureParser.m in Sources */, E157C37F2099CD9E00C0CD60 /* VBBNetworkManager.m in Sources */, + 7967A74F22B6715D004FA671 /* NSDateComponentsFormatter+VBB.m in Sources */, + 79653F5122BABAA60040A51F /* NSString+VBB.m in Sources */, E157C3782099CD9400C0CD60 /* VBBaseParser.m in Sources */, + 79AF31C922F61A8F006F7881 /* Realm-VBB.m in Sources */, E157C37B2099CD9A00C0CD60 /* VBBStation.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -639,6 +1296,21 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXTargetDependency section */ + 7968954022B5574E002EAF84 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7968953C22B5574E002EAF84 /* VBBWatch App */; + targetProxy = 7968953F22B5574E002EAF84 /* PBXContainerItemProxy */; + }; + 7968954F22B5574F002EAF84 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 7968954B22B5574F002EAF84 /* VBBWatch Extension */; + targetProxy = 7968954E22B5574F002EAF84 /* PBXContainerItemProxy */; + }; + 7968956B22B55762002EAF84 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 79A8680E22B54CA40002F85D /* VBBFramework-WatchOS */; + targetProxy = 7968956A22B55762002EAF84 /* PBXContainerItemProxy */; + }; 79B1496321DCB5A2001E5FEB /* PBXTargetDependency */ = { isa = PBXTargetDependency; target = E1AEBBE61A7B701D00196F97 /* VBBNow */; @@ -646,17 +1318,34 @@ }; E157C3402099CC2400C0CD60 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E157C3392099CC2400C0CD60 /* VBBFramework */; + target = E157C3392099CC2400C0CD60 /* VBBFramework-macOS */; targetProxy = E157C33F2099CC2400C0CD60 /* PBXContainerItemProxy */; }; E157C38C2099D5DD00C0CD60 /* PBXTargetDependency */ = { isa = PBXTargetDependency; - target = E157C3392099CC2400C0CD60 /* VBBFramework */; + target = E157C3392099CC2400C0CD60 /* VBBFramework-macOS */; targetProxy = E157C38B2099D5DD00C0CD60 /* PBXContainerItemProxy */; }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ + 7968954222B5574E002EAF84 /* Interface.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 7968954322B5574E002EAF84 /* Base */, + ); + name = Interface.storyboard; + sourceTree = ""; + }; + 79B2591722F6E526005224E2 /* Localizable.strings */ = { + isa = PBXVariantGroup; + children = ( + 79B2591622F6E526005224E2 /* en */, + 7929056523356C1C001D6737 /* de */, + ); + name = Localizable.strings; + sourceTree = ""; + }; E17F97A01A7C0E4800623FB2 /* InfoPlist.strings */ = { isa = PBXVariantGroup; children = ( @@ -676,9 +1365,198 @@ /* End PBXVariantGroup section */ /* Begin XCBuildConfiguration section */ - E157C3432099CC2400C0CD60 /* Debug */ = { + 7968955E22B5574F002EAF84 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = CB625DCF924575090FED786C /* Pods-VBBFrameworkPods-VBBWatch Extension.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 20; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_ASSET_PATHS = "VBBWatch\\ Extension/Support\\ Files/Preview\\ Content"; + DEVELOPMENT_TEAM = YE33ZK7Z99; + ENABLE_PREVIEWS = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "VBBWatch Extension/Support Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBWatch.watchkitapp.watchkitextension; + PRODUCT_NAME = "${TARGET_NAME}"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 6.0; + }; + name = Debug; + }; + 7968955F22B5574F002EAF84 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 0167B0997B867BBF926B3FB2 /* Pods-VBBFrameworkPods-VBBWatch Extension.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_COMPLICATION_NAME = Complication; + CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 20; + DEVELOPMENT_ASSET_PATHS = "VBBWatch\\ Extension/Support\\ Files/Preview\\ Content"; + DEVELOPMENT_TEAM = YE33ZK7Z99; + ENABLE_PREVIEWS = YES; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = "VBBWatch Extension/Support Files/Info.plist"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBWatch.watchkitapp.watchkitextension; + PRODUCT_NAME = "${TARGET_NAME}"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 6.0; + }; + name = Release; + }; + 7968956222B5574F002EAF84 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 20; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = YE33ZK7Z99; + GCC_C_LANGUAGE_STANDARD = gnu11; + IBSC_MODULE = VBBWatch_Extension; + INFOPLIST_FILE = "VBBWatch App/Info.plist"; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBWatch.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + WATCHOS_DEPLOYMENT_TARGET = 6.0; + }; + name = Debug; + }; + 7968956322B5574F002EAF84 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 20; + DEVELOPMENT_TEAM = YE33ZK7Z99; + GCC_C_LANGUAGE_STANDARD = gnu11; + IBSC_MODULE = VBBWatch_Extension; + INFOPLIST_FILE = "VBBWatch App/Info.plist"; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBWatch.watchkitapp; + PRODUCT_NAME = "$(TARGET_NAME)"; + SDKROOT = watchos; + SKIP_INSTALL = YES; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + TARGETED_DEVICE_FAMILY = 4; + VALIDATE_PRODUCT = YES; + WATCHOS_DEPLOYMENT_TARGET = 6.0; + }; + name = Release; + }; + 7968956622B5574F002EAF84 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 20; + DEBUG_INFORMATION_FORMAT = dwarf; + DEVELOPMENT_TEAM = YE33ZK7Z99; + GCC_C_LANGUAGE_STANDARD = gnu11; + MARKETING_VERSION = 1.0; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBWatch; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 7968956722B5574F002EAF84 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = "Apple Development"; + CODE_SIGN_STYLE = Automatic; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 20; + DEVELOPMENT_TEAM = YE33ZK7Z99; + GCC_C_LANGUAGE_STANDARD = gnu11; + MARKETING_VERSION = 1.0; + MTL_FAST_MATH = YES; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBWatch; + PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE_SPECIFIER = ""; + SDKROOT = iphoneos; + SWIFT_OPTIMIZATION_LEVEL = "-O"; + SWIFT_VERSION = 5.0; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 79A8682A22B54CA40002F85D /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 0B61806681AAA7E29F1AA122 /* Pods-VBBPods-VBBFramework.debug.xcconfig */; + baseConfigurationReference = 28E87E95EDA4B923462F4D83 /* Pods-VBBFrameworkPods-VBBFramework-WatchOS.debug.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; @@ -711,18 +1589,20 @@ INFOPLIST_FILE = VBBFramework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MODULEMAP_FILE = "VBBFramework/Support Files/VBBFramework.modulemap"; PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBFramework; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = VBBFramework; + SDKROOT = watchos; SKIP_INSTALL = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 6.0; }; name = Debug; }; - E157C3442099CC2400C0CD60 /* Release */ = { + 79A8682B22B54CA40002F85D /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = DA14C1F48BCDD3F011F7DA68 /* Pods-VBBPods-VBBFramework.release.xcconfig */; + baseConfigurationReference = 16D192B187425E69B9B2A938 /* Pods-VBBFrameworkPods-VBBFramework-WatchOS.release.xcconfig */; buildSettings = { APPLICATION_EXTENSION_API_ONLY = YES; CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; @@ -755,12 +1635,110 @@ INFOPLIST_FILE = VBBFramework/Info.plist; INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; + MODULEMAP_FILE = "VBBFramework/Support Files/VBBFramework.modulemap"; PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBFramework; - PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)"; + PRODUCT_NAME = VBBFramework; + SDKROOT = watchos; SKIP_INSTALL = YES; VERSIONING_SYSTEM = "apple-generic"; VERSION_INFO_PREFIX = ""; + WATCHOS_DEPLOYMENT_TARGET = 6.0; + }; + name = Release; + }; + E157C3432099CC2400C0CD60 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 3C7FF169CB98E57F7920091C /* Pods-VBBFrameworkPods-VBBFramework-macOS.debug.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 1; + DEBUG_INFORMATION_FORMAT = dwarf; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = YE33ZK7Z99; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = VBBFramework/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MODULEMAP_FILE = "VBBFramework/Support Files/VBBFramework.modulemap"; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBFramework; + PRODUCT_MODULE_NAME = VBBFramework; + PRODUCT_NAME = VBBFramework; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SUPPORTS_UIKITFORMAC = NO; + TARGETED_DEVICE_FAMILY = 1; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; + }; + name = Debug; + }; + E157C3442099CC2400C0CD60 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 20973B06F87F036D3A4110F2 /* Pods-VBBFrameworkPods-VBBFramework-macOS.release.xcconfig */; + buildSettings = { + APPLICATION_EXTENSION_API_ONLY = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++14"; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CODE_SIGN_IDENTITY = ""; + CODE_SIGN_STYLE = Automatic; + COMBINE_HIDPI_IMAGES = YES; + COPY_PHASE_STRIP = NO; + CURRENT_PROJECT_VERSION = 1; + DEFINES_MODULE = YES; + DEVELOPMENT_TEAM = YE33ZK7Z99; + DYLIB_COMPATIBILITY_VERSION = 1; + DYLIB_CURRENT_VERSION = 1; + DYLIB_INSTALL_NAME_BASE = "@rpath"; + FRAMEWORK_VERSION = A; + GCC_C_LANGUAGE_STANDARD = gnu11; + INFOPLIST_FILE = VBBFramework/Info.plist; + INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @loader_path/Frameworks"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MODULEMAP_FILE = "VBBFramework/Support Files/VBBFramework.modulemap"; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBFramework; + PRODUCT_MODULE_NAME = VBBFramework; + PRODUCT_NAME = VBBFramework; + SDKROOT = macosx; + SKIP_INSTALL = YES; + SUPPORTS_UIKITFORMAC = NO; + TARGETED_DEVICE_FAMILY = 1; + VERSIONING_SYSTEM = "apple-generic"; + VERSION_INFO_PREFIX = ""; }; name = Release; }; @@ -768,6 +1746,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -821,6 +1800,7 @@ isa = XCBuildConfiguration; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; CLANG_CXX_LIBRARY = "libc++"; CLANG_ENABLE_MODULES = YES; @@ -860,53 +1840,63 @@ MACOSX_DEPLOYMENT_TARGET = 10.11; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = macosx; + SWIFT_COMPILATION_MODE = wholemodule; }; name = Release; }; E19086E81A79870300364EA2 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B0957EF3840658A2EB7B3B1A /* Pods-VBBPods-VBB.debug.xcconfig */; + baseConfigurationReference = 7AA5C8D3A5AC7FE7FFE62ACD /* Pods-VBBFrameworkPods-VBB.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = VBB/VBB.entitlements; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 11; + DEFINES_MODULE = NO; DEVELOPMENT_TEAM = YE33ZK7Z99; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = "VBB//Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = "com.obrhoff.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 1.2; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBMac; + PRODUCT_NAME = VBBNow; }; name = Debug; }; E19086E91A79870300364EA2 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = B4EDD8701BB4D2A7152E0253 /* Pods-VBBPods-VBB.release.xcconfig */; + baseConfigurationReference = F0B41255AA6C835D0479A7B6 /* Pods-VBBFrameworkPods-VBB.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_ENTITLEMENTS = VBB/VBB.entitlements; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 11; + DEFINES_MODULE = NO; DEVELOPMENT_TEAM = YE33ZK7Z99; + ENABLE_HARDENED_RUNTIME = YES; INFOPLIST_FILE = "VBB//Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = "com.obrhoff.$(PRODUCT_NAME:rfc1034identifier)"; - PRODUCT_NAME = "$(TARGET_NAME)"; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 1.2; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBMac; + PRODUCT_NAME = VBBNow; }; name = Release; }; E1AEBBFE1A7B701D00196F97 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 16AAB8987028C777D0FBCE02 /* Pods-VBBPods-VBBNow.debug.xcconfig */; + baseConfigurationReference = 2BC934B59A728B7BEA0636B3 /* Pods-VBBFrameworkPods-VBBNow.debug.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "VBBNow/Supporting Files/VBBNow.entitlements"; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_TEAM = YE33ZK7Z99; + ENABLE_HARDENED_RUNTIME = YES; GCC_PREPROCESSOR_DEFINITIONS = ( "DEBUG=1", "$(inherited)", @@ -914,8 +1904,9 @@ HEADER_SEARCH_PATHS = "${SRCROOT}/**"; INFOPLIST_FILE = "VBBNow/Supporting Files/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBB.Widget; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 1.1; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBMac.Widget; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; @@ -923,19 +1914,21 @@ }; E1AEBBFF1A7B701D00196F97 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 67F15DD87868EF68F4B521BF /* Pods-VBBPods-VBBNow.release.xcconfig */; + baseConfigurationReference = 9F15AF78642C8708D51A0C35 /* Pods-VBBFrameworkPods-VBBNow.release.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - CLANG_ALLOW_NON_MODULAR_INCLUDES_IN_FRAMEWORK_MODULES = YES; CODE_SIGN_ENTITLEMENTS = "VBBNow/Supporting Files/VBBNow.entitlements"; CODE_SIGN_IDENTITY = "Mac Developer"; COMBINE_HIDPI_IMAGES = YES; + CURRENT_PROJECT_VERSION = 9; DEVELOPMENT_TEAM = YE33ZK7Z99; + ENABLE_HARDENED_RUNTIME = YES; HEADER_SEARCH_PATHS = "${SRCROOT}/**"; INFOPLIST_FILE = "VBBNow/Supporting Files/Info.plist"; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/../Frameworks @executable_path/../../../../Frameworks"; - MACOSX_DEPLOYMENT_TARGET = 10.11; - PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBB.Widget; + MACOSX_DEPLOYMENT_TARGET = 10.13; + MARKETING_VERSION = 1.1; + PRODUCT_BUNDLE_IDENTIFIER = com.obrhoff.VBBMac.Widget; PRODUCT_NAME = "$(TARGET_NAME)"; SKIP_INSTALL = YES; }; @@ -944,7 +1937,43 @@ /* End XCBuildConfiguration section */ /* Begin XCConfigurationList section */ - E157C3452099CC2400C0CD60 /* Build configuration list for PBXNativeTarget "VBBFramework" */ = { + 7968955D22B5574F002EAF84 /* Build configuration list for PBXNativeTarget "VBBWatch Extension" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7968955E22B5574F002EAF84 /* Debug */, + 7968955F22B5574F002EAF84 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7968956122B5574F002EAF84 /* Build configuration list for PBXNativeTarget "VBBWatch App" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7968956222B5574F002EAF84 /* Debug */, + 7968956322B5574F002EAF84 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 7968956522B5574F002EAF84 /* Build configuration list for PBXNativeTarget "VBBWatch" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 7968956622B5574F002EAF84 /* Debug */, + 7968956722B5574F002EAF84 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 79A8682922B54CA40002F85D /* Build configuration list for PBXNativeTarget "VBBFramework-WatchOS" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 79A8682A22B54CA40002F85D /* Debug */, + 79A8682B22B54CA40002F85D /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + E157C3452099CC2400C0CD60 /* Build configuration list for PBXNativeTarget "VBBFramework-macOS" */ = { isa = XCConfigurationList; buildConfigurations = ( E157C3432099CC2400C0CD60 /* Debug */, diff --git a/VBB.xcodeproj/xcshareddata/xcschemes/VBB.xcscheme b/VBB.xcodeproj/xcshareddata/xcschemes/VBB.xcscheme new file mode 100644 index 0000000..39e1ad7 --- /dev/null +++ b/VBB.xcodeproj/xcshareddata/xcschemes/VBB.xcscheme @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VBB.xcodeproj/xcshareddata/xcschemes/VBBFramework-WatchOS.xcscheme b/VBB.xcodeproj/xcshareddata/xcschemes/VBBFramework-WatchOS.xcscheme new file mode 100644 index 0000000..b319121 --- /dev/null +++ b/VBB.xcodeproj/xcshareddata/xcschemes/VBBFramework-WatchOS.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VBB.xcodeproj/xcshareddata/xcschemes/VBBFramework-macOS.xcscheme b/VBB.xcodeproj/xcshareddata/xcschemes/VBBFramework-macOS.xcscheme new file mode 100644 index 0000000..805501d --- /dev/null +++ b/VBB.xcodeproj/xcshareddata/xcschemes/VBBFramework-macOS.xcscheme @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VBB.xcodeproj/xcshareddata/xcschemes/VBBNow (macOS).xcscheme b/VBB.xcodeproj/xcshareddata/xcschemes/VBBNow (macOS).xcscheme new file mode 100644 index 0000000..25dfa6c --- /dev/null +++ b/VBB.xcodeproj/xcshareddata/xcschemes/VBBNow (macOS).xcscheme @@ -0,0 +1,100 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VBB.xcodeproj/xcshareddata/xcschemes/VBBWatch App.xcscheme b/VBB.xcodeproj/xcshareddata/xcschemes/VBBWatch App.xcscheme new file mode 100644 index 0000000..27d9785 --- /dev/null +++ b/VBB.xcodeproj/xcshareddata/xcschemes/VBBWatch App.xcscheme @@ -0,0 +1,105 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/VBB/Icons.xcassets/AppIcon.appiconset/Contents.json b/VBB/Icons.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..5177ecb --- /dev/null +++ b/VBB/Icons.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,68 @@ +{ + "images": [ + { + "size": "16x16", + "idiom": "mac", + "filename": "Icon_16x16.png", + "scale": "1x" + }, + { + "size": "16x16", + "idiom": "mac", + "filename": "Icon_16x16@2x.png", + "scale": "2x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "Icon_32x32.png", + "scale": "1x" + }, + { + "size": "32x32", + "idiom": "mac", + "filename": "Icon_32x32@2x.png", + "scale": "2x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "Icon_128x128.png", + "scale": "1x" + }, + { + "size": "128x128", + "idiom": "mac", + "filename": "Icon_128x128@2x.png", + "scale": "2x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "Icon_256x256.png", + "scale": "1x" + }, + { + "size": "256x256", + "idiom": "mac", + "filename": "Icon_256x256@2x.png", + "scale": "2x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "Icon_512x512.png", + "scale": "1x" + }, + { + "size": "512x512", + "idiom": "mac", + "filename": "Icon_512x512@2x.png", + "scale": "2x" + } + ], + "info": { + "version": 1, + "author": "xcode" + } +} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_128x128.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_128x128.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_128x128.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_128x128.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_128x128@2x.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_128x128@2x.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_128x128@2x.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_128x128@2x.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_16x16.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_16x16.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_16x16.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_16x16.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_16x16@2x.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_16x16@2x.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_16x16@2x.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_16x16@2x.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_256x256.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_256x256.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_256x256.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_256x256.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_256x256@2x.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_256x256@2x.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_256x256@2x.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_256x256@2x.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_32x32.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_32x32.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_32x32.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_32x32.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_32x32@2x.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_32x32@2x.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_32x32@2x.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_32x32@2x.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_512x512.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_512x512.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_512x512.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_512x512.png diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_512x512@2x.png b/VBB/Icons.xcassets/AppIcon.appiconset/Icon_512x512@2x.png similarity index 100% rename from VBBNow/Icons.xcassets/AppIcon.appiconset/Icon_512x512@2x.png rename to VBB/Icons.xcassets/AppIcon.appiconset/Icon_512x512@2x.png diff --git a/VBB/Info.plist b/VBB/Info.plist index c98cde8..ad5f6c4 100644 --- a/VBB/Info.plist +++ b/VBB/Info.plist @@ -15,11 +15,11 @@ CFBundlePackageType APPL CFBundleShortVersionString - 1.0.4 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 7 + $(CURRENT_PROJECT_VERSION) LSApplicationCategoryType public.app-category.travel LSMinimumSystemVersion diff --git a/VBBFramework/Info.plist b/VBBFramework/Info.plist index f476d83..6ab1586 100644 --- a/VBBFramework/Info.plist +++ b/VBBFramework/Info.plist @@ -1,26 +1,26 @@ - - CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) - CFBundleExecutable - $(EXECUTABLE_NAME) - CFBundleIdentifier - $(PRODUCT_BUNDLE_IDENTIFIER) - CFBundleInfoDictionaryVersion - 6.0 - CFBundleName - $(PRODUCT_NAME) - CFBundlePackageType - FMWK - CFBundleShortVersionString - 1.0 - CFBundleVersion - $(CURRENT_PROJECT_VERSION) - NSHumanReadableCopyright - Copyright © 2018 Dennis Oberhoff. All rights reserved. - NSPrincipalClass - - + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + FMWK + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + NSHumanReadableCopyright + Copyright © 2018 Dennis Oberhoff. All rights reserved. + NSPrincipalClass + + diff --git a/VBBFramework/Manager/VBBNetworkManager.h b/VBBFramework/Manager/VBBNetworkManager.h index 1a962ca..80d8cdb 100644 --- a/VBBFramework/Manager/VBBNetworkManager.h +++ b/VBBFramework/Manager/VBBNetworkManager.h @@ -7,10 +7,24 @@ // @import CoreLocation; +@import Realm; + #import "VBBLocation.h" +#import "VBBStation.h" + + +typedef NS_ENUM (NSInteger, VBBNetworkStatus) { + VBBNetworkStatusFinished = 0, + VBBNetworkStatusGeocoding = 1, + VBBNetworkStatusLoading = 2, + VBBNetworkStatusLoadingDetails = 3, + VBBNetworkStatusFailed = 4, +}; @interface VBBNetworkManager : NSObject --(void)fetchNearedStations:(CLLocation*)location andCompletionHandler:(void (^)(NSArray *stations, VBBLocation *location))completionHandler; +@property(nonatomic, readonly, assign) VBBNetworkStatus status; +- (void)fetchNearedStations:(CLLocation * _Nonnull)location + andCompletionHandler:(void (^ _Nonnull)(NSArray * _Nullable stations, VBBLocation * _Nullable location))completionHandler; @end diff --git a/VBBFramework/Manager/VBBNetworkManager.m b/VBBFramework/Manager/VBBNetworkManager.m index a760c83..ba982e7 100644 --- a/VBBFramework/Manager/VBBNetworkManager.m +++ b/VBBFramework/Manager/VBBNetworkManager.m @@ -9,120 +9,157 @@ @import CoreLocation; @import Contacts; @import MapKit; +@import Contacts; #import "VBBNetworkManager.h" #import "VBBStationParser.h" #import "VBBDepatureParser.h" -@interface VBBNetworkManager () +@interface VBBNetworkManager () + +@property(class, nonatomic, readonly) CNPostalAddressFormatter *addressFormatter; -@property (nonatomic, readwrite, strong) NSURLSession *session; +@property(nonatomic, readwrite, strong) NSURLSession *session; +@property(nonatomic, readwrite, strong) CLGeocoder *geocoder; +@property(nonatomic, readwrite, assign) VBBNetworkStatus status; @end @implementation VBBNetworkManager --(instancetype)init { +- (instancetype)init { self = [super init]; if (self) { - self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration ephemeralSessionConfiguration]]; - self.session.delegateQueue.underlyingQueue = [VBBPersistanceManager manager].operationQueue.underlyingQueue; + self.session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration] + delegate:self + delegateQueue:[[self class] operationQueue]]; } return self; } --(void)fetchNearedStations:(CLLocation*)location andCompletionHandler:(void (^)(NSArray *stations, VBBLocation *location))completionHandler{ - - [[VBBPersistanceManager manager] trim]; +- (void)fetchNearedStations:(CLLocation * _Nonnull)location + andCompletionHandler:(void (^ _Nonnull)(NSArray * _Nullable stations, VBBLocation * _Nullable location))completionHandler { - NSNumber *latitude = @(location.coordinate.latitude * 1000000); - NSNumber *longitude = @(location.coordinate.longitude * 1000000); - - NSMutableArray *query = [NSMutableArray array]; - [query addObject:[NSURLQueryItem queryItemWithName:@"performLocating" value:@"2"]]; - [query addObject:[NSURLQueryItem queryItemWithName:@"L" value:@"vs_java"]]; - [query addObject:[NSURLQueryItem queryItemWithName:@"look_x" value:longitude.stringValue]]; - [query addObject:[NSURLQueryItem queryItemWithName:@"look_y" value:latitude.stringValue]]; - [query addObject:[NSURLQueryItem queryItemWithName:@"look_maxdist" value:@"25000"]]; - [query addObject:[NSURLQueryItem queryItemWithName:@"look_maxno" value:@"10"]]; - - NSURLComponents *components = [NSURLComponents new]; - components.scheme = @"http"; - components.host = @"fahrinfo.vbb.de"; - components.path = @"/bin/query.exe/dol"; - components.queryItems = query.copy; + __weak typeof(self) weakSelf = self; - void (^ requestBlock)(VBBLocation *stationLocation) = ^void (VBBLocation *stationLocation) { + void (^ finalizeBlock)(NSArray *stations, VBBLocation *location) = ^void(NSArray *stations, VBBLocation * location) { + dispatch_async(dispatch_get_main_queue(), ^{ + weakSelf.status = VBBNetworkStatusFinished; + if (completionHandler) completionHandler(stations, location); + }); + }; + + void (^ stationsBlock)(VBBLocation *stationLocation) = ^void(VBBLocation *stationLocation) { + NSNumber *latitude = @(location.coordinate.latitude * 1000000); + NSNumber *longitude = @(location.coordinate.longitude * 1000000); + + NSMutableArray *query = [NSMutableArray array]; + [query addObject:[NSURLQueryItem queryItemWithName:@"performLocating" value:@"2"]]; + [query addObject:[NSURLQueryItem queryItemWithName:@"L" value:@"vs_java"]]; + [query addObject:[NSURLQueryItem queryItemWithName:@"look_x" value:longitude.stringValue]]; + [query addObject:[NSURLQueryItem queryItemWithName:@"look_y" value:latitude.stringValue]]; + [query addObject:[NSURLQueryItem queryItemWithName:@"look_maxdist" value:@"1000"]]; + [query addObject:[NSURLQueryItem queryItemWithName:@"look_maxno" value:@"10"]]; + + NSURLComponents *components = [NSURLComponents new]; + components.scheme = @"http"; + components.host = @"fahrinfo.vbb.de"; + components.path = @"/bin/query.exe/dol"; + components.queryItems = query.copy; + NSURLRequest *request = [NSURLRequest requestWithURL:components.URL]; - NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError * error) { + + NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { NSLog(@"%@: %@", NSStringFromClass([self class]), error.localizedDescription); - if (completionHandler) completionHandler(nil, stationLocation); + weakSelf.status = VBBNetworkStatusFailed; + finalizeBlock(nil, nil); return; } NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; VBBStationParser *stationParser = [VBBStationParser new]; parser.delegate = stationParser; [parser parse]; + + weakSelf.status = VBBNetworkStatusFinished; + + if (stationParser.stations.count == 0) { + finalizeBlock(nil, stationLocation); + return; + } + [self fetchDeparturesFromStations:stationParser.stations andCompletionHandler:^(NSArray *stations) { - if (completionHandler) completionHandler(stations, stationLocation); + finalizeBlock(stations, stationLocation); }]; }]; + + self.status = VBBNetworkStatusLoading; [task resume]; }; - + VBBLocation *storedLocation = [VBBPersistanceManager manager].storedLocation; + if (storedLocation && !location) { - requestBlock(storedLocation); + stationsBlock(storedLocation); + } else if (location && storedLocation && [storedLocation.location distanceFromLocation:location] < 15) { + stationsBlock(storedLocation); } else if (location) { - CLGeocoder *geocoder = [CLGeocoder new]; - [geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { + self.status = VBBNetworkStatusGeocoding; + self.geocoder = [CLGeocoder new]; + [self.geocoder reverseGeocodeLocation:location completionHandler:^(NSArray *placemarks, NSError *error) { CLPlacemark *placemark = placemarks.firstObject; VBBLocation *stationLocation = [VBBLocation new]; stationLocation.location = location; - stationLocation.address = [placemark.addressDictionary[@"FormattedAddressLines"] componentsJoinedByString:@", "]; stationLocation.date = [NSDate new]; - [[VBBPersistanceManager manager] storeLocation:stationLocation]; - requestBlock(stationLocation); + stationLocation.address = [[VBBNetworkManager addressFormatter] stringFromPostalAddress:placemark.postalAddress]; + [VBBPersistanceManager manager].storedLocation = stationLocation; + weakSelf.status = VBBNetworkStatusFinished; + stationsBlock(stationLocation); }]; } else { - if (completionHandler) completionHandler(nil, nil); + finalizeBlock(nil, nil); } } --(void)fetchDeparturesFromStations:(NSArray*)stations andCompletionHandler:(void (^)(NSArray *stations))completionHandler { - +- (void)fetchDeparturesFromStations:(NSArray *)stations andCompletionHandler:(void (^)(NSArray *stations))completionHandler { + __block NSUInteger count = stations.count; + __weak typeof(self) weakSelf = self; + void (^responseBlock)(VBBStation *station) = ^void(VBBStation *station) { if (--count) return; dispatch_async(dispatch_get_main_queue(), ^{ + weakSelf.status = VBBNetworkStatusFinished; if (completionHandler) completionHandler(stations); }); }; - for (VBBStation *station in stations) [self fetchDepature:station andCompletionHandler:responseBlock]; + self.status = VBBNetworkStatusLoadingDetails; + for (VBBStation *station in stations) { + [self fetchDepature:station andCompletionHandler:responseBlock]; + } } --(void)fetchDepature:(VBBStation *)station andCompletionHandler:(void (^)(VBBStation *station))completionHandler{ - - NSString *stationId = station.stationId.copy; - +- (void)fetchDepature:(VBBStation *)station andCompletionHandler:(void (^)(VBBStation *station))completionHandler { + + NSString * stationId = station.stationId.copy; + NSMutableArray *query = [NSMutableArray array]; [query addObject:[NSURLQueryItem queryItemWithName:@"boardType" value:@"yes"]]; [query addObject:[NSURLQueryItem queryItemWithName:@"disableEquivs" value:@"yes"]]; - [query addObject:[NSURLQueryItem queryItemWithName:@"maxJourneys" value:@"50"]]; + [query addObject:[NSURLQueryItem queryItemWithName:@"maxJourneys" value:@"30"]]; [query addObject:[NSURLQueryItem queryItemWithName:@"L" value:@"vs_java3"]]; [query addObject:[NSURLQueryItem queryItemWithName:@"start" value:@"yes"]]; [query addObject:[NSURLQueryItem queryItemWithName:@"input" value:station.stationId]]; - + NSURLComponents *components = [NSURLComponents new]; components.scheme = @"http"; components.host = @"fahrinfo.vbb.de"; components.path = @"/bin/stboard.exe/dn"; components.queryItems = query.copy; NSURLRequest *request = [NSURLRequest requestWithURL:components.URL]; - - NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData * data, NSURLResponse * response, NSError * error) { + + NSURLSessionDataTask *task = [self.session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) { if (error) { NSLog(@"%@: %@", NSStringFromClass([self class]), error.localizedDescription); if (completionHandler) completionHandler(nil); @@ -132,9 +169,33 @@ -(void)fetchDepature:(VBBStation *)station andCompletionHandler:(void (^)(VBBSta VBBDepatureParser *departureParser = [[VBBDepatureParser alloc] initWithStationId:stationId]; parser.delegate = departureParser; [parser parse]; + if (completionHandler) completionHandler(station); }]; [task resume]; } ++(CNPostalAddressFormatter *)addressFormatter { + static dispatch_once_t pred; + static CNPostalAddressFormatter *formatter; + dispatch_once(&pred, ^{ + formatter = [CNPostalAddressFormatter new]; + }); + return formatter; +} + ++ (NSOperationQueue *)operationQueue { + static dispatch_once_t onceToken; + static NSOperationQueue *operationQueue; + + dispatch_once(&onceToken, ^{ + dispatch_queue_t queue = dispatch_queue_create("com.obrhoff.vbbnow", DISPATCH_QUEUE_SERIAL); + operationQueue = [NSOperationQueue new]; + operationQueue.maxConcurrentOperationCount = 1; + operationQueue.qualityOfService = NSQualityOfServiceDefault; + operationQueue.underlyingQueue = queue; + }); + return operationQueue; +} + @end diff --git a/VBBFramework/Manager/VBBPersistanceManager.h b/VBBFramework/Manager/VBBPersistanceManager.h index 3be056c..43941db 100644 --- a/VBBFramework/Manager/VBBPersistanceManager.h +++ b/VBBFramework/Manager/VBBPersistanceManager.h @@ -14,12 +14,12 @@ @interface VBBPersistanceManager : NSObject -@property (nonatomic, readonly) NSOperationQueue *operationQueue; +@property(class, readonly, strong, nonnull) VBBPersistanceManager *manager; +@property(class, readonly, strong, nonnull) RLMRealm *realm; --(void)trim; --(VBBLocation*)storedLocation; --(void)storeLocation:(VBBLocation*)location; -+(VBBPersistanceManager *)manager; -+(RLMRealm*)realm; +@property(nonatomic, readonly, nonnull) NSOperationQueue *operationQueue; +@property(nonatomic, nullable) VBBLocation *storedLocation; + ++ (void)trim; @end diff --git a/VBBFramework/Manager/VBBPersistanceManager.m b/VBBFramework/Manager/VBBPersistanceManager.m index 53807fb..ed8df6d 100644 --- a/VBBFramework/Manager/VBBPersistanceManager.m +++ b/VBBFramework/Manager/VBBPersistanceManager.m @@ -9,29 +9,28 @@ #import "VBBPersistanceManager.h" #import "VBBDepature.h" - @interface VBBPersistanceManager () -@property (nonatomic, readonly) dispatch_queue_t backgroundQueue; +@property(nonatomic, readonly) dispatch_queue_t backgroundQueue; @end @implementation VBBPersistanceManager -- (void)trim { ++ (void)trim { RLMRealm *realm = [[self class] realm]; - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"arrivalDate < %@", [NSDate date]]; + NSDate *trimDate = [[NSDate date] dateByAddingTimeInterval:-60 * 60]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"scheduledDate < %@", trimDate] ; RLMResults *oldDates = [VBBDepature objectsInRealm:realm withPredicate:predicate]; - + [realm beginWriteTransaction]; [realm deleteObjects:oldDates]; [realm commitWriteTransaction]; } -- (void)storeLocation:(VBBLocation *)location { +- (void)setStoredLocation:(VBBLocation *)storedLocation { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; - NSData *data = [NSKeyedArchiver archivedDataWithRootObject:location]; - + NSData *data = [NSKeyedArchiver archivedDataWithRootObject:storedLocation]; [defaults setObject:data forKey:@"savedLocation"]; [defaults synchronize]; } @@ -39,7 +38,15 @@ - (void)storeLocation:(VBBLocation *)location { - (VBBLocation *)storedLocation { NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; NSData *data = [defaults dataForKey:@"savedLocation"]; - VBBLocation *location = [NSKeyedUnarchiver unarchiveObjectWithData:data]; + NSError *error; + + NSSet *classes = [NSSet setWithArray:@[[VBBLocation class], [CLLocation class], [NSMutableString class], [NSDate class]]]; + + VBBLocation *location = [NSKeyedUnarchiver unarchivedObjectOfClasses:classes fromData:data error:&error]; + + if (error) { + + } return location; } @@ -47,21 +54,22 @@ - (VBBLocation *)storedLocation { + (RLMRealm *)realm { static dispatch_once_t onceToken; dispatch_once(&onceToken, ^{ - NSString *documentPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; + NSString * documentPath = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES).firstObject; documentPath = [documentPath stringByAppendingPathComponent:[NSBundle mainBundle].bundleIdentifier]; - NSString *realmFileName = [documentPath stringByAppendingPathComponent:@"stations.realm"]; - + NSString * realmFileName = [documentPath stringByAppendingPathComponent:@"stations.realm"]; + NSFileManager *fileManager = [NSFileManager defaultManager]; - + BOOL isDirectory; if (![fileManager fileExistsAtPath:documentPath isDirectory:&isDirectory]) { [fileManager createDirectoryAtPath:documentPath withIntermediateDirectories:YES attributes:nil error:nil]; } - + NSURL *url = [NSURL URLWithString:realmFileName]; RLMRealmConfiguration *config = [RLMRealmConfiguration defaultConfiguration]; config.fileURL = url; - config.shouldCompactOnLaunch = ^BOOL(NSUInteger totalBytes, NSUInteger usedBytes){ + config.deleteRealmIfMigrationNeeded = YES; + config.shouldCompactOnLaunch = ^BOOL(NSUInteger totalBytes, NSUInteger usedBytes) { NSUInteger oneHundredMB = 10 * 1024 * 1024; BOOL needsCompact = (totalBytes > oneHundredMB) && (usedBytes / totalBytes) < 0.5; return needsCompact; @@ -71,32 +79,10 @@ + (RLMRealm *)realm { return [RLMRealm defaultRealm]; } -- (NSOperationQueue *)operationQueue { - static dispatch_once_t onceToken; - static NSOperationQueue *operationQueue; - - dispatch_once(&onceToken, ^{ - operationQueue = [NSOperationQueue new]; - operationQueue.maxConcurrentOperationCount = 1; - operationQueue.qualityOfService = NSQualityOfServiceBackground; - operationQueue.underlyingQueue = self.backgroundQueue; - }); - return operationQueue; -} - -- (dispatch_queue_t)backgroundQueue { - static dispatch_once_t queueCreationGuard; - static dispatch_queue_t backgroundQueue; - dispatch_once(&queueCreationGuard, ^{ - backgroundQueue = dispatch_queue_create("com.obrhoff.background", DISPATCH_QUEUE_CONCURRENT); - }); - return backgroundQueue; -} - + (VBBPersistanceManager *)manager { static dispatch_once_t pred; static VBBPersistanceManager *manager; - + dispatch_once(&pred, ^{ manager = [self new]; }); diff --git a/VBBFramework/Miscellaneous/NSBundle+VBB.h b/VBBFramework/Miscellaneous/NSBundle+VBB.h new file mode 100644 index 0000000..27d1da8 --- /dev/null +++ b/VBBFramework/Miscellaneous/NSBundle+VBB.h @@ -0,0 +1,15 @@ +// +// NSBundle.h +// VBB +// +// Created by Dennis Oberhoff on 02.08.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +@import Foundation; + +@interface NSBundle (VBB) + +@property (class, nonnull, readonly) NSBundle* frameworkBundle; + +@end diff --git a/VBBFramework/Miscellaneous/NSBundle+VBB.m b/VBBFramework/Miscellaneous/NSBundle+VBB.m new file mode 100644 index 0000000..75de6eb --- /dev/null +++ b/VBBFramework/Miscellaneous/NSBundle+VBB.m @@ -0,0 +1,23 @@ +// +// NSBundle.m +// VBB +// +// Created by Dennis Oberhoff on 02.08.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +#import "NSBundle+VBB.h" + +@interface BundleClass : NSObject +@end + +@implementation BundleClass +@end + +@implementation NSBundle (VBB) + ++(NSBundle* _Nonnull)frameworkBundle { + return [NSBundle bundleForClass:[BundleClass class]]; +} + +@end diff --git a/VBBFramework/Miscellaneous/NSDateComponentsFormatter+VBB.h b/VBBFramework/Miscellaneous/NSDateComponentsFormatter+VBB.h new file mode 100644 index 0000000..bb2b578 --- /dev/null +++ b/VBBFramework/Miscellaneous/NSDateComponentsFormatter+VBB.h @@ -0,0 +1,16 @@ +// +// Bla.h +// VBBFramework +// +// Created by Dennis Oberhoff on 16.06.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +#import + +@interface NSDateComponentsFormatter (BB) + +@property(class, readonly, nonnull) NSDateComponentsFormatter *timeFormatter; + +@end + diff --git a/VBBFramework/Miscellaneous/NSDateComponentsFormatter+VBB.m b/VBBFramework/Miscellaneous/NSDateComponentsFormatter+VBB.m new file mode 100644 index 0000000..4bd4d31 --- /dev/null +++ b/VBBFramework/Miscellaneous/NSDateComponentsFormatter+VBB.m @@ -0,0 +1,28 @@ +// +// Bla.m +// VBBFramework +// +// Created by Dennis Oberhoff on 16.06.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +#import "NSDateComponentsFormatter+VBB.h" + +@implementation NSDateComponentsFormatter (BB) + ++(NSDateComponentsFormatter *)timeFormatter { + static dispatch_once_t onceToken; + static NSDateComponentsFormatter *timeFormatter; + dispatch_once(&onceToken, ^{ + timeFormatter = [NSDateComponentsFormatter new]; + timeFormatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitHour | NSCalendarUnitDay; + timeFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleShort; + timeFormatter.includesApproximationPhrase = NO; + timeFormatter.includesTimeRemainingPhrase = NO; + timeFormatter.collapsesLargestUnit = YES; + timeFormatter.maximumUnitCount = 1; + }); + return timeFormatter; +} + +@end diff --git a/VBBFramework/Miscellaneous/NSString+VBB.h b/VBBFramework/Miscellaneous/NSString+VBB.h new file mode 100644 index 0000000..f04a0ee --- /dev/null +++ b/VBBFramework/Miscellaneous/NSString+VBB.h @@ -0,0 +1,15 @@ +// +// NSString+VBB.h +// VBBFramework +// +// Created by Dennis Oberhoff on 19.06.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +#import + +@interface NSString (VBB) + +- (NSString *)sha1; + +@end diff --git a/VBBFramework/Miscellaneous/NSString+VBB.m b/VBBFramework/Miscellaneous/NSString+VBB.m new file mode 100644 index 0000000..29d5698 --- /dev/null +++ b/VBBFramework/Miscellaneous/NSString+VBB.m @@ -0,0 +1,28 @@ +// +// NSString+VBB.m +// VBBFramework +// +// Created by Dennis Oberhoff on 19.06.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +#import "NSString+VBB.h" +#import + +@implementation NSString (VBB) + +- (NSString *)sha1 { + NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding]; + uint8_t digest[CC_SHA1_DIGEST_LENGTH]; + CC_SHA1(data.bytes, (CC_LONG)data.length, digest); + + NSMutableString *output = [NSMutableString stringWithCapacity:CC_SHA1_DIGEST_LENGTH * 2]; + + for (int i = 0; i < CC_SHA1_DIGEST_LENGTH; i++) + { + [output appendFormat:@"%02x", digest[i]]; + } + + return output; +} +@end diff --git a/VBBFramework/Miscellaneous/Realm-VBB.h b/VBBFramework/Miscellaneous/Realm-VBB.h new file mode 100644 index 0000000..3027d4a --- /dev/null +++ b/VBBFramework/Miscellaneous/Realm-VBB.h @@ -0,0 +1,21 @@ +// +// BB.h +// BicycleFramework-WatchOS +// +// Created by Dennis Oberhoff on 23.07.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +@import Realm; + +@interface RLMResults (VBB) + +-(NSArray* _Nonnull)mapItems; + +@end + +@interface RLMArray (VBB) + +-(NSArray* _Nonnull)mapItems; + +@end diff --git a/VBBFramework/Miscellaneous/Realm-VBB.m b/VBBFramework/Miscellaneous/Realm-VBB.m new file mode 100644 index 0000000..3ed1bcf --- /dev/null +++ b/VBBFramework/Miscellaneous/Realm-VBB.m @@ -0,0 +1,39 @@ +// +// BB.m +// BicycleFramework-WatchOS +// +// Created by Dennis Oberhoff on 23.07.19. +// Copyright © 2019 Dennis Oberhoff. All rights reserved. +// + +@import Foundation; + +#import "Realm-VBB.h" + +@implementation RLMResults (VBB) + +-(NSArray* _Nonnull)mapItems { + NSMutableArray *array = [NSMutableArray new]; + for (RLMObject *item in self) { + [array addObject:item]; + } + + return array.copy; +} + +@end + +@implementation RLMArray (VBB) + +-(NSArray* _Nonnull)mapItems { + NSMutableArray *array = [NSMutableArray new]; + for (RLMObject *item in self) { + [array addObject:item]; + } + + return array.copy; +} + +@end + + diff --git a/VBBFramework/Model/VBBDepature.h b/VBBFramework/Model/VBBDepature.h index ccee0c0..84a1ba8 100644 --- a/VBBFramework/Model/VBBDepature.h +++ b/VBBFramework/Model/VBBDepature.h @@ -6,14 +6,20 @@ // Copyright (c) 2015 Dennis Oberhoff. All rights reserved. // -#import +@import Realm; + #import "VBBLine.h" @interface VBBDepature : RLMObject -@property (nonatomic) NSDate *arrivalDate; -@property (readonly) RLMLinkingObjects *station; -@property (nonatomic) VBBLine *line; +@property(nonatomic, nullable) VBBLine *line; +@property(nonatomic, nonnull) NSString *departureId; +@property(nonatomic, nonnull) NSDate *scheduledDate; +@property(nonatomic, assign) NSTimeInterval delay; +@property(nonatomic, readonly, nonnull) NSDate *arrivalDate; +@property(nonatomic, readonly, assign) BOOL delayed; + +@property(readonly, nonnull) RLMLinkingObjects *station; @end diff --git a/VBBFramework/Model/VBBDepature.m b/VBBFramework/Model/VBBDepature.m index 1e9c837..32d4f63 100644 --- a/VBBFramework/Model/VBBDepature.m +++ b/VBBFramework/Model/VBBDepature.m @@ -11,9 +11,21 @@ @implementation VBBDepature -+(NSDictionary *)linkingObjectsProperties { - return [NSDictionary dictionaryWithObject:[RLMPropertyDescriptor descriptorWithClass:VBBStation.class propertyName:NSStringFromSelector(@selector(depatures))] forKey:NSStringFromSelector(@selector(station))]; +-(BOOL)delayed { + return self.delay > 0; } +-(NSDate *)arrivalDate { + return [self.scheduledDate dateByAddingTimeInterval:self.delay]; +} + ++ (NSDictionary *)linkingObjectsProperties { + return @{NSStringFromSelector(@selector(station)): [RLMPropertyDescriptor descriptorWithClass:VBBStation.class + propertyName:NSStringFromSelector(@selector(depatures))] }; +} + ++ (NSString *)primaryKey { + return NSStringFromSelector(@selector(departureId)); +} @end diff --git a/VBBFramework/Model/VBBLine.h b/VBBFramework/Model/VBBLine.h index 7c1b0fa..2b4ef2c 100644 --- a/VBBFramework/Model/VBBLine.h +++ b/VBBFramework/Model/VBBLine.h @@ -8,12 +8,25 @@ #import +typedef NS_ENUM (NSInteger, VBBLineType) { + VBBLineTypeSBahn = 1, + VBBLineTypeUBahn = 2, + VBBLineTypeTram = 4, + VBBLineTypeBus = 8, + VBBLineTypeMetro = 12, + VBBLineTypeBahn = 32, +}; + @interface VBBLine : RLMObject -@property (nonatomic) NSString *lineId; -@property (nonatomic) NSString *lineEnd; -@property (nonatomic) NSString *lineName; -@property (nonatomic) NSInteger departureType; +@property(readonly, nonnull) RLMLinkingObjects *departures; +@property(nonatomic, nonnull) NSString *lineId; +@property(nonatomic, nonnull) NSString *lineEnd; +@property(nonatomic, nonnull) NSString *lineName; +@property(nonatomic) NSInteger departureType; + +-(VBBLineType)lineType; ++(NSString* _Nonnull)assetNameForType:(VBBLineType)lineType; @end diff --git a/VBBFramework/Model/VBBLine.m b/VBBFramework/Model/VBBLine.m index d1bd7c9..e83f111 100644 --- a/VBBFramework/Model/VBBLine.m +++ b/VBBFramework/Model/VBBLine.m @@ -7,16 +7,48 @@ // #import "VBBLine.h" +#import "VBBDepature.h" @implementation VBBLine --(BOOL)isEqual:(VBBLine*)object { +- (BOOL)isEqual:(VBBLine *)object { return ([object isKindOfClass:[self class]]) ? ([self.lineEnd isEqualToString:object.lineEnd] && - [self.lineName isEqualToString:object.lineName]) : [super isEqual:object]; + [self.lineName isEqualToString:object.lineName]) : [super isEqual:object]; } -+(NSString *)primaryKey { +-(VBBLineType)lineType { + VBBLineType lineType = (VBBLineType) self.departureType; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"^Bus M\\d+"]; + if ([predicate evaluateWithObject:self.lineName]) { + return VBBLineTypeMetro; + } + return lineType; +} + ++(NSString*)assetNameForType:(VBBLineType)lineType; { + switch (lineType) { + case VBBLineTypeSBahn: + return @"SBahn"; + case VBBLineTypeUBahn: + return @"UBahn"; + case VBBLineTypeTram: + return @"Tram"; + case VBBLineTypeBus: + return @"Bus"; + case VBBLineTypeMetro: + return @"Metro"; + case VBBLineTypeBahn: + return @"Train"; + } +} + ++ (NSString *)primaryKey { return NSStringFromSelector(@selector(lineId)); } ++ (NSDictionary *)linkingObjectsProperties { + return @{NSStringFromSelector(@selector(departures)): [RLMPropertyDescriptor descriptorWithClass:VBBDepature.class + propertyName:NSStringFromSelector(@selector(line))] }; +} + @end diff --git a/VBBFramework/Model/VBBLocation.h b/VBBFramework/Model/VBBLocation.h index 394e5b6..929f251 100644 --- a/VBBFramework/Model/VBBLocation.h +++ b/VBBFramework/Model/VBBLocation.h @@ -9,10 +9,10 @@ @import CoreLocation; @import Contacts; -@interface VBBLocation : NSObject +@interface VBBLocation : NSObject -@property (nonatomic, readwrite, strong) CLLocation *location; -@property (nonatomic, readwrite, strong) NSString *address; -@property (nonatomic, readwrite, strong) NSDate *date; +@property(nonatomic, readwrite, strong, nullable) CLLocation *location; +@property(nonatomic, readwrite, strong, nullable) NSString *address; +@property(nonatomic, readwrite, strong, nullable) NSDate *date; @end diff --git a/VBBFramework/Model/VBBLocation.m b/VBBFramework/Model/VBBLocation.m index cb95720..af2c442 100644 --- a/VBBFramework/Model/VBBLocation.m +++ b/VBBFramework/Model/VBBLocation.m @@ -13,7 +13,7 @@ @implementation VBBLocation --(instancetype)initWithCoder:(NSCoder *)aDecoder { +- (instancetype)initWithCoder:(NSCoder *)aDecoder { VBBLocation *location = [VBBLocation new]; location.location = [aDecoder decodeObjectForKey:@"location"]; location.address = [aDecoder decodeObjectForKey:@"address"]; @@ -21,17 +21,22 @@ -(instancetype)initWithCoder:(NSCoder *)aDecoder { return location; } --(void)encodeWithCoder:(NSCoder *)aCoder { - [aCoder encodeObject:self.location forKey:@"location"]; - [aCoder encodeObject:self.date forKey:@"date"]; - [aCoder encodeObject:self.address forKey:@"address"]; +-(void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.location forKey:@"location"]; + [coder encodeObject:self.date forKey:@"date"]; + [coder encodeObject:self.address forKey:@"address"]; } --(BOOL)isEqual:(VBBLocation*)object { ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (BOOL)isEqual:(VBBLocation *)object { if ([object isKindOfClass:[self class]]) return NO; MKMapPoint this = MKMapPointForCoordinate(self.location.coordinate); MKMapPoint other = MKMapPointForCoordinate(object.location.coordinate); return MKMapPointEqualToPoint(this, other); } + @end diff --git a/VBBFramework/Model/VBBStation.h b/VBBFramework/Model/VBBStation.h index a24de2d..7455417 100644 --- a/VBBFramework/Model/VBBStation.h +++ b/VBBFramework/Model/VBBStation.h @@ -16,19 +16,21 @@ @interface VBBStation : RLMObject -@property (nonatomic) NSString *stationName; -@property (nonatomic) NSString *stationId; -@property (nonatomic) NSInteger stationClass; -@property (nonatomic) NSString *stationType; +@property(nonatomic, nonnull) NSString *stationName; +@property(nonatomic, nonnull) NSString *stationId; +@property(nonatomic, nonnull) NSString *stationType; +@property(nonatomic) NSInteger stationClass; -@property (readonly) CLLocation *location; +@property(nonnull, readonly) CLLocation *location; -@property RLMArray *depatures; -@property RLMArray *lines; +@property(nonnull) RLMArray *depatures; +@property(nonnull) RLMArray *lines; --(void)setLocation:(CLLocation*)location; --(CLLocation*)location; -+ (NSArray *)sortByRelevance:(VBBLocation*)userLocation andLimit:(NSUInteger)limit; ++ (NSArray * _Nonnull)sortByRelevance:(VBBLocation* _Nonnull)userLocation andLimit:(NSUInteger)limit; + +- (VBBDepature* _Nullable)nextDeparture: (NSTimeInterval)futureInterval; +- (void)setLocation:(CLLocation * _Nonnull)location; +- (CLLocation * _Nonnull)location; @end diff --git a/VBBFramework/Model/VBBStation.m b/VBBFramework/Model/VBBStation.m index 66c9fd2..8f714af 100644 --- a/VBBFramework/Model/VBBStation.m +++ b/VBBFramework/Model/VBBStation.m @@ -11,18 +11,26 @@ @interface VBBStation () -@property (nonatomic) double latitude; -@property (nonatomic) double longitude; +@property(nonatomic) double latitude; +@property(nonatomic) double longitude; @end @implementation VBBStation -+ (NSArray *)sortByRelevance:(VBBLocation*)userLocation andLimit:(NSUInteger)limit { - +- (VBBDepature*)nextDeparture: (NSTimeInterval)futureInterval { + NSDate *future = [NSDate dateWithTimeInterval:futureInterval sinceDate:[NSDate date]]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"scheduledDate > %@", future]; + VBBDepature *nextDepature = [[self.depatures objectsWithPredicate:predicate] + sortedResultsUsingKeyPath:NSStringFromSelector(@selector(scheduledDate)) ascending:YES].firstObject; + return nextDepature; +} + ++ (NSArray * _Nonnull)sortByRelevance:(VBBLocation* _Nonnull)userLocation andLimit:(NSUInteger)limit { + RLMRealm *realm = [[VBBPersistanceManager class] realm]; RLMResults *stations = [VBBStation allObjectsInRealm:realm]; - + NSDate *now = [NSDate date]; NSMutableArray *unsorted = [NSMutableArray arrayWithCapacity:stations.count]; for (VBBStation *station in stations) { @@ -31,34 +39,34 @@ + (NSArray *)sortByRelevance:(VBBLocation*)userLocation andLimit:(NSUInteger)lim NSDictionary *dict = @{@"station": station, @"distance": @(distance)}; [unsorted addObject:dict]; } - + NSSortOptions sortOptions = NSSortStable; [unsorted sortWithOptions:sortOptions usingComparator:^NSComparisonResult(NSDictionary *dictOne, NSDictionary *dictTwo) { return [dictOne[@"distance"] doubleValue] > [dictTwo[@"distance"] doubleValue]; }]; - + NSDate *future = [NSDate dateWithTimeInterval:60 sinceDate:now]; - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"arrivalDate > %@", future]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"scheduledDate > %@", future]; [unsorted enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSDictionary *dict, NSUInteger idx, BOOL *stop) { VBBStation *station = dict[@"station"]; VBBDepature *nextDepature = [station.depatures objectsWithPredicate:predicate].firstObject; - if (!nextDepature || [nextDepature.arrivalDate timeIntervalSinceDate:now] > 3600) [unsorted removeObject:dict]; + if (!nextDepature || [nextDepature.scheduledDate timeIntervalSinceDate:now] > 3600) [unsorted removeObject:dict]; }]; if (limit < unsorted.count) [unsorted removeObjectsInRange:NSMakeRange(limit, unsorted.count - limit)]; - - NSMutableArray *sortByRelevance = [NSMutableArray arrayWithCapacity:stations.count]; + + NSMutableArray *sortByRelevance = [NSMutableArray arrayWithCapacity:stations.count]; [unsorted enumerateObjectsUsingBlock:^(NSDictionary *placeDict, NSUInteger idx, BOOL *stop) { [sortByRelevance insertObject:placeDict[@"station"] atIndex:idx]; }]; return sortByRelevance.copy; } --(void)setLocation:(CLLocation *)location { +- (void)setLocation:(CLLocation *_Nonnull)location { self.latitude = location.coordinate.latitude; self.longitude = location.coordinate.longitude; } --(CLLocation *)location { +- (CLLocation *_Nonnull)location { return [[CLLocation alloc] initWithLatitude:self.latitude longitude:self.longitude]; } diff --git a/VBBFramework/Parser/VBBDepatureParser.h b/VBBFramework/Parser/VBBDepatureParser.h index 5658aae..9dcb838 100644 --- a/VBBFramework/Parser/VBBDepatureParser.h +++ b/VBBFramework/Parser/VBBDepatureParser.h @@ -11,6 +11,6 @@ @interface VBBDepatureParser : VBBaseParser --(instancetype)initWithStationId:(NSString*)stationId; +- (instancetype)initWithStationId:(NSString *)stationId; @end diff --git a/VBBFramework/Parser/VBBDepatureParser.m b/VBBFramework/Parser/VBBDepatureParser.m index 68020a0..94c4357 100644 --- a/VBBFramework/Parser/VBBDepatureParser.m +++ b/VBBFramework/Parser/VBBDepatureParser.m @@ -7,17 +7,18 @@ // #import "VBBDepatureParser.h" +#import "NSString+VBB.h" @interface VBBDepatureParser () -@property (nonatomic, readwrite, strong) VBBStation *station; -@property (nonatomic, readonly) NSDateFormatter *formatter; +@property(nonatomic, readwrite, strong) VBBStation *station; +@property(nonatomic, readonly) NSDateFormatter *formatter; @end @implementation VBBDepatureParser --(instancetype)initWithStationId:(NSString*)stationId { +- (instancetype)initWithStationId:(NSString *)stationId { self = [super init]; if (self) { self.station = [VBBStation objectInRealm:self.realm forPrimaryKey:stationId]; @@ -25,41 +26,64 @@ -(instancetype)initWithStationId:(NSString*)stationId { return self; } --(void)parserDidStartDocument:(NSXMLParser *)parser { +- (void)parserDidStartDocument:(NSXMLParser *)parser { [super parserDidStartDocument:parser]; - [self.realm deleteObjects:self.station.depatures]; } --(void)parseTable:(NSDictionary*)dict { +- (void)parseTable:(NSDictionary *)dict { + NSString *directionId = dict[@"dirnr"]; + NSString *direction = dict[@"dir"]; + NSString *lineKey = [NSString stringWithFormat:@"%@-%@", directionId, direction]; + NSString *lineId = lineKey.sha1; - VBBDepature *departure = [VBBDepature new]; - NSString *lineId = dict[@"dirnr"]; VBBLine *line = [VBBLine objectInRealm:self.realm forPrimaryKey:lineId]; if (!line) { line = [VBBLine new]; line.lineId = lineId; - line.lineEnd = dict[@"dir"]; - line.lineName = dict[@"hafasname"]; - line.departureType = [dict[@"class"] integerValue]; - [self.realm addObject:line]; } - if ([self.station.lines indexOfObject:line] == NSNotFound) [self.station.lines addObject:line]; + + line.lineEnd = dict[@"dir"]; + line.lineName = dict[@"hafasname"]; + line.departureType = [dict[@"class"] integerValue]; + [self.realm addOrUpdateObject:line]; + + if ([self.station.lines indexOfObject:line] == NSNotFound) { + [self.station.lines addObject:line]; + } + + NSString * dateFormatted = [NSString stringWithFormat:@"%@ %@", dict[@"fpDate"], dict[@"fpTime"]]; + NSDate *scheduledDate = [self.formatter dateFromString:dateFormatted]; + NSString *departureKey = [NSString stringWithFormat:@"%@-%@-%@-%@", self.station.stationId, line.lineId, line.lineEnd, dateFormatted]; + NSString *departureId = departureKey.sha1; + NSNumber *delay = dict[@"e_delay"]; + - NSString *dateFormatted = [NSString stringWithFormat:@"%@ %@", dict[@"fpDate"], dict[@"fpTime"]]; - departure.arrivalDate = [self.formatter dateFromString:dateFormatted]; + VBBDepature *departure = [VBBDepature objectInRealm:self.realm forPrimaryKey:departureId]; + + if (!departure) { + departure = [VBBDepature new]; + departure.departureId = departureId; + } + + departure.scheduledDate = scheduledDate; + departure.delay = delay.doubleValue * 60; departure.line = line; - [self.station.depatures addObject:departure]; + [self.realm addOrUpdateObject:departure]; + + if ([self.station.depatures indexOfObject:departure] == NSNotFound) { + [self.station.depatures addObject:departure]; + } } --(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName - namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName + namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"Journey"]) [self parseTable:attributeDict]; } --(NSDateFormatter*)formatter { +- (NSDateFormatter *)formatter { static dispatch_once_t onceToken; static NSDateFormatter *formatter; dispatch_once(&onceToken, ^{ diff --git a/VBBFramework/Parser/VBBStationParser.h b/VBBFramework/Parser/VBBStationParser.h index cac7396..a0d01ae 100644 --- a/VBBFramework/Parser/VBBStationParser.h +++ b/VBBFramework/Parser/VBBStationParser.h @@ -11,6 +11,6 @@ @interface VBBStationParser : VBBaseParser -@property (nonatomic, readonly, strong) NSArray *stations; +@property(nonatomic, readonly, strong) NSArray *stations; @end \ No newline at end of file diff --git a/VBBFramework/Parser/VBBStationParser.m b/VBBFramework/Parser/VBBStationParser.m index 75c25b9..a508583 100644 --- a/VBBFramework/Parser/VBBStationParser.m +++ b/VBBFramework/Parser/VBBStationParser.m @@ -10,43 +10,43 @@ @interface VBBStationParser () -@property (nonatomic, readwrite, strong) NSMutableArray *fetchedStations; +@property(nonatomic, readwrite, strong) NSMutableArray *fetchedStations; @end @implementation VBBStationParser --(void)parserDidStartDocument:(NSXMLParser *)parser { +- (void)parserDidStartDocument:(NSXMLParser *)parser { self.fetchedStations = [NSMutableArray array]; [super parserDidStartDocument:parser]; } --(void)parseStations:(NSDictionary*)dict { - NSString *stationId = dict[@"externalId"]; - VBBStation *station = [VBBStation objectInRealm:self.realm forPrimaryKey:stationId]; +- (void)parseStations:(NSDictionary *)dict { + NSString * stationId = dict[@"externalId"]; + VBBStation *station = [VBBStation objectInRealm:self.realm forPrimaryKey:stationId]; if (!station) { - NSNumber *latitude = @([dict[@"y"] doubleValue] / 1000000); - NSNumber *longitude = @([dict[@"x"] doubleValue] / 1000000); station = [VBBStation new]; - station.stationName = dict[@"n"]; station.stationId = stationId; - station.stationClass = [dict[@"class"] integerValue]; - station.stationType = dict[@"t"]; - station.location = [[CLLocation alloc] initWithLatitude:latitude.doubleValue longitude:longitude.doubleValue]; - [self.realm addOrUpdateObject:station]; } - [self.fetchedStations addObject:station]; + NSNumber *latitude = @([dict[@"y"] doubleValue] / 1000000); + NSNumber *longitude = @([dict[@"x"] doubleValue] / 1000000); + station.stationName = dict[@"n"]; + station.stationClass = [dict[@"class"] integerValue]; + station.stationType = dict[@"t"]; + station.location = [[CLLocation alloc] initWithLatitude:latitude.doubleValue longitude:longitude.doubleValue]; + [self.realm addOrUpdateObject:station]; + [self.fetchedStations addObject:station]; } --(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName - namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { +- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName + namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"MLc"]) [self parseStations:attributeDict]; } --(NSArray *)stations{ +- (NSArray *)stations { return self.fetchedStations.copy; } diff --git a/VBBFramework/Parser/VBBaseParser.h b/VBBFramework/Parser/VBBaseParser.h index 219fb79..f58bfe2 100644 --- a/VBBFramework/Parser/VBBaseParser.h +++ b/VBBFramework/Parser/VBBaseParser.h @@ -6,11 +6,12 @@ // Copyright (c) 2015 Dennis Oberhoff. All rights reserved. // +@import Realm; @import Foundation; #import "VBBPersistanceManager.h" @interface VBBaseParser : NSObject -@property (nonatomic, readonly, strong) RLMRealm *realm; +@property(nonatomic, readonly, strong) RLMRealm *realm; @end diff --git a/VBBFramework/Parser/VBBaseParser.m b/VBBFramework/Parser/VBBaseParser.m index 4442970..87079d4 100644 --- a/VBBFramework/Parser/VBBaseParser.m +++ b/VBBFramework/Parser/VBBaseParser.m @@ -8,15 +8,15 @@ #import "VBBaseParser.h" -@interface VBBaseParser() +@interface VBBaseParser () -@property (nonatomic, readwrite, strong) RLMRealm *realm; +@property(nonatomic, readwrite, strong) RLMRealm *realm; @end @implementation VBBaseParser --(instancetype)init{ +- (instancetype)init { self = [super init]; if (self) { self.realm = [[VBBPersistanceManager class] realm]; @@ -24,11 +24,11 @@ -(instancetype)init{ return self; } --(void)parserDidStartDocument:(NSXMLParser *)parser { +- (void)parserDidStartDocument:(NSXMLParser *)parser { [self.realm beginWriteTransaction]; } --(void)parserDidEndDocument:(NSXMLParser *)parser { +- (void)parserDidEndDocument:(NSXMLParser *)parser { [self.realm commitWriteTransaction]; } diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Bus.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Bus.colorset/Contents.json new file mode 100644 index 0000000..b0225b0 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Bus.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.639", + "alpha" : "1.000", + "blue" : "0.486", + "green" : "0.000" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Ferry.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Ferry.colorset/Contents.json new file mode 100644 index 0000000..1e49640 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Ferry.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.000", + "alpha" : "1.000", + "blue" : "0.753", + "green" : "0.502" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Metro.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Metro.colorset/Contents.json new file mode 100644 index 0000000..b77c0b0 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Metro.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.957", + "alpha" : "1.000", + "blue" : "0.125", + "green" : "0.475" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Other.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Other.colorset/Contents.json new file mode 100644 index 0000000..52882ad --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Other.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0x4D", + "alpha" : "1.000", + "blue" : "0x5E", + "green" : "0x55" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/SBahn.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/SBahn.colorset/Contents.json new file mode 100644 index 0000000..c4e3bde --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/SBahn.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.000", + "alpha" : "1.000", + "blue" : "0.208", + "green" : "0.435" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Train.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Train.colorset/Contents.json new file mode 100644 index 0000000..c2f0991 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Train.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.855", + "alpha" : "1.000", + "blue" : "0.114", + "green" : "0.145" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/Tram.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/Tram.colorset/Contents.json new file mode 100644 index 0000000..f45cd52 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/Tram.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.800", + "alpha" : "1.000", + "blue" : "0.000", + "green" : "0.000" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Colors/UBahn.colorset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Colors/UBahn.colorset/Contents.json new file mode 100644 index 0000000..519310e --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Colors/UBahn.colorset/Contents.json @@ -0,0 +1,20 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + }, + "colors" : [ + { + "idiom" : "universal", + "color" : { + "color-space" : "srgb", + "components" : { + "red" : "0.024", + "alpha" : "1.000", + "blue" : "0.671", + "green" : "0.392" + } + } + } + ] +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/Contents.json b/VBBFramework/Support Files/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Bus.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Bus.imageset/Contents.json new file mode 100644 index 0000000..ac7bd6d --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Bus.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "bus.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Bus.imageset/bus.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Bus.imageset/bus.pdf new file mode 100644 index 0000000..5d82577 Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Bus.imageset/bus.pdf differ diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ferry.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ferry.imageset/Contents.json new file mode 100644 index 0000000..cbb4aa9 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ferry.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ferry.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ferry.imageset/ferry.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ferry.imageset/ferry.pdf new file mode 100644 index 0000000..a101682 Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ferry.imageset/ferry.pdf differ diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Metro.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Metro.imageset/Contents.json new file mode 100644 index 0000000..33b26a7 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Metro.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "metro.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Metro.imageset/metro.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Metro.imageset/metro.pdf new file mode 100644 index 0000000..b5f1c29 Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Metro.imageset/metro.pdf differ diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/SBahn.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/SBahn.imageset/Contents.json new file mode 100644 index 0000000..91f81d0 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/SBahn.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "sbahn.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/SBahn.imageset/sbahn.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/SBahn.imageset/sbahn.pdf new file mode 100644 index 0000000..2bee581 Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/SBahn.imageset/sbahn.pdf differ diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Train.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Train.imageset/Contents.json new file mode 100644 index 0000000..2599cf1 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Train.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "bahn.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Train.imageset/bahn.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Train.imageset/bahn.pdf new file mode 100644 index 0000000..961d630 Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Train.imageset/bahn.pdf differ diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Tram.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Tram.imageset/Contents.json new file mode 100644 index 0000000..d7c07db --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Tram.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "tram.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Tram.imageset/tram.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Tram.imageset/tram.pdf new file mode 100644 index 0000000..c63fc48 Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Tram.imageset/tram.pdf differ diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ubahn.imageset/Contents.json b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ubahn.imageset/Contents.json new file mode 100644 index 0000000..84aa6d8 --- /dev/null +++ b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ubahn.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "ubahn.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "original", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ubahn.imageset/ubahn.pdf b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ubahn.imageset/ubahn.pdf new file mode 100644 index 0000000..80d66da Binary files /dev/null and b/VBBFramework/Support Files/Assets.xcassets/ServiceIcons/Ubahn.imageset/ubahn.pdf differ diff --git a/VBBFramework/Support Files/VBBFramework-umbrella.h b/VBBFramework/Support Files/VBBFramework-umbrella.h new file mode 100644 index 0000000..1ab8822 --- /dev/null +++ b/VBBFramework/Support Files/VBBFramework-umbrella.h @@ -0,0 +1,16 @@ +#ifdef __OBJC__ +#else +#ifndef FOUNDATION_EXPORT +#if defined(__cplusplus) +#define FOUNDATION_EXPORT extern "C" +#else +#define FOUNDATION_EXPORT extern +#endif +#endif +#endif + +#import "VBBFramework.h" + +FOUNDATION_EXPORT double #import "VBBFrameworkVersionNumber; +FOUNDATION_EXPORT const unsigned char #import "VBBFrameworkVersionString[]; + diff --git a/VBBFramework/VBBFramework.h b/VBBFramework/Support Files/VBBFramework.h similarity index 81% rename from VBBFramework/VBBFramework.h rename to VBBFramework/Support Files/VBBFramework.h index 165dbec..f92ca02 100644 --- a/VBBFramework/VBBFramework.h +++ b/VBBFramework/Support Files/VBBFramework.h @@ -6,7 +6,7 @@ // Copyright © 2018 Dennis Oberhoff. All rights reserved. // -#import +#import //! Project version number for VBBFramework. FOUNDATION_EXPORT double VBBFrameworkVersionNumber; @@ -18,8 +18,10 @@ FOUNDATION_EXPORT const unsigned char VBBFrameworkVersionString[]; #import #import - #import #import #import #import +#import +#import +#import diff --git a/VBBFramework/Support Files/VBBFramework.modulemap b/VBBFramework/Support Files/VBBFramework.modulemap new file mode 100644 index 0000000..3574706 --- /dev/null +++ b/VBBFramework/Support Files/VBBFramework.modulemap @@ -0,0 +1,6 @@ +framework module VBBFramework { + umbrella header "VBBFramework.h" + + export * + module * { export * } +} diff --git a/VBBNow/Icons.xcassets/AppIcon.appiconset/Contents.json b/VBBNow/Icons.xcassets/AppIcon.appiconset/Contents.json deleted file mode 100644 index db41bc0..0000000 --- a/VBBNow/Icons.xcassets/AppIcon.appiconset/Contents.json +++ /dev/null @@ -1,68 +0,0 @@ -{ - "images" : [ - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "Icon_16x16.png", - "scale" : "1x" - }, - { - "size" : "16x16", - "idiom" : "mac", - "filename" : "Icon_16x16@2x.png", - "scale" : "2x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "Icon_32x32.png", - "scale" : "1x" - }, - { - "size" : "32x32", - "idiom" : "mac", - "filename" : "Icon_32x32@2x.png", - "scale" : "2x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "Icon_128x128.png", - "scale" : "1x" - }, - { - "size" : "128x128", - "idiom" : "mac", - "filename" : "Icon_128x128@2x.png", - "scale" : "2x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "Icon_256x256.png", - "scale" : "1x" - }, - { - "size" : "256x256", - "idiom" : "mac", - "filename" : "Icon_256x256@2x.png", - "scale" : "2x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "Icon_512x512.png", - "scale" : "1x" - }, - { - "size" : "512x512", - "idiom" : "mac", - "filename" : "Icon_512x512@2x.png", - "scale" : "2x" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/bus.imageset/Contents.json b/VBBNow/Icons.xcassets/bus.imageset/Contents.json deleted file mode 100644 index cace7ff..0000000 --- a/VBBNow/Icons.xcassets/bus.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "bus.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "bus@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "bus@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/bus.imageset/bus.png b/VBBNow/Icons.xcassets/bus.imageset/bus.png deleted file mode 100644 index b3791cb..0000000 Binary files a/VBBNow/Icons.xcassets/bus.imageset/bus.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/bus.imageset/bus@2x.png b/VBBNow/Icons.xcassets/bus.imageset/bus@2x.png deleted file mode 100644 index 43656e9..0000000 Binary files a/VBBNow/Icons.xcassets/bus.imageset/bus@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/bus.imageset/bus@3x.png b/VBBNow/Icons.xcassets/bus.imageset/bus@3x.png deleted file mode 100644 index c6cdf10..0000000 Binary files a/VBBNow/Icons.xcassets/bus.imageset/bus@3x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/ferry.imageset/Contents.json b/VBBNow/Icons.xcassets/ferry.imageset/Contents.json deleted file mode 100644 index f658d72..0000000 --- a/VBBNow/Icons.xcassets/ferry.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "ferry.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "ferry@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "ferry@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/ferry.imageset/ferry.png b/VBBNow/Icons.xcassets/ferry.imageset/ferry.png deleted file mode 100644 index 60a6b83..0000000 Binary files a/VBBNow/Icons.xcassets/ferry.imageset/ferry.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/ferry.imageset/ferry@2x.png b/VBBNow/Icons.xcassets/ferry.imageset/ferry@2x.png deleted file mode 100644 index 10b1b7e..0000000 Binary files a/VBBNow/Icons.xcassets/ferry.imageset/ferry@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/ferry.imageset/ferry@3x.png b/VBBNow/Icons.xcassets/ferry.imageset/ferry@3x.png deleted file mode 100644 index f0df6a3..0000000 Binary files a/VBBNow/Icons.xcassets/ferry.imageset/ferry@3x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/metroBus.imageset/Contents.json b/VBBNow/Icons.xcassets/metroBus.imageset/Contents.json deleted file mode 100644 index 1fb7b27..0000000 --- a/VBBNow/Icons.xcassets/metroBus.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "MetroBus.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "MetroBus@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "MetroBus@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus.png b/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus.png deleted file mode 100644 index e5841fd..0000000 Binary files a/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus@2x.png b/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus@2x.png deleted file mode 100644 index 532b86f..0000000 Binary files a/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus@3x.png b/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus@3x.png deleted file mode 100644 index fc97b50..0000000 Binary files a/VBBNow/Icons.xcassets/metroBus.imageset/MetroBus@3x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/sbahn.imageset/Contents.json b/VBBNow/Icons.xcassets/sbahn.imageset/Contents.json deleted file mode 100644 index 9e20749..0000000 --- a/VBBNow/Icons.xcassets/sbahn.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "sbahn.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "sbahn@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "sbahn@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/sbahn.imageset/sbahn.png b/VBBNow/Icons.xcassets/sbahn.imageset/sbahn.png deleted file mode 100644 index f063fbb..0000000 Binary files a/VBBNow/Icons.xcassets/sbahn.imageset/sbahn.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/sbahn.imageset/sbahn@2x.png b/VBBNow/Icons.xcassets/sbahn.imageset/sbahn@2x.png deleted file mode 100644 index 8d03add..0000000 Binary files a/VBBNow/Icons.xcassets/sbahn.imageset/sbahn@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/sbahn.imageset/sbahn@3x.png b/VBBNow/Icons.xcassets/sbahn.imageset/sbahn@3x.png deleted file mode 100644 index 2a78c96..0000000 Binary files a/VBBNow/Icons.xcassets/sbahn.imageset/sbahn@3x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/train.imageset/Contents.json b/VBBNow/Icons.xcassets/train.imageset/Contents.json deleted file mode 100644 index aa0867a..0000000 --- a/VBBNow/Icons.xcassets/train.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "local.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "local@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "local@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/train.imageset/local.png b/VBBNow/Icons.xcassets/train.imageset/local.png deleted file mode 100644 index 3edc20a..0000000 Binary files a/VBBNow/Icons.xcassets/train.imageset/local.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/train.imageset/local@2x.png b/VBBNow/Icons.xcassets/train.imageset/local@2x.png deleted file mode 100644 index dd35baf..0000000 Binary files a/VBBNow/Icons.xcassets/train.imageset/local@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/train.imageset/local@3x.png b/VBBNow/Icons.xcassets/train.imageset/local@3x.png deleted file mode 100644 index 599609f..0000000 Binary files a/VBBNow/Icons.xcassets/train.imageset/local@3x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/tram.imageset/Contents.json b/VBBNow/Icons.xcassets/tram.imageset/Contents.json deleted file mode 100644 index 79c9cb9..0000000 --- a/VBBNow/Icons.xcassets/tram.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "tram.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "tram@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "tram@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/tram.imageset/tram.png b/VBBNow/Icons.xcassets/tram.imageset/tram.png deleted file mode 100644 index bff6c72..0000000 Binary files a/VBBNow/Icons.xcassets/tram.imageset/tram.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/tram.imageset/tram@2x.png b/VBBNow/Icons.xcassets/tram.imageset/tram@2x.png deleted file mode 100644 index 0649d51..0000000 Binary files a/VBBNow/Icons.xcassets/tram.imageset/tram@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/tram.imageset/tram@3x.png b/VBBNow/Icons.xcassets/tram.imageset/tram@3x.png deleted file mode 100644 index e2dd215..0000000 Binary files a/VBBNow/Icons.xcassets/tram.imageset/tram@3x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/ubahn.imageset/Contents.json b/VBBNow/Icons.xcassets/ubahn.imageset/Contents.json deleted file mode 100644 index fef7fa3..0000000 --- a/VBBNow/Icons.xcassets/ubahn.imageset/Contents.json +++ /dev/null @@ -1,23 +0,0 @@ -{ - "images" : [ - { - "idiom" : "universal", - "scale" : "1x", - "filename" : "Ubahn.png" - }, - { - "idiom" : "universal", - "scale" : "2x", - "filename" : "Ubahn@2x.png" - }, - { - "idiom" : "universal", - "scale" : "3x", - "filename" : "Ubahn@3x.png" - } - ], - "info" : { - "version" : 1, - "author" : "xcode" - } -} \ No newline at end of file diff --git a/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn.png b/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn.png deleted file mode 100644 index d0c5005..0000000 Binary files a/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn@2x.png b/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn@2x.png deleted file mode 100644 index ef5acb4..0000000 Binary files a/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn@2x.png and /dev/null differ diff --git a/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn@3x.png b/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn@3x.png deleted file mode 100644 index 57557fc..0000000 Binary files a/VBBNow/Icons.xcassets/ubahn.imageset/Ubahn@3x.png and /dev/null differ diff --git a/VBBNow/Supporting Files/Info.plist b/VBBNow/Supporting Files/Info.plist index 57b53b8..98996d6 100644 --- a/VBBNow/Supporting Files/Info.plist +++ b/VBBNow/Supporting Files/Info.plist @@ -17,11 +17,11 @@ CFBundlePackageType XPC! CFBundleShortVersionString - 1.0.3 + $(MARKETING_VERSION) CFBundleSignature ???? CFBundleVersion - 6 + $(CURRENT_PROJECT_VERSION) LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) NSAppTransportSecurity diff --git a/VBBNow/Supporting Files/vbbnow.entitlements b/VBBNow/Supporting Files/vbbnow.entitlements index 9f2bc64..fc07546 100644 --- a/VBBNow/Supporting Files/vbbnow.entitlements +++ b/VBBNow/Supporting Files/vbbnow.entitlements @@ -6,8 +6,6 @@ com.apple.security.network.client - com.apple.security.network.server - com.apple.security.personal-information.location diff --git a/VBBNow/ViewController/VBBListRowViewController.h b/VBBNow/ViewController/VBBListRowViewController.h index a3e5403..aeb0172 100644 --- a/VBBNow/ViewController/VBBListRowViewController.h +++ b/VBBNow/ViewController/VBBListRowViewController.h @@ -11,12 +11,12 @@ @interface VBBListRowViewController : NSViewController -@property (nonatomic, weak) IBOutlet NSTextField *lineNameLabel; -@property (nonatomic, weak) IBOutlet NSTextField *lineEndLabel; -@property (nonatomic, weak) IBOutlet NSTextField *stationLabel; -@property (nonatomic, weak) IBOutlet NSTextField *timeLabel; -@property (nonatomic, weak) IBOutlet NSTextField *timeDescLabel; +@property(nonatomic, weak) IBOutlet NSTextField *lineNameLabel; +@property(nonatomic, weak) IBOutlet NSTextField *lineEndLabel; +@property(nonatomic, weak) IBOutlet NSTextField *stationLabel; +@property(nonatomic, weak) IBOutlet NSTextField *timeLabel; +@property(nonatomic, weak) IBOutlet NSTextField *timeDescLabel; -@property (nonatomic, weak) IBOutlet NSImageView *iconView; +@property(nonatomic, weak) IBOutlet NSImageView *iconView; @end diff --git a/VBBNow/ViewController/VBBListRowViewController.m b/VBBNow/ViewController/VBBListRowViewController.m index 9451a6f..2bcf6d6 100644 --- a/VBBNow/ViewController/VBBListRowViewController.m +++ b/VBBNow/ViewController/VBBListRowViewController.m @@ -8,77 +8,45 @@ @import VBBFramework; -#import #import "VBBListRowViewController.h" @interface VBBListRowViewController () -@property (nonatomic, readwrite, strong) CALayer *seperatorLayer; +@property(nonatomic, readwrite, strong) CALayer *seperatorLayer; @end @implementation VBBListRowViewController --(void)viewDidLoad{ +- (void)viewDidLoad { self.seperatorLayer = [CALayer new]; [self.view.layer addSublayer:self.seperatorLayer]; [super viewDidLoad]; } --(void)viewDidLayout { - self.seperatorLayer.frame = CGRectMake(CGRectGetMaxX(self.timeLabel.frame), CGRectGetMinY(self.stationLabel.frame), - 2.5, CGRectGetMinY(self.timeLabel.frame) + CGRectGetMaxY(self.timeDescLabel.frame)); +- (void)viewDidLayout { + self.seperatorLayer.frame = CGRectMake(CGRectGetMaxX(self.timeLabel.frame), CGRectGetMinY(self.stationLabel.frame), + 2.5, CGRectGetMinY(self.timeLabel.frame) + CGRectGetMaxY(self.timeDescLabel.frame)); } --(void)setInformations: (VBBStation *)station { - +- (void)setInformations:(VBBStation *)station { NSDate *future = [NSDate dateWithTimeInterval:60 sinceDate:[NSDate date]]; - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"arrivalDate > %@", future]; + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"scheduledDate > %@", future]; VBBDepature *nextDepature = [station.depatures objectsWithPredicate:predicate].firstObject; - NSTimeInterval left = [nextDepature.arrivalDate timeIntervalSinceDate:[NSDate date]]; - - NSArray *timeDescriptions = [[[self timeFormatter] stringFromTimeInterval:left] componentsSeparatedByString:@" "]; + NSTimeInterval seconds = [nextDepature.arrivalDate timeIntervalSinceDate:[NSDate date]]; + NSArray *timeDescriptions = [[[NSDateComponentsFormatter timeFormatter] stringFromTimeInterval:seconds] componentsSeparatedByString:@" "]; + self.stationLabel.stringValue = station.stationName; - self.timeLabel.stringValue = timeDescriptions.firstObject; - self.timeDescLabel.stringValue = timeDescriptions.lastObject; + self.timeLabel.stringValue = timeDescriptions.firstObject; + self.timeDescLabel.stringValue = timeDescriptions.lastObject; self.lineEndLabel.stringValue = nextDepature.line.lineEnd; self.lineNameLabel.stringValue = nextDepature.line.lineName; - - NSImage *image; - NSColor *color = [NSColor colorWithWhite:0.5 alpha:0.5]; - - switch (nextDepature.line.departureType) { - case 1: - image = [NSImage imageNamed:@"sbahn"]; - color = [NSColor colorWithRed:0 green:0.6 blue:0.37 alpha:1]; - break; - case 2: - image = [NSImage imageNamed:@"ubahn"]; - color = [NSColor colorWithRed:0 green:0.35 blue:0.58 alpha:1]; - break; - case 4: - image = [NSImage imageNamed:@"tram"]; - color = [NSColor colorWithRed:0.88 green:0 blue:0 alpha:1]; - break; - case 8: { - NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", @"^Bus M\\d+"]; - if ([predicate evaluateWithObject:nextDepature.line.lineName]) { - image = [NSImage imageNamed:@"metroBus"]; - color = [NSColor colorWithRed:1 green:0.44 blue:0 alpha:1]; - } else { - image = [NSImage imageNamed:@"bus"]; - color = [NSColor colorWithRed:0.65 green:0 blue:0.42 alpha:1]; - } - } - break; - case 32 : - image = [NSImage imageNamed:@"train"]; - color = [NSColor colorWithRed:0.82 green:0 blue:0 alpha:1]; - break; - default: - break; - } - + + NSBundle *frameworkBundle = [NSBundle frameworkBundle]; + NSString *assetName = [VBBLine assetNameForType:nextDepature.line.lineType]; + NSImage *image = [frameworkBundle imageForResource:assetName]; + NSColor *color = [NSColor colorNamed:assetName bundle:frameworkBundle]; + self.seperatorLayer.backgroundColor = color.CGColor; self.iconView.image = image; } @@ -87,22 +55,9 @@ - (NSString *)nibName { return NSStringFromClass([self class]); } --(void)setRepresentedObject:(id)representedObject { +- (void)setRepresentedObject:(id)representedObject { [super setRepresentedObject:representedObject]; [self setInformations:representedObject]; } --(NSDateComponentsFormatter*)timeFormatter { - static dispatch_once_t onceToken; - static NSDateComponentsFormatter *timeFormatter; - dispatch_once(&onceToken, ^{ - timeFormatter = [NSDateComponentsFormatter new]; - timeFormatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitMinute | NSCalendarUnitDay; - timeFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleShort; - timeFormatter.includesApproximationPhrase = NO; - timeFormatter.includesTimeRemainingPhrase = NO; - }); - return timeFormatter; -} - @end diff --git a/VBBNow/ViewController/VBBTodayViewController.m b/VBBNow/ViewController/VBBTodayViewController.m index 6cd6af2..44f4ad5 100644 --- a/VBBNow/ViewController/VBBTodayViewController.m +++ b/VBBNow/ViewController/VBBTodayViewController.m @@ -15,17 +15,18 @@ #import "VBBListRowViewController.h" typedef void (^didUpdateLocationBlock)(CLLocation *location); + typedef void (^didChangeAuthorizationStatus)(CLAuthorizationStatus status); @interface VBBTodayViewController () -@property (nonatomic, readwrite, strong) VBBNetworkManager *networkManager; -@property (nonatomic, readwrite, strong) CLLocationManager *locationManager; -@property (nonatomic, readwrite, strong) NSTimer *reloadTimer; -@property (nonatomic, readwrite, weak) IBOutlet NSTextField *locationLabel; -@property (nonatomic, readwrite, weak) IBOutlet NCWidgetListViewController *listViewController; -@property (nonatomic, readwrite, copy) didUpdateLocationBlock didUpdateLocationBlock; -@property (nonatomic, readwrite, copy) didChangeAuthorizationStatus didChangeAuthorizationStatus; +@property(nonatomic, readwrite, strong) VBBNetworkManager *networkManager; +@property(nonatomic, readwrite, strong) CLLocationManager *locationManager; +@property(nonatomic, readwrite, strong) NSTimer *reloadTimer; +@property(nonatomic, readwrite, weak) IBOutlet NSTextField *locationLabel; +@property(nonatomic, readwrite, weak) IBOutlet NCWidgetListViewController *listViewController; +@property(nonatomic, readwrite, copy) didUpdateLocationBlock didUpdateLocationBlock; +@property(nonatomic, readwrite, copy) didChangeAuthorizationStatus didChangeAuthorizationStatus; @end @@ -38,23 +39,23 @@ - (void)viewDidLoad { self.networkManager = [VBBNetworkManager new]; self.locationManager = [CLLocationManager new]; self.locationManager.delegate = self; - + VBBLocation *storedLocation = [VBBPersistanceManager manager].storedLocation; - if (storedLocation.address) [self.locationLabel setStringValue:storedLocation.address]; + if (storedLocation.address) [self.locationLabel setStringValue:[storedLocation.address stringByReplacingOccurrencesOfString:@"\n" withString:@", "]]; self.listViewController.preferredContentSize = CGSizeMake(320, 350); - self.listViewController.contents = [[VBBStation class] sortByRelevance:storedLocation andLimit:5]; + self.listViewController.contents = [VBBStation sortByRelevance:storedLocation andLimit:5]; } --(void)reloadData { - +- (void)reloadData { + [self.reloadTimer invalidate]; - + VBBLocation *location = [VBBPersistanceManager manager].storedLocation; - + if (!location) { return; } - + CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"]; opacity.toValue = @(0.0); opacity.duration = 0.35; @@ -65,7 +66,7 @@ -(void)reloadData { [opacity setValue:@"opacity" forKey:@"identifier"]; [opacity setValue:location forKey:@"location"]; [self.view.layer addAnimation:opacity forKey:@"opacity"]; - + NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitSecond fromDate:[NSDate date]]; NSTimeInterval refreshInterval = 60 - components.second; @@ -75,24 +76,27 @@ -(void)reloadData { #pragma mark - NCWidgetProviding --(void)fetchNearby: (void (^)(NCUpdateResult result))completionHandler { - +- (void)fetchNearby:(void (^)(NCUpdateResult result))completionHandler { + __weak typeof(self) weakSelf = self; - + void (^completionBlock)(NSArray *stations, VBBLocation *location) = ^(NSArray *stations, VBBLocation *location) { dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf reloadData]; completionHandler(stations.count ? NCUpdateResultNewData : NCUpdateResultFailed); }); }; - + void (^responseBlock)(CLLocation *location) = ^void(CLLocation *location) { + if (location == nil) { + location = [VBBPersistanceManager manager].storedLocation.location; + } [self.networkManager fetchNearedStations:location andCompletionHandler:completionBlock]; }; - + [self setDidUpdateLocationBlock:responseBlock]; [self.locationManager startUpdatingLocation]; - + } - (void)widgetPerformUpdateWithCompletionHandler:(void (^)(NCUpdateResult result))completionHandler { @@ -124,9 +128,9 @@ - (BOOL)widgetAllowsEditing { #pragma mark CoreAnimation Delegate --(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { - - NSString *key = [anim valueForKey:@"identifier"]; +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { + + NSString * key = [anim valueForKey:@"identifier"]; if ([key isEqualTo:@"opacity"]) { VBBLocation *location = [anim valueForKey:@"location"]; CABasicAnimation *opacity = [CABasicAnimation animationWithKeyPath:@"opacity"]; @@ -138,28 +142,28 @@ -(void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag { opacity.fromValue = [self.view.layer.presentationLayer ?: self.view.layer valueForKeyPath:opacity.keyPath]; [CATransaction begin]; [CATransaction setDisableActions:YES]; - self.listViewController.contents = [[VBBStation class] sortByRelevance:location andLimit:5]; + self.listViewController.contents = [VBBStation sortByRelevance:location andLimit:5]; [self.view.layer setValue:opacity.toValue forKeyPath:opacity.keyPath]; - if (location.address) [self.locationLabel setStringValue:location.address]; + if (location.address) [self.locationLabel setStringValue:[location.address stringByReplacingOccurrencesOfString:@"\n" withString:@", "]]; [CATransaction commit]; [self.view.layer addAnimation:opacity forKey:@"opacity"]; } - + } #pragma mark CLLocationManagerDelegate --(void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { +- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations { if (self.didUpdateLocationBlock) self.didUpdateLocationBlock(locations.firstObject); self.didUpdateLocationBlock = nil; } --(void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { +- (void)locationManager:(CLLocationManager *)manager didFailWithError:(NSError *)error { if (self.didUpdateLocationBlock) self.didUpdateLocationBlock(nil); self.didUpdateLocationBlock = nil; } --(void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { +- (void)locationManager:(CLLocationManager *)manager didChangeAuthorizationStatus:(CLAuthorizationStatus)status { if (self.didChangeAuthorizationStatus) { self.didChangeAuthorizationStatus(status); self.didChangeAuthorizationStatus = nil; diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/Contents.json b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..a4e81b8 --- /dev/null +++ b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,101 @@ +{ + "version" : "1.0", + "images" : [ + { + "subtype" : "38mm", + "scale" : "2x", + "role" : "quickLook", + "filename" : "watch_quickLook-38mm@2x.png", + "size" : "86x86", + "idiom" : "watch", + "expected-size" : "172" + }, + { + "subtype" : "38mm", + "scale" : "2x", + "role" : "appLauncher", + "filename" : "watch_appLauncher-38mm@2x.png", + "size" : "40x40", + "idiom" : "watch", + "expected-size" : "80" + }, + { + "subtype" : "42mm", + "scale" : "2x", + "role" : "quickLook", + "filename" : "watch_quickLook-42mm@2x.png", + "size" : "98x98", + "idiom" : "watch", + "expected-size" : "196" + }, + { + "subtype" : "40mm", + "scale" : "2x", + "role" : "appLauncher", + "filename" : "watch_appLauncher-40mm@2x.png", + "size" : "44x44", + "idiom" : "watch", + "expected-size" : "88" + }, + { + "subtype" : "44mm", + "scale" : "2x", + "role" : "quickLook", + "filename" : "watch_quickLook-44mm@2x.png", + "size" : "108x108", + "idiom" : "watch", + "expected-size" : "216" + }, + { + "subtype" : "44mm", + "scale" : "2x", + "role" : "appLauncher", + "filename" : "watch_appLauncher-44mm@2x.png", + "size" : "50x50", + "idiom" : "watch", + "expected-size" : "100" + }, + { + "subtype" : "38mm", + "scale" : "2x", + "role" : "notificationCenter", + "filename" : "watch_notificationCenter-38mm@2x.png", + "size" : "24x24", + "idiom" : "watch", + "expected-size" : "48" + }, + { + "subtype" : "42mm", + "scale" : "2x", + "role" : "notificationCenter", + "filename" : "watch_notificationCenter-42mm@2x.png", + "size" : "27.5x27.5", + "idiom" : "watch", + "expected-size" : "55" + }, + { + "role" : "companionSettings", + "size" : "29x29", + "filename" : "watch_companionSettings-@3x.png", + "scale" : "3x", + "idiom" : "watch", + "expected-size" : "87" + }, + { + "role" : "companionSettings", + "size" : "29x29", + "filename" : "watch_companionSettings-@2x.png", + "scale" : "2x", + "idiom" : "watch", + "expected-size" : "58" + }, + { + "size" : "1024x1024", + "filename" : "watch-marketing.png", + "scale" : "1x", + "idiom" : "watch-marketing", + "expected-size" : "1024" + } + ], + "author" : "Iconizer" +} \ No newline at end of file diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch-marketing.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch-marketing.png new file mode 100644 index 0000000..485e17e Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch-marketing.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-38mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-38mm@2x.png new file mode 100644 index 0000000..79531ef Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-38mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-40mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-40mm@2x.png new file mode 100644 index 0000000..20bbd41 Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-40mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-44mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-44mm@2x.png new file mode 100644 index 0000000..dc907f3 Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_appLauncher-44mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_companionSettings-@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_companionSettings-@2x.png new file mode 100644 index 0000000..c629be5 Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_companionSettings-@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_companionSettings-@3x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_companionSettings-@3x.png new file mode 100644 index 0000000..47fa277 Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_companionSettings-@3x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_notificationCenter-38mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_notificationCenter-38mm@2x.png new file mode 100644 index 0000000..5d278aa Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_notificationCenter-38mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_notificationCenter-42mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_notificationCenter-42mm@2x.png new file mode 100644 index 0000000..9f3f353 Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_notificationCenter-42mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-38mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-38mm@2x.png new file mode 100644 index 0000000..a4617af Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-38mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-42mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-42mm@2x.png new file mode 100644 index 0000000..fb28c5b Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-42mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-44mm@2x.png b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-44mm@2x.png new file mode 100644 index 0000000..b408b7f Binary files /dev/null and b/VBBWatch App/Assets.xcassets/AppIcon.appiconset/watch_quickLook-44mm@2x.png differ diff --git a/VBBWatch App/Assets.xcassets/Contents.json b/VBBWatch App/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/VBBWatch App/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch App/Base.lproj/Interface.storyboard b/VBBWatch App/Base.lproj/Interface.storyboard new file mode 100644 index 0000000..a766c41 --- /dev/null +++ b/VBBWatch App/Base.lproj/Interface.storyboard @@ -0,0 +1,17 @@ + + + + + + + + + + + + + + + + + diff --git a/VBBWatch App/Info.plist b/VBBWatch App/Info.plist new file mode 100644 index 0000000..af76646 --- /dev/null +++ b/VBBWatch App/Info.plist @@ -0,0 +1,31 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + VBBNow + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + + WKWatchKitApp + + + diff --git a/VBBWatch Extension/Controller/HostingController.swift b/VBBWatch Extension/Controller/HostingController.swift new file mode 100644 index 0000000..f27c142 --- /dev/null +++ b/VBBWatch Extension/Controller/HostingController.swift @@ -0,0 +1,15 @@ +import CoreLocation +import Foundation +import SwiftUI +import VBBFramework +import WatchKit + +class HostingController: WKHostingController { + override init() { + super.init() + } + + override var body: ParentView { + return ParentView(presenter: ParentPresenter()) + } +} diff --git a/VBBWatch Extension/ExtensionDelegate.swift b/VBBWatch Extension/ExtensionDelegate.swift new file mode 100644 index 0000000..de53725 --- /dev/null +++ b/VBBWatch Extension/ExtensionDelegate.swift @@ -0,0 +1,17 @@ +import Foundation +import VBBFramework +import WatchKit + +class ExtensionDelegate: NSObject, WKExtensionDelegate { + func applicationDidFinishLaunching() { + VBBPersistanceManager.trim() + } + + func applicationDidBecomeActive() { + NotificationCenter.default.post(name: .active, object: self) + } + + func applicationWillResignActive() { + NotificationCenter.default.post(name: .resign, object: self) + } +} diff --git a/VBBWatch Extension/Extensions/NSNotification-Extensions.swift b/VBBWatch Extension/Extensions/NSNotification-Extensions.swift new file mode 100644 index 0000000..16fbffc --- /dev/null +++ b/VBBWatch Extension/Extensions/NSNotification-Extensions.swift @@ -0,0 +1,6 @@ +import Foundation + +extension NSNotification.Name { + static let active = NSNotification.Name("applicationDidBecomeActive") + static let resign = NSNotification.Name("applicationWillResignActive") +} diff --git a/VBBWatch Extension/Extensions/TimeInterval-Extension.swift b/VBBWatch Extension/Extensions/TimeInterval-Extension.swift new file mode 100644 index 0000000..22114b0 --- /dev/null +++ b/VBBWatch Extension/Extensions/TimeInterval-Extension.swift @@ -0,0 +1,6 @@ +import Foundation + +extension TimeInterval { + static let backgroundInterval: TimeInterval = 60 * 10 + static let deparuteUpdateInterval: TimeInterval = 60 +} diff --git a/VBBWatch Extension/Extensions/VBBDeparture-Extension.swift b/VBBWatch Extension/Extensions/VBBDeparture-Extension.swift new file mode 100644 index 0000000..f270c2d --- /dev/null +++ b/VBBWatch Extension/Extensions/VBBDeparture-Extension.swift @@ -0,0 +1,5 @@ +import Foundation +import SwiftUI +import VBBFramework + +extension VBBDepature: Identifiable {} diff --git a/VBBWatch Extension/Extensions/VBBLine-Extension.swift b/VBBWatch Extension/Extensions/VBBLine-Extension.swift new file mode 100644 index 0000000..4765832 --- /dev/null +++ b/VBBWatch Extension/Extensions/VBBLine-Extension.swift @@ -0,0 +1,25 @@ +import Foundation +import SwiftUI +import UIKit +import VBBFramework + +extension VBBLineType { + var assetsName: String { + switch self { + case .sBahn: + return "SBahn" + case .uBahn: + return "UBahn" + case .tram: + return "Tram" + case .bus: + return "Bus" + case .metro: + return "Metro" + case .bahn: + return "Train" + @unknown default: + fatalError() + } + } +} diff --git a/VBBWatch Extension/Extensions/VBBNetworkStatus-Extension.swift b/VBBWatch Extension/Extensions/VBBNetworkStatus-Extension.swift new file mode 100644 index 0000000..bec93e5 --- /dev/null +++ b/VBBWatch Extension/Extensions/VBBNetworkStatus-Extension.swift @@ -0,0 +1,21 @@ +import Foundation +import VBBFramework + +extension VBBNetworkStatus { + var statusText: String { + let localizedKey: String + switch self { + case .geocoding: + localizedKey = "STATUS_GEOCODING" + case .loading: + localizedKey = "STATUS_LOADING_STATIONS" + case .loadingDetails: + localizedKey = "STATUS_LOADING_STATIONS_DETAILS" + case .failed: + localizedKey = "STATUS_FAILED" + default: + localizedKey = "STATUS_LOADING_UNKNOWN" + } + return NSLocalizedString(localizedKey, comment: "") + } +} diff --git a/VBBWatch Extension/Extensions/VBBStation-Extension.swift b/VBBWatch Extension/Extensions/VBBStation-Extension.swift new file mode 100644 index 0000000..03a30cc --- /dev/null +++ b/VBBWatch Extension/Extensions/VBBStation-Extension.swift @@ -0,0 +1,5 @@ +import Foundation +import SwiftUI +import VBBFramework + +extension VBBStation: Identifiable {} diff --git a/VBBWatch Extension/Extensions/View-Gradient.swift b/VBBWatch Extension/Extensions/View-Gradient.swift new file mode 100644 index 0000000..cec24be --- /dev/null +++ b/VBBWatch Extension/Extensions/View-Gradient.swift @@ -0,0 +1,21 @@ +import Foundation +import SwiftUI +import VBBFramework + +extension View { + func gradientColor(_ type: VBBLineType, + cornerRadius _: CGFloat = 8.0, + intensity: Double = 0.7) -> some View { + return gradientColor(Color(VBBLine.assetName(for: type), bundle: Bundle.framework), + intensity: intensity) + } + + func gradientColor(_ color: Color, + cornerRadius: CGFloat = 8.0, + intensity: Double = 0.7) -> some View { + background(LinearGradient(gradient: Gradient(colors: [color.opacity(intensity), color]), + startPoint: .top, endPoint: .bottom)) + .background(Color.white) + .cornerRadius(cornerRadius) + } +} diff --git a/VBBWatch Extension/Presenter/DepartureListPresenter.swift b/VBBWatch Extension/Presenter/DepartureListPresenter.swift new file mode 100644 index 0000000..f419824 --- /dev/null +++ b/VBBWatch Extension/Presenter/DepartureListPresenter.swift @@ -0,0 +1,152 @@ +import Combine +import CoreLocation +import Foundation +import SwiftUI +import VBBFramework + +final class DepartureListPresenter: NSObject, ObservableObject { + var objectWillChange = PassthroughSubject() + private let networkManager = VBBNetworkManager() + private let locationManager = CLLocationManager() + private var timer: Timer? + private var lastFetch: Date? + private var observer: NSKeyValueObservation? + + private var departures: [VBBStation: [VBBDepature]] = [:] + + @Published var stations: [VBBStation] = [] { + didSet { + objectWillChange.send() + } + } + + @Published var location: VBBLocation? { + didSet { + objectWillChange.send() + } + } + + var status: VBBNetworkStatus { + return networkManager.status + } + + var isLoading: Bool { + let states: [VBBNetworkStatus] = [.geocoding, .loading, .loadingDetails] + return states.contains(self.status) + } + + override init() { + super.init() + NotificationCenter.default.addObserver(self, selector: #selector(didBecomeActive), name: .active, object: nil) + + locationManager.delegate = self + locationManager.desiredAccuracy = kCLLocationAccuracyThreeKilometers + + configureTimer() + updateProperties() + observer = networkManager.observe(\.status) { [weak self] _, _ in + DispatchQueue.main.async { self?.objectWillChange.send() } + } + } + + func update() { + locationManager.requestLocation() + } + + @objc func didBecomeActive() { + updateProperties() + + let lastTimeInterval = fabs(lastFetch?.timeIntervalSinceNow ?? 0) + if lastTimeInterval > .backgroundInterval { + fetch() + } + } + + deinit { + timer?.invalidate() + observer?.invalidate() + } +} + +extension DepartureListPresenter { + func departures(_ station: VBBStation) -> [VBBDepature] { + return departures[station] ?? [] + } +} + +private extension DepartureListPresenter { + func updateProperties() { + guard let location = VBBPersistanceManager.manager.storedLocation else { + return + } + + let stations = VBBStation.sort(byRelevance: location, andLimit: 3) + stations.forEach { station in + let lines = station.lines.mapItems().compactMap { $0 as? VBBLine } + var departures = lines.compactMap { + $0.departures.mapItems().compactMap { $0 as? VBBDepature } + .sorted(by: { (firstDeparture, secondDeparture) -> Bool in + firstDeparture.arrivalDate < secondDeparture.arrivalDate + }).filter { + $0.arrivalDate > Date() + }.first + } + + departures.sort { (firstDeparture, secondDeparture) -> Bool in + let firstType = firstDeparture.line?.lineType() ?? .uBahn + let secondType = secondDeparture.line?.lineType() ?? .uBahn + let firstArrival = firstDeparture.arrivalDate + let secondArrival = secondDeparture.arrivalDate + return firstType == secondType ? firstArrival < secondArrival : firstType.rawValue < secondType.rawValue + } + + self.departures[station] = departures + } + + self.stations = stations + } + + func fetch() { + let storedLocation = VBBPersistanceManager.manager.storedLocation + let currentLocation = locationManager.location ?? storedLocation?.location + + guard let location = currentLocation, status == .finished || status == .failed else { + return + } + + networkManager.fetchNearedStations(location) { [weak self] _, location in + guard let location = location else { + return + } + self?.lastFetch = Date() + self?.location = location + self?.updateProperties() + } + } + + func configureTimer() { + let components = Calendar.current.component(.second, from: Date()) + let refreshInterval = 60.0 - TimeInterval(components) + 1 + + timer?.invalidate() + timer = Timer.scheduledTimer(withTimeInterval: refreshInterval, repeats: false, block: { [weak self] _ in + self?.updateProperties() + self?.configureTimer() + }) + } +} + +extension DepartureListPresenter: CLLocationManagerDelegate { + func locationManager(_: CLLocationManager, didUpdateLocations _: [CLLocation]) { + fetch() + } + + func locationManager(_: CLLocationManager, didFailWithError _: Error) { + fetch() + } + + func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { + guard status == .authorizedWhenInUse else { return } + manager.requestLocation() + } +} diff --git a/VBBWatch Extension/Presenter/DeparturePresenter.swift b/VBBWatch Extension/Presenter/DeparturePresenter.swift new file mode 100644 index 0000000..7642db0 --- /dev/null +++ b/VBBWatch Extension/Presenter/DeparturePresenter.swift @@ -0,0 +1,58 @@ +import Combine +import Foundation +import SwiftUI +import VBBFramework + +final class DeparturePresenter: ObservableObject { + var objectWillChange = PassthroughSubject() + var timeMinutesText: String = "" + var timeUnitsText: String = "" + var lineEnd: String = "" + var lineName: String = "" + var stationName: String = "" + var timer: Timer? + + var lineImage: Image? + var lineType: VBBLineType = .bahn + var departure: VBBDepature? + var station: VBBStation? + + init(departure: VBBDepature?) { + self.departure = departure + configureContent() + configureTimer() + } + + deinit { + timer?.invalidate() + } +} + +private extension DeparturePresenter { + func configureTimer() { + timer = Timer.scheduledTimer(withTimeInterval: .deparuteUpdateInterval, repeats: false, block: { [weak self] _ in + self?.configureContent() + self?.configureTimer() + }) + } + + func configureContent() { + station = departure?.station.firstObject() as? VBBStation + lineType = departure?.line?.lineType() ?? .bus + + let assetName = VBBLine.assetName(for: lineType) + let departureInterval = departure?.arrivalDate.timeIntervalSince(Date()) ?? 0 + let timeComponents = DateComponentsFormatter.time.string(from: departureInterval)? + .components(separatedBy: " ") ?? [String]() + + stationName = station?.stationName ?? "" + lineName = departure?.line?.lineName ?? "" + lineImage = Image(assetName, bundle: Bundle.framework) + lineEnd = "▶︎ \(departure?.line?.lineEnd ?? "Osloer Straße")" + + timeMinutesText = timeComponents.first ?? "2" + timeUnitsText = timeComponents.last ?? "min" + + objectWillChange.send() + } +} diff --git a/VBBWatch Extension/Presenter/LinePresenter.swift b/VBBWatch Extension/Presenter/LinePresenter.swift new file mode 100644 index 0000000..a682599 --- /dev/null +++ b/VBBWatch Extension/Presenter/LinePresenter.swift @@ -0,0 +1,29 @@ +import Combine +import Foundation +import Realm +import VBBFramework + +final class LinePresenter: ObservableObject { + var objectWillChange = PassthroughSubject() + var departures: [VBBDepature] = [] + var notificationToken: RLMNotificationToken? + let lineName: String + + init(departure: VBBDepature?) { + let station = departure?.station.firstObject() as? VBBStation + lineName = station?.stationName ?? "" + + if let station = station { + let predicate = NSPredicate(format: "scheduledDate > %@ AND (ANY station == %@)", NSDate(), station) + let sortDescriptor = [RLMSortDescriptor(keyPath: #keyPath(VBBDepature.scheduledDate), ascending: true)] + let results = VBBDepature.objects(with: predicate).sortedResults(using: sortDescriptor) + notificationToken = results.addNotificationBlock { [weak self] results, _, _ in + self?.departures = results?.mapItems().compactMap { $0 as? VBBDepature } ?? [] + } + } + } + + deinit { + notificationToken?.invalidate() + } +} diff --git a/VBBWatch Extension/Presenter/OnboardingPresenter.swift b/VBBWatch Extension/Presenter/OnboardingPresenter.swift new file mode 100644 index 0000000..514f950 --- /dev/null +++ b/VBBWatch Extension/Presenter/OnboardingPresenter.swift @@ -0,0 +1,28 @@ +import Combine +import Foundation +import SwiftUI +import VBBFramework + +final class OnboardingPresenter: ObservableObject { + enum Page: Int, CaseIterable, Identifiable { + case welcome + case description + case permission + + var id: Int { + return rawValue + } + } + + @Published var currentPage: Page = .welcome + let locationManager = CLLocationManager() + + func next() { + switch currentPage { + case .welcome: + currentPage = .description + case .description, .permission: + currentPage = .permission + } + } +} diff --git a/VBBWatch Extension/Presenter/ParentPresenter.swift b/VBBWatch Extension/Presenter/ParentPresenter.swift new file mode 100644 index 0000000..4f11c36 --- /dev/null +++ b/VBBWatch Extension/Presenter/ParentPresenter.swift @@ -0,0 +1,28 @@ +import Combine +import CoreLocation +import Foundation +import SwiftUI +import VBBFramework + +final class ParentPresenter: NSObject, ObservableObject { + private let locationManager = CLLocationManager() + var objectWillChange = PassthroughSubject() + + @Published var permission: CLAuthorizationStatus = .notDetermined { + didSet { + objectWillChange.send(()) + } + } + + public override init() { + super.init() + permission = CLLocationManager.authorizationStatus() + locationManager.delegate = self + } +} + +extension ParentPresenter: CLLocationManagerDelegate { + public func locationManager(_: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) { + permission = status + } +} diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Circular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Contents.json new file mode 100644 index 0000000..1571c7e --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Contents.json @@ -0,0 +1,48 @@ +{ + "assets" : [ + { + "idiom" : "watch", + "filename" : "Circular.imageset", + "role" : "circular" + }, + { + "idiom" : "watch", + "filename" : "Extra Large.imageset", + "role" : "extra-large" + }, + { + "idiom" : "watch", + "filename" : "Graphic Bezel.imageset", + "role" : "graphic-bezel" + }, + { + "idiom" : "watch", + "filename" : "Graphic Circular.imageset", + "role" : "graphic-circular" + }, + { + "idiom" : "watch", + "filename" : "Graphic Corner.imageset", + "role" : "graphic-corner" + }, + { + "idiom" : "watch", + "filename" : "Graphic Large Rectangular.imageset", + "role" : "graphic-large-rectangular" + }, + { + "idiom" : "watch", + "filename" : "Modular.imageset", + "role" : "modular" + }, + { + "idiom" : "watch", + "filename" : "Utilitarian.imageset", + "role" : "utilitarian" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Extra Large.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Bezel.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Circular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Corner.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Graphic Large Rectangular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Modular.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json new file mode 100644 index 0000000..aefef29 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Complication.complicationset/Utilitarian.imageset/Contents.json @@ -0,0 +1,28 @@ +{ + "images" : [ + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : "<=145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">161" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">145" + }, + { + "idiom" : "watch", + "scale" : "2x", + "screen-width" : ">183" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Location.imageset/Contents.json b/VBBWatch Extension/Support Files/Assets.xcassets/Location.imageset/Contents.json new file mode 100644 index 0000000..2726d44 --- /dev/null +++ b/VBBWatch Extension/Support Files/Assets.xcassets/Location.imageset/Contents.json @@ -0,0 +1,16 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "Location.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + }, + "properties" : { + "template-rendering-intent" : "template", + "preserves-vector-representation" : true + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/Assets.xcassets/Location.imageset/Location.pdf b/VBBWatch Extension/Support Files/Assets.xcassets/Location.imageset/Location.pdf new file mode 100644 index 0000000..61c31d3 Binary files /dev/null and b/VBBWatch Extension/Support Files/Assets.xcassets/Location.imageset/Location.pdf differ diff --git a/VBBWatch Extension/Support Files/English.lproj/Localizable.strings b/VBBWatch Extension/Support Files/English.lproj/Localizable.strings new file mode 100644 index 0000000..4b2cb96 --- /dev/null +++ b/VBBWatch Extension/Support Files/English.lproj/Localizable.strings @@ -0,0 +1,7 @@ +/* + Localizable.strings + VBB + + Created by Dennis Oberhoff on 04.08.19. + Copyright © 2019 Dennis Oberhoff. All rights reserved. +*/ diff --git a/VBBWatch Extension/Support Files/Info.plist b/VBBWatch Extension/Support Files/Info.plist new file mode 100644 index 0000000..ee1735c --- /dev/null +++ b/VBBWatch Extension/Support Files/Info.plist @@ -0,0 +1,67 @@ + + + + + CFBundleDevelopmentRegion + $(DEVELOPMENT_LANGUAGE) + CFBundleDisplayName + VBBNow Extension + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + $(PRODUCT_BUNDLE_IDENTIFIER) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + $(PRODUCT_BUNDLE_PACKAGE_TYPE) + CFBundleShortVersionString + 1.0 + CFBundleVersion + $(CURRENT_PROJECT_VERSION) + MKDirectionsApplicationSupportedModes + + NSAppTransportSecurity + + NSExceptionDomains + + fahrinfo.vbb.de + + NSExceptionAllowsInsecureHTTPLoads + + NSExceptionRequiresForwardSecrecy + + NSIncludesSubdomains + + + + + NSExtension + + NSExtensionAttributes + + WKAppBundleIdentifier + com.obrhoff.VBBWatch.watchkitapp + + NSExtensionPointIdentifier + com.apple.watchkit + + NSLocationAlwaysAndWhenInUseUsageDescription + Text + NSLocationWhenInUseUsageDescription + Text + UIBackgroundModes + + location + + WKBackgroundModes + + alarm + + WKExtensionDelegateClassName + $(PRODUCT_MODULE_NAME).ExtensionDelegate + WKWatchOnly + + + diff --git a/VBBWatch Extension/Support Files/Preview Content/Preview Assets.xcassets/Contents.json b/VBBWatch Extension/Support Files/Preview Content/Preview Assets.xcassets/Contents.json new file mode 100644 index 0000000..da4a164 --- /dev/null +++ b/VBBWatch Extension/Support Files/Preview Content/Preview Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/VBBWatch Extension/Support Files/de.lproj/Localizable.strings b/VBBWatch Extension/Support Files/de.lproj/Localizable.strings new file mode 100644 index 0000000..baac788 --- /dev/null +++ b/VBBWatch Extension/Support Files/de.lproj/Localizable.strings @@ -0,0 +1,23 @@ +/* + Localizable.strings + VBB + + Created by Dennis Oberhoff on 04.08.19. + Copyright © 2019 Dennis Oberhoff. All rights reserved. +*/ + +"NEXT" = "Weiter"; +"ALLOW" = "Erlauben"; + +"VBBNOW_TITLE" = "VBB"; +"VBBNOW_TITLE_PERMISSIONS" = "Erlaubnis"; +"VBBNOW_INTRODUCTION_TEXT" = "Wilkommen VBBNow."; +"VBBNOW_INTRODUCTION_DETAIL_TEXT" = "VBBNow zeigt dir in Echtzeit die Abfahrtzeiten des Nahverkehrs in deiner Nähe an."; +"VBBNOW_INTRODUCTION_PERMISSION_TEXT" = "Damit VBBNow funktioniert, braucht es einen Zugang zu einer Umgebung."; + +"STATUS_GEOCODING" = "Geocoding..."; +"STATUS_LOADING_STATIONS" = "Lade Stationen"; +"STATUS_LOADING_STATIONS_DETAILS" = "Lade Stationsdetails"; +"STATUS_FAILED" = "Fehler :("; +"STATUS_LOADING_UNKNOWN" = "Unbekannter Standort"; +"STATUS_RELOAD" = "Stationen Neuladen"; diff --git a/VBBWatch Extension/Support Files/en.lproj/Localizable.strings b/VBBWatch Extension/Support Files/en.lproj/Localizable.strings new file mode 100644 index 0000000..1cc4356 --- /dev/null +++ b/VBBWatch Extension/Support Files/en.lproj/Localizable.strings @@ -0,0 +1,25 @@ +/* + Localizable.strings + VBB + + Created by Dennis Oberhoff on 04.08.19. + Copyright © 2019 Dennis Oberhoff. All rights reserved. +*/ + +"NEXT" = "Next"; +"ALLOW" = "Allow"; + +"VBBNOW_TITLE" = "VBB"; +"VBBNOW_TITLE_PERMISSIONS" = "Permissions"; +"VBBNOW_INTRODUCTION_TEXT" = "Welcome to VBBNow. A Transit App for Berlin/Brandenburg."; +"VBBNOW_INTRODUCTION_DETAIL_TEXT" = "VBBNow shows you realtime departure times in Berlin/Brandenburg."; +"VBBNOW_INTRODUCTION_PERMISSION_TEXT" = "VBBNow work only with access to your location."; + +"STATUS_GEOCODING" = "Geocoding..."; +"STATUS_LOADING_STATIONS" = "Loading stations"; +"STATUS_LOADING_STATIONS_DETAILS" = "Loading station details"; +"STATUS_FAILED" = "Failed :("; +"STATUS_LOADING_UNKNOWN" = "Unknown Location"; +"STATUS_RELOAD" = "Refresh Stations"; + +"NO_STATIONS" = "No Stations around you."; diff --git a/VBBWatch Extension/Views/DepartureListView.swift b/VBBWatch Extension/Views/DepartureListView.swift new file mode 100644 index 0000000..76c8573 --- /dev/null +++ b/VBBWatch Extension/Views/DepartureListView.swift @@ -0,0 +1,104 @@ +import SwiftUI +import VBBFramework + +struct DepartureListView: View { + @ObservedObject var presenter: DepartureListPresenter + + var body: some View { + Group { + if !self.presenter.stations.isEmpty { + self.listView + } else if self.presenter.status == .loading { + self.loadingView + } else { + self.emptyView + } + }.navigationBarTitle("VBBNow").onAppear { + self.presenter.didBecomeActive() + }.contextMenu(menuItems: { + Button(action: { + self.presenter.update() + }, label: { + VStack { + Image(systemName: "arrow.clockwise") + .font(.title) + Text("STATUS_RELOAD") + } + }) + }) + } +} + +private extension DepartureListView { + var listView: some View { + List { + Group { + if self.presenter.isLoading { + HStack(alignment: .center) { + Spacer() + LoadingView(strokeBackgroundColor: .clear, + lineColor: .white) + .frame(width: 22, height: 22, alignment: .center) + Spacer() + } + } + + ForEach(self.presenter.stations) { (station: VBBStation) in + Section(header: Text(station.stationName) + .font(.footnote)) { + ForEach(self.presenter.departures(station)) { (departure: VBBDepature) in + NavigationLink(destination: LineView(presenter: LinePresenter(departure: departure))) { + DepartureView(presenter: DeparturePresenter(departure: departure)) + } + .listRowInsets(EdgeInsets(top: 4, leading: 0, bottom: 4, trailing: 0)) + }.navigationBarTitle(Text(station.stationName)) + } + } + + }.listRowPlatterColor(.clear) + + }.listStyle(CarouselListStyle()) + } + + var loadingView: some View { + VStack { + LoadingView(strokeBackgroundColor: .clear, lineColor: .white) + .frame(width: 22, height: 22, alignment: .center) + Text(self.loadingTitle) + .multilineTextAlignment(.center) + .lineLimit(2) + .minimumScaleFactor(0.75) + } + } + + var emptyView: some View { + VStack { + Image(systemName: "location.slash.fill") + .font(.title) + .foregroundColor(.primary) + + Text("NO_STATIONS") + .font(.subheadline) + .foregroundColor(.secondary) + .multilineTextAlignment(.center) + } + .padding() + } + + var loadingTitle: String { + switch presenter.status { + case .finished: + return presenter.location?.address ?? presenter.status.statusText + default: + return presenter.status.statusText + } + } +} + +#if DEBUG + struct DepartureList_Previews: PreviewProvider { + static var previews: some View { + DepartureListView(presenter: DepartureListPresenter()) + } + } +#endif diff --git a/VBBWatch Extension/Views/DepartureView.swift b/VBBWatch Extension/Views/DepartureView.swift new file mode 100644 index 0000000..7bbcb3e --- /dev/null +++ b/VBBWatch Extension/Views/DepartureView.swift @@ -0,0 +1,41 @@ +import Foundation +import SwiftUI +import VBBFramework + +struct DepartureView: View { + @ObservedObject var presenter: DeparturePresenter + + var body: some View { + HStack(alignment: .center) { + (Text(presenter.timeMinutesText) + .font(.system(size: 24, design: .rounded)).bold() + + Text("\n") + + Text(presenter.timeUnitsText).font(.subheadline)) + .multilineTextAlignment(.center) + Divider() + VStack(alignment: .leading, spacing: 2) { + Text(presenter.lineName) + .font(.system(size: 26, design: .rounded)) + .bold() + .minimumScaleFactor(0.8) + Divider() + Text(presenter.lineEnd) + .font(.system(size: 16, design: .default)) + .lineLimit(3) + .truncationMode(.tail) + } + } + .padding() + .frame(idealWidth: 90) + .gradientColor(presenter.lineType) + .drawingGroup() + } +} + +#if DEBUG + struct DepartureView_Previews: PreviewProvider { + static var previews: some View { + DepartureView(presenter: DeparturePresenter(departure: nil)) + } + } +#endif diff --git a/VBBWatch Extension/Views/LineView.swift b/VBBWatch Extension/Views/LineView.swift new file mode 100644 index 0000000..5cdab7a --- /dev/null +++ b/VBBWatch Extension/Views/LineView.swift @@ -0,0 +1,27 @@ +import Foundation +import Realm +import SwiftUI +import VBBFramework + +struct LineView: View { + @ObservedObject var presenter: LinePresenter + + var body: some View { + List { + ForEach(presenter.departures) { departure in + DepartureView(presenter: DeparturePresenter(departure: departure)) + .listRowPlatterColor(.clear) + .listRowInsets(EdgeInsets(top: 4, leading: 0, bottom: 4, trailing: 0)) + .fixedSize(horizontal: false, vertical: true) + } + }.navigationBarTitle(Text(self.presenter.lineName)) + } +} + +#if DEBUG + struct LineView_Previews: PreviewProvider { + static var previews: some View { + LineView(presenter: LinePresenter(departure: nil)) + } + } +#endif diff --git a/VBBWatch Extension/Views/LoadingView.swift b/VBBWatch Extension/Views/LoadingView.swift new file mode 100644 index 0000000..7b5be05 --- /dev/null +++ b/VBBWatch Extension/Views/LoadingView.swift @@ -0,0 +1,28 @@ +import SwiftUI + +struct LoadingView: View { + @State private var animate = false + @State var strokeWidth: CGFloat = 4 + @State var duration: TimeInterval = 1.25 + @State var strokeBackgroundColor: Color = .clear + @State var lineColor: Color = .white + + var body: some View { + ZStack { + Circle() + .stroke(Color.purple, lineWidth: strokeWidth) + .opacity(0.2) + + Circle() + .trim(from: 1 / 8, to: 1 / 2) + .stroke(lineColor, lineWidth: strokeWidth) + .rotationEffect(.degrees(animate ? 1 : -360), anchor: .center) + .animation(Animation.linear(duration: duration).repeatForever(autoreverses: false)) + } + .padding(2) + .drawingGroup() + .onAppear { + self.animate.toggle() + } + } +} diff --git a/VBBWatch Extension/Views/OnboardingView.swift b/VBBWatch Extension/Views/OnboardingView.swift new file mode 100644 index 0000000..6a7e68f --- /dev/null +++ b/VBBWatch Extension/Views/OnboardingView.swift @@ -0,0 +1,125 @@ +import Combine +import Foundation +import SwiftUI +import VBBFramework + +struct OnboardingView: View { + @ObservedObject var presenter: OnboardingPresenter + + init(presenter: OnboardingPresenter = OnboardingPresenter()) { + self.presenter = presenter + } + + var body: some View { + ScrollView { + ZStack { + ForEach([self.presenter.currentPage]) { page in + OnboardingPageView(title: page.title, + subtitle: page.subtitle, + buttonTitle: page.buttonTitle, + lineType: page.lineType) { + switch page { + case .welcome, .description: + self.presenter.next() + case .permission: + self.presenter.locationManager.requestWhenInUseAuthorization() + } + } + }.transition(.asymmetric(insertion: .move(edge: .trailing), removal: .move(edge: .leading))) + } + } + } +} + +struct OnboardingPageView: View { + let title: LocalizedStringKey + let subtitle: LocalizedStringKey + let buttonTitle: LocalizedStringKey + let lineType: VBBLineType + let primaryAction: () -> Void + + init(title: LocalizedStringKey, subtitle: LocalizedStringKey, buttonTitle: LocalizedStringKey, lineType: VBBLineType, primaryAction: @escaping (() -> Void)) { + self.title = title + self.subtitle = subtitle + self.lineType = lineType + self.buttonTitle = buttonTitle + self.primaryAction = primaryAction + } + + var body: some View { + VStack { + Text(title) + .foregroundColor(.primary) + .font(.system(size: 24, design: .rounded)) + .bold() + + Text(subtitle) + .foregroundColor(.secondary) + .font(.body) + .multilineTextAlignment(.center) + + Button(action: self.primaryAction) { + Text(self.buttonTitle) + }.gradientColor(self.lineType) + }.padding() + } +} + +private extension OnboardingPresenter.Page { + var title: LocalizedStringKey { + switch self { + case .welcome, .description: + return "VBBNOW_TITLE" + case .permission: + return "VBBNOW_TITLE_PERMISSIONS" + } + } + + var subtitle: LocalizedStringKey { + switch self { + case .welcome: + return "VBBNOW_INTRODUCTION_TEXT" + case .description: + return "VBBNOW_INTRODUCTION_DETAIL_TEXT" + case .permission: + return "VBBNOW_INTRODUCTION_PERMISSION_TEXT" + } + } + + var buttonTitle: LocalizedStringKey { + switch self { + case .welcome, .description: + return "NEXT" + case .permission: + return "ALLOW" + } + } + + var lineType: VBBLineType { + switch self { + case .welcome: + return .uBahn + case .permission: + return .bus + case .description: + return .tram + } + } +} + +#if DEBUG + struct OnboardingView_Previews: PreviewProvider { + static var previews: some View { + OnboardingView() + } + } + + struct OnboardingPageView_Previews: PreviewProvider { + static var previews: some View { + OnboardingPageView(title: "Title", + subtitle: "This is a title with nothing to mean", + buttonTitle: "Text", lineType: .metro, + primaryAction: {}) + } + } +#endif diff --git a/VBBWatch Extension/Views/ParentView.swift b/VBBWatch Extension/Views/ParentView.swift new file mode 100644 index 0000000..3826b8c --- /dev/null +++ b/VBBWatch Extension/Views/ParentView.swift @@ -0,0 +1,26 @@ + +import Combine +import SwiftUI +import VBBFramework + +struct ParentView: View { + @ObservedObject var presenter: ParentPresenter + + var body: some View { + Group { + if presenter.permission == .authorizedWhenInUse { + DepartureListView(presenter: DepartureListPresenter()) + } else { + OnboardingView() + } + }.animation(.default) + } +} + +#if DEBUG + struct ParentView_Previews: PreviewProvider { + static var previews: some View { + ParentView(presenter: ParentPresenter()) + } + } +#endif