diff --git a/iOS/Hydra-Info.plist b/iOS/Hydra-Info.plist
index ad533dd5..bf2fcd00 100644
--- a/iOS/Hydra-Info.plist
+++ b/iOS/Hydra-Info.plist
@@ -27,7 +27,7 @@
CFBundlePackageType
APPL
CFBundleShortVersionString
- 1.2
+ 2.0.1
CFBundleSignature
????
CFBundleURLTypes
@@ -40,11 +40,23 @@
CFBundleVersion
- 1.2.2
+ 2.0.15
FacebookAppID
146947948791011
LSRequiresIPhoneOS
+ NSAppTransportSecurity
+
+ NSAllowsArbitraryLoads
+
+ ugent.be
+
+ NSIncludesSubdomains
+
+ NSTemporaryExceptionAllowsInsecureHTTPLoads
+
+
+
NSLocationWhenInUseUsageDescription
We hebben uw locatie nodig om deze te kunnen tonen op de kaarten.
UIBackgroundModes
@@ -52,17 +64,28 @@
audio
UILaunchStoryboardName
- DashboardViewController
+ MainStoryboard
UIPrerenderedIcon
+ UIRequiresFullScreen
+
UIStatusBarHidden
+ UIStatusBarHidden~ipad
+
UIStatusBarStyle
- UIStatusBarStyleBlackOpaque
+ UIStatusBarStyleLightContent
UISupportedInterfaceOrientations
UIInterfaceOrientationPortrait
+ UISupportedInterfaceOrientations~ipad
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
UIViewControllerBasedStatusBarAppearance
diff --git a/iOS/Hydra.xcodeproj/project.pbxproj b/iOS/Hydra.xcodeproj/project.pbxproj
index 5df87ff1..3e3cd47f 100644
--- a/iOS/Hydra.xcodeproj/project.pbxproj
+++ b/iOS/Hydra.xcodeproj/project.pbxproj
@@ -9,9 +9,7 @@
/* Begin PBXBuildFile section */
395C117A16272D8000B99F9B /* NewsViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 395C117916272D8000B99F9B /* NewsViewController.m */; };
395C117D1627437000B99F9B /* NewsDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 395C117C1627437000B99F9B /* NewsDetailViewController.m */; };
- 3B0D77EC15BB0945002B23C1 /* BadgedButton.m in Sources */ = {isa = PBXBuildFile; fileRef = 3BAFFE7D15BB04B600921E7D /* BadgedButton.m */; };
3B436DF815B8915300984D3F /* InfoViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B436DF715B8915200984D3F /* InfoViewController.m */; };
- 3B7AD3B915BC830F0026BB62 /* RestoMenuView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B7AD3B815BC830F0026BB62 /* RestoMenuView.m */; };
3B93FB9F1630939200C962DC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B93FB9E1630939200C962DC /* AudioToolbox.framework */; };
3B93FBA7163095F900C962DC /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B93FB9E1630939200C962DC /* AudioToolbox.framework */; };
3B93FBAA1630969900C962DC /* UrgentPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 3B93FBA91630969900C962DC /* UrgentPlayer.m */; };
@@ -20,24 +18,65 @@
445C81FC16C45D7A0080819C /* button-settings.png in Resources */ = {isa = PBXBuildFile; fileRef = 445C81FA16C45D7A0080819C /* button-settings.png */; };
445C81FD16C45D7A0080819C /* button-settings@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 445C81FB16C45D7A0080819C /* button-settings@2x.png */; };
44A29C58162DA88E001A573C /* EventKitUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 44A29C57162DA88E001A573C /* EventKitUI.framework */; };
+ 9004F58F1B7F2FB60041FAA6 /* resto-map-icon@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9004F58D1B7F2FB60041FAA6 /* resto-map-icon@2x.png */; };
+ 9004F5901B7F2FB60041FAA6 /* resto-map-icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 9004F58E1B7F2FB60041FAA6 /* resto-map-icon.png */; };
9015D0FA1A8ABA4B00228ADC /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 908E536419BE4F3900F1DA57 /* Images.xcassets */; };
+ 901603DC1B716DED002E0D60 /* HomeNewsItemCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 901603DB1B716DED002E0D60 /* HomeNewsItemCollectionViewCell.swift */; };
902939441A8C22EB00868221 /* info-bloklocaties.html in Resources */ = {isa = PBXBuildFile; fileRef = 902939431A8C22EB00868221 /* info-bloklocaties.html */; };
+ 9035BF121B6C1753008E7875 /* schamper.png in Resources */ = {isa = PBXBuildFile; fileRef = 9035BF111B6C1753008E7875 /* schamper.png */; };
+ 9035BF141B6C1F5D008E7875 /* HomeSchamperCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9035BF131B6C1F5D008E7875 /* HomeSchamperCollectionViewCell.swift */; };
+ 9035BF161B6C37FE008E7875 /* home-zeus.png in Resources */ = {isa = PBXBuildFile; fileRef = 9035BF151B6C37FE008E7875 /* home-zeus.png */; };
+ 9035BF181B6CB52A008E7875 /* HomeActivityCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9035BF171B6CB52A008E7875 /* HomeActivityCollectionViewCell.swift */; };
+ 9035BF1A1B6CF663008E7875 /* LocationService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9035BF191B6CF663008E7875 /* LocationService.swift */; };
+ 903A8AF61C04F369002DAF5B /* ActivityOverviewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 903A8AF51C04F369002DAF5B /* ActivityOverviewCell.swift */; };
+ 903A8AF81C04FBF7002DAF5B /* ActivityOverviewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 903A8AF71C04FBF7002DAF5B /* ActivityOverviewCell.xib */; };
90410B101848DF9100331F6C /* info-guide.png in Resources */ = {isa = PBXBuildFile; fileRef = 90410B0E1848DF9100331F6C /* info-guide.png */; };
90410B111848DF9100331F6C /* info-guide@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 90410B0F1848DF9100331F6C /* info-guide@2x.png */; };
+ 904166231B7A689500D231EF /* tabbar-urgent@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 904166211B7A689500D231EF /* tabbar-urgent@2x.png */; };
+ 904166241B7A689500D231EF /* tabbar-urgent.png in Resources */ = {isa = PBXBuildFile; fileRef = 904166221B7A689500D231EF /* tabbar-urgent.png */; };
+ 904166261B7A837C00D231EF /* tabbar-settings.png in Resources */ = {isa = PBXBuildFile; fileRef = 904166251B7A837C00D231EF /* tabbar-settings.png */; };
+ 9041C3681B7E67B600E4A50C /* RestoMenuCollectionCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9041C3671B7E67B600E4A50C /* RestoMenuCollectionCell.swift */; };
+ 9041C36D1B7E801B00E4A50C /* RestoMenuHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9041C36C1B7E801B00E4A50C /* RestoMenuHeader.swift */; };
904BC46C17E2014A0000FED6 /* dot-question.png in Resources */ = {isa = PBXBuildFile; fileRef = 904BC46817E2014A0000FED6 /* dot-question.png */; };
904BC46D17E2014A0000FED6 /* dot-question@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 904BC46917E2014A0000FED6 /* dot-question@2x.png */; };
+ 905EB0131BC809C600F38679 /* tabbar-settings@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 905EB0121BC809C600F38679 /* tabbar-settings@2x.png */; };
+ 905EB0151BC80A3800F38679 /* tabbar-news@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 905EB0141BC80A3800F38679 /* tabbar-news@2x.png */; };
+ 905EB0171BC80B2100F38679 /* tabbar-activities@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 905EB0161BC80B2000F38679 /* tabbar-activities@2x.png */; };
+ 9068BA781B7BB437005F79FA /* tabbar-resto@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9068BA771B7BB437005F79FA /* tabbar-resto@2x.png */; };
+ 9068BA7A1B7BB560005F79FA /* tabbar-home@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9068BA791B7BB560005F79FA /* tabbar-home@2x.png */; };
+ 9068BA7C1B7BB684005F79FA /* tabbar-info@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 9068BA7B1B7BB684005F79FA /* tabbar-info@2x.png */; };
906C1D8917C8A4A600145CD3 /* MapViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 906C1D8817C8A4A600145CD3 /* MapViewController.m */; };
+ 907CD3CA1B7E52B600DD7539 /* RestoMenuViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 907CD3C91B7E52B600DD7539 /* RestoMenuViewController.swift */; };
908CA4DD1A8D439C00F8C31F /* info-mapmarker.png in Resources */ = {isa = PBXBuildFile; fileRef = 908CA4DB1A8D439C00F8C31F /* info-mapmarker.png */; };
908CA4DE1A8D439C00F8C31F /* info-mapmarker@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 908CA4DC1A8D439C00F8C31F /* info-mapmarker@2x.png */; };
908DFF03188E932D00D526DC /* Pods-acknowledgements.plist in Resources */ = {isa = PBXBuildFile; fileRef = 908DFF02188E932D00D526DC /* Pods-acknowledgements.plist */; };
908E536519BE4F3900F1DA57 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 908E536419BE4F3900F1DA57 /* Images.xcassets */; };
+ 90969AD21BFF5D8D006EDD9D /* AssociationStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90969AD11BFF5D8D006EDD9D /* AssociationStore.swift */; };
+ 90969AD41BFF5F90006EDD9D /* RestoStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90969AD31BFF5F90006EDD9D /* RestoStore.swift */; };
+ 90969AD61BFF6014006EDD9D /* SchamperStore.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90969AD51BFF6014006EDD9D /* SchamperStore.swift */; };
90B1029717A85E9200669CCD /* kalender.css in Resources */ = {isa = PBXBuildFile; fileRef = 90B1029617A85E9200669CCD /* kalender.css */; };
+ 90B1EF0C1B7A5DC300E733C1 /* tabbar-home.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF0B1B7A5DC300E733C1 /* tabbar-home.png */; };
+ 90B1EF0E1B7A5EF000E733C1 /* tabbar-resto.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF0D1B7A5EF000E733C1 /* tabbar-resto.png */; };
+ 90B1EF101B7A5FDB00E733C1 /* tabbar-info.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF0F1B7A5FDB00E733C1 /* tabbar-info.png */; };
+ 90B1EF121B7A606E00E733C1 /* tabbar-activities.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF111B7A606E00E733C1 /* tabbar-activities.png */; };
+ 90B1EF141B7A60B000E733C1 /* tabbar-news.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF131B7A60B000E733C1 /* tabbar-news.png */; };
+ 90B1EF161B7A60FC00E733C1 /* tabbar-schamper@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF151B7A60FC00E733C1 /* tabbar-schamper@2x.png */; };
+ 90B1EF181B7A61DD00E733C1 /* tabbar-schamper.png in Resources */ = {isa = PBXBuildFile; fileRef = 90B1EF171B7A61DD00E733C1 /* tabbar-schamper.png */; };
90BAB266162749BD0043BA92 /* SchamperDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90BAB265162749BC0043BA92 /* SchamperDetailViewController.m */; };
+ 90BE1F891B6AB3390061888C /* HomeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90BE1F881B6AB3390061888C /* HomeViewController.swift */; };
+ 90BE1F8D1B6AB61D0061888C /* MainStoryboard.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90BE1F8C1B6AB61D0061888C /* MainStoryboard.storyboard */; };
+ 90BE1F901B6AB8780061888C /* home-header.png in Resources */ = {isa = PBXBuildFile; fileRef = 90BE1F8E1B6AB8780061888C /* home-header.png */; };
+ 90BE1F911B6AB8780061888C /* home-background.png in Resources */ = {isa = PBXBuildFile; fileRef = 90BE1F8F1B6AB8780061888C /* home-background.png */; };
90C532AB16A325A200857EB0 /* FacebookEvent.m in Sources */ = {isa = PBXBuildFile; fileRef = 90C532AA16A325A200857EB0 /* FacebookEvent.m */; };
+ 90C8CA2E1B6AE3E80073E026 /* HomeFeedService.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90C8CA2D1B6AE3E80073E026 /* HomeFeedService.swift */; };
+ 90D55B9B1B7A4CE800813179 /* HydraTabbarController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90D55B9A1B7A4CE800813179 /* HydraTabbarController.swift */; };
+ 90DDFB791B6BB3D300DDAFA0 /* HomeRestoCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90DDFB781B6BB3D300DDAFA0 /* HomeRestoCollectionViewCell.swift */; };
90E814F31854C76C00075F96 /* ios7-Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 90E814F11854C76C00075F96 /* ios7-Default-568h@2x.png */; };
90E814F41854C76C00075F96 /* ios7-Default@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 90E814F21854C76C00075F96 /* ios7-Default@2x.png */; };
- 90EB7BE31688BCC700A9582D /* RestoInfoView.m in Sources */ = {isa = PBXBuildFile; fileRef = 90EB7BE21688BCC700A9582D /* RestoInfoView.m */; };
+ 90E8DDC11B6AD45C0059F71B /* home-button-bar.png in Resources */ = {isa = PBXBuildFile; fileRef = 90E8DDC01B6AD45C0059F71B /* home-button-bar.png */; };
90EB7BEA1688ECE300A9582D /* RestoLegendItem.m in Sources */ = {isa = PBXBuildFile; fileRef = 90EB7BE91688ECE300A9582D /* RestoLegendItem.m */; };
+ 90EE4CD01BB7193900C2DD32 /* RestoMenuInfoCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90EE4CCF1BB7193900C2DD32 /* RestoMenuInfoCollectionViewCell.swift */; };
+ 90EF4A591B6D8AE40034AD8F /* HomeUrgentCollectionViewCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 90EF4A581B6D8AE40034AD8F /* HomeUrgentCollectionViewCell.swift */; };
90F0525E168C663F004CAFFC /* RestoMapController.m in Sources */ = {isa = PBXBuildFile; fileRef = 90F0525C168C663F004CAFFC /* RestoMapController.m */; };
90F05261168C7022004CAFFC /* CoreLocation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90F05260168C7022004CAFFC /* CoreLocation.framework */; };
90F05263168C7726004CAFFC /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 90F05262168C7726004CAFFC /* MapKit.framework */; };
@@ -135,7 +174,6 @@
F59D170115BD693F00B6F892 /* info-doctors@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F59D16F115BD693F00B6F892 /* info-doctors@2x.png */; };
F59D170915BD7CE500B6F892 /* info-content.plist in Resources */ = {isa = PBXBuildFile; fileRef = F59D170715BD7CE500B6F892 /* info-content.plist */; };
F59D170A15BD7CE500B6F892 /* info-sport-openingsuren.html in Resources */ = {isa = PBXBuildFile; fileRef = F59D170815BD7CE500B6F892 /* info-sport-openingsuren.html */; };
- F59D170B15BD7E7E00B6F892 /* DashboardViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = F5EBF10F159DFD3B00EB5D26 /* DashboardViewController.xib */; };
F59D170E15BD811000B6F892 /* info-sport-aanbod.html in Resources */ = {isa = PBXBuildFile; fileRef = F59D170D15BD811000B6F892 /* info-sport-aanbod.html */; };
F59D171015BD813E00B6F892 /* webview.css in Resources */ = {isa = PBXBuildFile; fileRef = F59D170F15BD813E00B6F892 /* webview.css */; };
F5A81CBE15CF1BA700FE033B /* external-link.png in Resources */ = {isa = PBXBuildFile; fileRef = F5A81CBD15CF1BA700FE033B /* external-link.png */; };
@@ -168,7 +206,6 @@
F5BAEC8F1518868200F6A1B1 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5BAEC8E1518868200F6A1B1 /* CoreGraphics.framework */; };
F5BAEC971518868200F6A1B1 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BAEC961518868200F6A1B1 /* main.m */; };
F5BAEC9B1518868200F6A1B1 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BAEC9A1518868200F6A1B1 /* AppDelegate.m */; };
- F5BAECA41518868200F6A1B1 /* DashboardViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BAECA31518868200F6A1B1 /* DashboardViewController.m */; };
F5BAECB01518868200F6A1B1 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5BAEC8A1518868200F6A1B1 /* UIKit.framework */; };
F5BAECB11518868200F6A1B1 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5BAEC8C1518868200F6A1B1 /* Foundation.framework */; };
F5BAECBC1518868200F6A1B1 /* HydraTests.m in Sources */ = {isa = PBXBuildFile; fileRef = F5BAECBB1518868200F6A1B1 /* HydraTests.m */; };
@@ -211,12 +248,10 @@
F5E851D516C44BD7003DF993 /* hydra-logo@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = F5E851D316C44BD7003DF993 /* hydra-logo@2x.png */; };
F5EBF0E0164BE583002C14BF /* SORelativeDateTransformer.bundle in Resources */ = {isa = PBXBuildFile; fileRef = F5EBF0DD164BE583002C14BF /* SORelativeDateTransformer.bundle */; };
F5EBF0E1164BE583002C14BF /* SORelativeDateTransformer.m in Sources */ = {isa = PBXBuildFile; fileRef = F5EBF0DF164BE583002C14BF /* SORelativeDateTransformer.m */; };
- F5EBF117159E040700EB5D26 /* RestoMenuController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5EBF115159E040700EB5D26 /* RestoMenuController.m */; };
F5EBF11D159E092300EB5D26 /* SchamperViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = F5EBF11B159E092300EB5D26 /* SchamperViewController.m */; };
F5EBF13D159E13E600EB5D26 /* MobileCoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5EBF13C159E13E600EB5D26 /* MobileCoreServices.framework */; };
F5EBF143159E13FD00EB5D26 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F5EBF142159E13FD00EB5D26 /* QuartzCore.framework */; };
F5EBF14C159E1E3600EB5D26 /* SchamperArticle.m in Sources */ = {isa = PBXBuildFile; fileRef = F5EBF14B159E1E3600EB5D26 /* SchamperArticle.m */; };
- F5F43C1415BAC8A7003C2AAE /* Associations.plist in Resources */ = {isa = PBXBuildFile; fileRef = F5F43C1315BAC8A7003C2AAE /* Associations.plist */; };
F5F43C3E15BAD246003C2AAE /* AssociationNewsItem.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F43C3D15BAD246003C2AAE /* AssociationNewsItem.m */; };
F5F43C4115BAD2CC003C2AAE /* AssociationActivity.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F43C4015BAD2CC003C2AAE /* AssociationActivity.m */; };
F5F43C4415BAD2EB003C2AAE /* AssociationStore.m in Sources */ = {isa = PBXBuildFile; fileRef = F5F43C4315BAD2EB003C2AAE /* AssociationStore.m */; };
@@ -268,41 +303,78 @@
39B9A4055F5F374AA56058ED /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; };
3B436DF615B8915200984D3F /* InfoViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InfoViewController.h; sourceTree = ""; };
3B436DF715B8915200984D3F /* InfoViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InfoViewController.m; sourceTree = ""; };
- 3B7AD3B715BC830F0026BB62 /* RestoMenuView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoMenuView.h; sourceTree = ""; };
- 3B7AD3B815BC830F0026BB62 /* RestoMenuView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoMenuView.m; sourceTree = ""; };
3B93FB9E1630939200C962DC /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
3B93FBA81630969900C962DC /* UrgentPlayer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = UrgentPlayer.h; sourceTree = ""; };
3B93FBA91630969900C962DC /* UrgentPlayer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UrgentPlayer.m; sourceTree = ""; };
3B93FBAB16309E2100C962DC /* AVFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AVFoundation.framework; path = System/Library/Frameworks/AVFoundation.framework; sourceTree = SDKROOT; };
- 3BAFFE7C15BB04B600921E7D /* BadgedButton.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = BadgedButton.h; sourceTree = ""; };
- 3BAFFE7D15BB04B600921E7D /* BadgedButton.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BadgedButton.m; sourceTree = ""; };
445C81F316C3DB0B0080819C /* AssociationPreferenceController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssociationPreferenceController.h; sourceTree = ""; };
445C81F416C3DB0B0080819C /* AssociationPreferenceController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AssociationPreferenceController.m; sourceTree = ""; };
445C81FA16C45D7A0080819C /* button-settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button-settings.png"; sourceTree = ""; };
445C81FB16C45D7A0080819C /* button-settings@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "button-settings@2x.png"; sourceTree = ""; };
44A29C57162DA88E001A573C /* EventKitUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = EventKitUI.framework; path = System/Library/Frameworks/EventKitUI.framework; sourceTree = SDKROOT; };
+ 9004F58D1B7F2FB60041FAA6 /* resto-map-icon@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "resto-map-icon@2x.png"; sourceTree = ""; };
+ 9004F58E1B7F2FB60041FAA6 /* resto-map-icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "resto-map-icon.png"; sourceTree = ""; };
+ 901603DB1B716DED002E0D60 /* HomeNewsItemCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeNewsItemCollectionViewCell.swift; sourceTree = ""; };
902939431A8C22EB00868221 /* info-bloklocaties.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = "info-bloklocaties.html"; sourceTree = ""; };
+ 9035BF111B6C1753008E7875 /* schamper.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = schamper.png; sourceTree = ""; };
+ 9035BF131B6C1F5D008E7875 /* HomeSchamperCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeSchamperCollectionViewCell.swift; sourceTree = ""; };
+ 9035BF151B6C37FE008E7875 /* home-zeus.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "home-zeus.png"; sourceTree = ""; };
+ 9035BF171B6CB52A008E7875 /* HomeActivityCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeActivityCollectionViewCell.swift; sourceTree = ""; };
+ 9035BF191B6CF663008E7875 /* LocationService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LocationService.swift; sourceTree = ""; };
+ 903A8AF51C04F369002DAF5B /* ActivityOverviewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ActivityOverviewCell.swift; sourceTree = ""; };
+ 903A8AF71C04FBF7002DAF5B /* ActivityOverviewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = ActivityOverviewCell.xib; sourceTree = ""; };
90410B0E1848DF9100331F6C /* info-guide.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info-guide.png"; sourceTree = ""; };
90410B0F1848DF9100331F6C /* info-guide@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info-guide@2x.png"; sourceTree = ""; };
+ 904166211B7A689500D231EF /* tabbar-urgent@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-urgent@2x.png"; sourceTree = ""; };
+ 904166221B7A689500D231EF /* tabbar-urgent.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-urgent.png"; sourceTree = ""; };
+ 904166251B7A837C00D231EF /* tabbar-settings.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-settings.png"; sourceTree = ""; };
+ 9041C3671B7E67B600E4A50C /* RestoMenuCollectionCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoMenuCollectionCell.swift; sourceTree = ""; };
+ 9041C36C1B7E801B00E4A50C /* RestoMenuHeader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoMenuHeader.swift; sourceTree = ""; };
904BC46817E2014A0000FED6 /* dot-question.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dot-question.png"; sourceTree = ""; };
904BC46917E2014A0000FED6 /* dot-question@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "dot-question@2x.png"; sourceTree = ""; };
+ 905EB0121BC809C600F38679 /* tabbar-settings@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-settings@2x.png"; sourceTree = ""; };
+ 905EB0141BC80A3800F38679 /* tabbar-news@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-news@2x.png"; sourceTree = ""; };
+ 905EB0161BC80B2000F38679 /* tabbar-activities@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-activities@2x.png"; sourceTree = ""; };
+ 9068BA771B7BB437005F79FA /* tabbar-resto@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-resto@2x.png"; sourceTree = ""; };
+ 9068BA791B7BB560005F79FA /* tabbar-home@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-home@2x.png"; sourceTree = ""; };
+ 9068BA7B1B7BB684005F79FA /* tabbar-info@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-info@2x.png"; sourceTree = ""; };
906C1D8717C8A4A600145CD3 /* MapViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MapViewController.h; sourceTree = ""; };
906C1D8817C8A4A600145CD3 /* MapViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MapViewController.m; sourceTree = ""; };
+ 907CD3C91B7E52B600DD7539 /* RestoMenuViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoMenuViewController.swift; sourceTree = ""; };
908CA4DB1A8D439C00F8C31F /* info-mapmarker.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info-mapmarker.png"; sourceTree = ""; };
908CA4DC1A8D439C00F8C31F /* info-mapmarker@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "info-mapmarker@2x.png"; sourceTree = ""; };
908DFF02188E932D00D526DC /* Pods-acknowledgements.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = "Pods-acknowledgements.plist"; sourceTree = ""; };
908E536419BE4F3900F1DA57 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; };
+ 90969AD11BFF5D8D006EDD9D /* AssociationStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AssociationStore.swift; sourceTree = ""; };
+ 90969AD31BFF5F90006EDD9D /* RestoStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoStore.swift; sourceTree = ""; };
+ 90969AD51BFF6014006EDD9D /* SchamperStore.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SchamperStore.swift; sourceTree = ""; };
90B1029617A85E9200669CCD /* kalender.css */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.css; path = kalender.css; sourceTree = ""; };
+ 90B1EF0B1B7A5DC300E733C1 /* tabbar-home.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-home.png"; sourceTree = ""; };
+ 90B1EF0D1B7A5EF000E733C1 /* tabbar-resto.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-resto.png"; sourceTree = ""; };
+ 90B1EF0F1B7A5FDB00E733C1 /* tabbar-info.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-info.png"; sourceTree = ""; };
+ 90B1EF111B7A606E00E733C1 /* tabbar-activities.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-activities.png"; sourceTree = ""; };
+ 90B1EF131B7A60B000E733C1 /* tabbar-news.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-news.png"; sourceTree = ""; };
+ 90B1EF151B7A60FC00E733C1 /* tabbar-schamper@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-schamper@2x.png"; sourceTree = ""; };
+ 90B1EF171B7A61DD00E733C1 /* tabbar-schamper.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "tabbar-schamper.png"; sourceTree = ""; };
90BAB264162749BC0043BA92 /* SchamperDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchamperDetailViewController.h; sourceTree = ""; };
90BAB265162749BC0043BA92 /* SchamperDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SchamperDetailViewController.m; sourceTree = ""; };
+ 90BE1F871B6AB3390061888C /* Hydra-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = "Hydra-Bridging-Header.h"; path = "Hydra/Hydra-Bridging-Header.h"; sourceTree = ""; };
+ 90BE1F881B6AB3390061888C /* HomeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeViewController.swift; sourceTree = ""; };
+ 90BE1F8C1B6AB61D0061888C /* MainStoryboard.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = MainStoryboard.storyboard; sourceTree = ""; };
+ 90BE1F8E1B6AB8780061888C /* home-header.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "home-header.png"; sourceTree = ""; };
+ 90BE1F8F1B6AB8780061888C /* home-background.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "home-background.png"; sourceTree = ""; };
90C532A916A325A200857EB0 /* FacebookEvent.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FacebookEvent.h; sourceTree = ""; };
90C532AA16A325A200857EB0 /* FacebookEvent.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FacebookEvent.m; sourceTree = ""; };
+ 90C8CA2D1B6AE3E80073E026 /* HomeFeedService.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeFeedService.swift; sourceTree = ""; };
+ 90D55B9A1B7A4CE800813179 /* HydraTabbarController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HydraTabbarController.swift; sourceTree = ""; };
+ 90DDFB781B6BB3D300DDAFA0 /* HomeRestoCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeRestoCollectionViewCell.swift; sourceTree = ""; };
90E814F11854C76C00075F96 /* ios7-Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ios7-Default-568h@2x.png"; sourceTree = ""; };
90E814F21854C76C00075F96 /* ios7-Default@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "ios7-Default@2x.png"; sourceTree = ""; };
- 90EB7BE11688BCC700A9582D /* RestoInfoView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoInfoView.h; sourceTree = ""; };
- 90EB7BE21688BCC700A9582D /* RestoInfoView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoInfoView.m; sourceTree = ""; };
+ 90E8DDC01B6AD45C0059F71B /* home-button-bar.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "home-button-bar.png"; sourceTree = ""; };
90EB7BE81688ECE300A9582D /* RestoLegendItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoLegendItem.h; sourceTree = ""; };
90EB7BE91688ECE300A9582D /* RestoLegendItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoLegendItem.m; sourceTree = ""; };
+ 90EE4CCF1BB7193900C2DD32 /* RestoMenuInfoCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RestoMenuInfoCollectionViewCell.swift; sourceTree = ""; };
+ 90EF4A581B6D8AE40034AD8F /* HomeUrgentCollectionViewCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HomeUrgentCollectionViewCell.swift; sourceTree = ""; };
90F0525B168C663F004CAFFC /* RestoMapController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoMapController.h; sourceTree = ""; };
90F0525C168C663F004CAFFC /* RestoMapController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoMapController.m; sourceTree = ""; };
90F05260168C7022004CAFFC /* CoreLocation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreLocation.framework; path = System/Library/Frameworks/CoreLocation.framework; sourceTree = SDKROOT; };
@@ -456,8 +528,6 @@
F5BAEC961518868200F6A1B1 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; lineEnding = 0; name = main.m; path = Hydra/main.m; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objc; };
F5BAEC991518868200F6A1B1 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = AppDelegate.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
F5BAEC9A1518868200F6A1B1 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; };
- F5BAECA21518868200F6A1B1 /* DashboardViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = DashboardViewController.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
- F5BAECA31518868200F6A1B1 /* DashboardViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DashboardViewController.m; sourceTree = ""; };
F5BAECAD1518868200F6A1B1 /* HydraTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HydraTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F5BAECB61518868200F6A1B1 /* HydraTests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "HydraTests-Info.plist"; sourceTree = ""; };
F5BAECBA1518868200F6A1B1 /* HydraTests.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; lineEnding = 0; path = HydraTests.h; sourceTree = ""; xcLanguageSpecificationIdentifier = xcode.lang.objcpp; };
@@ -506,16 +576,12 @@
F5EBF0DD164BE583002C14BF /* SORelativeDateTransformer.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = SORelativeDateTransformer.bundle; sourceTree = ""; };
F5EBF0DE164BE583002C14BF /* SORelativeDateTransformer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SORelativeDateTransformer.h; sourceTree = ""; };
F5EBF0DF164BE583002C14BF /* SORelativeDateTransformer.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SORelativeDateTransformer.m; sourceTree = ""; };
- F5EBF112159DFDEC00EB5D26 /* nl */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = nl; path = nl.lproj/DashboardViewController.xib; sourceTree = ""; };
- F5EBF114159E040700EB5D26 /* RestoMenuController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RestoMenuController.h; sourceTree = ""; };
- F5EBF115159E040700EB5D26 /* RestoMenuController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RestoMenuController.m; sourceTree = ""; wrapsLines = 0; };
F5EBF11A159E092300EB5D26 /* SchamperViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchamperViewController.h; sourceTree = ""; };
F5EBF11B159E092300EB5D26 /* SchamperViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SchamperViewController.m; sourceTree = ""; };
F5EBF13C159E13E600EB5D26 /* MobileCoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MobileCoreServices.framework; path = System/Library/Frameworks/MobileCoreServices.framework; sourceTree = SDKROOT; };
F5EBF142159E13FD00EB5D26 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
F5EBF14A159E1E3600EB5D26 /* SchamperArticle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SchamperArticle.h; sourceTree = ""; };
F5EBF14B159E1E3600EB5D26 /* SchamperArticle.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SchamperArticle.m; sourceTree = ""; };
- F5F43C1315BAC8A7003C2AAE /* Associations.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Associations.plist; path = Resources/Associations.plist; sourceTree = ""; };
F5F43C3C15BAD246003C2AAE /* AssociationNewsItem.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssociationNewsItem.h; sourceTree = ""; };
F5F43C3D15BAD246003C2AAE /* AssociationNewsItem.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AssociationNewsItem.m; sourceTree = ""; };
F5F43C3F15BAD2CC003C2AAE /* AssociationActivity.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AssociationActivity.h; sourceTree = ""; };
@@ -583,10 +649,9 @@
3B059BF215B99B4800B4C1DA /* Custom views */ = {
isa = PBXGroup;
children = (
- 3BAFFE7C15BB04B600921E7D /* BadgedButton.h */,
- 3BAFFE7D15BB04B600921E7D /* BadgedButton.m */,
F5ACC3AF16D2693F00626EAE /* CustomTableViewCell.h */,
F5ACC3B016D2694000626EAE /* CustomTableViewCell.m */,
+ 90DDFB7B1B6BB40100DDAFA0 /* Home */,
);
name = "Custom views";
sourceTree = "";
@@ -594,14 +659,12 @@
3B7AD3B615BC82EB0026BB62 /* Resto */ = {
isa = PBXGroup;
children = (
- 90EB7BE11688BCC700A9582D /* RestoInfoView.h */,
- 90EB7BE21688BCC700A9582D /* RestoInfoView.m */,
90F0525B168C663F004CAFFC /* RestoMapController.h */,
90F0525C168C663F004CAFFC /* RestoMapController.m */,
- 3B7AD3B715BC830F0026BB62 /* RestoMenuView.h */,
- 3B7AD3B815BC830F0026BB62 /* RestoMenuView.m */,
- F5EBF114159E040700EB5D26 /* RestoMenuController.h */,
- F5EBF115159E040700EB5D26 /* RestoMenuController.m */,
+ 9041C3671B7E67B600E4A50C /* RestoMenuCollectionCell.swift */,
+ 9041C36C1B7E801B00E4A50C /* RestoMenuHeader.swift */,
+ 90EE4CCF1BB7193900C2DD32 /* RestoMenuInfoCollectionViewCell.swift */,
+ 907CD3C91B7E52B600DD7539 /* RestoMenuViewController.swift */,
);
name = Resto;
sourceTree = "";
@@ -611,18 +674,43 @@
children = (
F5F43C4215BAD2EB003C2AAE /* AssociationStore.h */,
F5F43C4315BAD2EB003C2AAE /* AssociationStore.m */,
+ 90969AD11BFF5D8D006EDD9D /* AssociationStore.swift */,
+ 90C8CA2D1B6AE3E80073E026 /* HomeFeedService.swift */,
+ 9035BF191B6CF663008E7875 /* LocationService.swift */,
+ F5C6093616D2DFCB0043BD44 /* PreferencesService.h */,
+ F5C6093716D2DFCB0043BD44 /* PreferencesService.m */,
F55895C515B6100C0001B399 /* RestoStore.h */,
F55895C615B610130001B399 /* RestoStore.m */,
+ 90969AD31BFF5F90006EDD9D /* RestoStore.swift */,
F5D36BBF15B5BDA500B6E017 /* SchamperStore.h */,
F5D36BC015B5BDA500B6E017 /* SchamperStore.m */,
+ 90969AD51BFF6014006EDD9D /* SchamperStore.swift */,
3B93FBA81630969900C962DC /* UrgentPlayer.h */,
3B93FBA91630969900C962DC /* UrgentPlayer.m */,
- F5C6093616D2DFCB0043BD44 /* PreferencesService.h */,
- F5C6093716D2DFCB0043BD44 /* PreferencesService.m */,
);
name = Services;
sourceTree = "";
};
+ 90BE1F861B6AB30F0061888C /* Home */ = {
+ isa = PBXGroup;
+ children = (
+ 90BE1F881B6AB3390061888C /* HomeViewController.swift */,
+ );
+ name = Home;
+ sourceTree = "";
+ };
+ 90DDFB7B1B6BB40100DDAFA0 /* Home */ = {
+ isa = PBXGroup;
+ children = (
+ 9035BF171B6CB52A008E7875 /* HomeActivityCollectionViewCell.swift */,
+ 90DDFB781B6BB3D300DDAFA0 /* HomeRestoCollectionViewCell.swift */,
+ 9035BF131B6C1F5D008E7875 /* HomeSchamperCollectionViewCell.swift */,
+ 90EF4A581B6D8AE40034AD8F /* HomeUrgentCollectionViewCell.swift */,
+ 901603DB1B716DED002E0D60 /* HomeNewsItemCollectionViewCell.swift */,
+ );
+ name = Home;
+ sourceTree = "";
+ };
B007FEAAB912E2F80EF4FE3C /* Pods */ = {
isa = PBXGroup;
children = (
@@ -709,6 +797,8 @@
F5016BA81627665800BBDB0A /* ActivityDetailController.m */,
F52A8B7717CD366E00C3379C /* ActivityMapController.h */,
F52A8B7817CD366E00C3379C /* ActivityMapController.m */,
+ 903A8AF51C04F369002DAF5B /* ActivityOverviewCell.swift */,
+ 903A8AF71C04FBF7002DAF5B /* ActivityOverviewCell.xib */,
);
name = Activities;
sourceTree = "";
@@ -802,6 +892,10 @@
F5A81CC115CF1CC500FE033B /* external-link@2x.png */,
F53D2489159DB50800F408AB /* header-bg.png */,
F5E7F06B15EF9407004024AA /* header-bg@2x.png */,
+ 90BE1F8F1B6AB8780061888C /* home-background.png */,
+ 90E8DDC01B6AD45C0059F71B /* home-button-bar.png */,
+ 90BE1F8E1B6AB8780061888C /* home-header.png */,
+ 9035BF151B6C37FE008E7875 /* home-zeus.png */,
F5E851D216C44BD7003DF993 /* hydra-logo.png */,
F5E851D316C44BD7003DF993 /* hydra-logo@2x.png */,
F520A2DB166E933500EE340F /* icon-calendar.png */,
@@ -820,6 +914,8 @@
F59D16E715BD693F00B6F892 /* info-bicycle@2x.png */,
F59D16F015BD693F00B6F892 /* info-doctors.png */,
F59D16F115BD693F00B6F892 /* info-doctors@2x.png */,
+ 90410B0E1848DF9100331F6C /* info-guide.png */,
+ 90410B0F1848DF9100331F6C /* info-guide@2x.png */,
F59D16EA15BD693F00B6F892 /* info-library.png */,
F59D16EB15BD693F00B6F892 /* info-library@2x.png */,
908CA4DB1A8D439C00F8C31F /* info-mapmarker.png */,
@@ -830,8 +926,6 @@
F59D16ED15BD693F00B6F892 /* info-more@2x.png */,
F59D16EE15BD693F00B6F892 /* info-sports.png */,
F59D16EF15BD693F00B6F892 /* info-sports@2x.png */,
- 90410B0E1848DF9100331F6C /* info-guide.png */,
- 90410B0F1848DF9100331F6C /* info-guide@2x.png */,
F5C4618B166E442000874D79 /* navigation-down.png */,
F5C4618C166E442000874D79 /* navigation-down@2x.png */,
F5C4618D166E442000874D79 /* navigation-up.png */,
@@ -840,8 +934,27 @@
F5329E0115B9858900C4C5DF /* resto-closed@2x.jpg */,
F54B160015B7FFE6000A4407 /* resto-logo.png */,
F54B160115B7FFE6000A4407 /* resto-logo@2x.png */,
+ 9004F58E1B7F2FB60041FAA6 /* resto-map-icon.png */,
+ 9004F58D1B7F2FB60041FAA6 /* resto-map-icon@2x.png */,
F533DABB163163E2001269A8 /* schamper-bg.png */,
F557EA45163431FC00635CDD /* schamper-bg@2x.png */,
+ 9035BF111B6C1753008E7875 /* schamper.png */,
+ 90B1EF111B7A606E00E733C1 /* tabbar-activities.png */,
+ 905EB0161BC80B2000F38679 /* tabbar-activities@2x.png */,
+ 90B1EF0B1B7A5DC300E733C1 /* tabbar-home.png */,
+ 9068BA791B7BB560005F79FA /* tabbar-home@2x.png */,
+ 90B1EF0F1B7A5FDB00E733C1 /* tabbar-info.png */,
+ 9068BA7B1B7BB684005F79FA /* tabbar-info@2x.png */,
+ 90B1EF131B7A60B000E733C1 /* tabbar-news.png */,
+ 905EB0141BC80A3800F38679 /* tabbar-news@2x.png */,
+ 90B1EF0D1B7A5EF000E733C1 /* tabbar-resto.png */,
+ 9068BA771B7BB437005F79FA /* tabbar-resto@2x.png */,
+ 90B1EF171B7A61DD00E733C1 /* tabbar-schamper.png */,
+ 90B1EF151B7A60FC00E733C1 /* tabbar-schamper@2x.png */,
+ 904166251B7A837C00D231EF /* tabbar-settings.png */,
+ 905EB0121BC809C600F38679 /* tabbar-settings@2x.png */,
+ 904166221B7A689500D231EF /* tabbar-urgent.png */,
+ 904166211B7A689500D231EF /* tabbar-urgent@2x.png */,
F5E851CE16C44B47003DF993 /* urgent-bg.jpg */,
F5E851CF16C44B47003DF993 /* urgent-bg@2x.jpg */,
F5B650AC16C135A900989ADB /* urgent-logo.png */,
@@ -986,11 +1099,10 @@
F53A5E8316700B28009EA4CC /* ApplicationWithRemoteSupport.m */,
F57CB9DB15B84C4E00D87CB3 /* Categories */,
F5EBF119159E04B500EB5D26 /* Controllers */,
- 3B059BF215B99B4800B4C1DA /* Custom views */,
+ 908E536419BE4F3900F1DA57 /* Images.xcassets */,
F5EBF11F159E09C700EB5D26 /* Models */,
3B93FBA01630942500C962DC /* Services */,
F59CEE9716A189290038FD24 /* Social */,
- 908E536419BE4F3900F1DA57 /* Images.xcassets */,
);
path = Hydra;
sourceTree = "";
@@ -999,7 +1111,6 @@
isa = PBXGroup;
children = (
F5BAEC961518868200F6A1B1 /* main.m */,
- F5F43C1315BAC8A7003C2AAE /* Associations.plist */,
F5BC3D8D162EBB5100E4A902 /* Default-568h@2x.png */,
F5D36BB315B5BD2A00B6E017 /* Default.png */,
F5D36BB415B5BD2A00B6E017 /* Default@2x.png */,
@@ -1007,6 +1118,7 @@
90E814F21854C76C00075F96 /* ios7-Default@2x.png */,
F5BAEC921518868200F6A1B1 /* Hydra-Info.plist */,
F5D36BD815B5CD1500B6E017 /* Hydra-Prefix.pch */,
+ 90BE1F871B6AB3390061888C /* Hydra-Bridging-Header.h */,
F5CE522016C2BDA70033A52B /* Errors.strings */,
F56D76701699ED4D002CF245 /* Icons */,
F53D2488159DB4DB00F408AB /* Images */,
@@ -1049,9 +1161,8 @@
isa = PBXGroup;
children = (
F536359C16A69C86000A50C4 /* Activities */,
- F5BAECA21518868200F6A1B1 /* DashboardViewController.h */,
- F5BAECA31518868200F6A1B1 /* DashboardViewController.m */,
- F5EBF10F159DFD3B00EB5D26 /* DashboardViewController.xib */,
+ 90BE1F861B6AB30F0061888C /* Home */,
+ 90D55B9A1B7A4CE800813179 /* HydraTabbarController.swift */,
3B436DF615B8915200984D3F /* InfoViewController.h */,
3B436DF715B8915200984D3F /* InfoViewController.m */,
F536359E16A69C94000A50C4 /* News */,
@@ -1062,6 +1173,8 @@
F53A5E7416700242009EA4CC /* UrgentViewController.h */,
F53A5E7516700242009EA4CC /* UrgentViewController.m */,
F56F139E169731FE003D4447 /* UrgentViewController.xib */,
+ 90BE1F8C1B6AB61D0061888C /* MainStoryboard.storyboard */,
+ 3B059BF215B99B4800B4C1DA /* Custom views */,
);
name = Controllers;
sourceTree = "";
@@ -1095,6 +1208,7 @@
buildConfigurationList = F49F79391A1671960040987F /* Build configuration list for PBXNativeTarget "RestoMenuToday" */;
buildPhases = (
F49F79281A1671950040987F /* Sources */,
+ 90EE4CD11BB804F600C2DD32 /* ShellScript */,
F49F79291A1671950040987F /* Frameworks */,
F49F792A1A1671950040987F /* Resources */,
);
@@ -1152,6 +1266,8 @@
F5BAEC7D1518868100F6A1B1 /* Project object */ = {
isa = PBXProject;
attributes = {
+ LastSwiftMigration = 0700;
+ LastSwiftUpdateCheck = 0700;
LastUpgradeCheck = 0500;
ORGANIZATIONNAME = "Zeus WPI";
TargetAttributes = {
@@ -1199,32 +1315,36 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- F59D170B15BD7E7E00B6F892 /* DashboardViewController.xib in Resources */,
F53D248A159DB50800F408AB /* header-bg.png in Resources */,
F58408B7159DDA0E00EE7010 /* button-activities-active.png in Resources */,
908CA4DD1A8D439C00F8C31F /* info-mapmarker.png in Resources */,
+ 905EB0151BC80A3800F38679 /* tabbar-news@2x.png in Resources */,
F58408B8159DDA0E00EE7010 /* button-activities.png in Resources */,
F58408BB159DDA0E00EE7010 /* button-info-active.png in Resources */,
F58408BC159DDA0E00EE7010 /* button-info.png in Resources */,
F58408BD159DDA0E00EE7010 /* button-news-active.png in Resources */,
+ 905EB0131BC809C600F38679 /* tabbar-settings@2x.png in Resources */,
F58408BE159DDA0E00EE7010 /* button-news.png in Resources */,
F58408BF159DDA0E00EE7010 /* button-resto-active.png in Resources */,
F58408C0159DDA0E00EE7010 /* button-resto.png in Resources */,
F58408C1159DDA0E00EE7010 /* button-schamper-active.png in Resources */,
+ 90BE1F8D1B6AB61D0061888C /* MainStoryboard.storyboard in Resources */,
F58408C2159DDA0E00EE7010 /* button-schamper.png in Resources */,
F5D36BB715B5BD2A00B6E017 /* Default.png in Resources */,
F5D36BB815B5BD2A00B6E017 /* Default@2x.png in Resources */,
+ 904166261B7A837C00D231EF /* tabbar-settings.png in Resources */,
F54B160215B7FFE6000A4407 /* resto-logo.png in Resources */,
F54B160315B7FFE6000A4407 /* resto-logo@2x.png in Resources */,
F5B9F2F117CEAA040042C8A4 /* Icon-Small-iOS6@2x.png in Resources */,
F57E7E0E15B837F100D2A59E /* icon-meal.png in Resources */,
F57E7E0F15B837F100D2A59E /* icon-soup.png in Resources */,
F57E7E1015B837F100D2A59E /* icon-vegetables.png in Resources */,
+ 903A8AF81C04FBF7002DAF5B /* ActivityOverviewCell.xib in Resources */,
F5329E0215B9858900C4C5DF /* resto-closed.jpg in Resources */,
F5329E0315B9858900C4C5DF /* resto-closed@2x.jpg in Resources */,
904BC46C17E2014A0000FED6 /* dot-question.png in Resources */,
- F5F43C1415BAC8A7003C2AAE /* Associations.plist in Resources */,
F59D16F415BD693F00B6F892 /* info-academiccalendar.png in Resources */,
+ 90B1EF141B7A60B000E733C1 /* tabbar-news.png in Resources */,
F59D16F515BD693F00B6F892 /* info-academiccalendar@2x.png in Resources */,
904BC46D17E2014A0000FED6 /* dot-question@2x.png in Resources */,
F59D16F615BD693F00B6F892 /* info-bicycle.png in Resources */,
@@ -1251,9 +1371,12 @@
F5A81CBE15CF1BA700FE033B /* external-link.png in Resources */,
F5A81CC215CF1CC500FE033B /* external-link-active.png in Resources */,
F5A81CC315CF1CC500FE033B /* external-link-active@2x.png in Resources */,
+ 90BE1F901B6AB8780061888C /* home-header.png in Resources */,
F5A81CC415CF1CC500FE033B /* external-link@2x.png in Resources */,
F5E7F06C15EF9408004024AA /* header-bg@2x.png in Resources */,
+ 90B1EF101B7A5FDB00E733C1 /* tabbar-info.png in Resources */,
F5E7F07215EFAA51004024AA /* button-activities-active@2x.png in Resources */,
+ 90B1EF0C1B7A5DC300E733C1 /* tabbar-home.png in Resources */,
F5E7F07315EFAA51004024AA /* button-activities@2x.png in Resources */,
F5D2B6B515EFE2DE003EA54C /* button-news@2x.png in Resources */,
F5D2B6B715EFEAAF003EA54C /* button-news-active@2x.png in Resources */,
@@ -1261,7 +1384,11 @@
F5FC117015F0211300B3F127 /* button-info@2x.png in Resources */,
F5FC117115F0211300B3F127 /* button-resto-active@2x.png in Resources */,
F5FC117215F0211300B3F127 /* button-resto@2x.png in Resources */,
+ 905EB0171BC80B2100F38679 /* tabbar-activities@2x.png in Resources */,
+ 9068BA7C1B7BB684005F79FA /* tabbar-info@2x.png in Resources */,
+ 90B1EF181B7A61DD00E733C1 /* tabbar-schamper.png in Resources */,
F5FC117315F0211300B3F127 /* button-schamper-active@2x.png in Resources */,
+ 9068BA7A1B7BB560005F79FA /* tabbar-home@2x.png in Resources */,
F5FC117415F0211300B3F127 /* button-schamper@2x.png in Resources */,
F5BC3D8E162EBB5100E4A902 /* Default-568h@2x.png in Resources */,
F5D3B612162EF02F00698C3E /* button-feedback.png in Resources */,
@@ -1269,9 +1396,14 @@
908E536519BE4F3900F1DA57 /* Images.xcassets in Resources */,
F533DABA16315E87001269A8 /* schamper.css in Resources */,
F533DABC163163E2001269A8 /* schamper-bg.png in Resources */,
+ 90B1EF121B7A606E00E733C1 /* tabbar-activities.png in Resources */,
F557EA46163431FC00635CDD /* schamper-bg@2x.png in Resources */,
+ 90BE1F911B6AB8780061888C /* home-background.png in Resources */,
90E814F41854C76C00075F96 /* ios7-Default@2x.png in Resources */,
+ 9068BA781B7BB437005F79FA /* tabbar-resto@2x.png in Resources */,
+ 9035BF161B6C37FE008E7875 /* home-zeus.png in Resources */,
F5EBF0E0164BE583002C14BF /* SORelativeDateTransformer.bundle in Resources */,
+ 9004F58F1B7F2FB60041FAA6 /* resto-map-icon@2x.png in Resources */,
F5C4618F166E442000874D79 /* navigation-down.png in Resources */,
F5C46190166E442000874D79 /* navigation-down@2x.png in Resources */,
F5C46191166E442000874D79 /* navigation-up.png in Resources */,
@@ -1301,7 +1433,9 @@
F5D51CF716B6D44800826B51 /* info-minerva@2x.png in Resources */,
F567044416BD5D8100C6B00D /* icon-meal@2x.png in Resources */,
F567044516BD5D8100C6B00D /* icon-soup@2x.png in Resources */,
+ 9004F5901B7F2FB60041FAA6 /* resto-map-icon.png in Resources */,
F567044616BD5D8100C6B00D /* icon-vegetables@2x.png in Resources */,
+ 90E8DDC11B6AD45C0059F71B /* home-button-bar.png in Resources */,
F567044716BD5D8100C6B00D /* info-minerva.png in Resources */,
F5B6509C16C129B700989ADB /* btn-urgent-bg-highlighted.png in Resources */,
F5B6509D16C129B700989ADB /* btn-urgent-bg-highlighted@2x.png in Resources */,
@@ -1310,6 +1444,7 @@
F5B9F2F317CEAA040042C8A4 /* iTunesArtwork.png in Resources */,
F5B650A416C12A9300989ADB /* btn-urgent-pause.png in Resources */,
F5B650A516C12A9300989ADB /* btn-urgent-pause@2x.png in Resources */,
+ 9035BF121B6C1753008E7875 /* schamper.png in Resources */,
F5B650A616C12A9300989ADB /* btn-urgent-play.png in Resources */,
F5B650A716C12A9300989ADB /* btn-urgent-play@2x.png in Resources */,
F5B650AE16C135A900989ADB /* urgent-logo.png in Resources */,
@@ -1321,6 +1456,7 @@
445C81FD16C45D7A0080819C /* button-settings@2x.png in Resources */,
F5E851BE16C43174003DF993 /* btn-urgent-facebook.png in Resources */,
F5E851BF16C43174003DF993 /* btn-urgent-facebook@2x.png in Resources */,
+ 904166231B7A689500D231EF /* tabbar-urgent@2x.png in Resources */,
F5E851C016C43174003DF993 /* btn-urgent-home.png in Resources */,
F5E851C116C43174003DF993 /* btn-urgent-home@2x.png in Resources */,
F5E851C216C43174003DF993 /* btn-urgent-mail.png in Resources */,
@@ -1329,15 +1465,18 @@
F5B9F2F417CEAA040042C8A4 /* iTunesArtwork@2x.png in Resources */,
F5E851C516C43174003DF993 /* btn-urgent-soundcloud@2x.png in Resources */,
F5E851C616C43174003DF993 /* btn-urgent-twitter.png in Resources */,
+ 90B1EF0E1B7A5EF000E733C1 /* tabbar-resto.png in Resources */,
F5E851C716C43174003DF993 /* btn-urgent-twitter@2x.png in Resources */,
F5B9F2E817CEA96F0042C8A4 /* Icon-iOS6.png in Resources */,
F5E851CC16C447C4003DF993 /* urgent-nowplaying.jpg in Resources */,
F5E851CD16C447C4003DF993 /* urgent-nowplaying@2x.jpg in Resources */,
+ 90B1EF161B7A60FC00E733C1 /* tabbar-schamper@2x.png in Resources */,
F5E851D016C44B47003DF993 /* urgent-bg.jpg in Resources */,
F5E851D116C44B47003DF993 /* urgent-bg@2x.jpg in Resources */,
F5B9F2EA17CEA96F0042C8A4 /* Icon-iOS7@2x.png in Resources */,
F5E851D416C44BD7003DF993 /* hydra-logo.png in Resources */,
F5E851D516C44BD7003DF993 /* hydra-logo@2x.png in Resources */,
+ 904166241B7A689500D231EF /* tabbar-urgent.png in Resources */,
90B1029717A85E9200669CCD /* kalender.css in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
@@ -1366,6 +1505,19 @@
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n";
};
+ 90EE4CD11BB804F600C2DD32 /* ShellScript */ = {
+ isa = PBXShellScriptBuildPhase;
+ buildActionMask = 2147483647;
+ files = (
+ );
+ inputPaths = (
+ );
+ outputPaths = (
+ );
+ runOnlyForDeploymentPostprocessing = 0;
+ shellPath = /bin/bash;
+ shellScript = "src_plist=${PROJECT_DIR}/${INFOPLIST_FILE}\nbuild_plist=${BUILT_PRODUCTS_DIR}/${INFOPLIST_PATH}\n\nif [ $CONFIGURATION == Release ]; then\n # increment the build number (ie 1.0.115 to 1.0.116)\n echo \"Bumping build number...\"\n\n full_version=$(/usr/libexec/PlistBuddy -c \"Print :CFBundleVersion\" \"${src_plist}\")\n if [[ \"${full_version}\" == \"\" ]]; then\n echo \"No build number in ${src_plist}\"\n exit 2\n fi\n\n version=${full_version%.*}\n build=${full_version##*.}\n \n new_version=\"$version.$(($build+1))\"\n /usr/libexec/Plistbuddy -c \"Set :CFBundleVersion $new_version\" \"${src_plist}\"\n echo \"Bumped build number to $new_version\"\nfi";
+ };
F5D3B621162EFBD400698C3E /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@@ -1400,12 +1552,12 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
- 3B0D77EC15BB0945002B23C1 /* BadgedButton.m in Sources */,
F5BAEC971518868200F6A1B1 /* main.m in Sources */,
+ 907CD3CA1B7E52B600DD7539 /* RestoMenuViewController.swift in Sources */,
+ 90969AD41BFF5F90006EDD9D /* RestoStore.swift in Sources */,
F5BAEC9B1518868200F6A1B1 /* AppDelegate.m in Sources */,
- F5BAECA41518868200F6A1B1 /* DashboardViewController.m in Sources */,
- F5EBF117159E040700EB5D26 /* RestoMenuController.m in Sources */,
F5EBF11D159E092300EB5D26 /* SchamperViewController.m in Sources */,
+ 90EE4CD01BB7193900C2DD32 /* RestoMenuInfoCollectionViewCell.swift in Sources */,
F5EBF14C159E1E3600EB5D26 /* SchamperArticle.m in Sources */,
F5D36BC115B5BDA500B6E017 /* SchamperStore.m in Sources */,
F50EE09715B5F587000F1992 /* WebViewController.m in Sources */,
@@ -1418,26 +1570,37 @@
F5F43C4115BAD2CC003C2AAE /* AssociationActivity.m in Sources */,
F5F43C4415BAD2EB003C2AAE /* AssociationStore.m in Sources */,
F5F43C4715BAD42E003C2AAE /* Association.m in Sources */,
- 3B7AD3B915BC830F0026BB62 /* RestoMenuView.m in Sources */,
395C117A16272D8000B99F9B /* NewsViewController.m in Sources */,
395C117D1627437000B99F9B /* NewsDetailViewController.m in Sources */,
90BAB266162749BD0043BA92 /* SchamperDetailViewController.m in Sources */,
F5016BA6162756F300BBDB0A /* ActivitiesController.m in Sources */,
+ 90969AD21BFF5D8D006EDD9D /* AssociationStore.swift in Sources */,
+ 9041C3681B7E67B600E4A50C /* RestoMenuCollectionCell.swift in Sources */,
F5016BA91627665800BBDB0A /* ActivityDetailController.m in Sources */,
3B93FBAA1630969900C962DC /* UrgentPlayer.m in Sources */,
+ 90C8CA2E1B6AE3E80073E026 /* HomeFeedService.swift in Sources */,
F52A8B7917CD366E00C3379C /* ActivityMapController.m in Sources */,
F5EBF0E1164BE583002C14BF /* SORelativeDateTransformer.m in Sources */,
+ 9035BF181B6CB52A008E7875 /* HomeActivityCollectionViewCell.swift in Sources */,
F53A5E7716700242009EA4CC /* UrgentViewController.m in Sources */,
F53A5E8416700B29009EA4CC /* ApplicationWithRemoteSupport.m in Sources */,
+ 90BE1F891B6AB3390061888C /* HomeViewController.swift in Sources */,
F52B9B77168507BD000B71D6 /* NSDateFormatter+AppLocale.m in Sources */,
- 90EB7BE31688BCC700A9582D /* RestoInfoView.m in Sources */,
+ 90EF4A591B6D8AE40034AD8F /* HomeUrgentCollectionViewCell.swift in Sources */,
90EB7BEA1688ECE300A9582D /* RestoLegendItem.m in Sources */,
+ 901603DC1B716DED002E0D60 /* HomeNewsItemCollectionViewCell.swift in Sources */,
90F0525E168C663F004CAFFC /* RestoMapController.m in Sources */,
+ 9035BF141B6C1F5D008E7875 /* HomeSchamperCollectionViewCell.swift in Sources */,
+ 90D55B9B1B7A4CE800813179 /* HydraTabbarController.swift in Sources */,
+ 90DDFB791B6BB3D300DDAFA0 /* HomeRestoCollectionViewCell.swift in Sources */,
90F05266168C7D19004CAFFC /* RestoLocation.m in Sources */,
F59CEE8A16A188050038FD24 /* FacebookSession.m in Sources */,
90C532AB16A325A200857EB0 /* FacebookEvent.m in Sources */,
F55E89EC16A4AF8E008595CB /* ShareKitConfigurator.m in Sources */,
F569582716AA095800C45D00 /* UINavigationController+ReplaceController.m in Sources */,
+ 90969AD61BFF6014006EDD9D /* SchamperStore.swift in Sources */,
+ 9041C36D1B7E801B00E4A50C /* RestoMenuHeader.swift in Sources */,
+ 9035BF1A1B6CF663008E7875 /* LocationService.swift in Sources */,
445C81F516C3DB0B0080819C /* AssociationPreferenceController.m in Sources */,
F5DF2FB916C41DDE003B05EC /* MarqueeLabel.m in Sources */,
F521D11616C53A1200B686B2 /* PreferencesController.m in Sources */,
@@ -1445,6 +1608,7 @@
F5ACC3B116D2694000626EAE /* CustomTableViewCell.m in Sources */,
F5C6093816D2DFCB0043BD44 /* PreferencesService.m in Sources */,
906C1D8917C8A4A600145CD3 /* MapViewController.m in Sources */,
+ 903A8AF61C04F369002DAF5B /* ActivityOverviewCell.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@@ -1496,14 +1660,6 @@
name = Errors.strings;
sourceTree = "";
};
- F5EBF10F159DFD3B00EB5D26 /* DashboardViewController.xib */ = {
- isa = PBXVariantGroup;
- children = (
- F5EBF112159DFDEC00EB5D26 /* nl */,
- );
- name = DashboardViewController.xib;
- sourceTree = "";
- };
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
@@ -1543,8 +1699,10 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
@@ -1579,7 +1737,9 @@
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @executable_path/../../Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_NAME = "$(TARGET_NAME)";
+ PROVISIONING_PROFILE = "";
SKIP_INSTALL = YES;
+ TARGETED_DEVICE_FAMILY = "1,2";
};
name = Release;
};
@@ -1592,6 +1752,7 @@
CODE_SIGN_IDENTITY = "iPhone Developer";
COPY_PHASE_STRIP = NO;
CUSTOM_IDENTIFIER_SUFFIX = "-dev";
+ ENABLE_BITCODE = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
@@ -1619,6 +1780,7 @@
CODE_SIGN_IDENTITY = "iPhone Distribution";
COPY_PHASE_STRIP = YES;
CUSTOM_IDENTIFIER_SUFFIX = "";
+ ENABLE_BITCODE = NO;
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=0";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_SHADOW = YES;
@@ -1640,6 +1802,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CUSTOM_BUNDLE_DISPLAY_NAME = "${PRODUCT_NAME} β";
@@ -1649,8 +1812,12 @@
GCC_PREFIX_HEADER = "Hydra/Hydra-Prefix.pch";
INFOPLIST_FILE = "Hydra-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Hydra/Hydra-Bridging-Header.h";
+ SWIFT_OPTIMIZATION_LEVEL = "-Onone";
+ TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
};
name = Debug;
@@ -1661,6 +1828,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;
+ CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CUSTOM_BUNDLE_DISPLAY_NAME = "${PRODUCT_NAME}";
@@ -1670,8 +1838,11 @@
GCC_PREFIX_HEADER = "Hydra/Hydra-Prefix.pch";
INFOPLIST_FILE = "Hydra-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
+ LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks";
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = "";
+ SWIFT_OBJC_BRIDGING_HEADER = "Hydra/Hydra-Bridging-Header.h";
+ TARGETED_DEVICE_FAMILY = "1,2";
WRAPPER_EXTENSION = app;
};
name = Release;
diff --git a/iOS/Hydra/ActivitiesController.m b/iOS/Hydra/ActivitiesController.m
index 4a5f57a3..b7cb3068 100644
--- a/iOS/Hydra/ActivitiesController.m
+++ b/iOS/Hydra/ActivitiesController.m
@@ -15,11 +15,9 @@
#import "NSDateFormatter+AppLocale.h"
#import "PreferencesService.h"
#import "RMPickerViewController.h"
+#import "Hydra-Swift.h"
#import
-#define kCellTitleLabel 101
-#define kCellSubtitleLabel 102
-
@interface ActivitiesController ()
@property (nonatomic, assign) BOOL activitiesUpdated;
@@ -87,6 +85,9 @@ - (void)viewDidLoad
[RMPickerViewController setLocalizedTitleForCancelButton:@"Sluit"];
[RMPickerViewController setLocalizedTitleForSelectButton:@"Gereed"];
+
+ UINib *nib = [UINib nibWithNibName:@"ActivityOverviewCell" bundle:nil];
+ [self.tableView registerNib:nib forCellReuseIdentifier:@"ActivityOverviewCell"];
}
- (void)viewWillAppear:(BOOL)animated
@@ -209,88 +210,20 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInte
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
- return 46;
+ return 44;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
- UILabel *titleLabel, *subtitleLabel;
-
NSDate *date = self.days[indexPath.section];
AssociationActivity *activity = self.data[date][indexPath.row];
- static NSString *NoHighlightCellIdentifier = @"ActivityCellNoHighlight";
- static NSString *HighlightCellIdentifier = @"ActivityCellHighlight";
- UITableViewCell *cell;
-
- if (!activity.highlighted) {
- // request cell without the special star view
- cell = [tableView dequeueReusableCellWithIdentifier:NoHighlightCellIdentifier];
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
- reuseIdentifier:NoHighlightCellIdentifier];
- [self setupCell:cell withRightMargin:10];
- }
- }
- else {
- // request cell with special star view
- cell = [tableView dequeueReusableCellWithIdentifier:HighlightCellIdentifier];
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
- reuseIdentifier:HighlightCellIdentifier];
- [self setupCell:cell withRightMargin:40];
-
- UIImageView *star = [[UIImageView alloc] initWithImage:
- [UIImage imageNamed:@"icon-star"]];
- star.frame = CGRectMake(286, 8, 27, 27);
- [cell.contentView addSubview:star];
- }
- }
- titleLabel = (UILabel *)[cell viewWithTag:kCellTitleLabel];
- subtitleLabel = (UILabel *)[cell viewWithTag:kCellSubtitleLabel];
-
- static NSDateFormatter *dateFormatter = nil;
- if (!dateFormatter) {
- dateFormatter = [NSDateFormatter H_dateFormatterWithAppLocale];
- dateFormatter.dateFormat = @"HH.mm";
- }
-
- cell.textLabel.text = [dateFormatter stringFromDate:activity.start];
- titleLabel.text = activity.title;
- subtitleLabel.text = activity.association.displayName;
+ static NSString *CellIdentifier = @"ActivityOverviewCell";
+ ActivityOverviewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
+ cell.activity = activity;
return cell;
}
-- (void)setupCell:(UITableViewCell *)cell withRightMargin:(int)rightMargin
-{
- cell.textLabel.font = [UIFont boldSystemFontOfSize:15.0f];
- cell.textLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1];
- cell.textLabel.highlightedTextColor = [UIColor colorWithWhite:0.94 alpha:1];
-
- // iOS7
- if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
- cell.separatorInset = UIEdgeInsetsZero;
- }
-
- CGFloat offsetX = IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0") ? 64 : 60;
- CGFloat width = self.view.bounds.size.width - offsetX - rightMargin;
-
- CGRect titleFrame = CGRectMake(offsetX, 4, width, 20);
- UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
- titleLabel.tag = kCellTitleLabel;
- titleLabel.font = [UIFont boldSystemFontOfSize:17.0f];
- titleLabel.highlightedTextColor = [UIColor whiteColor];
- [cell.contentView addSubview:titleLabel];
-
- CGRect subtitleFrame = CGRectMake(offsetX, 24, width, 16);
- UILabel *subtitleLabel = [[UILabel alloc] initWithFrame:subtitleFrame];
- subtitleLabel.tag = kCellSubtitleLabel;
- subtitleLabel.font = [UIFont systemFontOfSize:13.0f];
- subtitleLabel.textColor = [UIColor colorWithWhite:0.2 alpha:1];
- subtitleLabel.highlightedTextColor = [UIColor whiteColor];
- [cell.contentView addSubview:subtitleLabel];
-}
-
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
NSDate *date = self.days[indexPath.section];
@@ -439,70 +372,13 @@ - (void)didSelectActivity:(AssociationActivity *)activity
- (void)dateButtonTapped:(id)sender
{
- if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
- RMPickerViewController *pickerVC = [RMPickerViewController pickerController];
- pickerVC.delegate = self;
- UIPickerView *picker = pickerVC.picker;
- NSInteger row = ((NSIndexPath *)[self.tableView indexPathsForVisibleRows][0]).section;
- [picker selectRow:row inComponent:0 animated:NO];
+ RMPickerViewController *pickerVC = [RMPickerViewController pickerController];
+ pickerVC.delegate = self;
+ UIPickerView *picker = pickerVC.picker;
+ NSInteger row = ((NSIndexPath *)[self.tableView indexPathsForVisibleRows][0]).section;
+ [picker selectRow:row inComponent:0 animated:NO];
- [pickerVC show];
- } else {
- // TODO: this is abuse of UIActionSheet, and shouldn't be used like this
- UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:nil
- delegate:nil
- cancelButtonTitle:nil
- destructiveButtonTitle:nil
- otherButtonTitles:nil];
-
- BOOL iOS7 = IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0");
-
- // Create toolbar
- UIBarButtonItem *flexSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace
- target:nil action:nil];
- UIBarButtonItem *doneBtn = [[UIBarButtonItem alloc] initWithTitle:@"Gereed" style:UIBarButtonItemStyleBordered
- target:self action:@selector(dismissActionSheet:)];
- UIToolbar *pickerToolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
- pickerToolbar.tintColor = [UIColor hydraTintColor];
- pickerToolbar.items = @[flexSpace, doneBtn];
-
- if (iOS7) {
- // Add a gray border to the bottom of the toolbar
- CALayer *border = [CALayer layer];
- border.borderColor = [UIColor lightGrayColor].CGColor;
- border.borderWidth = 0.25;
- border.frame = CGRectMake(0, pickerToolbar.frame.size.height,
- pickerToolbar.frame.size.width, 0.25);
- [pickerToolbar.layer addSublayer:border];
- }
-
- [actionSheet addSubview:pickerToolbar];
-
- UILabel *title = [[UILabel alloc] initWithFrame:CGRectMake(0, 12, 290, 22)];
- title.font = [UIFont boldSystemFontOfSize:18];
- title.text = @"Selecteer een dag";
- title.textAlignment = NSTextAlignmentCenter;
- title.backgroundColor = [UIColor clearColor];
-
- if (!iOS7) {
- title.textColor = [UIColor whiteColor];
- title.shadowColor = [UIColor darkTextColor];
- }
- [actionSheet addSubview:title];
-
- // Create datepicker
- self.datePicker = [[UIPickerView alloc] initWithFrame:CGRectMake(0, iOS7 ? 34 : 44, 0, 0)];
- self.datePicker.showsSelectionIndicator = YES;
- self.datePicker.dataSource = self;
- self.datePicker.delegate = self;
- [actionSheet addSubview:self.datePicker];
-
- NSIndexPath *firstSection = [self.tableView indexPathsForVisibleRows][0];
- [self.datePicker selectRow:firstSection.section inComponent:0 animated:NO];
-
- [actionSheet showInView:self.view];
- [actionSheet setBounds:CGRectMake(0, 0, 320, 500)];
- }
+ [pickerVC show];
}
- (NSInteger)numberOfComponentsInPickerView:(UIPickerView *)pickerView
diff --git a/iOS/Hydra/ActivityDetailController.m b/iOS/Hydra/ActivityDetailController.m
index 43a350c3..1575f0b6 100644
--- a/iOS/Hydra/ActivityDetailController.m
+++ b/iOS/Hydra/ActivityDetailController.m
@@ -274,12 +274,7 @@ - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPa
// Different calculation for UITextView
if (!self.descriptionView) {
self.descriptionView = [self createDescriptionView];
- if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
- width = tableView.frame.size.width;
- } else {
- width = tableView.frame.size.width - 20;
- self.descriptionView.frame = CGRectMake(0, 0, width, 0);
- }
+ width = tableView.frame.size.width;
}
if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"8.0")) {
UIEdgeInsets textContainerInsets = self.descriptionView.textContainerInset;
@@ -502,11 +497,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView infoCellForRowAtIndex:(N
cell.textLabel.text = @"Gasten";
cell.alignToTop = YES;
- if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")){
- cell.accessoryType = UITableViewCellAccessoryDetailButton;
- } else {
- cell.accessoryType = UITableViewCellAccessoryDetailDisclosureButton;
- }
+ cell.accessoryType = UITableViewCellAccessoryDetailButton;
FacebookEvent *event = self.activity.facebookEvent;
if (event.friendsAttending.count > 0) {
@@ -683,16 +674,12 @@ - (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexP
- (void)addEventToCalendar
{
EKEventStore *store = [[EKEventStore alloc] init];
- if ([store respondsToSelector:@selector(requestAccessToEntityType:completion:)]) {
- [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
- if (!granted) return;
- [self performSelectorOnMainThread:@selector(addEventWithCalendarStore:)
- withObject:store waitUntilDone:NO];
- }];
- }
- else {
- [self addEventWithCalendarStore:store];
- }
+
+ [store requestAccessToEntityType:EKEntityTypeEvent completion:^(BOOL granted, NSError *error) {
+ if (!granted) return;
+ [self performSelectorOnMainThread:@selector(addEventWithCalendarStore:)
+ withObject:store waitUntilDone:NO];
+ }];
}
- (void)addEventWithCalendarStore:(EKEventStore *)store
diff --git a/iOS/Hydra/ActivityOverviewCell.swift b/iOS/Hydra/ActivityOverviewCell.swift
new file mode 100644
index 00000000..bb62cf35
--- /dev/null
+++ b/iOS/Hydra/ActivityOverviewCell.swift
@@ -0,0 +1,30 @@
+//
+// ActivityOverviewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 24/11/2015.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+@objc class ActivityOverviewCell: UITableViewCell {
+
+ @IBOutlet weak var titleLabel: UILabel!
+ @IBOutlet weak var associationLabel: UILabel!
+ @IBOutlet weak var dateLabel: UILabel!
+
+ var activity: AssociationActivity? {
+ didSet {
+ associationLabel.text = activity?.association.displayName
+ titleLabel.text = activity?.title
+
+ let dateStartFormatter = NSDateFormatter.H_dateFormatterWithAppLocale()
+ dateStartFormatter.dateFormat = "H:mm";
+ dateLabel.text = "\(dateStartFormatter.stringFromDate((self.activity?.start)!))"
+
+ //TODO: do something if highlighted
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/iOS/Hydra/ActivityOverviewCell.xib b/iOS/Hydra/ActivityOverviewCell.xib
new file mode 100644
index 00000000..8585e85d
--- /dev/null
+++ b/iOS/Hydra/ActivityOverviewCell.xib
@@ -0,0 +1,77 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/Hydra/AppDelegate.m b/iOS/Hydra/AppDelegate.m
index 6560f493..b398a55a 100644
--- a/iOS/Hydra/AppDelegate.m
+++ b/iOS/Hydra/AppDelegate.m
@@ -8,7 +8,6 @@
#import "AppDelegate.h"
#import "UIColor+AppColors.h"
-#import "DashboardViewController.h"
#import "ShareKitConfigurator.h"
#import "FacebookSession.h"
#import "SchamperStore.h"
@@ -65,18 +64,14 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
// Restore Facebook-session
[[FacebookSession sharedSession] openWithAllowLoginUI:NO];
- // Create and setup controllers
- DashboardViewController *dashboard = [[DashboardViewController alloc] init];
- self.navController = [[UINavigationController alloc] initWithRootViewController:dashboard];
- self.navController.navigationBar.tintColor = [UIColor hydraTintColor];
-
- // iOS7 specific appearance
- if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
- self.navController.view.backgroundColor = [UIColor hydraBackgroundColor];
- }
-
+ // Start storyboard
+ UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:[NSBundle mainBundle]];
+ UIViewController *rootvc = [storyboard instantiateInitialViewController];
+
+ // Set root view controller and make windows visible
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- self.window.rootViewController = self.navController;
+ self.window.rootViewController = rootvc;
+
[self.window makeKeyAndVisible];
return YES;
diff --git a/iOS/Hydra/Association.h b/iOS/Hydra/Association.h
index 9095e8c9..169906aa 100644
--- a/iOS/Hydra/Association.h
+++ b/iOS/Hydra/Association.h
@@ -1,5 +1,5 @@
//
-// Assocation.h
+// Association.h
// Hydra
//
// Created by Pieter De Baets on 21/07/12.
@@ -20,9 +20,9 @@
// Check that the current association list is up-to-date with the one provided
// in the application bundle
-+ (NSDictionary *)updateAssociations:(NSDictionary *)associations;
+ (RKObjectMapping *)objectMapping;
++ (RKObjectMapping *)objectMappingActivities;
- (BOOL)matches:(NSString *)query;
-@end
+@end
\ No newline at end of file
diff --git a/iOS/Hydra/Association.m b/iOS/Hydra/Association.m
index 8b17c7d6..13ab0618 100644
--- a/iOS/Hydra/Association.m
+++ b/iOS/Hydra/Association.m
@@ -1,5 +1,5 @@
//
-// Assocation.m
+// Association.m
// Hydra
//
// Created by Pieter De Baets on 21/07/12.
@@ -10,56 +10,8 @@
#import "NSDate+Utilities.h"
#import
-NSString *const AssociationsLastUpdatedPref = @"AssociationsLastUpdated";
-
@implementation Association
-+ (NSDictionary *)updateAssociations:(NSDictionary *)associations
-{
- NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
- NSDate *lastModified = [userDefaults valueForKey:AssociationsLastUpdatedPref];
- NSDate *currentVersion = [self currentVersion];
-
- if (!associations || [currentVersion isLaterThanDate:lastModified]) {
- associations = [self loadFromPlist];
- [userDefaults setObject:currentVersion forKey:AssociationsLastUpdatedPref];
- }
- return associations;
-}
-
-+ (NSString *)initializationPath
-{
- return [[NSBundle mainBundle] pathForResource:@"Associations" ofType:@"plist"];
-}
-
-+ (NSDate *)currentVersion
-{
- NSFileManager *manager = [NSFileManager defaultManager];
- NSString *filePath = [self initializationPath];
-
- NSDictionary *attributes = [manager attributesOfItemAtPath:filePath error:nil];
- return attributes[NSFileModificationDate];
-}
-
-+ (NSDictionary *)loadFromPlist
-{
- NSArray *bundled = [NSArray arrayWithContentsOfFile:[self initializationPath]];
-
- NSMutableDictionary *associations = [NSMutableDictionary dictionaryWithCapacity:bundled.count];
- for (NSUInteger i = 0; i < bundled.count; i++) {
- NSDictionary *props = bundled[i];
-
- Association *assoc = [[Association alloc] init];
- assoc.displayName = props[@"displayName"];
- assoc.fullName = props[@"fullName"];
- assoc.internalName = props[@"internalName"];
- assoc.parentAssociation = props[@"parentAssociation"];
-
- associations[assoc.internalName] = assoc;
- }
- return associations;
-}
-
- (NSString *)displayedFullName
{
if (_fullName) {
@@ -84,8 +36,8 @@ - (BOOL)matches:(NSString *)query
{
NSStringCompareOptions opts = NSCaseInsensitiveSearch | NSDiacriticInsensitiveSearch;
return (_internalName && [_internalName rangeOfString:query options:opts].location != NSNotFound) ||
- (_displayName && [_displayName rangeOfString:query options:opts].location != NSNotFound) ||
- (_fullName && [_fullName rangeOfString:query options:opts].location != NSNotFound);
+ (_displayName && [_displayName rangeOfString:query options:opts].location != NSNotFound) ||
+ (_fullName && [_fullName rangeOfString:query options:opts].location != NSNotFound);
}
- (NSString *)description
@@ -93,14 +45,23 @@ - (NSString *)description
return [NSString stringWithFormat:@"", self.displayName];
}
-+ (RKObjectMapping *)objectMapping
++ (RKObjectMapping *)objectMappingActivities
{
RKObjectMapping *mapping = [RKObjectMapping mappingForClass:self];
[mapping addAttributeMappingsFromDictionary:@{
- @"internal_name": @"internalName",
- @"full_name": @"fullName",
- @"display_name": @"displayName"
- }];
+ @"internal_name": @"internalName",
+ @"full_name": @"fullName",
+ @"display_name": @"displayName"
+ }];
+ return mapping;
+}
+
++ (RKObjectMapping *)objectMapping
+{
+ RKObjectMapping *mapping = [RKObjectMapping mappingForClass:self];
+ [mapping addAttributeMappingsFromArray:@[
+ @"displayName", @"fullName", @"internalName", @"parentAssociation"
+ ]];
return mapping;
}
@@ -142,4 +103,4 @@ - (id)copyWithZone:(NSZone *)zone
return self;
}
-@end
+@end
\ No newline at end of file
diff --git a/iOS/Hydra/AssociationActivity.m b/iOS/Hydra/AssociationActivity.m
index cee438ce..0afbb539 100644
--- a/iOS/Hydra/AssociationActivity.m
+++ b/iOS/Hydra/AssociationActivity.m
@@ -30,7 +30,7 @@ + (RKObjectMapping *)objectMapping
@"description": @"descriptionText"
}];
[objectMapping addRelationshipMappingWithSourceKeyPath:@"association"
- mapping:[Association objectMapping]];
+ mapping:[Association objectMappingActivities]];
return objectMapping;
}
diff --git a/iOS/Hydra/AssociationNewsItem.m b/iOS/Hydra/AssociationNewsItem.m
index b7f5a509..d584ccf2 100644
--- a/iOS/Hydra/AssociationNewsItem.m
+++ b/iOS/Hydra/AssociationNewsItem.m
@@ -15,7 +15,7 @@ @implementation AssociationNewsItem
- (NSString *)description
{
- return [NSString stringWithFormat:@"", self.title];
+ return [NSString stringWithFormat:@"", self.title];
}
+ (RKObjectMapping *)objectMapping
@@ -23,7 +23,7 @@ + (RKObjectMapping *)objectMapping
RKObjectMapping *objectMapping = [RKObjectMapping mappingForClass:self];
[objectMapping addAttributeMappingsFromArray:@[@"title", @"date", @"content", @"highlighted"]];
[objectMapping addAttributeMappingsFromDictionary:@{@"id": @"itemId"}];
- [objectMapping addRelationshipMappingWithSourceKeyPath:@"association" mapping:[Association objectMapping]];
+ [objectMapping addRelationshipMappingWithSourceKeyPath:@"association" mapping:[Association objectMappingActivities]];
return objectMapping;
}
@@ -65,4 +65,4 @@ - (void)setRead:(BOOL)read
}
}
-@end
+@end
\ No newline at end of file
diff --git a/iOS/Hydra/AssociationPreferenceController.m b/iOS/Hydra/AssociationPreferenceController.m
index 103acc4b..027322df 100644
--- a/iOS/Hydra/AssociationPreferenceController.m
+++ b/iOS/Hydra/AssociationPreferenceController.m
@@ -26,7 +26,7 @@ @implementation AssociationPreferenceController
- (id)init
{
if (self = [super initWithStyle:UITableViewStylePlain]) {
- [self loadAssocations];
+ [self loadAssociations];
}
return self;
}
@@ -34,11 +34,11 @@ - (id)init
- (void)loadView
{
[super loadView];
-
+
UISearchBar *searchBar = [[UISearchBar alloc] initWithFrame:CGRectMake(0, 0, 320, 44)];
searchBar.placeholder = @"Zoek een vereniging";
self.tableView.tableHeaderView = searchBar;
-
+
// TODO: replace cancel button in search-mode by 'OK'
self.searchController = [[UISearchDisplayController alloc]
initWithSearchBar:searchBar contentsController:self];
@@ -64,16 +64,16 @@ - (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interface
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
-- (void)loadAssocations
+- (void)loadAssociations
{
- NSArray *all = [[AssociationStore sharedStore] assocations];
-
+ NSArray *all = [[AssociationStore sharedStore] associations];
+
// Get all unique parent organisations
NSSet *convents = [NSSet setWithArray:[all valueForKey:@"parentAssociation"]];
NSSortDescriptor *sort = [NSSortDescriptor sortDescriptorWithKey:nil ascending:YES];
self.convents = [convents sortedArrayUsingDescriptors:@[sort]];
self.filteredConvents = [self.convents mutableCopy];
-
+
// Group by parentAssociation
NSMutableDictionary *grouped = [[NSMutableDictionary alloc] init];
sort = [NSSortDescriptor sortDescriptorWithKey:@"fullName" ascending:YES];
@@ -97,7 +97,7 @@ - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldRe
return [evaluatedObject matches:query];
}];
self.filteredAssociations[convent] = [self.associations[convent] filteredArrayUsingPredicate:filter];
-
+
// Remove convent from list if it does not have any items
if ([self.filteredAssociations[convent] count] == 0) {
[self.filteredConvents removeObject:convent];
@@ -115,7 +115,7 @@ - (BOOL)searchDisplayController:(UISearchDisplayController *)controller shouldRe
self.filteredAssociations = [self.associations mutableCopy];
self.filteredConvents = [self.convents mutableCopy];
}
-
+
return YES;
}
@@ -135,7 +135,7 @@ - (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInte
else {
internalName = self.filteredConvents[section];
}
-
+
Association *association = [[AssociationStore sharedStore] associationWithName:internalName];
return association.displayName;
}
@@ -168,7 +168,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
}
-
+
Association *association;
if (tableView == self.tableView) {
NSString *convent = self.convents[indexPath.section];
@@ -179,7 +179,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
association = self.filteredAssociations[convent][indexPath.row];
}
cell.textLabel.text = association.fullName;
-
+
NSArray *preferred = [PreferencesService sharedService].preferredAssociations;
if ([preferred containsObject:association.internalName]){
cell.accessoryType = UITableViewCellAccessoryCheckmark;
@@ -187,7 +187,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
else {
cell.accessoryType = nil;
}
-
+
return cell;
}
@@ -202,7 +202,7 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
NSString *convent = self.filteredConvents[indexPath.section];
name = [self.filteredAssociations[convent][indexPath.row] internalName];
}
-
+
PreferencesService *prefs = [PreferencesService sharedService];
NSMutableArray *preferred = [prefs.preferredAssociations mutableCopy];
if ([preferred containsObject:name]) {
@@ -212,10 +212,10 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
[preferred addObject:name];
}
prefs.preferredAssociations = preferred;
-
+
[tableView reloadRowsAtIndexPaths:@[indexPath]
withRowAnimation:UITableViewRowAnimationAutomatic];
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
-@end
+@end
\ No newline at end of file
diff --git a/iOS/Hydra/AssociationStore.h b/iOS/Hydra/AssociationStore.h
index a9f22d33..d3526689 100644
--- a/iOS/Hydra/AssociationStore.h
+++ b/iOS/Hydra/AssociationStore.h
@@ -15,7 +15,7 @@ extern NSString *const AssociationStoreDidUpdateActivitiesNotification;
@interface AssociationStore : NSObject
-@property (nonatomic, strong, readonly) NSArray *assocations;
+@property (nonatomic, strong, readonly) NSArray *associations;
@property (nonatomic, strong, readonly) NSArray *activities;
@property (nonatomic, strong, readonly) NSArray *newsItems;
@@ -28,4 +28,4 @@ extern NSString *const AssociationStoreDidUpdateActivitiesNotification;
- (void)syncStorage;
- (void)markStorageOutdated;
-@end
+@end
\ No newline at end of file
diff --git a/iOS/Hydra/AssociationStore.m b/iOS/Hydra/AssociationStore.m
index e48ed76e..f899ed30 100644
--- a/iOS/Hydra/AssociationStore.m
+++ b/iOS/Hydra/AssociationStore.m
@@ -17,21 +17,24 @@
#define kBaseUrl @"http://student.ugent.be/hydra/api/1.0/"
#define kActivitiesResource @"all_activities.json"
#define kNewsResource @"all_news.json"
+#define kAssociationResource @"associations.json"
#define kUpdateInterval (15 * 60)
NSString *const AssociationStoreDidUpdateNewsNotification =
- @"AssociationStoreDidUpdateNewsNotification";
+@"AssociationStoreDidUpdateNewsNotification";
NSString *const AssociationStoreDidUpdateActivitiesNotification =
- @"AssociationStoreDidUpdateActivitiesNotification";
+@"AssociationStoreDidUpdateActivitiesNotification";
@interface AssociationStore ()
@property (nonatomic, strong) NSDictionary *associationLookup;
+@property (nonatomic, strong) NSArray *associations;
@property (nonatomic, strong) NSArray *newsItems;
@property (nonatomic, strong) NSArray *activities;
@property (nonatomic, strong) NSDate *newsLastUpdated;
@property (nonatomic, strong) NSDate *activitiesLastUpdated;
+@property (nonatomic, strong) NSDate *associationsLastUpdated;
@property (nonatomic, strong) RKObjectManager *objectManager;
@property (nonatomic, strong) NSMutableArray *activeRequests;
@@ -71,7 +74,6 @@ - (id)init
- (void)sharedInit
{
- self.associationLookup = [Association updateAssociations:self.associationLookup];
self.activeRequests = [[NSMutableArray alloc] init];
self.objectManager = [RKObjectManager managerWithBaseURL:[NSURL URLWithString:kBaseUrl]];
@@ -91,19 +93,21 @@ - (void)dealloc
- (id)initWithCoder:(NSCoder *)decoder
{
if (self = [super init]) {
- _associationLookup = [decoder decodeObjectForKey:@"associationLookup"];
- AssertClassOrNil(_associationLookup, NSDictionary);
-
+ _associations = [decoder decodeObjectForKey:@"associations"];
+ AssertClassOrNil(_associations, NSArray);
+ _associationsLastUpdated = [decoder decodeObjectForKey:@"associationsLastUpdated"];
+ AssertClassOrNil(_associationsLastUpdated, NSDate);
+
_newsItems = [decoder decodeObjectForKey:@"newsItems"];
AssertClassOrNil(_newsItems, NSArray);
_newsLastUpdated = [decoder decodeObjectForKey:@"newsLastUpdated"];
AssertClassOrNil(_newsLastUpdated, NSDate);
-
+
_activities = [decoder decodeObjectForKey:@"activities"];
AssertClassOrNil(_activities, NSArray);
_activitiesLastUpdated = [decoder decodeObjectForKey:@"activitiesLastUpdated"];
AssertClassOrNil(_activitiesLastUpdated, NSDate);
-
+
[self sharedInit];
}
return self;
@@ -111,7 +115,8 @@ - (id)initWithCoder:(NSCoder *)decoder
- (void)encodeWithCoder:(NSCoder *)coder
{
- [coder encodeObject:_associationLookup forKey:@"associationLookup"];
+ [coder encodeObject:_associationsLastUpdated forKey:@"associationsLastUpdated"];
+ [coder encodeObject:_associations forKey:@"associations"];
[coder encodeObject:_newsLastUpdated forKey:@"newsLastUpdated"];
[coder encodeObject:_newsItems forKey:@"newsItems"];
[coder encodeObject:_activitiesLastUpdated forKey:@"activitiesLastUpdated"];
@@ -122,9 +127,9 @@ + (NSString *)storeCachePath
{
// Get cache directory
NSArray *cacheDirectories =
- NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
+ NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cacheDirectory = cacheDirectories[0];
-
+
return [cacheDirectory stringByAppendingPathComponent:@"association.archive"];
}
@@ -133,10 +138,10 @@ - (void)syncStorage
if (!self.storageOutdated) {
return;
}
-
+
// Immediately mark the cache as being updated, as this is an async operation
self.storageOutdated = NO;
-
+
dispatch_queue_t async = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(async, ^{
[NSKeyedArchiver archiveRootObject:self toFile:self.class.storeCachePath];
@@ -150,36 +155,41 @@ - (void)markStorageOutdated
#pragma mark - Accessors
-- (NSArray *)assocations
-{
- return [self.associationLookup allValues];
-}
-
- (Association *)associationWithName:(NSString *)internalName
{
+ if (self.associationLookup == nil) {
+ [self createAssociationsLookup];
+ }
Association *association = self.associationLookup[internalName];
-
+
// If the association is unknown, just give a fake record
if (!association) {
association = [[Association alloc] init];
association.internalName = internalName;
association.displayName = internalName;
}
-
+
return association;
}
+- (NSArray *)associations
+{
+ [self _updateResource:kAssociationResource lastUpdated:self.associationsLastUpdated
+ objectMapping:[Association objectMapping]];
+ return _associations;
+}
+
- (NSArray *)activities
{
[self _updateResource:kActivitiesResource lastUpdated:self.activitiesLastUpdated
- objectMapping:[AssociationActivity objectMapping]];
+ objectMapping:[AssociationActivity objectMapping]];
return _activities;
}
- (NSArray *)newsItems
{
[self _updateResource:kNewsResource lastUpdated:self.newsLastUpdated
- objectMapping:[AssociationNewsItem objectMapping]];
+ objectMapping:[AssociationNewsItem objectMapping]];
return _newsItems;
}
@@ -188,14 +198,22 @@ - (void)reloadActivities
// Force reload, remove cache-entry
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self _updateResource:kActivitiesResource lastUpdated:nil
- objectMapping:[AssociationActivity objectMapping]];
+ objectMapping:[AssociationActivity objectMapping]];
+ [self reloadAssociations];
}
- (void)reloadNewsItems
{
[[NSURLCache sharedURLCache] removeAllCachedResponses];
[self _updateResource:kNewsResource lastUpdated:nil
- objectMapping:[AssociationNewsItem objectMapping]];
+ objectMapping:[AssociationNewsItem objectMapping]];
+ [self reloadAssociations];
+}
+
+- (void)reloadAssociations
+{
+ [self _updateResource:kAssociationResource lastUpdated:nil
+ objectMapping:[Association objectMapping]];
}
#pragma mark - RestKit Object loading
@@ -203,32 +221,32 @@ - (void)reloadNewsItems
- (void)_updateResource:(NSString *)resource lastUpdated:(NSDate *)lastUpdated objectMapping:(RKObjectMapping *)mapping
{
DLog(@"updateResource %@ (last: %@ => %f)", resource, lastUpdated, [lastUpdated timeIntervalSinceNow]);
-
+
// Check if an update is required
if (lastUpdated && [lastUpdated timeIntervalSinceNow] > -kUpdateInterval) {
return;
}
-
+
// Already working on request
if ([self.activeRequests containsObject:resource]) {
- return;
+ return;
}
-
+
DLog(@"Updating %@", resource);
[self.activeRequests addObject:resource];
[self.objectManager addResponseDescriptor:
- [RKResponseDescriptor responseDescriptorWithMapping:mapping
- method:RKRequestMethodGET
- pathPattern:resource
- keyPath:nil
- statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
+ [RKResponseDescriptor responseDescriptorWithMapping:mapping
+ method:RKRequestMethodGET
+ pathPattern:resource
+ keyPath:nil
+ statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)]];
[self.objectManager getObjectsAtPath:resource
parameters:nil
success:^(RKObjectRequestOperation *operation, RKMappingResult *mappingResult) {
- [self _processResult:mappingResult forResource:resource];
+ [self _processResult:mappingResult forResource:resource];
}
failure:^(RKObjectRequestOperation *operation, NSError *error) {
- [self _processError:error forResource:resource];
+ [self _processError:error forResource:resource];
}];
}
@@ -236,52 +254,56 @@ - (void)_processResult:(RKMappingResult *)mappingResult forResource:(NSString *)
{
NSString *notification = nil;
NSArray *objects = [mappingResult array];
-
+
// Received some NewsItems
if ([resource isEqualToString:kNewsResource]) {
- NSMutableSet *readItems = [NSMutableSet set];
- // Using direct access because accessors reload the data
- for (AssociationNewsItem *item in _newsItems) {
- if (item.read) {
- [readItems addObject:@(item.itemId)];
+ NSMutableSet *readItems = [NSMutableSet set];
+ // Using direct access because accessors reload the data
+ for (AssociationNewsItem *item in _newsItems) {
+ if (item.read) {
+ [readItems addObject:@(item.itemId)];
+ }
}
- }
- for (AssociationNewsItem *item in objects) {
- if ([readItems containsObject:@(item.itemId)]) {
- item.read = YES;
+ for (AssociationNewsItem *item in objects) {
+ if ([readItems containsObject:@(item.itemId)]) {
+ item.read = YES;
+ }
}
- }
- self.newsItems = objects;
- self.newsLastUpdated = [NSDate date];
- notification = AssociationStoreDidUpdateNewsNotification;
+ self.newsItems = objects;
+ self.newsLastUpdated = [NSDate date];
+ notification = AssociationStoreDidUpdateNewsNotification;
}
// Received Activities
else if ([resource isEqualToString:kActivitiesResource]) {
- NSMutableDictionary *availableEvents = [NSMutableDictionary dictionary];
- // Using direct access because accessors reload the data
- for (AssociationActivity *activity in _activities) {
- if ([activity hasFacebookEvent]) {
- availableEvents[activity.facebookId] = activity;
+ NSMutableDictionary *availableEvents = [NSMutableDictionary dictionary];
+ // Using direct access because accessors reload the data
+ for (AssociationActivity *activity in _activities) {
+ if ([activity hasFacebookEvent]) {
+ availableEvents[activity.facebookId] = activity;
+ }
}
- }
- for (AssociationActivity *activity in objects) {
- if ([availableEvents objectForKey:activity.facebookId]) {
- AssociationActivity *oldActivity = availableEvents[activity.facebookId];
- activity.facebookEvent = oldActivity.facebookEvent;
+ for (AssociationActivity *activity in objects) {
+ if ([availableEvents objectForKey:activity.facebookId]) {
+ AssociationActivity *oldActivity = availableEvents[activity.facebookId];
+ activity.facebookEvent = oldActivity.facebookEvent;
+ }
}
- }
- self.activities = objects;
- self.activitiesLastUpdated = [NSDate date];
- notification = AssociationStoreDidUpdateActivitiesNotification;
+ self.activities = objects;
+ self.activitiesLastUpdated = [NSDate date];
+ notification = AssociationStoreDidUpdateActivitiesNotification;
}
-
+ else if ([resource isEqualToString:kAssociationResource]) {
+ self.associations = objects;
+ [self createAssociationsLookup];
+ }
+
[self markStorageOutdated];
[self syncStorage];
-
+
// Send notification
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:notification object:self userInfo:nil];
-
+
[self.activeRequests removeObject:resource];
}
@@ -290,7 +312,7 @@ - (void)_processError:(NSError *)error forResource:(NSString *)resource
NSLog(@"Updating resource %@ failed: %@", resource, error);
AppDelegate *app = (AppDelegate *)[[UIApplication sharedApplication] delegate];
[app handleError:error];
-
+
NSString *notification = nil;
if ([resource isEqualToString:kNewsResource]) {
notification = AssociationStoreDidUpdateNewsNotification;
@@ -300,21 +322,32 @@ - (void)_processError:(NSError *)error forResource:(NSString *)resource
}
NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
[center postNotificationName:notification object:self userInfo:nil];
-
+
// Only clear the request after 10 seconds, to prevent failed requests
// restarting due to related succesful requests
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, 10 * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void) {
- [self.activeRequests removeObject:resource];
+ [self.activeRequests removeObject:resource];
});
}
+#pragma mark - Utility functions
+- (void)createAssociationsLookup
+{
+ NSMutableDictionary *associationsLookup = [NSMutableDictionary dictionary];
+ for (Association *association in self.associations) {
+ associationsLookup[association.internalName] = association;
+ }
+
+ self.associationLookup = associationsLookup;
+}
+
#pragma mark - Notifications
- (void)facebookEventUpdated:(NSNotification *)notification
{
[self markStorageOutdated];
-
+
// Call method in 10 seconds so multiple changes are written at once
[[self class] cancelPreviousPerformRequestsWithTarget:self
selector:@selector(syncStorage)
@@ -322,4 +355,4 @@ - (void)facebookEventUpdated:(NSNotification *)notification
[self performSelector:@selector(syncStorage) withObject:nil afterDelay:10];
}
-@end
+@end
\ No newline at end of file
diff --git a/iOS/Hydra/AssociationStore.swift b/iOS/Hydra/AssociationStore.swift
new file mode 100644
index 00000000..1819629d
--- /dev/null
+++ b/iOS/Hydra/AssociationStore.swift
@@ -0,0 +1,65 @@
+//
+// AssociationStore.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 20/11/2015.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import Foundation
+
+extension AssociationStore: FeedItemProtocol {
+ func feedItems() -> [FeedItem] {
+ return getActivities() + getNewsItems()
+ }
+
+ private func getActivities() -> [FeedItem] {
+ var feedItems = [FeedItem]()
+ let preferencesService = PreferencesService.sharedService()
+ if let activities = activities as? [AssociationActivity] {
+ var filter: ((AssociationActivity) -> (Bool))
+ if preferencesService.filterAssociations {
+ let associations = preferencesService.preferredAssociations
+ filter = { activity in activity.highlighted || associations.contains { activity.association.internalName == ($0 as! String) } }
+ } else {
+ filter = { $0.highlighted }
+ feedItems.append(FeedItem(itemType: .SettingsItem, object: nil, priority: 850))
+ }
+
+ for activity in activities.filter(filter) {
+ // Force load facebookEvent
+ if let facebookEvent = activity.facebookEvent {
+ facebookEvent.update()
+ }
+ var priority = 999 //TODO: calculate priorities, with more options
+ priority -= activity.start.daysAfterDate(NSDate()) * 100
+ if priority > 0 {
+ feedItems.append(FeedItem(itemType: .ActivityItem, object: activity, priority: priority))
+ }
+ }
+ }
+ return feedItems
+ }
+
+ private func getNewsItems() -> [FeedItem] {
+ var feedItems = [FeedItem]()
+
+ if let newsItems = newsItems as? [AssociationNewsItem] {
+ for newsItem in newsItems {
+ var priority = 999
+ let daysOld = newsItem.date.daysBeforeDate(NSDate())
+ if newsItem.highlighted {
+ priority -= 25*daysOld
+ } else {
+ priority -= 90*daysOld
+ }
+
+ if priority > 0 {
+ feedItems.append(FeedItem(itemType: .NewsItem, object: newsItem, priority: priority))
+ }
+ }
+ }
+
+ return feedItems
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/BadgedButton.h b/iOS/Hydra/BadgedButton.h
deleted file mode 100644
index d51e201f..00000000
--- a/iOS/Hydra/BadgedButton.h
+++ /dev/null
@@ -1,16 +0,0 @@
-//
-// DashboardButton.h
-// Hydra
-//
-// Created by Yasser Deceukelier on 20/07/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import
-
-@interface BadgedButton : UIButton
-
-- (id)initWithFrame:(CGRect)frame;
-- (void)setBadgeNumber:(int)number;
-
-@end
diff --git a/iOS/Hydra/BadgedButton.m b/iOS/Hydra/BadgedButton.m
deleted file mode 100644
index 95f3be4c..00000000
--- a/iOS/Hydra/BadgedButton.m
+++ /dev/null
@@ -1,110 +0,0 @@
-//
-// DashboardButton.m
-// Hydra
-//
-// Created by Yasser Deceukelier on 20/07/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import "BadgedButton.h"
-#import
-
-#define kBadgeFontSize 15
-
-@implementation BadgedButton
-{
- // two layer 1 text & 1 badge, so the text can be centerd in the badge
- // no __weak, because not supported on iOS 4
- __unsafe_unretained CATextLayer *_textLayer;
- __unsafe_unretained CALayer *_badgeLayer;
-
- UIFont *badgeFont;
- CGFloat badgeHeight;
-}
-
-#pragma mark - Badge properties
-
-- (void)setBadgeText:(NSString *)badgeText
-{
- [_textLayer setString:badgeText];
-
- //under development!!!
- CGSize textSize = [badgeText sizeWithAttributes:@{NSFontAttributeName: badgeFont}];
- CGFloat textWidth = MAX(textSize.height, textSize.width);
- CGRect textFrame = CGRectMake(0, badgeHeight -textSize.height, textWidth, textSize.height);
-
- CGFloat badgeWidth = ([_textLayer.string length] > 1 ? textWidth+badgeHeight/2 : badgeHeight);
- textFrame.origin.x = (badgeWidth -textWidth)/2;
- _textLayer.frame = textFrame;
-
- CGRect badgeFrame = CGRectMake(self.frame.size.width -2*badgeWidth/3, -badgeHeight/3, badgeWidth, badgeHeight);
- _badgeLayer.frame = badgeFrame;
-
- UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:_badgeLayer.bounds cornerRadius:_badgeLayer.cornerRadius];
- _badgeLayer.shadowPath = shadowPath.CGPath;
-
- _badgeLayer.hidden = (badgeText ? NO : YES);
-}
-
-- (void)setBadgeNumber:(int)number
-{
- if(number != 0) {
- [self setBadgeText:[NSString stringWithFormat:@"%d", number]];
- }
- else {
- [self setBadgeText:nil];
- }
-}
-
-#pragma mark - Badge setup
-
-- (id)initWithFrame:(CGRect)frame
-{
- self = [super initWithFrame:frame];
- if(self) {
- [self setupBadgeLayers];
- }
- return self;
-}
-
-- (void)awakeFromNib
-{
- [self setupBadgeLayers];
-}
-
-- (void)setupBadgeLayers
-{
- // Somehow the red background is peeking through the border??
- // Is it also visible on an actual device or just in the simulator???
-
- badgeFont = [UIFont boldSystemFontOfSize:kBadgeFontSize];
- CGFloat newlineSpace = [badgeFont lineHeight] - [badgeFont ascender];
- badgeHeight = [badgeFont lineHeight] + newlineSpace;
-
- CAGradientLayer *badgeLayer = [CAGradientLayer layer];
- badgeLayer.colors = @[(id)[UIColor colorWithRed:1 green:.5 blue:.5 alpha:1].CGColor,
- (id)[UIColor colorWithRed:.8 green:0 blue:0 alpha:1].CGColor];
- badgeLayer.cornerRadius = badgeHeight/2;
- badgeLayer.borderWidth = 2;
- badgeLayer.borderColor = [UIColor whiteColor].CGColor;
- badgeLayer.hidden = YES;
- badgeLayer.shadowColor = [[UIColor blackColor] CGColor]; //Note: ca shadows may slow down scrolling on actual devices, no problem as long as scrolling (or rotation isn't enabled in the Dashboard
- badgeLayer.shadowOpacity = 0.5;
- badgeLayer.shadowOffset = CGSizeMake(0, 4.0);
- [self.layer addSublayer:badgeLayer];
- _badgeLayer = badgeLayer;
-
- CATextLayer *textLayer = [CATextLayer layer];
- textLayer.alignmentMode = kCAAlignmentCenter;
- textLayer.wrapped = YES;
- textLayer.fontSize = kBadgeFontSize;
-
- CGFontRef cgFont = CGFontCreateWithFontName((__bridge CFStringRef)badgeFont.fontName);
- textLayer.font = cgFont;
- CGFontRelease(cgFont);
-
- [badgeLayer addSublayer:textLayer];
- _textLayer = textLayer;
-}
-
-@end
diff --git a/iOS/Hydra/DashboardViewController.h b/iOS/Hydra/DashboardViewController.h
deleted file mode 100644
index c9a53aeb..00000000
--- a/iOS/Hydra/DashboardViewController.h
+++ /dev/null
@@ -1,32 +0,0 @@
-//
-// MasterViewController.h
-// Hydra
-//
-// Created by Pieter De Baets on 20/03/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import
-#import "BadgedButton.h"
-
-@interface DashboardViewController : UIViewController
-
-@property (nonatomic, unsafe_unretained) IBOutlet BadgedButton *newsButton;
-@property (nonatomic, unsafe_unretained) IBOutlet BadgedButton *activitiesButton;
-@property (nonatomic, unsafe_unretained) IBOutlet BadgedButton *infoButton;
-@property (nonatomic, unsafe_unretained) IBOutlet BadgedButton *restoButton;
-@property (nonatomic, unsafe_unretained) IBOutlet BadgedButton *urgentButton;
-@property (nonatomic, unsafe_unretained) IBOutlet BadgedButton *schamperButton;
-@property (nonatomic, unsafe_unretained) IBOutlet UIButton *feedbackButton;
-@property (nonatomic, unsafe_unretained) IBOutlet UIButton *preferencesButton;
-
-- (IBAction)showNews:(id)sender;
-- (IBAction)showActivities:(id)sender;
-- (IBAction)showInfo:(id)sender;
-- (IBAction)showResto:(id)sender;
-- (IBAction)showUrgent:(id)sender;
-- (IBAction)showSchamper:(id)sender;
-- (IBAction)showFeedbackView:(id)sender;
-- (IBAction)showPreferences:(id)sender;
-
-@end
diff --git a/iOS/Hydra/DashboardViewController.m b/iOS/Hydra/DashboardViewController.m
deleted file mode 100644
index 3123faef..00000000
--- a/iOS/Hydra/DashboardViewController.m
+++ /dev/null
@@ -1,244 +0,0 @@
-//
-// MasterViewController.m
-// Hydra
-//
-// Created by Pieter De Baets on 20/03/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import "DashboardViewController.h"
-
-#import
-
-#import "ActivitiesController.h"
-#import "InfoViewController.h"
-#import "NewsViewController.h"
-#import "PreferencesController.h"
-#import "RestoMenuController.h"
-#import "SchamperViewController.h"
-#import "UrgentViewController.h"
-
-#define EasterEggEnabled 0
-
-@interface DashboardViewController ()
-
-@property (nonatomic, strong) UISwipeGestureRecognizer *gestureRecognizer;
-@property (nonatomic, unsafe_unretained) UITextField *codeField;
-@property (nonatomic, strong) NSArray *requiredMoves;
-@property (nonatomic, assign) NSUInteger movesPerformed;
-
-@end
-
-@implementation DashboardViewController
-
-- (void)viewDidLoad
-{
-#if BETA_RELEASE
- self.feedbackButton.hidden = NO;
-#endif
-
-#if EasterEggEnabled
- self.requiredMoves = @[
- @(UISwipeGestureRecognizerDirectionUp), @(UISwipeGestureRecognizerDirectionUp),
- @(UISwipeGestureRecognizerDirectionDown), @(UISwipeGestureRecognizerDirectionDown),
- @(UISwipeGestureRecognizerDirectionLeft), @(UISwipeGestureRecognizerDirectionRight),
- @(UISwipeGestureRecognizerDirectionLeft), @(UISwipeGestureRecognizerDirectionRight),
- @"b", @"a"
- ];
- self.codeField = nil;
-#endif
-
-#ifdef __IPHONE_7_0
- // iOS 7 layout
- if ([self respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) {
- [self setNeedsStatusBarAppearanceUpdate];
- }
- else {
- // TODO: create IBOutlet for this
- UIView *headerView = self.view.subviews[0];
- CGRect headerFrame = headerView.frame;
- headerFrame.size.height -= 10;
- headerView.frame = headerFrame;
- }
-#endif
-}
-
-- (void)viewWillAppear:(BOOL)animated
-{
- [super viewWillAppear:animated];
- [self.navigationController setNavigationBarHidden:YES animated:animated];
-
-#ifdef __IPHONE_7_0
- if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
- [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
- }
-#endif
-
-#if EasterEggEnabled
- [self configureMoveDetectionForMove:0];
-#endif
-}
-
-- (void)viewDidAppear:(BOOL)animated
-{
- [super viewDidAppear:animated];
- GAI_Track(@"Home");
-}
-
-- (void)viewWillDisappear:(BOOL)animated
-{
- [super viewWillDisappear:animated];
- [self.navigationController setNavigationBarHidden:NO animated:animated];
- [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault animated:YES];
-}
-
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-{
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
-}
-
-#pragma mark - Button actions
-
-- (IBAction)showNews:(id)sender
-{
- DLog(@"Dashboard switching to News");
- NewsViewController *c = [[NewsViewController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-- (IBAction)showActivities:(id)sender
-{
- DLog(@"Dashboard switching to Activities");
- ActivitiesController *c = [[ActivitiesController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-- (IBAction)showInfo:(id)sender
-{
- DLog(@"Dashboard switching to Info");
- InfoViewController *c = [[InfoViewController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-- (IBAction)showResto:(id)sender
-{
- DLog(@"Dashboard switching to Resto");
- UIViewController *c = [[RestoMenuController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-- (IBAction)showUrgent:(id)sender
-{
- DLog(@"Dashboard switching to Urgent");
- UIViewController *c = [[UrgentViewController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-- (IBAction)showSchamper:(id)sender
-{
- DLog(@"Dashboard switching to Schamper");
- UIViewController *c = [[SchamperViewController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-- (IBAction)showFeedbackView:(id)sender
-{
- MFMailComposeViewController *controller = [[MFMailComposeViewController alloc] init];
- [controller setMailComposeDelegate:self];
- [controller setToRecipients:@[@"hydra@zeus.ugent.be"]];
- [controller setSubject:@"Bericht via Hydra"];
- [self presentViewController:controller animated:YES completion:nil];
-}
-
-- (void)mailComposeController:(MFMailComposeViewController *)controller
- didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error
-{
- [controller dismissViewControllerAnimated:YES completion:nil];
-}
-
--(IBAction)showPreferences:(id)sender
-{
- DLog(@"Dashboard switching to Preferences");
- UIViewController *c = [[PreferencesController alloc] init];
- [self.navigationController pushViewController:c animated:YES];
-}
-
-#pragma mark - Surprise feature
-
-#if EasterEggEnabled
-- (void)configureMoveDetectionForMove:(NSUInteger)move
-{
- if (move == [self.requiredMoves count]) {
- UrgentPlayer *urgentPlayer = [UrgentPlayer sharedPlayer];
- [urgentPlayer start];
-
- UILog(@"Congratulations, you won the game!");
- move = 0;
- }
- self.movesPerformed = move;
-
- id nextMove = (self.requiredMoves)[move];
- if ([nextMove isKindOfClass:[NSNumber class]]) {
- if (!self.gestureRecognizer) {
- self.gestureRecognizer = [[UISwipeGestureRecognizer alloc] init];
- [self.gestureRecognizer addTarget:self action:@selector(handleGesture:)];
- [self.view addGestureRecognizer:self.gestureRecognizer];
-
- [self.codeField removeFromSuperview];
- [self.codeField resignFirstResponder];
- self.codeField = nil;
- }
-
- self.gestureRecognizer.direction = [nextMove intValue];
- }
- else if ([nextMove isKindOfClass:[NSString class]]) {
- if (!self.codeField) {
- self.codeField = [[UITextField alloc] init];
- self.codeField.hidden = YES;
- self.codeField.delegate = self;
- self.codeField.autocapitalizationType = UITextAutocapitalizationTypeNone;
- self.codeField.returnKeyType = UIReturnKeyDone;
- [self.view addSubview:self.codeField];
-
- [self.view removeGestureRecognizer:self.gestureRecognizer];
- self.gestureRecognizer = nil;
- }
-
- // Store the string to be matched in the textfield, for easy comparison
- self.codeField.text = nextMove;
- [self.codeField becomeFirstResponder];
- }
-}
-
-- (void)handleGesture:(UIGestureRecognizer *)recognizer
-{
- [self configureMoveDetectionForMove:(self.movesPerformed + 1)];
- DLog(@"Surprise progress: %d/%d", self.movesPerformed, [self.requiredMoves count]);
-}
-
-- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event
-{
- [self configureMoveDetectionForMove:0];
-}
-
-- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string
-{
- if ([string caseInsensitiveCompare:textField.text] == NSOrderedSame) {
- [self configureMoveDetectionForMove:(self.movesPerformed + 1)];
- DLog(@"Surprise progress: %d/%d", self.movesPerformed, [self.requiredMoves count]);
- }
- else {
- [self configureMoveDetectionForMove:0];
- }
- return NO;
-}
-
-- (BOOL)textFieldShouldReturn:(UITextField *)textField
-{
- [textField resignFirstResponder];
- [self configureMoveDetectionForMove:0];
- return NO;
-}
-#endif
-
-@end
diff --git a/iOS/Hydra/HomeActivityCollectionViewCell.swift b/iOS/Hydra/HomeActivityCollectionViewCell.swift
new file mode 100644
index 00000000..422574fe
--- /dev/null
+++ b/iOS/Hydra/HomeActivityCollectionViewCell.swift
@@ -0,0 +1,66 @@
+//
+// HomeActivityCollectionViewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 01/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HomeActivityCollectionViewCell: UICollectionViewCell {
+ @IBOutlet weak var titleLabel: UILabel!
+ @IBOutlet weak var associationLabel: UILabel!
+ @IBOutlet weak var dateLabel: UILabel!
+ @IBOutlet weak var descriptionLabel: UILabel!
+ @IBOutlet weak var locationLabel: UILabel!
+ @IBOutlet weak var imageView: UIImageView!
+
+ var activity: AssociationActivity? {
+ didSet {
+ let longDateFormatter = NSDateFormatter.H_dateFormatterWithAppLocale()
+ longDateFormatter.timeStyle = .ShortStyle
+ longDateFormatter.dateStyle = .LongStyle
+ longDateFormatter.doesRelativeDateFormatting = true
+
+ let shortDateFormatter = NSDateFormatter.H_dateFormatterWithAppLocale()
+ shortDateFormatter.timeStyle = .ShortStyle
+ shortDateFormatter.dateStyle = .NoStyle
+
+ associationLabel.text = activity?.association.displayName
+ titleLabel.text = activity?.title
+
+ if (self.activity!.end != nil) {
+ if self.activity!.start.dateByAddingDays(1).isLaterThanDate(self.activity!.end) {
+ dateLabel.text = "\(longDateFormatter.stringFromDate((self.activity?.start)!)) - \(shortDateFormatter.stringFromDate((self.activity?.end)!))"
+ } else {
+ dateLabel.text = "\(longDateFormatter.stringFromDate((self.activity?.start)!)) - \(longDateFormatter.stringFromDate((self.activity?.end)!))"
+ }
+ } else {
+ dateLabel.text = longDateFormatter.stringFromDate((self.activity?.start)!)
+ }
+
+ descriptionLabel.text = activity?.descriptionText
+ var distance: Double? = nil
+ if (activity?.latitude != nil && activity?.longitude != nil) {
+ distance = LocationService.sharedService.calculateDistance(activity!.latitude, longitude: activity!.longitude)
+ }
+
+ if let d = distance where d < 100*1000{
+ if d < 1000 {
+ locationLabel.text = activity!.location + " (\(Int(d))m)"
+ } else {
+ locationLabel.text = activity!.location + " (\(Int(d/1000))km)"
+ }
+ } else {
+ locationLabel.text = activity?.location
+ }
+
+ if let url = activity?.facebookEvent?.smallImageUrl {
+ imageView.sd_setImageWithURL(url, placeholderImage: imageView.image)
+ } else {
+ imageView.image = nil
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/HomeFeedService.swift b/iOS/Hydra/HomeFeedService.swift
new file mode 100644
index 00000000..3fb0955d
--- /dev/null
+++ b/iOS/Hydra/HomeFeedService.swift
@@ -0,0 +1,107 @@
+//
+// HomeFeedService.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 31/07/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import Foundation
+
+let HomeFeedDidUpdateFeedNotification = "HomeFeedDidUpdateFeedNotification"
+let UpdateInterval: Double = 30 * 60 // half an hour
+
+class HomeFeedService {
+
+ static let sharedService = HomeFeedService()
+
+ let associationStore = AssociationStore.sharedStore()
+ let restoStore = RestoStore.sharedStore()
+ let schamperStore = SchamperStore.sharedStore()
+ let preferencesService = PreferencesService.sharedService()
+ let locationService = LocationService.sharedService
+
+ var previousRefresh = NSDate()
+
+ private init() {
+ refreshStores()
+ locationService.startUpdating()
+
+ let notifications = [RestoStoreDidReceiveMenuNotification, AssociationStoreDidUpdateActivitiesNotification, AssociationStoreDidUpdateNewsNotification, SchamperStoreDidUpdateArticlesNotification]
+ for notification in notifications {
+ NSNotificationCenter.defaultCenter().addObserver(self, selector: "storeUpdatedNotification:", name: notification, object: nil)
+ }
+ }
+
+
+ @objc func storeUpdatedNotification(notification: NSNotification) {
+ NSNotificationCenter.defaultCenter().postNotificationName(HomeFeedDidUpdateFeedNotification, object: nil)
+ }
+
+ deinit {
+ NSNotificationCenter.defaultCenter().removeObserver(self)
+ }
+
+ func refreshStoresIfNecessary()
+ {
+ if self.previousRefresh.timeIntervalSinceNow > -UpdateInterval {
+ self.refreshStores()
+ } else {
+ NSNotificationCenter.defaultCenter().postNotificationName(HomeFeedDidUpdateFeedNotification, object: nil)
+ }
+ }
+
+ func refreshStores() {
+ previousRefresh = NSDate()
+ associationStore.reloadActivities()
+ associationStore.reloadNewsItems()
+
+ restoStore.menuForDay(NSDate())
+ restoStore.locations
+
+ schamperStore.reloadArticles()
+ }
+
+ func createFeed() -> [FeedItem] {
+ var list = [FeedItem]()
+
+ let feedItemProviders: [FeedItemProtocol] = [associationStore, restoStore, schamperStore]
+
+ for provider in feedItemProviders {
+ list.appendContentsOf(provider.feedItems())
+ }
+
+ // Urgent.fm
+ list.append(FeedItem(itemType: .UrgentItem, object: nil, priority: 825))
+
+ list.sortInPlace{ $0.priority > $1.priority }
+
+ return list
+ }
+}
+
+protocol FeedItemProtocol {
+ func feedItems() -> [FeedItem]
+}
+
+struct FeedItem {
+ let itemType: FeedItemType
+ let object: AnyObject?
+ let priority: Int
+
+ init(itemType: FeedItemType, object: AnyObject?, priority: Int) {
+ self.itemType = itemType
+ self.object = object
+ self.priority = priority
+ }
+}
+
+enum FeedItemType {
+ case NewsItem
+ case ActivityItem
+ case InfoItem
+ case RestoItem
+ case UrgentItem
+ case SchamperNewsItem
+ case SettingsItem
+}
\ No newline at end of file
diff --git a/iOS/Hydra/HomeNewsItemCollectionViewCell.swift b/iOS/Hydra/HomeNewsItemCollectionViewCell.swift
new file mode 100644
index 00000000..afd84c80
--- /dev/null
+++ b/iOS/Hydra/HomeNewsItemCollectionViewCell.swift
@@ -0,0 +1,26 @@
+//
+// HomeNewsItemCollectionViewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 05/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HomeNewsItemCollectionViewCell: UICollectionViewCell {
+ @IBOutlet weak var titleLabel: UILabel!
+ @IBOutlet weak var assocationLabel: UILabel!
+ @IBOutlet weak var dateLabel: UILabel!
+ @IBOutlet weak var highlightImage: UIImageView!
+
+ var article: AssociationNewsItem? {
+ didSet {
+ titleLabel.text = article?.title
+ let dateTransformer = SORelativeDateTransformer()
+ dateLabel.text = dateTransformer.transformedValue(article?.date) as! String?
+ assocationLabel.text = article?.association.displayName
+ highlightImage.hidden = !article!.highlighted
+ }
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/HomeRestoCollectionViewCell.swift b/iOS/Hydra/HomeRestoCollectionViewCell.swift
new file mode 100644
index 00000000..ddde6f6e
--- /dev/null
+++ b/iOS/Hydra/HomeRestoCollectionViewCell.swift
@@ -0,0 +1,73 @@
+//
+// HomeRestoCollectionViewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 31/07/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HomeRestoCollectionViewCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate {
+ @IBOutlet weak var tableView: UITableView!
+ @IBOutlet weak var dayLabel: UILabel!
+ @IBOutlet weak var closedLabel: UILabel!
+
+ var restoMenu: RestoMenu? {
+ didSet {
+ if restoMenu != nil {
+ closedLabel.hidden = restoMenu!.open
+ if restoMenu!.day.isToday() {
+ dayLabel.text = "vandaag"
+ } else if restoMenu!.day.isTomorrow() {
+ dayLabel.text = "morgen"
+ } else {
+ let formatter = NSDateFormatter.H_dateFormatterWithAppLocale()
+ formatter.dateFormat = "EEEE d MMMM"
+ dayLabel.text = formatter.stringFromDate(restoMenu!.day)
+ }
+ } else {
+ dayLabel.text = ""
+ closedLabel.hidden = false
+ }
+ tableView.reloadData()
+ self.layoutSubviews() // call this to force an update after setting the new menu, so the tableview height changes.
+ }
+ }
+
+ override func awakeFromNib() {
+ tableView.separatorColor = UIColor.clearColor()
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ if restoMenu!.open {
+ if let count = restoMenu?.meat.count where restoMenu!.open{
+ return count
+ }
+ }
+ return 0
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCellWithIdentifier("restoMenuTableViewCell") as? HomeRestoMenuItemTableViewCell
+
+ cell!.menuItem = restoMenu?.meat[indexPath.row] as? RestoMenuItem
+
+ return cell!
+ }
+}
+
+class HomeRestoMenuItemTableViewCell: UITableViewCell {
+ @IBOutlet weak var nameLabel: UILabel!
+ @IBOutlet weak var priceLabel: UILabel!
+
+ var menuItem: RestoMenuItem? {
+ didSet {
+ if let menuItem = menuItem {
+ nameLabel.text = menuItem.name
+ priceLabel.text = menuItem.price
+ self.contentView.layoutIfNeeded() // relayout when prices are added
+ }
+ }
+ }
+}
diff --git a/iOS/Hydra/HomeSchamperCollectionViewCell.swift b/iOS/Hydra/HomeSchamperCollectionViewCell.swift
new file mode 100644
index 00000000..9fa19899
--- /dev/null
+++ b/iOS/Hydra/HomeSchamperCollectionViewCell.swift
@@ -0,0 +1,25 @@
+//
+// HomeSchamperCollectionViewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 31/07/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HomeSchamperCollectionViewCell: UICollectionViewCell {
+ @IBOutlet weak var titleLabel: UILabel!
+ @IBOutlet weak var dateLabel: UILabel!
+ @IBOutlet weak var authorLabel: UILabel!
+
+ var article: SchamperArticle? {
+ didSet {
+ titleLabel.text = article?.title
+ let dateTransformer = SORelativeDateTransformer()
+ dateLabel.text = dateTransformer.transformedValue(article?.date) as! String?
+ authorLabel.text = article?.author
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/iOS/Hydra/HomeUrgentCollectionViewCell.swift b/iOS/Hydra/HomeUrgentCollectionViewCell.swift
new file mode 100644
index 00000000..0f6b4952
--- /dev/null
+++ b/iOS/Hydra/HomeUrgentCollectionViewCell.swift
@@ -0,0 +1,37 @@
+//
+// HomeUrgentCollectionViewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 02/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HomeUrgentCollectionViewCell: UICollectionViewCell {
+ @IBOutlet weak var button: UIButton!
+
+ let notificationCenter = NSNotificationCenter.defaultCenter()
+
+ override func awakeFromNib() {
+ notificationCenter.addObserver(self, selector: "playerStatusChanged:", name: UrgentPlayerDidChangeStateNotification, object: nil)
+ button.selected = UrgentPlayer.sharedPlayer().isPlaying()
+ }
+
+ deinit {
+ notificationCenter.removeObserver(self)
+ }
+
+ @IBAction func playButtonTapped(sender: UIButton) {
+ let player = UrgentPlayer.sharedPlayer()
+ if player.isPlaying() {
+ player.pause()
+ } else {
+ player.play()
+ }
+ }
+
+ func playerStatusChanged(notification: NSNotification) {
+ button.selected = UrgentPlayer.sharedPlayer().isPlaying()
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/HomeViewController.swift b/iOS/Hydra/HomeViewController.swift
new file mode 100644
index 00000000..957513c7
--- /dev/null
+++ b/iOS/Hydra/HomeViewController.swift
@@ -0,0 +1,191 @@
+//
+// HomeViewController.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 30/07/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HomeViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UICollectionViewDelegateFlowLayout {
+ @IBOutlet weak var feedCollectionView: UICollectionView!
+
+ let homeFeedService = HomeFeedService.sharedService
+
+ var feedItems = HomeFeedService.sharedService.createFeed()
+ let refreshControl = UIRefreshControl()
+ var lastUpdated = NSDate()
+
+ override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
+ super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
+ sharedInit()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ sharedInit()
+ }
+
+ private func sharedInit() {
+ NSNotificationCenter.defaultCenter().addObserver(self, selector: "homeFeedUpdatedNotification:", name: HomeFeedDidUpdateFeedNotification, object: nil)
+ }
+
+ deinit {
+ NSNotificationCenter.defaultCenter().removeObserver(self)
+ }
+
+ func homeFeedUpdatedNotification(notification: NSNotification) {
+ self.feedItems = HomeFeedService.sharedService.createFeed()
+ self.feedCollectionView?.reloadData()
+
+ self.refreshControl.endRefreshing()
+ }
+
+ // MARK - View initialization
+ override func viewDidLoad() {
+ super.viewDidLoad()
+
+ refreshControl.tintColor = .whiteColor()
+ refreshControl.addTarget(self, action: "startRefresh", forControlEvents: .ValueChanged)
+ feedCollectionView.addSubview(refreshControl)
+
+ // REMOVE ME IF THE BUG IS FIXED, THIS IS FUCKING UGLY
+ NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("refreshDataTimer"), userInfo: nil, repeats: false)
+ }
+
+ func refreshDataTimer(){ // REMOVE ME WHEN THE BUG IS FIXED
+ self.feedCollectionView?.reloadData()
+ }
+
+ override func viewWillAppear(animated: Bool) {
+ super.viewWillAppear(animated)
+
+ self.navigationController?.navigationBarHidden = true
+ UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
+
+ HomeFeedService.sharedService.refreshStoresIfNecessary()
+ }
+
+ override func viewWillDisappear(animated: Bool) {
+ super.viewWillDisappear(animated)
+
+ self.navigationController?.navigationBarHidden = false
+ UIApplication.sharedApplication().setStatusBarStyle(.Default, animated: false)
+ }
+
+ override func viewDidAppear(animated: Bool) {
+ UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: animated)
+ }
+
+ override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
+ // this is called when changing layout :)
+ self.feedCollectionView.collectionViewLayout.invalidateLayout()
+ }
+
+ func startRefresh() {
+ self.homeFeedService.refreshStores()
+ }
+
+ // MARK: - UICollectionViewDataSource and Delegate methods
+ func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+ return feedItems.count;
+ }
+
+ func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
+ let feedItem = feedItems[indexPath.row]
+
+ switch feedItem.itemType {
+ case .RestoItem:
+ let cell = collectionView.dequeueReusableCellWithReuseIdentifier("restoCell", forIndexPath: indexPath) as? HomeRestoCollectionViewCell
+ cell?.restoMenu = feedItem.object as? RestoMenu
+ cell?.layoutIfNeeded() // iOS 9 bug
+ return cell!
+ case .SchamperNewsItem:
+ let cell = collectionView.dequeueReusableCellWithReuseIdentifier("schamperCell", forIndexPath: indexPath) as? HomeSchamperCollectionViewCell
+ cell!.article = feedItem.object as? SchamperArticle
+ cell?.layoutIfNeeded() // iOS 9 bug
+ return cell!
+ case .ActivityItem:
+ let cell = collectionView.dequeueReusableCellWithReuseIdentifier("activityCell", forIndexPath: indexPath) as? HomeActivityCollectionViewCell
+ cell?.activity = feedItem.object as? AssociationActivity
+ cell?.layoutIfNeeded() // iOS 9 bug
+ return cell!
+ case .NewsItem:
+ let cell = collectionView.dequeueReusableCellWithReuseIdentifier("newsItemCell", forIndexPath: indexPath) as? HomeNewsItemCollectionViewCell
+ cell?.article = feedItem.object as? AssociationNewsItem
+ return cell!
+ case .UrgentItem:
+ return collectionView.dequeueReusableCellWithReuseIdentifier("urgentfmCell", forIndexPath: indexPath)
+ case .SettingsItem:
+ return collectionView.dequeueReusableCellWithReuseIdentifier("settingsCell", forIndexPath: indexPath)
+ default:
+ return collectionView.dequeueReusableCellWithReuseIdentifier("testCell", forIndexPath: indexPath)
+ }
+ }
+
+ func collectionView(collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, atIndexPath indexPath: NSIndexPath) -> UICollectionReusableView {
+ return collectionView.dequeueReusableSupplementaryViewOfKind(kind, withReuseIdentifier: "homeHeader", forIndexPath: indexPath)
+ }
+
+ func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
+ let feedItem = feedItems[indexPath.row]
+
+ switch feedItem.itemType {
+ case .RestoItem:
+ let restoMenu = feedItem.object as? RestoMenu
+ var count = 1
+ if (restoMenu != nil && restoMenu!.open) {
+ count = restoMenu!.meat.count
+ }
+
+ return CGSizeMake(self.view.frame.size.width, CGFloat(90+count*15))
+ case .ActivityItem:
+ let activity = feedItem.object as? AssociationActivity
+ //TODO: guess height of cell
+ let activity_height = activity!.descriptionText.isEmpty ? 60 : 0
+
+ return CGSizeMake(self.view.frame.size.width, CGFloat(180 - activity_height))
+ case .SettingsItem:
+ return CGSizeMake(self.view.frame.size.width, 80)
+ case .NewsItem:
+ return CGSizeMake(self.view.frame.size.width, 100)
+ default:
+ return CGSizeMake(self.view.frame.size.width, 135) //TODO: per type
+ }
+ }
+
+ func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, insetForSectionAtIndex section: Int) -> UIEdgeInsets {
+ return UIEdgeInsetsMake(10, 0, 0, 0)
+ }
+
+ func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
+ let feedItem = feedItems[indexPath.row]
+
+ switch feedItem.itemType {
+ case .RestoItem:
+ let index = self.tabBarController?.viewControllers?.indexOf({$0.tabBarItem.tag == 221}) // using hardcoded tag of Resto Menu viewcontroller
+ self.tabBarController?.selectedIndex = index!
+ let navigationController = self.tabBarController?.viewControllers![index!] as? UINavigationController
+ if let menuController = navigationController?.visibleViewController as? RestoMenuViewController {
+ let menu = feedItem.object as! RestoMenu
+ menuController.scrollToDate(menu.day)
+ }
+ case .ActivityItem:
+ self.navigationController?.pushViewController(ActivityDetailController(activity: feedItem.object as! AssociationActivity, delegate: nil), animated: true)
+ case .SchamperNewsItem:
+ let article = feedItem.object as! SchamperArticle
+ if !article.read {
+ article.read = true
+ SchamperStore.sharedStore().syncStorage()
+ }
+
+ self.navigationController?.pushViewController(SchamperDetailViewController(article: article), animated: true)
+ case .NewsItem:
+ self.navigationController?.pushViewController(NewsDetailViewController(newsItem: feedItem.object as! AssociationNewsItem), animated: true)
+ case .SettingsItem:
+ self.navigationController?.pushViewController(PreferencesController(), animated: true)
+ default: break
+ }
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/Hydra-Bridging-Header.h b/iOS/Hydra/Hydra-Bridging-Header.h
new file mode 100644
index 00000000..4b2d02e0
--- /dev/null
+++ b/iOS/Hydra/Hydra-Bridging-Header.h
@@ -0,0 +1,42 @@
+//
+// Use this file to import your target's public headers that you would like to expose to Swift.
+//
+
+// Services
+#import "AssociationStore.h"
+#import "PreferencesService.h"
+#import "RestoStore.h"
+#import "SchamperStore.h"
+#import "UrgentPlayer.h"
+
+// Models
+#import "Association.h"
+#import "AssociationActivity.h"
+#import "AssociationNewsItem.h"
+#import "NewsDetailViewController.h"
+#import "RestoLegendItem.h"
+#import "RestoMenu.h"
+#import "SchamperArticle.h"
+#import "FacebookEvent.h"
+
+// Controllers
+#import "NewsViewController.h"
+#import "ActivitiesController.h"
+#import "ActivityDetailController.h"
+#import "InfoViewController.h"
+#import "PreferencesController.h"
+#import "RestoMapController.h"
+#import "SchamperViewController.h"
+#import "SchamperDetailViewController.h"
+#import "UrgentViewController.h"
+
+// Categories and extenions
+#import "NSDateFormatter+AppLocale.h"
+
+// Third party classes
+#import "NSDate+Utilities.h"
+#import "SORelativeDateTransformer.h"
+
+
+// Remove from bridiging header when removing iOS 7 support, so we can use the iOS >= 8 frameworks in Cocoapods
+#import "UIImageView+WebCache.h"
diff --git a/iOS/Hydra/Hydra-Prefix.pch b/iOS/Hydra/Hydra-Prefix.pch
index ba315fb0..794c6486 100644
--- a/iOS/Hydra/Hydra-Prefix.pch
+++ b/iOS/Hydra/Hydra-Prefix.pch
@@ -4,7 +4,7 @@
#import
-#ifndef __IPHONE_5_0
+#ifndef __IPHONE_7_0
#warning "This project uses features only available in iOS SDK 5.0 and later."
#endif
diff --git a/iOS/Hydra/HydraTabbarController.swift b/iOS/Hydra/HydraTabbarController.swift
new file mode 100644
index 00000000..abbc8a54
--- /dev/null
+++ b/iOS/Hydra/HydraTabbarController.swift
@@ -0,0 +1,90 @@
+//
+// HydraTabbarController.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 11/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class HydraTabBarController: UITabBarController, UITabBarControllerDelegate {
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ self.delegate = self
+
+ let newsViewController = UINavigationController(rootViewController: NewsViewController())
+ let activityController = UINavigationController(rootViewController: ActivitiesController())
+ let infoController = UINavigationController(rootViewController: InfoViewController())
+ let schamperController = UINavigationController(rootViewController: SchamperViewController())
+ let prefsController = UINavigationController(rootViewController: PreferencesController())
+ let urgentController = UrgentViewController()
+
+ infoController.tabBarItem.configure(nil, image: "info", tag: 231)
+ activityController.tabBarItem.configure(nil, image: "activities", tag: 232)
+ schamperController.tabBarItem.configure(nil, image: "schamper", tag: 233)
+ newsViewController.tabBarItem.configure(nil, image: "news", tag: 234)
+ urgentController.tabBarItem.configure("Urgent.fm", image: "urgent", tag: 235)
+ prefsController.tabBarItem.configure("Voorkeuren", image: "settings", tag: 236)
+
+ var viewControllers = self.viewControllers!
+ viewControllers.appendContentsOf([infoController, activityController, newsViewController, schamperController, urgentController, prefsController])
+
+ self.viewControllers = orderViewControllers(viewControllers)
+
+ // Fix gray tabbars
+ self.tabBar.translucent = false
+ }
+
+ func orderViewControllers(viewControllers: [UIViewController]) -> [UIViewController]{
+ let tagsOrder = PreferencesService.sharedService().hydraTabBarOrder as! [Int]
+ if tagsOrder.count == 0 {
+ return viewControllers
+ }
+
+ var orderedViewControllers = [UIViewController]()
+ var oldViewControllers = viewControllers
+
+ for tag in tagsOrder {
+ let controller_index: Int? = oldViewControllers.indexOf({ (el) -> Bool in
+ el.tabBarItem.tag == tag
+ })
+ if let index = controller_index {
+ orderedViewControllers.append(oldViewControllers.removeAtIndex(index))
+ }
+ }
+
+ // Add all other viewcontrollers, it's possible new ones are added
+ orderedViewControllers.appendContentsOf(oldViewControllers)
+ return orderedViewControllers
+ }
+
+ // MARK: UITabBarControllerDelegate
+ func tabBarController(tabBarController: UITabBarController, didEndCustomizingViewControllers viewControllers: [UIViewController], changed: Bool) {
+ debugPrint("didEndCustomizingViewControllers called")
+ if !changed {
+ return
+ }
+
+ var tagsOrder = [Int]()
+ for controller in viewControllers {
+ tagsOrder.append(controller.tabBarItem.tag)
+ }
+
+ PreferencesService.sharedService().hydraTabBarOrder = tagsOrder
+ }
+}
+
+// MARK: UITabBarItem functions
+extension UITabBarItem {
+
+ // Configure UITabBarItem with string, image and tag
+ func configure(title: String?, image: String, tag: Int) {
+ if let title = title {
+ self.title = title
+ }
+ self.image = UIImage(named: "tabbar-" + image + ".png")
+ self.tag = tag
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/Images.xcassets/AppIcon-2.appiconset/Contents.json b/iOS/Hydra/Images.xcassets/AppIcon-2.appiconset/Contents.json
index a93eae40..5705af91 100644
--- a/iOS/Hydra/Images.xcassets/AppIcon-2.appiconset/Contents.json
+++ b/iOS/Hydra/Images.xcassets/AppIcon-2.appiconset/Contents.json
@@ -6,12 +6,22 @@
"filename" : "Icon-Small-iOS6@2x.png",
"scale" : "2x"
},
+ {
+ "idiom" : "iphone",
+ "size" : "29x29",
+ "scale" : "3x"
+ },
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Small-iOS7@2x.png",
"scale" : "2x"
},
+ {
+ "idiom" : "iphone",
+ "size" : "40x40",
+ "scale" : "3x"
+ },
{
"size" : "60x60",
"idiom" : "iphone",
diff --git a/iOS/Hydra/InfoViewController.m b/iOS/Hydra/InfoViewController.m
index 466c5198..753f8884 100644
--- a/iOS/Hydra/InfoViewController.m
+++ b/iOS/Hydra/InfoViewController.m
@@ -6,6 +6,8 @@
// Copyright (c) 2012 Zeus WPI. All rights reserved.
//
+@import SafariServices;
+
#import "InfoViewController.h"
#import "WebViewController.h"
@@ -76,10 +78,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
if(!cell) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:CellIdentifier];
- // iOS7
- if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
- cell.separatorInset = UIEdgeInsetsZero;
- }
+ cell.separatorInset = UIEdgeInsetsZero;
}
cell.contentView.backgroundColor = [UIColor whiteColor];
@@ -141,8 +140,12 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
NSURL *url = nil;
if (item[@"url-ios"]) url = [NSURL URLWithString:item[@"url-ios"]];
else url = [NSURL URLWithString:item[@"url"]];
-
- [[UIApplication sharedApplication] openURL:url];
+ if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"9")) {
+ SFSafariViewController *svc = [[SFSafariViewController alloc] initWithURL:url];
+ [self.navigationController presentViewController:svc animated:YES completion:nil];
+ } else {
+ [[UIApplication sharedApplication] openURL:url];
+ }
[tableView deselectRowAtIndexPath:indexPath animated:YES];
}
else {
diff --git a/iOS/Hydra/LocationService.swift b/iOS/Hydra/LocationService.swift
new file mode 100644
index 00000000..a2b7e1e9
--- /dev/null
+++ b/iOS/Hydra/LocationService.swift
@@ -0,0 +1,65 @@
+//
+// LocationService.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 01/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import Foundation
+import CoreLocation
+
+public class LocationService: NSObject, CLLocationManagerDelegate {
+
+ static let sharedService = LocationService()
+
+ public var allowedLocation: Bool = false
+
+ private var locationManager: CLLocationManager = CLLocationManager()
+ private var location: CLLocation?
+
+ private override init() {
+ super.init()
+ self.locationManager.delegate = self
+ self.locationManager.pausesLocationUpdatesAutomatically = true
+ self.locationManager.distanceFilter = 100.0
+ self.locationManager.desiredAccuracy = kCLLocationAccuracyHundredMeters
+ }
+
+ public func startUpdating() {
+ let status = CLLocationManager.authorizationStatus()
+ if status == CLAuthorizationStatus.Restricted || status == CLAuthorizationStatus.Denied {
+ allowedLocation = false
+ return
+ } else if status == .NotDetermined {
+ if #available(iOS 8.0, *) {
+ locationManager.requestWhenInUseAuthorization()
+ }
+ }
+ allowedLocation = true
+
+ self.locationManager.startUpdatingLocation()
+ }
+
+ public func pauseUpdating() { //TODO: call this
+ self.locationManager.stopUpdatingLocation()
+ }
+
+ public func calculateDistance(latitude: Double, longitude: Double) -> CLLocationDistance? {
+ if !allowedLocation || location == nil{
+ return nil
+ }
+ return location?.distanceFromLocation(CLLocation(latitude: latitude, longitude: longitude))
+ }
+
+ //MARK: - Implement core location delegate methods
+ @objc public func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
+ debugPrint("Locations updated")
+
+ location = locations[0]
+ }
+
+ @objc public func locationManagerDidResumeLocationUpdates(manager: CLLocationManager) {
+ debugPrint("Resumed location updates")
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/MainStoryboard.storyboard b/iOS/Hydra/MainStoryboard.storyboard
new file mode 100644
index 00000000..cdb15719
--- /dev/null
+++ b/iOS/Hydra/MainStoryboard.storyboard
@@ -0,0 +1,1444 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/iOS/Hydra/MapViewController.m b/iOS/Hydra/MapViewController.m
index 32e11d09..204b4e28 100644
--- a/iOS/Hydra/MapViewController.m
+++ b/iOS/Hydra/MapViewController.m
@@ -25,11 +25,7 @@ @implementation MapViewController
- (void)loadView
{
-#ifdef __IPHONE_7_0
- if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
- self.edgesForExtendedLayout = UIRectEdgeNone;
- }
-#endif
+ self.edgesForExtendedLayout = UIRectEdgeNone;
CGRect bounds = [UIScreen mainScreen].bounds;
self.view = [[UIView alloc] initWithFrame:bounds];
@@ -210,27 +206,18 @@ - (void)routeButtonTapped:(UIButton *)sender
// Check for iOS 6
Class mapItemClass = [MKMapItem class];
- if (mapItemClass && [mapItemClass respondsToSelector:@selector(openMapsWithItems:launchOptions:)]) {
- // Create an MKMapItem to pass to the Maps app
- MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinates
- addressDictionary:nil];
- MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
- [mapItem setName:annotation.title];
-
- // Route between the current location and the mapitem
- MKMapItem *currentLocationMapItem = [MKMapItem mapItemForCurrentLocation];
- [MKMapItem openMapsWithItems:@[currentLocationMapItem, mapItem]
- launchOptions:@{
- MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeWalking
- }];
- }
- // iOS < 6 use maps.apple.com
- else {
- CLLocationCoordinate2D user = self.mapView.userLocation.coordinate;
- NSString *url = [NSString stringWithFormat:@"http://maps.apple.com/maps?saddr=%f,%f&daddr=%f,%f&dirflg=w",
- user.latitude, user.longitude, coordinates.latitude, coordinates.longitude];
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:url]];
- }
+ // Create an MKMapItem to pass to the Maps app
+ MKPlacemark *placemark = [[MKPlacemark alloc] initWithCoordinate:coordinates
+ addressDictionary:nil];
+ MKMapItem *mapItem = [[MKMapItem alloc] initWithPlacemark:placemark];
+ [mapItem setName:annotation.title];
+
+ // Route between the current location and the mapitem
+ MKMapItem *currentLocationMapItem = [MKMapItem mapItemForCurrentLocation];
+ [MKMapItem openMapsWithItems:@[currentLocationMapItem, mapItem]
+ launchOptions:@{
+ MKLaunchOptionsDirectionsModeKey : MKLaunchOptionsDirectionsModeWalking
+ }];
}
#pragma mark - User tracking
diff --git a/iOS/Hydra/NewsDetailViewController.m b/iOS/Hydra/NewsDetailViewController.m
index b1d9ce14..009f0c57 100644
--- a/iOS/Hydra/NewsDetailViewController.m
+++ b/iOS/Hydra/NewsDetailViewController.m
@@ -29,11 +29,8 @@ - (id)initWithNewsItem:(AssociationNewsItem *)newsItem
- (void)viewDidLoad
{
-#ifdef __IPHONE_7_0
- if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
- self.edgesForExtendedLayout = UIRectEdgeNone;
- }
-#endif
+ self.edgesForExtendedLayout = UIRectEdgeNone;
+
CGSize viewSize = self.view.bounds.size;
CGSize contentSize = CGSizeMake(viewSize.width - 20, CGFLOAT_MAX);
self.view.backgroundColor = [UIColor whiteColor];
diff --git a/iOS/Hydra/NewsViewController.m b/iOS/Hydra/NewsViewController.m
index 8782ff7b..2fbb6391 100644
--- a/iOS/Hydra/NewsViewController.m
+++ b/iOS/Hydra/NewsViewController.m
@@ -105,10 +105,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle
reuseIdentifier:CellIdentifier];
cell.detailTextLabel.textColor = [UIColor colorWithWhite:0.3 alpha:1];
- // iOS7
- if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
- cell.separatorInset = UIEdgeInsetsZero;
- }
+ cell.separatorInset = UIEdgeInsetsZero;
}
AssociationNewsItem *newsItem = self.newsItems[indexPath.row];
diff --git a/iOS/Hydra/PreferencesService.h b/iOS/Hydra/PreferencesService.h
index 93d1a0f9..690ac6ca 100644
--- a/iOS/Hydra/PreferencesService.h
+++ b/iOS/Hydra/PreferencesService.h
@@ -14,6 +14,7 @@
@property (nonatomic, assign) BOOL filterAssociations;
@property (nonatomic, strong) NSArray *preferredAssociations;
+@property (nonatomic, strong) NSArray *hydraTabBarOrder;
@property (nonatomic, assign) BOOL shownFacebookPrompt;
@end
diff --git a/iOS/Hydra/PreferencesService.m b/iOS/Hydra/PreferencesService.m
index addeff21..34a67b07 100644
--- a/iOS/Hydra/PreferencesService.m
+++ b/iOS/Hydra/PreferencesService.m
@@ -10,9 +10,9 @@
#define kFilterAssociationsKey @"useAssociationFilter"
#define kPreferredAssociationsKey @"preferredAssociations"
+#define kHydraTabBarOrder @"hydraTabBarOrder"
#define kShownFacebookPrompt @"shownFacebookPrompt"
-
@interface PreferencesService ()
@property (nonatomic, strong) NSUserDefaults *settings;
@@ -79,4 +79,21 @@ - (void)setPreferredAssociations:(NSArray *)preferredAssociations
[self didChangeValueForKey:@"preferredAssociations"];
}
+
+- (NSArray *)hydraTabBarOrder
+{
+ NSArray *list = [self.settings objectForKey:kHydraTabBarOrder];
+ AssertClassOrNil(list, NSArray);
+ if (list == nil) {
+ list = [[NSArray alloc] init];
+ }
+ return list;
+}
+
+- (void)setHydraTabBarOrder:(NSArray *)hydraTabBarOrder
+{
+ [self willChangeValueForKey:kHydraTabBarOrder];
+ [self.settings setObject:hydraTabBarOrder forKey:kHydraTabBarOrder];
+ [self didChangeValueForKey:kHydraTabBarOrder];
+}
@end
diff --git a/iOS/Hydra/RestoInfoView.h b/iOS/Hydra/RestoInfoView.h
deleted file mode 100644
index 30c6c723..00000000
--- a/iOS/Hydra/RestoInfoView.h
+++ /dev/null
@@ -1,17 +0,0 @@
-//
-// RestoInfoView.h
-// Hydra
-//
-// Created by Feliciaan De Palmenaer on 24/12/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import
-
-@interface RestoInfoView : UIView
-
-@property (nonatomic, strong) NSArray *legend;
-
-- (id)initWithFrame:(CGRect)frame;
-
-@end
diff --git a/iOS/Hydra/RestoInfoView.m b/iOS/Hydra/RestoInfoView.m
deleted file mode 100644
index ca9e19ae..00000000
--- a/iOS/Hydra/RestoInfoView.m
+++ /dev/null
@@ -1,180 +0,0 @@
-//
-// RestoInfoView.m
-// Hydra
-//
-// Created by Feliciaan De Palmenaer on 24/12/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import "RestoInfoView.h"
-#import "RestoLegendItem.h"
-#import "RestoMapController.h"
-#import "RestoStore.h"
-#import "AppDelegate.h"
-
-#define kCellKeyLabel 101
-#define kCellValueLabel 102
-
-@interface RestoInfoView ()
-
-@property (nonatomic, unsafe_unretained) UITableView *tableView;
-
-@end
-@implementation RestoInfoView
-
-#pragma mark - Properties and init
-
-- (id)initWithFrame:(CGRect)frame
-{
- if (self = [super initWithFrame:frame]) {
- [self createView];
- }
- return self;
-}
-
-- (void)createView
-{
- // background
- UIImage *background = [UIImage imageNamed:@"header-bg.png"];
- UIImageView *backgroundView = [[UIImageView alloc] initWithFrame:self.bounds];
- backgroundView.image = background;
- backgroundView.contentMode = UIViewContentModeScaleToFill;
- backgroundView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- [self addSubview:backgroundView];
-
- // Header view
- UIView *headerView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, self.frame.size.width, 208)];
-
- // logo
- UIImage *logo = [UIImage imageNamed:@"resto-logo.png"];
- UIImageView *imageView = [[UIImageView alloc] initWithImage:logo];
- [imageView setFrame:CGRectMake(self.frame.size.width/2-50, 0, 100, 100)];
- [headerView addSubview:imageView];
-
- // resto info
- UILabel *infoLabel = [[UILabel alloc] initWithFrame:CGRectMake(30, CGRectGetMaxY(imageView.frame),
- self.frame.size.width - 60, 80)];
- infoLabel.text = @"De resto's van de UGent zijn elke weekdag open van 11u15 tot 14u. 's Avonds kan je ook terecht in resto De Brug van 17u30 tot 21u.";
- infoLabel.backgroundColor = [UIColor clearColor];
- infoLabel.textColor = [UIColor whiteColor];
- infoLabel.font = [UIFont systemFontOfSize:14];
- infoLabel.textAlignment = NSTextAlignmentCenter;
- infoLabel.numberOfLines = 4;
- [headerView addSubview:infoLabel];
-
- // title
- CGRect titleFrame = CGRectMake(0, CGRectGetMaxY(infoLabel.frame) + 5, self.frame.size.width, 20);
- UILabel *headerTitle = [[UILabel alloc] initWithFrame:titleFrame];
- headerTitle.text = @"Legende";
- headerTitle.textAlignment = NSTextAlignmentCenter;
- headerTitle.font = [UIFont boldSystemFontOfSize:13];
- headerTitle.textColor = [UIColor whiteColor];
- headerTitle.backgroundColor = [UIColor clearColor];
- [headerView addSubview:headerTitle];
-
- // Tableview
- UITableView *tableView = [[UITableView alloc] initWithFrame:self.bounds
- style:UITableViewStylePlain];
- tableView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- tableView.delegate = self;
- tableView.dataSource = self;
- tableView.bounces = NO;
- tableView.separatorColor = [UIColor clearColor];
- tableView.backgroundColor = [UIColor clearColor];
- tableView.allowsSelection = NO;
- tableView.tableHeaderView = headerView;
- tableView.contentInset = UIEdgeInsetsMake(10, 0, 10, 0);
- tableView.scrollIndicatorInsets = UIEdgeInsetsMake(5, 0, 5, 0);
- [self addSubview:tableView];
- self.tableView = tableView;
-}
-
-- (void)setLegend:(NSArray *)legend
-{
- _legend = legend;
- [self.tableView reloadData];
-}
-
-#pragma mark - Table view datasource
-
-- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-{
- return self.legend.count;
-}
-
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-{
- RestoLegendItem *legend = self.legend[indexPath.row];
-
- UILabel *keyLabel, *valueLabel;
-
- static NSString *cellIdentifier = @"RestoLegendViewCell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
- if (cell == nil) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
- reuseIdentifier:cellIdentifier];
- cell.textLabel.font = [UIFont boldSystemFontOfSize:15];
- cell.textLabel.textColor = [UIColor colorWithWhite:0.5 alpha:1];
- cell.backgroundColor = [UIColor clearColor];
-
- keyLabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 0, 40, 19)];
- keyLabel.tag = kCellKeyLabel;
- keyLabel.font = [UIFont boldSystemFontOfSize:13];
- keyLabel.backgroundColor = [UIColor clearColor];
- keyLabel.textColor = [UIColor whiteColor];
- keyLabel.textAlignment = NSTextAlignmentRight;
- [cell.contentView addSubview:keyLabel];
-
- CGFloat valueX = CGRectGetMaxX(keyLabel.frame) + 10;
- CGRect valueFrame = CGRectMake(valueX, 0, cell.frame.size.width - valueX - 20,
- cell.frame.size.height);
- valueLabel = [[UILabel alloc] initWithFrame:valueFrame];
- valueLabel.autoresizingMask = UIViewAutoresizingFlexibleHeight
- | UIViewAutoresizingFlexibleWidth;
- valueLabel.numberOfLines = 0;
- valueLabel.lineBreakMode = NSLineBreakByWordWrapping;
- valueLabel.tag = kCellValueLabel;
- valueLabel.font = [UIFont systemFontOfSize:13];
- valueLabel.backgroundColor = [UIColor clearColor];
- valueLabel.textColor = [UIColor whiteColor];
- [cell.contentView addSubview:valueLabel];
- }
- else {
- keyLabel = (UILabel *)[cell viewWithTag:kCellKeyLabel];
- valueLabel = (UILabel *)[cell viewWithTag:kCellValueLabel];
- }
-
- if ([legend.style isEqual:@"bold"]) {
- keyLabel.font = [UIFont boldSystemFontOfSize:13];
- }
- else {
- keyLabel.font = [UIFont systemFontOfSize:13];
- }
-
- valueLabel.text = legend.value;
- keyLabel.text = legend.key;
-
- return cell;
-
-}
-
-- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
-{
- RestoLegendItem *legend = self.legend[indexPath.row];
-
- CGSize constraintSize = CGSizeMake(200, CGFLOAT_MAX);
-
- NSMutableParagraphStyle * paragraphStyle = [[NSMutableParagraphStyle alloc] init];
- paragraphStyle.lineBreakMode = NSLineBreakByWordWrapping;
- paragraphStyle.alignment = NSTextAlignmentLeft;
-
- NSDictionary *attributes = @{ NSFontAttributeName: [UIFont systemFontOfSize:13], NSParagraphStyleAttributeName: paragraphStyle};
-
- CGSize labelSize = [legend.value boundingRectWithSize:constraintSize
- options:NSStringDrawingUsesLineFragmentOrigin
- attributes:attributes
- context:nil].size;
- return labelSize.height + 5;
-}
-
-@end
diff --git a/iOS/Hydra/RestoMapController.m b/iOS/Hydra/RestoMapController.m
index f0372b9f..0075526c 100644
--- a/iOS/Hydra/RestoMapController.m
+++ b/iOS/Hydra/RestoMapController.m
@@ -7,7 +7,6 @@
//
#import "RestoMapController.h"
-#import "RestoMenuController.h"
#import "RestoLocation.h"
#import "RestoStore.h"
#import "UINavigationController+ReplaceController.h"
@@ -67,12 +66,6 @@ - (void)viewDidLoad
{
[super viewDidLoad];
self.title = @"Resto Map";
-
- // Add button to navigation bar
- UIBarButtonItem *menuButton = [[UIBarButtonItem alloc] initWithTitle:@"Menu"
- style:UIBarButtonItemStylePlain
- target:self action:@selector(menuButtonTapped:)];
- self.navigationItem.rightBarButtonItem = menuButton;
}
- (void)viewDidAppear:(BOOL)animated
@@ -86,13 +79,6 @@ - (void)dealloc
[[NSNotificationCenter defaultCenter] removeObserver:self];
}
-- (void)menuButtonTapped:(id)sender
-{
- RestoMenuController *menuController = [[RestoMenuController alloc] init];
- [self.navigationController H_replaceViewControllerWith:menuController
- options:UIViewAnimationOptionTransitionFlipFromLeft];
-}
-
- (void)mapLocationUpdated
{
if (self.searchController.isActive) {
@@ -243,10 +229,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
cell.textLabel.backgroundColor = [UIColor clearColor];
cell.detailTextLabel.backgroundColor = [UIColor clearColor];
- // iOS7
- if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
- cell.separatorInset = UIEdgeInsetsZero;
- }
+ cell.separatorInset = UIEdgeInsetsZero;
}
RestoLocation *resto = self.filteredMapItems[indexPath.row];
diff --git a/iOS/Hydra/RestoMenuCollectionCell.swift b/iOS/Hydra/RestoMenuCollectionCell.swift
new file mode 100644
index 00000000..b7da92f9
--- /dev/null
+++ b/iOS/Hydra/RestoMenuCollectionCell.swift
@@ -0,0 +1,132 @@
+//
+// RestoMenuCollectionCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 14/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class RestoMenuCollectionCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate {
+ @IBOutlet weak var tableView: UITableView!
+
+ var restoMenu: RestoMenu? {
+ didSet {
+ tableView.reloadData()
+ }
+ }
+
+ override func awakeFromNib() {
+ tableView.separatorColor = UIColor.clearColor()
+ }
+
+ func numberOfSectionsInTableView(tableView: UITableView) -> Int {
+ return 4; //TODO: add maaltijdsoep
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ if let menu = restoMenu where menu.open {
+ let restoMenuSection = RestoMenuSection(rawValue: section)
+ switch restoMenuSection! {
+ case .Soup:
+ return restoMenu?.soup != nil ? 1 : 0
+ case .Meat:
+ return (restoMenu?.meat.count)!
+ case .Vegetable:
+ return (restoMenu?.vegetables.count)!
+ default:
+ return 0
+ }
+
+ }
+ return 0
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCellWithIdentifier("menuItemCell") as? RestoMenuItemTableViewCell
+
+ cell?.backgroundColor = UIColor.clearColor() // for iPads, for some strange the cells lose their color
+
+ let restoMenuSection = RestoMenuSection(rawValue: indexPath.section)
+ switch restoMenuSection! {
+ case .Soup:
+ cell!.menuItem = restoMenu?.soup
+ case .Meat:
+ cell!.menuItem = restoMenu?.meat[indexPath.row] as? RestoMenuItem
+ case .Vegetable:
+ cell!.vegetable = restoMenu?.vegetables[indexPath.row] as? String
+ default: break
+ }
+
+ return cell!
+ }
+
+ // Using footers of the previous section instead of headers so they scroll
+ func tableView(tableView: UITableView, heightForFooterInSection section: Int) -> CGFloat {
+ // Zero height for last section footer
+ return section < 3 ? 40 : 0
+ }
+
+ func tableView(tableView: UITableView, viewForFooterInSection section: Int) -> UIView?{
+ // Return nil if last footer
+ if section == 3 {
+ return nil
+ }
+ let frame = CGRectMake(0, 0, self.bounds.width, 40)
+ let header = UIView(frame: frame)
+
+ let label = UILabel(frame: frame)
+ label.textAlignment = .Center
+ if #available(iOS 8.2, *) {
+ label.font = UIFont.systemFontOfSize(20, weight: UIFontWeightLight)
+ } else {
+ // Fallback on earlier versions
+ label.font = UIFont.systemFontOfSize(20)
+ }
+ label.baselineAdjustment = .AlignCenters
+ label.textColor = UIColor.whiteColor()
+ let restoMenuSection = RestoMenuSection(rawValue: section+1)
+ switch restoMenuSection! {
+ case .Soup:
+ label.text = "SOEP"
+ case .Meat:
+ label.text = "VLEES & VEGGIE"
+ case .Vegetable:
+ label.text = "GROENTEN"
+ default:
+ return header
+ }
+
+ header.addSubview(label)
+ return header
+ }
+}
+
+class RestoMenuItemTableViewCell: UITableViewCell {
+ @IBOutlet weak var nameLabel: UILabel!
+ @IBOutlet weak var priceLabel: UILabel!
+
+ var menuItem: RestoMenuItem? {
+ didSet {
+ if let menuItem = menuItem {
+ nameLabel.text = menuItem.name
+ priceLabel.text = menuItem.price
+ self.contentView.layoutIfNeeded() // relayout when prices are added
+ }
+ }
+ }
+
+ var vegetable: String? {
+ didSet {
+ if let vegetable = vegetable {
+ nameLabel.text = vegetable
+ priceLabel.text = ""
+ }
+ }
+ }
+}
+
+enum RestoMenuSection: Int {
+ case Soup = 1, Meat = 3, Vegetable = 2, Empty = 0
+}
\ No newline at end of file
diff --git a/iOS/Hydra/RestoMenuController.h b/iOS/Hydra/RestoMenuController.h
deleted file mode 100644
index bae0016a..00000000
--- a/iOS/Hydra/RestoMenuController.h
+++ /dev/null
@@ -1,13 +0,0 @@
-//
-// RestoMenuController.h
-// Hydra
-//
-// Created by Pieter De Baets on 29/06/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import
-
-@interface RestoMenuController : UIViewController
-
-@end
diff --git a/iOS/Hydra/RestoMenuController.m b/iOS/Hydra/RestoMenuController.m
deleted file mode 100644
index 026f651c..00000000
--- a/iOS/Hydra/RestoMenuController.m
+++ /dev/null
@@ -1,319 +0,0 @@
-//
-// RestoMenuController.m
-// Hydra
-//
-// Created by Pieter De Baets on 29/06/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-#import
-#import "SMPageControl.h"
-#import "NSDate+Utilities.h"
-#import "RestoInfoView.h"
-#import "RestoMapController.h"
-#import "RestoMenu.h"
-#import "RestoMenuController.h"
-#import "RestoMenuView.h"
-#import "RestoStore.h"
-#import "UIColor+AppColors.h"
-#import "UINavigationController+ReplaceController.h"
-
-#define kRestoDaysShown 5
-
-@interface RestoMenuController ()
-
-@property (nonatomic, unsafe_unretained) UIScrollView *scrollView;
-@property (nonatomic, unsafe_unretained) SMPageControl *pageControl;
-@property (nonatomic, unsafe_unretained) RestoInfoView *infoSheet;
-@property (nonatomic, unsafe_unretained) RestoMenuView *menuSheetA;
-@property (nonatomic, unsafe_unretained) RestoMenuView *menuSheetB;
-
-@property (nonatomic, strong) NSArray *days;
-@property (nonatomic, strong) NSMutableArray *menus;
-
-@property (nonatomic, assign) NSUInteger pageControlUsed;
-
-@end
-
-@implementation RestoMenuController
-
-#pragma mark Setting up the view & viewcontroller
-
-- (id)init
-{
- if (self = [super init]) {
- // Check for updates
- NSNotificationCenter *center = [NSNotificationCenter defaultCenter];
- [center addObserver:self selector:@selector(reloadMenu)
- name:RestoStoreDidReceiveMenuNotification object:nil];
- [center addObserver:self selector:@selector(reloadInfo)
- name:RestoStoreDidUpdateInfoNotification object:nil];
- [center addObserver:self selector:@selector(applicationDidBecomeActive:)
- name:UIApplicationDidBecomeActiveNotification object:nil];
- }
- return self;
-}
-
-- (void)loadView
-{
-#ifdef __IPHONE_7_0
- if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
- self.edgesForExtendedLayout = UIRectEdgeNone;
- }
-#endif
-
- CGRect bounds = [UIScreen mainScreen].bounds;
- self.view = [[UIView alloc] initWithFrame:bounds];
- self.view.backgroundColor = [UIColor hydraBackgroundColor];
- self.title = @"Resto Menu";
-
- UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:bounds];
- scrollView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- scrollView.pagingEnabled = YES;
- scrollView.delegate = self;
- scrollView.showsHorizontalScrollIndicator = NO;
- [self.view addSubview:scrollView];
- self.scrollView = scrollView;
-
- CGRect pageControlFrame = CGRectMake(0, bounds.size.height - 36, bounds.size.width, 36);
- SMPageControl *pageControl = [[SMPageControl alloc] initWithFrame:pageControlFrame];
- pageControl.autoresizingMask = UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleWidth;
- [pageControl addTarget:self action:@selector(pageChanged:)
- forControlEvents:UIControlEventValueChanged];
- [self.view addSubview:pageControl];
- self.pageControl = pageControl;
-
- // Sheets
- CGSize viewSize = self.scrollView.frame.size;
- CGRect sheetFrame = CGRectMake(20, 20, viewSize.width - 40, viewSize.height - 60);
-
- self.menuSheetA = [self addSheet:[[RestoMenuView alloc] initWithFrame:sheetFrame]];
- self.menuSheetB = [self addSheet:[[RestoMenuView alloc] initWithFrame:sheetFrame]];
- self.infoSheet = [self addSheet:[[RestoInfoView alloc] initWithFrame:sheetFrame]];
-
- // Add button to navigation bar
- UIBarButtonItem *mapButton = [[UIBarButtonItem alloc] initWithTitle:@"Kaart"
- style:UIBarButtonItemStylePlain
- target:self action:@selector(mapButtonTapped:)];
- [self.navigationItem setRightBarButtonItem:mapButton];
-}
-
-- (void)viewDidLoad
-{
- [super viewDidLoad];
-
- // Update views
- [self reloadMenu];
- [self reloadInfo];
-
- // Setup scrollview
- [self updateView:self.menuSheetA toIndex:0];
- [self updateView:self.menuSheetB toIndex:1];
-
- CGSize viewSize = self.scrollView.frame.size;
- self.scrollView.contentSize = CGSizeMake(viewSize.width * (self.days.count + 1), 1);
- self.scrollView.contentOffset = CGPointMake(viewSize.width, 0);
-
- // Setup pageControl
- self.pageControlUsed = 0;
- self.pageControl.numberOfPages = self.days.count + 1;
- [self.pageControl setImageMask:[UIImage imageNamed:@"dot-question"] forPage:0];
- self.pageControl.currentPage = 1;
-}
-
-- (void)viewDidAppear:(BOOL)animated
-{
- [super viewDidAppear:animated];
- GAI_Track(@"Resto Menu");
-}
-
-- (void)applicationDidBecomeActive:(NSNotification *)notification
-{
- // Update days
- NSDate *firstDay = self.days[0];
- [self calculateDays];
-
- // Check if day changed
- if (![firstDay isEqualToDateIgnoringTime:self.days[0]]) {
- [self reloadMenu];
- [self scrollViewDidScroll:self.scrollView];
- }
-}
-
-- (void)viewDidLayoutSubviews
-{
- // Restyle the sheets to keep the shadow the right size
- [self setupSheetStyle:self.menuSheetA];
- [self setupSheetStyle:self.menuSheetB];
- [self setupSheetStyle:self.infoSheet];
-}
-
-- (void)dealloc
-{
- [[NSNotificationCenter defaultCenter] removeObserver:self];
-}
-
-- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
-{
- return (interfaceOrientation == UIInterfaceOrientationPortrait);
-}
-
-#pragma mark - Sheets
-#define kPageCornerRadius 10
-
-- (id)addSheet:(UIView *)contentView
-{
- // Use the outer view for shadows, the contentView uses maskToBounds for rounded corners
- UIView *holderView = [[UIView alloc] initWithFrame:contentView.frame];
- holderView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight;
- [self.scrollView addSubview:holderView];
-
- contentView.frame = holderView.bounds;
- contentView.autoresizingMask = holderView.autoresizingMask;
- [holderView addSubview:contentView];
-
- return contentView;
-}
-
-- (void)setupSheetStyle:(UIView *)contentView
-{
- CALayer *layer = contentView.superview.layer;
- layer.cornerRadius = kPageCornerRadius;
-
- UIBezierPath *shadowPath = [UIBezierPath bezierPathWithRoundedRect:layer.bounds
- cornerRadius:kPageCornerRadius];
- layer.shadowPath = shadowPath.CGPath;
- layer.shadowColor = [UIColor blackColor].CGColor;
- layer.shadowOpacity = 0.3;
- layer.shadowOffset = CGSizeMake(1.5, 3.0);
-
- contentView.layer.cornerRadius = kPageCornerRadius;
- contentView.layer.masksToBounds = YES;
-}
-
-#pragma mark - Buttons
-
-- (void)mapButtonTapped:(id)sender
-{
- RestoMapController *mapController = [[RestoMapController alloc] init];
- [self.navigationController H_replaceViewControllerWith:mapController
- options:UIViewAnimationOptionTransitionFlipFromLeft];
-}
-
-#pragma mark - Loading days & menus
-
-- (void)calculateDays
-{
- NSDate *day = [NSDate date];
- NSMutableArray *days = [NSMutableArray arrayWithCapacity:kRestoDaysShown];
-
- // Find the next 5 days to display
- while (days.count < kRestoDaysShown) {
- if ([day isTypicallyWorkday]) {
- [days addObject:day];
- }
- day = [day dateByAddingDays:1];
- }
- self.days = days;
-}
-
-- (void)reloadMenu
-{
- if (!self.days.count) [self calculateDays];
-
- RestoStore *store = [RestoStore sharedStore];
- NSMutableArray *menus = [[NSMutableArray alloc] init];
- for (NSUInteger i = 0; i < self.days.count; i++) {
- id menu = [store menuForDay:self.days[i]];
- if (!menu) menu = [NSNull null];
- menus[i] = menu;
- }
- self.menus = menus;
-}
-
-- (void)setMenus:(NSMutableArray *)menus
-{
- _menus = menus;
-
- NSUInteger currentIndex = [self.days indexOfObject:self.menuSheetA.day];
- if (currentIndex != NSNotFound) {
- [self.menuSheetA configureWithDay:self.days[currentIndex]
- menu:self.menus[currentIndex]];
- }
-
- NSUInteger nextIndex = [self.days indexOfObject:self.menuSheetB.day];
- if (nextIndex != NSNotFound) {
- [self.menuSheetB configureWithDay:self.days[nextIndex]
- menu:self.menus[nextIndex]];
- }
-}
-
-- (void)reloadInfo
-{
- self.infoSheet.legend = [RestoStore sharedStore].legend;
-}
-
-#pragma mark - View scrolling and page changing
-
-- (void)scrollViewDidScroll:(UIScrollView *)scrollView
-{
- CGFloat pageWidth = scrollView.frame.size.width;
- float fractionalPage = scrollView.contentOffset.x / pageWidth;
-
- if (self.pageControlUsed == 0) {
- self.pageControl.currentPage = round(fractionalPage);
- }
-
- // Nothing needs to change for the InfoView
- if (fractionalPage < 1) return;
-
- NSInteger lowerNumber = floor(fractionalPage) - 1;
- NSInteger upperNumber = lowerNumber + 1;
-
- NSDate *lowerDate = self.days[lowerNumber];
- NSDate *upperDate = nil;
- if (upperNumber < kRestoDaysShown) {
- upperDate = self.days[upperNumber];
- }
-
- // Goal: apply lower and upper date to menuSheetA and menuSheetB
- // with the least amount of changes possible
- if (self.menuSheetA.day != lowerDate && self.menuSheetA.day != upperDate) {
- NSUInteger newIndex = self.menuSheetB.day == upperDate ? lowerNumber : upperNumber;
- [self updateView:self.menuSheetA toIndex:newIndex];
- }
- if (self.menuSheetB.day != lowerDate && self.menuSheetB.day != upperDate) {
- NSUInteger newIndex = self.menuSheetA.day == upperDate ? lowerNumber : upperNumber;
- [self updateView:self.menuSheetB toIndex:newIndex];
- }
-}
-
-- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)sender
-{
- self.pageControlUsed--;
-}
-
-- (void)pageChanged:(UIPageControl *)sender
-{
- DLog(@"UIPageControl requesting page %ld", (long)self.pageControl.currentPage);
-
- CGRect newPage = self.scrollView.bounds;
- newPage.origin.x = newPage.size.width * self.pageControl.currentPage;
- [self.scrollView scrollRectToVisible:newPage animated:YES];
-
- // Keep track of active UIPageControl animations
- self.pageControlUsed++;
-}
-
-- (void)updateView:(RestoMenuView *)view toIndex:(NSInteger)index
-{
- if (index >= kRestoDaysShown || view.day == self.days[index]) return;
-
- CGSize viewSize = self.view.bounds.size;
- CGRect frame = CGRectMake(viewSize.width * (index + 1) + 20, 20,
- viewSize.width - 40, viewSize.height - 60);
- view.superview.frame = frame;
-
- [view configureWithDay:self.days[index] menu:self.menus[index]];
-}
-
-@end
diff --git a/iOS/Hydra/RestoMenuHeader.swift b/iOS/Hydra/RestoMenuHeader.swift
new file mode 100644
index 00000000..26d4b9e2
--- /dev/null
+++ b/iOS/Hydra/RestoMenuHeader.swift
@@ -0,0 +1,66 @@
+//
+// RestoMenuHeader.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 14/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class RestoMenuHeaderView: UIView {
+ @IBOutlet weak var controller: RestoMenuViewController?
+ @IBOutlet weak var infoView: UIView?
+ @IBOutlet weak var day1View: UIView?
+ @IBOutlet weak var day2View: UIView?
+ @IBOutlet weak var day3View: UIView?
+ @IBOutlet weak var day4View: UIView?
+ @IBOutlet weak var day5View: UIView?
+ @IBOutlet weak var mapView: UIView?
+
+ @IBAction func infoViewPressed(gestureRecognizer: UITapGestureRecognizer) {
+ controller?.scrollToIndex(0)
+ }
+
+ @IBAction func viewPressed(gestureRecognizer: UITapGestureRecognizer) {
+ controller?.scrollToIndex((gestureRecognizer.view?.tag)!)
+ }
+
+ func updateDays() {
+ for (index, day) in (controller?.days.enumerate())! {
+ updateView(day, onIndex: index)
+ }
+ }
+
+ func updateView(date: NSDate, onIndex index: Int) {
+ // Index only days so + 1
+ let view = headerViews()[index+1]
+ let dayLabel = view?.viewWithTag(998) as! UILabel
+ let numberLabel = view?.viewWithTag(999) as! UILabel
+
+ let formatter = NSDateFormatter.H_dateFormatterWithAppLocale()
+ formatter.dateFormat = "EE"
+ dayLabel.text = formatter.stringFromDate(date).uppercaseString
+ formatter.dateFormat = "d"
+ numberLabel.text = formatter.stringFromDate(date)
+ }
+
+ func selectedIndex(index: Int) {
+ // modify background of label
+ for view in headerViews() {
+ let numberLabel = view?.viewWithTag(999) as! UILabel
+ numberLabel.backgroundColor = UIColor.clearColor()
+ numberLabel.layer.borderColor = UIColor.clearColor().CGColor
+ }
+ let view = headerViews()[index]
+ let numberLabel = view?.viewWithTag(999) as! UILabel
+ numberLabel.layer.masksToBounds = true
+ numberLabel.layer.borderColor = UIColor.whiteColor().CGColor
+ numberLabel.layer.borderWidth = 2
+ numberLabel.layer.cornerRadius = 15
+ }
+
+ func headerViews() -> [UIView?] {
+ return [infoView, day1View, day2View, day3View, day4View, day5View]
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/RestoMenuInfoCollectionViewCell.swift b/iOS/Hydra/RestoMenuInfoCollectionViewCell.swift
new file mode 100644
index 00000000..528fc724
--- /dev/null
+++ b/iOS/Hydra/RestoMenuInfoCollectionViewCell.swift
@@ -0,0 +1,72 @@
+//
+// RestoMenuInfoCollectionViewCell.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 26/09/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class RestoMenuInfoCollectionViewCell: UICollectionViewCell, UITableViewDataSource, UITableViewDelegate {
+ @IBOutlet weak var tableView: UITableView!
+
+ var legend: [RestoLegendItem]? {
+ didSet {
+ tableView.reloadData()
+ }
+ }
+
+ func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
+ if let legend = self.legend {
+ return legend.count
+ }
+ return 0
+ }
+
+ func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
+ let cell = tableView.dequeueReusableCellWithIdentifier("infoItemCell") as? RestoLegendItemTableViewCell
+
+ cell?.item = legend?[indexPath.item]
+
+ return cell!
+ }
+
+ func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
+ let item = legend?[indexPath.item]
+
+ let size = CGSizeMake(tableView.frame.width - 40, CGFloat.max)
+ let paragraphStyle = NSParagraphStyle()
+ //paragraphStyle.lineBreakMode = NSLineBreakMode.ByWordWrapping
+ //paragraphStyle.alignment = NSTextAlignment.Left
+
+ let attributes = [
+ NSFontAttributeName: UIFont.systemFontOfSize(15),
+ NSParagraphStyleAttributeName: paragraphStyle
+ ]
+
+ let mutableText = NSMutableAttributedString(string: (item?.value)!, attributes: attributes)
+
+ let options = unsafeBitCast(NSStringDrawingOptions.UsesLineFragmentOrigin.rawValue |
+ NSStringDrawingOptions.UsesFontLeading.rawValue,
+ NSStringDrawingOptions.self)
+
+ let labelSize: CGSize = mutableText.boundingRectWithSize(size, options: options, context: nil).size
+
+ return labelSize.height + 5
+ }
+}
+
+class RestoLegendItemTableViewCell: UITableViewCell {
+ @IBOutlet weak var keyLabel: UILabel!
+ @IBOutlet weak var valueLabel: UILabel!
+
+ var item: RestoLegendItem? {
+ didSet {
+ if let item = item {
+ keyLabel.text = item.key
+ valueLabel.text = item.value
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/RestoMenuView.h b/iOS/Hydra/RestoMenuView.h
deleted file mode 100644
index 312bfed8..00000000
--- a/iOS/Hydra/RestoMenuView.h
+++ /dev/null
@@ -1,19 +0,0 @@
-//
-// RestoMenuView.h
-// Hydra
-//
-// Created by Yasser Deceukelier on 22/07/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import
-#import "RestoMenu.h"
-
-@interface RestoMenuView : UIView
-
-@property (nonatomic, strong, readonly) NSDate *day;
-
-- (id)initWithFrame:(CGRect)frame;
-- (void)configureWithDay:(NSDate *)day menu:(RestoMenu *)menu;
-
-@end
diff --git a/iOS/Hydra/RestoMenuView.m b/iOS/Hydra/RestoMenuView.m
deleted file mode 100644
index d9dd0831..00000000
--- a/iOS/Hydra/RestoMenuView.m
+++ /dev/null
@@ -1,259 +0,0 @@
-//
-// RestoMenuView.m
-// Hydra
-//
-// Created by Yasser Deceukelier on 22/07/12.
-// Copyright (c) 2012 Zeus WPI. All rights reserved.
-//
-
-#import "RestoMenuView.h"
-#import "NSDate+Utilities.h"
-#import "NSDateFormatter+AppLocale.h"
-
-@interface RestoMenuView ()
-
-@property (nonatomic, strong) NSDate *day;
-@property (nonatomic, strong) RestoMenu *menu;
-
-@property (nonatomic, unsafe_unretained) UIView *contentView;
-@property (nonatomic, unsafe_unretained) UILabel *dateHeader;
-@property (nonatomic, unsafe_unretained) UITableView *tableView;
-@property (nonatomic, unsafe_unretained) UIImageView *closedView;
-@property (nonatomic, unsafe_unretained) UIActivityIndicatorView *spinner;
-
-@property (nonatomic, strong) UIView *soupHeader;
-@property (nonatomic, strong) UIView *meatHeader;
-@property (nonatomic, strong) UIView *vegetableHeader;
-
-@end
-
-@implementation RestoMenuView
-
-#pragma mark - Constants
-
-#define kDateHeaderHeight 45
-#define kSectionHeaderHeight 48
-#define kRowHeight 22
-#define kCellLabelTag 101
-
-#pragma mark - Properties and init
-
-- (id)initWithFrame:(CGRect)frame
-{
- if (self = [super initWithFrame:frame]) {
- [self createView];
- }
- return self;
-}
-
-- (void)configureWithDay:(NSDate *)day menu:(id)menu
-{
- if (![self.day isEqual:day] || ![self.menu isEqual:menu]) {
- self.day = day;
- self.menu = (menu != [NSNull null]) ? menu : nil;
- [self reloadData];
- }
-}
-
-- (void)createView
-{
- self.backgroundColor = [UIColor whiteColor];
-
- CGRect headerFrame = CGRectMake(0, 0, self.frame.size.width, kDateHeaderHeight);
- UIImageView *header = [[UIImageView alloc] initWithFrame:headerFrame];
- header.contentMode = UIViewContentModeScaleToFill;
- header.image = [UIImage imageNamed:@"header-bg"];
- [self addSubview:header];
-
- CGRect dateHeaderFrame = CGRectMake(0, 3, self.frame.size.width, kDateHeaderHeight - 3);
- UILabel *dateHeader = [[UILabel alloc] initWithFrame:dateHeaderFrame];
- dateHeader.font = [UIFont boldSystemFontOfSize:19];
- dateHeader.textAlignment = NSTextAlignmentCenter;
- dateHeader.textColor = [UIColor whiteColor];
- dateHeader.backgroundColor = [UIColor clearColor];
- dateHeader.shadowColor = [UIColor blackColor];
- dateHeader.shadowOffset = CGSizeMake(0, 2);
- [header addSubview:dateHeader];
- self.dateHeader = dateHeader;
-
- CGRect tableFrame = CGRectMake(0, headerFrame.size.height, self.frame.size.width,
- self.bounds.size.height - headerFrame.size.height - 3);
- UITableView *tableView = [[UITableView alloc] initWithFrame:tableFrame style:UITableViewStylePlain];
- tableView.delegate = self;
- tableView.dataSource = self;
- tableView.bounces = NO;
- tableView.rowHeight = kRowHeight;
- tableView.separatorColor = [UIColor clearColor];
- tableView.allowsSelection = NO;
- tableView.contentInset = UIEdgeInsetsMake(0, 0, 5, 0);
- tableView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
- [self addSubview:tableView];
- self.tableView = tableView;
-
- UIActivityIndicatorView *spinner = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
- spinner.center = CGPointMake(CGRectGetMidX(self.bounds), CGRectGetMidY(self.bounds));
- spinner.autoresizingMask = UIViewAutoresizingFlexibleTopMargin
- | UIViewAutoresizingFlexibleBottomMargin;
- [self addSubview:spinner];
- self.spinner = spinner;
-
- CGRect closedFrame = CGRectMake(0, kDateHeaderHeight, self.frame.size.width,
- self.frame.size.height - 2*kDateHeaderHeight);
- UIImageView *closedView = [[UIImageView alloc] initWithFrame:closedFrame];
- closedView.image = [UIImage imageNamed:@"resto-closed.jpg"];
- closedView.contentMode = UIViewContentModeCenter;
- closedView.autoresizingMask = UIViewAutoresizingFlexibleTopMargin
- | UIViewAutoresizingFlexibleBottomMargin;
- [self addSubview:closedView];
- self.closedView = closedView;
-}
-
-- (void)reloadData
-{
- NSString *dateString;
- if ([self.day isToday]) dateString = @"Vandaag";
- else if ([self.day isTomorrow]) dateString = @"Morgen";
- else {
- // Create capitalized, formatted string
- NSDateFormatter *formatter = [NSDateFormatter H_dateFormatterWithAppLocale];
- [formatter setDateFormat:@"EEEE d MMMM"];
- dateString = [formatter stringFromDate:self.day];
- dateString = [dateString stringByReplacingCharactersInRange:NSMakeRange(0, 1)
- withString:[[dateString substringToIndex:1] capitalizedString]];
- }
- self.dateHeader.text = dateString;
-
- self.spinner.hidden = (self.menu != nil);
- if (!self.spinner.hidden) [self.spinner startAnimating];
- self.closedView.hidden = (self.menu == nil || self.menu.open);
-
- [self.tableView reloadData];
-}
-
-#pragma mark - Table view datasource
-
-- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
-{
- return (self.menu.open ? 4 : 0);
-}
-
-- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
-{
- switch (section) {
- case 1: return 1;
- case 2: return self.menu.meat.count;
- case 3: return self.menu.vegetables.count;
- default: return 0;
- }
-}
-
-- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
-{
- UILabel *textLabel;
-
- static NSString *cellIdentifier = @"RestoMenuViewCell";
- UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
- if(!cell) {
- cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1
- reuseIdentifier:cellIdentifier];
- CGRect labelFrame = CGRectMake(10, 0, self.tableView.frame.size.width - 70, kRowHeight - 1);
- textLabel = [[UILabel alloc] initWithFrame:labelFrame];
- textLabel.tag = kCellLabelTag;
- textLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
- [cell.contentView addSubview:textLabel];
-
- cell.detailTextLabel.textColor = textLabel.textColor;
- }
- else {
- textLabel = (UILabel *)[cell viewWithTag:kCellLabelTag];
- }
-
- textLabel.font = [UIFont systemFontOfSize:15];
- cell.detailTextLabel.font = textLabel.font;
-
- if(indexPath.section == 1) {
- textLabel.text = self.menu.soup.name;
- cell.detailTextLabel.text = self.menu.soup.price;
- }
- else if (indexPath.section == 2) {
- RestoMenuItem *item = self.menu.meat[indexPath.row];
-
- if(item.recommended) {
- textLabel.font = [UIFont boldSystemFontOfSize:15];
- cell.detailTextLabel.font = textLabel.font;
- }
-
- textLabel.text = item.name;
- cell.detailTextLabel.text = item.price;
- }
- else { // section == 3
- textLabel.text = (self.menu.vegetables)[indexPath.row];
- }
-
- return cell;
-}
-
-#pragma mark - Table view delegate
-
-// Using footers of the previous section instead of headers so they scroll
-- (CGFloat)tableView:(UITableView *)tableView heightForFooterInSection:(NSInteger)section {
- return (section < 3) ? kSectionHeaderHeight : 0;
-}
-
-- (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
-{
- if(section == 0) {
- if(!self.soupHeader) {
- UIImage *soupImage = [UIImage imageNamed:@"icon-soup"];
- self.soupHeader = [self headerWithImage:soupImage andTitle:@"Soep"];
- }
- return self.soupHeader;
- }
- else if(section == 1) {
- if(!self.meatHeader) {
- UIImage *meatImage = [UIImage imageNamed:@"icon-meal"];
- self.meatHeader = [self headerWithImage:meatImage andTitle:@"Vlees en veggie"];
- }
- return self.meatHeader;
- }
- else if(section == 2) {
- if(!self.vegetableHeader) {
- UIImage *vegetableImage = [UIImage imageNamed:@"icon-vegetables"];
- self.vegetableHeader = [self headerWithImage:vegetableImage andTitle:@"Groenten"];
- }
- return self.vegetableHeader;
- }
- else {
- return nil;
- }
-}
-
-#pragma mark - Utility methods
-
-- (UIView *)headerWithImage:(UIImage *)image andTitle:(NSString *)title
-{
- CGRect headerFrame = CGRectMake(0, 0, self.bounds.size.width, kSectionHeaderHeight);
- UIView *header = [[UIView alloc] initWithFrame:headerFrame];
- header.backgroundColor = [UIColor whiteColor];
-
- UIFont *font = [UIFont fontWithName:@"Futura-Medium" size:18];
- CGSize textSize = [title sizeWithAttributes:@{NSFontAttributeName: font}];
- CGFloat offsetX = roundf((self.bounds.size.width - textSize.width - 34) / 2);
-
- CGRect iconFrame = CGRectMake(offsetX - 20, 13, 30, 30);
- UIImageView *iconView = [[UIImageView alloc] initWithFrame:iconFrame];
- iconView.image = image;
- [header addSubview:iconView];
-
- CGRect titleFrame = CGRectMake(offsetX + 17, 19, textSize.width, 22);
- UILabel *titleLabel = [[UILabel alloc] initWithFrame:titleFrame];
- titleLabel.textAlignment = NSTextAlignmentCenter;
- titleLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters;
- titleLabel.font = font;
- titleLabel.text = title;
- [header addSubview:titleLabel];
-
- return header;
-}
-
-@end
diff --git a/iOS/Hydra/RestoMenuViewController.swift b/iOS/Hydra/RestoMenuViewController.swift
new file mode 100644
index 00000000..3d0ea174
--- /dev/null
+++ b/iOS/Hydra/RestoMenuViewController.swift
@@ -0,0 +1,231 @@
+//
+// RestoMenuViewController.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 14/08/15.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import UIKit
+
+class RestoMenuViewController: UIViewController {
+ @IBOutlet weak var collectionView: UICollectionView?
+ @IBOutlet weak var restoMenuHeader: RestoMenuHeaderView?
+
+ var days: [NSDate] = []
+ var menus: [RestoMenu?] = []
+ var legend: [RestoLegendItem] = []
+
+ var currentIndex: Int = 1
+
+ override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: NSBundle?) {
+ super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
+ initialize()
+ }
+
+ required init?(coder aDecoder: NSCoder) {
+ super.init(coder: aDecoder)
+ initialize()
+ }
+
+ func initialize() {
+ let center = NSNotificationCenter.defaultCenter()
+ center.addObserver(self, selector: "reloadMenu", name: RestoStoreDidReceiveMenuNotification, object: nil)
+ center.addObserver(self, selector: "reloadInfo", name: RestoStoreDidUpdateInfoNotification, object: nil)
+ center.addObserver(self, selector: "applicationDidBecomeActive:", name: UIApplicationDidBecomeActiveNotification, object: nil)
+
+ days = calculateDays()
+ }
+
+ deinit {
+ NSNotificationCenter.defaultCenter().removeObserver(self)
+ }
+
+ override func viewDidLoad() {
+ super.viewDidLoad()
+ self.loadMenu()
+ self.legend = (RestoStore.sharedStore().legend as? [RestoLegendItem])!
+
+ // update days and reloadData
+ self.restoMenuHeader?.updateDays()
+ //self.collectionView?.reloadData() // Uncomment when bug is fixed
+ //self.scrollToIndex(self.currentIndex, animated: false)
+
+ // REMOVE ME IF THE BUG IS FIXED, THIS IS UGLY
+ NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: Selector("refreshDataTimer:"), userInfo: nil, repeats: false)
+ }
+
+ override func viewDidAppear(animated: Bool) {
+ UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: animated)
+ }
+
+ func refreshDataTimer(timer: NSTimer){ // REMOVE ME WHEN THE BUG IS FIXED
+ self.collectionView?.reloadData()
+ self.scrollToIndex(self.currentIndex, animated: false)
+ }
+
+ override func viewWillAppear(animated: Bool) {
+ super.viewWillAppear(animated)
+
+ self.days = calculateDays()
+ self.restoMenuHeader?.updateDays()
+ //do not hide if in moreController
+ if self.parentViewController != self.tabBarController?.moreNavigationController {
+ if UIApplication.sharedApplication().statusBarStyle != .LightContent {
+ UIApplication.sharedApplication().setStatusBarStyle(.LightContent, animated: false)
+ }
+ self.navigationController?.navigationBarHidden = true
+ }
+ // scroll to today
+ self.scrollToIndex(currentIndex, animated: false)
+ }
+
+ override func viewWillDisappear(animated: Bool) {
+ super.viewWillDisappear(animated)
+
+ self.navigationController?.navigationBarHidden = false
+ UIApplication.sharedApplication().setStatusBarStyle(.Default, animated: false)
+ }
+
+ override func didRotateFromInterfaceOrientation(fromInterfaceOrientation: UIInterfaceOrientation) {
+ // this is called when changing layout :)
+ self.collectionView?.collectionViewLayout.invalidateLayout()
+ self.scrollToIndex(currentIndex, animated: true)
+ }
+
+ func loadMenu() {
+ // New menus are available
+ let store = RestoStore.sharedStore()
+ var menus = [RestoMenu?]()
+ for day in days {
+ let menu = store.menuForDay(day) as RestoMenu?
+ menus.append(menu)
+ }
+ self.menus = menus
+ }
+
+ func reloadMenu() {
+ debugPrint("Reloading menu")
+ self.loadMenu()
+ self.collectionView?.reloadData()
+ }
+
+ func reloadInfo() {
+ // New info is available
+ debugPrint("Reloading info")
+ self.legend = (RestoStore.sharedStore().legend as? [RestoLegendItem])!
+ self.collectionView?.reloadData()
+ }
+
+ func applicationDidBecomeActive(notification: NSNotification) {
+ let firstDay = self.days[0]
+ self.days = self.calculateDays()
+
+ if !firstDay.isEqualToDateIgnoringTime(self.days[0]) {
+ self.reloadMenu()
+ }
+ }
+
+ func calculateDays() -> [NSDate] {
+ // Find the next x days to display
+ var day = NSDate()
+ var days = [NSDate]()
+ while (days.count < 5) {
+ if day.isTypicallyWorkday() {
+ days.append(day)
+ }
+ day = day.dateByAddingDays(1)
+ }
+ return days
+ }
+
+ // MARK: - Headerview actions
+
+ @IBAction func mapViewPressed(gestureRecognizer: UITapGestureRecognizer) {
+ debugPrint("Map view pressed!")
+ if let navigationController = self.navigationController {
+ navigationController.pushViewController(RestoMapController(), animated: true)
+ } else {
+ fatalError("An navigationcontroller should be present")
+ }
+ }
+}
+
+// MARK: - Collection view data source & delegate
+extension RestoMenuViewController: UICollectionViewDataSource, UICollectionViewDelegate {
+ func collectionView(collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
+ return self.days.count + 1
+ }
+
+ func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {
+
+ switch indexPath.row {
+ case 0: // info cell
+ let cell = collectionView.dequeueReusableCellWithReuseIdentifier("infoCell", forIndexPath: indexPath) as! RestoMenuInfoCollectionViewCell
+
+ cell.legend = self.legend
+ return cell
+ case 1...self.days.count:
+ let menu = self.menus[indexPath.row-1]
+ if menu!.open {
+ let cell = collectionView.dequeueReusableCellWithReuseIdentifier("restoMenuOpenCell", forIndexPath: indexPath) as! RestoMenuCollectionCell
+
+ cell.restoMenu = menu
+ return cell
+ }
+
+ return collectionView.dequeueReusableCellWithReuseIdentifier("restoMenuClosedCell", forIndexPath: indexPath)
+ default:
+ debugPrint("Shouldn't be here")
+ return collectionView.dequeueReusableCellWithReuseIdentifier("infoCell", forIndexPath: indexPath)
+ }
+ }
+
+ func collectionView(collectionView: UICollectionView, layout collectionViewLayout: UICollectionViewLayout, sizeForItemAtIndexPath indexPath: NSIndexPath) -> CGSize {
+ return CGSizeMake(collectionView.frame.size.width, collectionView.frame.size.height) // cells always fill the whole screen
+ }
+}
+
+extension RestoMenuViewController: UIScrollViewDelegate {
+ func scrollViewWillEndDragging(scrollView: UIScrollView, withVelocity velocity: CGPoint, targetContentOffset: UnsafeMutablePointer) {
+ // Stop if velocity is 0
+ if velocity.x == 0{
+ return
+ }
+
+ let pageWidth = Float(self.collectionView!.frame.size.width)
+ let currentOffset = Float(scrollView.contentOffset.x)
+ let targetOffset = Float(targetContentOffset.memory.x) + pageWidth/2
+
+ let index = max(min(Int(round(targetOffset / pageWidth))-1, (self.collectionView?.numberOfItemsInSection(0))!-1),0)
+
+ targetContentOffset.memory = CGPointMake(CGFloat(currentOffset), 0)
+
+ self.scrollToIndex(index, animated: true)
+ }
+
+ func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
+ if decelerate {
+ let index = Int((scrollView.contentOffset.x + self.collectionView!.frame.size.width/2) / self.collectionView!.frame.size.width)
+ scrollToIndex(index)
+ }
+ }
+}
+
+// MARK: - Header view actions
+extension RestoMenuViewController {
+ func scrollToIndex(index: Int, animated: Bool = true) {
+ self.collectionView?.scrollToItemAtIndexPath(NSIndexPath(forRow: index, inSection: 0), atScrollPosition: UICollectionViewScrollPosition.CenteredHorizontally, animated: animated)
+ self.restoMenuHeader?.selectedIndex(index)
+ currentIndex = index
+ }
+
+ func scrollToDate(date: NSDate) {
+ for (index, day) in days.enumerate() {
+ if day.dateAtStartOfDay().isEqualToDate(date.dateAtStartOfDay()) {
+ self.scrollToIndex(index+1)
+ return
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/RestoStore.swift b/iOS/Hydra/RestoStore.swift
new file mode 100644
index 00000000..d0837544
--- /dev/null
+++ b/iOS/Hydra/RestoStore.swift
@@ -0,0 +1,37 @@
+//
+// RestoStore.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 20/11/2015.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import Foundation
+
+extension RestoStore: FeedItemProtocol {
+ func feedItems() -> [FeedItem] {
+ var day = NSDate()
+ if day.hour > 20 {
+ day = day.dateByAddingDays(1)
+ }
+ var feedItems = [FeedItem]()
+
+ // Find the next x days to display
+ while (feedItems.count < 5) { //TODO: replace with var
+ if day.isTypicallyWorkday() {
+ var menu = menuForDay(day)
+
+ if (menu == nil) {
+ menu = RestoMenu()
+ menu.open = false
+ menu.day = day
+ }
+
+ feedItems.append(FeedItem(itemType: .RestoItem, object: menu, priority: 1000 - 100*feedItems.count))
+ }
+ day = day.dateByAddingDays(1)
+ }
+
+ return feedItems
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/SchamperDetailViewController.m b/iOS/Hydra/SchamperDetailViewController.m
index 6cbd7403..6d764f5a 100644
--- a/iOS/Hydra/SchamperDetailViewController.m
+++ b/iOS/Hydra/SchamperDetailViewController.m
@@ -35,11 +35,7 @@ - (void)viewDidLoad
{
[super viewDidLoad];
-#ifdef __IPHONE_7_0
- if ([self respondsToSelector:@selector(setAutomaticallyAdjustsScrollViewInsets:)]) {
- self.automaticallyAdjustsScrollViewInsets = NO;
- }
-#endif
+ self.automaticallyAdjustsScrollViewInsets = NO;
// Set tracked name
self.trackedViewName = [@"Schamper > " stringByAppendingString:self.article.title];
@@ -63,7 +59,7 @@ - (void)viewDidLoad
UIScrollView *scrollView = self.webView.scrollView;
scrollView.delegate = self;
- CGFloat scrollOffset = IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0") ? 64 : 44;
+ CGFloat scrollOffset = 64;
scrollView.contentInset = UIEdgeInsetsMake(scrollOffset, 0, 0, 0);
scrollView.scrollIndicatorInsets = scrollView.contentInset;
@@ -160,13 +156,8 @@ - (void)setNavigationBarHidden:(BOOL)hide
// This will cause a recursive call in this method
[self.navigationController setNavigationBarHidden:hide animated:YES];
- if (IOS_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
- [[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
- scrollView.contentInset = UIEdgeInsetsMake(hide ? 0 : 64, 0, 0, 0);
- }
- else {
- scrollView.contentInset = UIEdgeInsetsMake(hide ? 0 : 44, 0, 0, 0);
- }
+ [[UIApplication sharedApplication] setStatusBarHidden:hide withAnimation:UIStatusBarAnimationSlide];
+ scrollView.contentInset = UIEdgeInsetsMake(hide ? 0 : 64, 0, 0, 0);
scrollView.scrollIndicatorInsets = scrollView.contentInset;
self.animationActive = false;
diff --git a/iOS/Hydra/SchamperStore.swift b/iOS/Hydra/SchamperStore.swift
new file mode 100644
index 00000000..1ac703b9
--- /dev/null
+++ b/iOS/Hydra/SchamperStore.swift
@@ -0,0 +1,30 @@
+//
+// SchamperStore.swift
+// Hydra
+//
+// Created by Feliciaan De Palmenaer on 20/11/2015.
+// Copyright © 2015 Zeus WPI. All rights reserved.
+//
+
+import Foundation
+
+extension SchamperStore: FeedItemProtocol {
+ func feedItems() -> [FeedItem] {
+ var feedItems = [FeedItem]()
+ if let articles = articles as? [SchamperArticle] {
+ for article in articles { //TODO: test articles and sort them
+ let daysOld = article.date.daysBeforeDate(NSDate())
+ var priority = 999
+ if !article.read {
+ priority = priority - daysOld*40
+ } else {
+ priority = priority - daysOld*150
+ }
+ if priority > 0 {
+ feedItems.append(FeedItem(itemType: .SchamperNewsItem, object: article, priority: priority))
+ }
+ }
+ }
+ return feedItems
+ }
+}
\ No newline at end of file
diff --git a/iOS/Hydra/SchamperViewController.m b/iOS/Hydra/SchamperViewController.m
index afbbae8e..c967a661 100644
--- a/iOS/Hydra/SchamperViewController.m
+++ b/iOS/Hydra/SchamperViewController.m
@@ -77,6 +77,14 @@ - (void)viewDidAppear:(BOOL)animated
}
}
+- (void)viewWillAppear:(BOOL)animated
+{
+ [super viewWillAppear:animated];
+
+ // Reload data to show just read articles
+ [self.tableView reloadData];
+}
+
- (void)viewWillDisappear:(BOOL)animated
{
[super viewWillDisappear:animated];
@@ -110,10 +118,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
reuseIdentifier:CellIdentifier];
cell.detailTextLabel.textColor = [UIColor colorWithWhite:0.3 alpha:1];
- // iOS7
- if ([cell respondsToSelector:@selector(setSeparatorInset:)]) {
- cell.separatorInset = UIEdgeInsetsZero;
- }
+ cell.separatorInset = UIEdgeInsetsZero;
}
SchamperArticle *article = self.articles[indexPath.row];
diff --git a/iOS/Hydra/UrgentPlayer.m b/iOS/Hydra/UrgentPlayer.m
index 7416ba63..209e86aa 100644
--- a/iOS/Hydra/UrgentPlayer.m
+++ b/iOS/Hydra/UrgentPlayer.m
@@ -20,6 +20,8 @@
#define kShowResourcePath @"http://urgent.fm/nowplaying/program.php"
#define kStreamResourcePath @"http://urgent.stream.flumotion.com/urgent/high.mp3.m3u"
+#define UrgentNowPlayingEnabled 0
+
NSString *const UrgentPlayerDidUpdateSongNotification =
@"UrgentPlayerDidUpdateSongNotification";
NSString *const UrgentPlayerDidUpdateShowNotification =
@@ -163,6 +165,7 @@ - (void)audioRouteChanged:(NSNotification *)notification
- (void)playerStateChanged
{
+#if UrgentNowPlayingEnabled
// Update timers
if ([self isPlaying]) {
// The state of updateSongTimer and updateShowTimer should always be equal
@@ -176,10 +179,11 @@ - (void)playerStateChanged
self.currentSong = nil;
self.previousSong = nil;
}
-
[self updateNowPlaying];
+#endif
}
+#if UrgentNowPlayingEnabled
- (void)updateNowPlaying
{
MPNowPlayingInfoCenter *center = [MPNowPlayingInfoCenter defaultCenter];
@@ -293,6 +297,7 @@ - (void)showUpdateTimerFired:(NSTimer *)sender
}
}];
}
+#endif
- (void)fetchString:(NSString *)resource withCompletion:(void (^)(NSString *result))completion
{
diff --git a/iOS/Hydra/UrgentViewController.m b/iOS/Hydra/UrgentViewController.m
index 8c425a76..4b1f22e6 100644
--- a/iOS/Hydra/UrgentViewController.m
+++ b/iOS/Hydra/UrgentViewController.m
@@ -46,11 +46,7 @@ - (void)viewDidLoad
{
[super viewDidLoad];
-#ifdef __IPHONE_7_0
- if ([self respondsToSelector:@selector(setEdgesForExtendedLayout:)]) {
- self.edgesForExtendedLayout = UIRectEdgeNone;
- }
-#endif
+ self.edgesForExtendedLayout = UIRectEdgeNone;
// Set state for highlighted|selected
UIImage *selectedImage = [self.playButton imageForState:UIControlStateSelected];
@@ -82,6 +78,9 @@ - (void)viewDidLoad
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
+ if (self.parentViewController != self.tabBarController.moreNavigationController) {
+ [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent];
+ }
GAI_Track(@"Urgent");
}
@@ -96,6 +95,11 @@ - (void)viewWillAppear:(BOOL)animated
[MarqueeLabel controllerViewAppearing:self];
}
+- (void)viewWillDisappear:(BOOL)animated
+{
+ [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleDefault];
+}
+
#pragma mark - Buttons
- (void)playButtonTapped:(id)sender
diff --git a/iOS/Hydra/nl.lproj/DashboardViewController.xib b/iOS/Hydra/nl.lproj/DashboardViewController.xib
deleted file mode 100644
index a2cf4f44..00000000
--- a/iOS/Hydra/nl.lproj/DashboardViewController.xib
+++ /dev/null
@@ -1,684 +0,0 @@
-
-
-
- 1280
- 12F37
- 4510
- 1187.39
- 626.00
-
-
- IBProxyObject
- IBUIButton
- IBUIImageView
- IBUIView
-
-
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
-
-
-
-
-
-
-
- NO
-
-
-
- view
-
-
-
- 3
-
-
-
- activitiesButton
-
-
-
- 44
-
-
-
- infoButton
-
-
-
- 46
-
-
-
- newsButton
-
-
-
- 47
-
-
-
- restoButton
-
-
-
- 48
-
-
-
- schamperButton
-
-
-
- 49
-
-
-
- urgentButton
-
-
-
- 56
-
-
-
- feedbackButton
-
-
-
- 57
-
-
-
- preferencesButton
-
-
-
- 60
-
-
-
- showNews:
-
-
- 7
-
- 19
-
-
-
- showActivities:
-
-
- 7
-
- 32
-
-
-
- showInfo:
-
-
- 7
-
- 33
-
-
-
- showUrgent:
-
-
- 7
-
- 54
-
-
-
- showResto:
-
-
- 7
-
- 34
-
-
-
- showSchamper:
-
-
- 7
-
- 37
-
-
-
- showFeedbackView:
-
-
- 7
-
- 53
-
-
-
- showPreferences:
-
-
- 7
-
- 61
-
-
-
-
-
- 0
-
-
-
-
-
- 1
-
-
-
-
-
-
-
-
-
-
-
-
-
- -1
-
-
- File's Owner
-
-
- -2
-
-
-
-
- 18
-
-
- Button - Nieuws
-
-
- 22
-
-
- Button - Activiteiten
-
-
- 24
-
-
- Button - Info
-
-
- 26
-
-
- Button - GSR
-
-
- 28
-
-
- Button - Resto
-
-
- 30
-
-
- Button - Schamper
-
-
- pbl-6n-bXm
-
-
-
-
-
-
-
-
-
-
- 5
-
-
-
-
- 6
-
-
-
-
- 52
-
-
-
-
- 58
-
-
-
-
-
-
- DashboardViewController
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- UIResponder
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- BadgedButton
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- BadgedButton
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- BadgedButton
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- BadgedButton
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- BadgedButton
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- BadgedButton
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
- com.apple.InterfaceBuilder.IBCocoaTouchPlugin
-
-
-
-
-
-
-
- 0
- IBCocoaTouchFramework
- YES
-
- com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS
-
-
-
- com.apple.InterfaceBuilder.CocoaTouchPlugin.InterfaceBuilder3
-
-
- YES
- 3
-
- {137, 100}
- {137, 100}
- {34, 34}
- {137, 100}
- {137, 100}
- {137, 100}
- {137, 100}
- {137, 100}
- {137, 100}
- {137, 100}
- {137, 100}
- {34, 34}
- {137, 100}
- {137, 100}
- {1, 94}
- {134, 50}
-
- 3742
-
-
diff --git a/iOS/Hydra/nl.lproj/UrgentViewController.xib b/iOS/Hydra/nl.lproj/UrgentViewController.xib
index 4f7df0c7..f392622e 100644
--- a/iOS/Hydra/nl.lproj/UrgentViewController.xib
+++ b/iOS/Hydra/nl.lproj/UrgentViewController.xib
@@ -1,9 +1,9 @@
-
+
-
+
@@ -18,17 +18,19 @@
-
+
+
-
+
+
@@ -144,23 +155,27 @@
+
+
@@ -200,6 +215,7 @@
+
diff --git a/iOS/Images/home-background.png b/iOS/Images/home-background.png
new file mode 100644
index 00000000..75e43378
Binary files /dev/null and b/iOS/Images/home-background.png differ
diff --git a/iOS/Images/home-button-bar.png b/iOS/Images/home-button-bar.png
new file mode 100644
index 00000000..6f487d30
Binary files /dev/null and b/iOS/Images/home-button-bar.png differ
diff --git a/iOS/Images/home-header.png b/iOS/Images/home-header.png
new file mode 100644
index 00000000..a8f40b4c
Binary files /dev/null and b/iOS/Images/home-header.png differ
diff --git a/iOS/Images/home-zeus.png b/iOS/Images/home-zeus.png
new file mode 100644
index 00000000..e35c6066
Binary files /dev/null and b/iOS/Images/home-zeus.png differ
diff --git a/iOS/Images/resto-map-icon.png b/iOS/Images/resto-map-icon.png
new file mode 100644
index 00000000..a38c0eda
Binary files /dev/null and b/iOS/Images/resto-map-icon.png differ
diff --git a/iOS/Images/resto-map-icon@2x.png b/iOS/Images/resto-map-icon@2x.png
new file mode 100644
index 00000000..ab2d07af
Binary files /dev/null and b/iOS/Images/resto-map-icon@2x.png differ
diff --git a/iOS/Images/schamper.png b/iOS/Images/schamper.png
new file mode 100644
index 00000000..063b7132
Binary files /dev/null and b/iOS/Images/schamper.png differ
diff --git a/iOS/Images/tabbar-activities.png b/iOS/Images/tabbar-activities.png
new file mode 100644
index 00000000..377d985f
Binary files /dev/null and b/iOS/Images/tabbar-activities.png differ
diff --git a/iOS/Images/tabbar-activities@2x.png b/iOS/Images/tabbar-activities@2x.png
new file mode 100644
index 00000000..b9373ce1
Binary files /dev/null and b/iOS/Images/tabbar-activities@2x.png differ
diff --git a/iOS/Images/tabbar-home.png b/iOS/Images/tabbar-home.png
new file mode 100644
index 00000000..9f61d7bf
Binary files /dev/null and b/iOS/Images/tabbar-home.png differ
diff --git a/iOS/Images/tabbar-home@2x.png b/iOS/Images/tabbar-home@2x.png
new file mode 100644
index 00000000..3094f5be
Binary files /dev/null and b/iOS/Images/tabbar-home@2x.png differ
diff --git a/iOS/Images/tabbar-info.png b/iOS/Images/tabbar-info.png
new file mode 100644
index 00000000..691eb124
Binary files /dev/null and b/iOS/Images/tabbar-info.png differ
diff --git a/iOS/Images/tabbar-info@2x.png b/iOS/Images/tabbar-info@2x.png
new file mode 100644
index 00000000..8989b51b
Binary files /dev/null and b/iOS/Images/tabbar-info@2x.png differ
diff --git a/iOS/Images/tabbar-news.png b/iOS/Images/tabbar-news.png
new file mode 100644
index 00000000..33f2c01c
Binary files /dev/null and b/iOS/Images/tabbar-news.png differ
diff --git a/iOS/Images/tabbar-news@2x.png b/iOS/Images/tabbar-news@2x.png
new file mode 100644
index 00000000..285e4602
Binary files /dev/null and b/iOS/Images/tabbar-news@2x.png differ
diff --git a/iOS/Images/tabbar-resto.png b/iOS/Images/tabbar-resto.png
new file mode 100644
index 00000000..3d33d461
Binary files /dev/null and b/iOS/Images/tabbar-resto.png differ
diff --git a/iOS/Images/tabbar-resto@2x.png b/iOS/Images/tabbar-resto@2x.png
new file mode 100644
index 00000000..95fd2b38
Binary files /dev/null and b/iOS/Images/tabbar-resto@2x.png differ
diff --git a/iOS/Images/tabbar-schamper.png b/iOS/Images/tabbar-schamper.png
new file mode 100644
index 00000000..616abac8
Binary files /dev/null and b/iOS/Images/tabbar-schamper.png differ
diff --git a/iOS/Images/tabbar-schamper@2x.png b/iOS/Images/tabbar-schamper@2x.png
new file mode 100644
index 00000000..348c509f
Binary files /dev/null and b/iOS/Images/tabbar-schamper@2x.png differ
diff --git a/iOS/Images/tabbar-settings.png b/iOS/Images/tabbar-settings.png
new file mode 100644
index 00000000..36831bab
Binary files /dev/null and b/iOS/Images/tabbar-settings.png differ
diff --git a/iOS/Images/tabbar-settings@2x.png b/iOS/Images/tabbar-settings@2x.png
new file mode 100644
index 00000000..38ae36e7
Binary files /dev/null and b/iOS/Images/tabbar-settings@2x.png differ
diff --git a/iOS/Images/tabbar-urgent.png b/iOS/Images/tabbar-urgent.png
new file mode 100644
index 00000000..6153bd52
Binary files /dev/null and b/iOS/Images/tabbar-urgent.png differ
diff --git a/iOS/Images/tabbar-urgent@2x.png b/iOS/Images/tabbar-urgent@2x.png
new file mode 100644
index 00000000..2ea6225b
Binary files /dev/null and b/iOS/Images/tabbar-urgent@2x.png differ
diff --git a/iOS/Podfile.lock b/iOS/Podfile.lock
index 6949a843..5902decf 100644
--- a/iOS/Podfile.lock
+++ b/iOS/Podfile.lock
@@ -108,4 +108,4 @@ SPEC CHECKSUMS:
VTAcknowledgementsViewController: f2391b007c3abafd3b3afccda7d8914a59b44309
XMLReader: c7e54b707c368e2fa545d8313276b4de13a36ff5
-COCOAPODS: 0.36.3
+COCOAPODS: 0.38.2
diff --git a/iOS/Resources/Associations.plist b/iOS/Resources/Associations.plist
deleted file mode 100644
index 5045085f..00000000
--- a/iOS/Resources/Associations.plist
+++ /dev/null
@@ -1,1058 +0,0 @@
-
-
-
-
-
- displayName
- Chemica
- internalName
- CHEMICA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Dentalia
- internalName
- DENTALIA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Filologica
- internalName
- FILOLOGICA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Faculteiten Konvent
- internalName
- FKCENTRAAL
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Gentse Biologische Kring
- internalName
- GBK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Geografica
- internalName
- GEOGRAFI
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Geologica
- internalName
- GEOLOGIC
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Gentse Farma Kring
- internalName
- GFK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Hermes
- internalName
- HERMES
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- HILOK
- fullName
- Hoger instituut voor lichamelijke opvoeding en kinesitherapie
- internalName
- HILOK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Kunsthistorische kring
- internalName
- KHK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Kring Moraal en Filosofie
- internalName
- KMF
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Moeder lies
- internalName
- LIES
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Lila
- internalName
- LILA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Lombrosiana
- internalName
- LOMBRO
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Oosterse Afrikaanse Kring
- internalName
- OAK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Politeia
- internalName
- POLITEIA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Slavia
- internalName
- SLAVIA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Biomedische Kring
- internalName
- VBK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Diergeneeskundige Kring
- internalName
- VDK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Economische Kring
- internalName
- VEK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- VeTo
- internalName
- VETO
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Geneeskundige Kring
- internalName
- VGKFGEN
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Geschiedkundige Kring
- internalName
- VGKFLWI
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Logopedische en Audiologische Kring
- internalName
- VLAK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Levenstechnische Kring
- internalName
- VLK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Psychologische en Pedagogische Kring
- internalName
- VPPK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Rechtsgenootschap
- internalName
- VRG
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Vlaamse Technische Kring
- internalName
- VTK
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- WiNA
- internalName
- WINA
- parentAssociation
- FKCENTRAAL
-
-
- displayName
- Home Astrid
- internalName
- ASTRID
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- Home Bertha de Vriese
- internalName
- BERTHA
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- Home Boudewijn
- internalName
- BOUDEWIJN
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- Home Fabiola
- internalName
- FABIOLA
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- Home Konvent
- internalName
- HKCENTRAAL
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- Home Vermeylen
- internalName
- VERMEYL
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- Home Vesalius
- internalName
- VESALIUS
- parentAssociation
- HKCENTRAAL
-
-
- displayName
- AIESEC
- internalName
- AIESEC
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- BEST
- fullName
- Board of European Students of Technology Ghent
- internalName
- BEST
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- ChiSAG
- fullName
- Chinese Students Organisation
- internalName
- CHISAG
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- ESN
- fullName
- Erasmus Student Network
- internalName
- ESN
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Internationaal Konvent
- internalName
- IKCENTRAAL
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Indonesian Students Association Ghent
- internalName
- INDOSAG
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- ISAG
- fullName
- International Students Association
- internalName
- ISAG
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Iaas
- fullName
- International Association of Agricultural Students
- internalName
- Iaas
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Students' Welcome Club
- internalName
- SWC
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Tomo No Kai
- internalName
- TNOK
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Vinasag
- internalName
- VINASAG
- parentAssociation
- IKCENTRAAL
-
-
- displayName
- Fotoklas
- internalName
- FOTOKLAS
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- GUDc
- fullName
- Gentse Universitaire Dansclub
- internalName
- GUDC
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- GUHO
- fullName
- Gents Universitair Harmonie Orkest
- internalName
- GUHO
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- Gents Universitair Koor
- internalName
- GUK
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- GUSO
- fullName
- Gents Universitair Symfonisch Orkest
- internalName
- GUSO
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- Kultureel Konvent
- internalName
- KULTKCENTRAAL
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- Matrak
- internalName
- MATRAK
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- Schildersatelier
- internalName
- SCHILDER
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- Studentenfanfare
- internalName
- SF
- parentAssociation
- KULTKCENTRAAL
-
-
- displayName
- Actief Linkse Studenten
- internalName
- ALS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Anarchistisch Kollectief
- internalName
- ANARCH
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- CDS
- fullName
- Christen Democratische Studenten
- internalName
- CDS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Comac
- internalName
- COMAC
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- GPS
- fullName
- StudentenPastoraal Gent
- internalName
- GPS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- GRAS Gent
- fullName
- Groen Alternatieve Studenten
- internalName
- GRAS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- International Fellowship of Christian Students
- internalName
- IFECS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Jonge Europese Federalisten
- internalName
- JEF
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Jong N-VA UGent
- internalName
- JONGNVA
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Jongsocialisten StuGent
- internalName
- JS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- KASPER
- internalName
- KASPER
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- KVHV
- fullName
- Katholiek Vlaams Hoogstudenten Verbond
- internalName
- KVHV
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- L2 UGent
- internalName
- L2UGENT
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- LVSV
- fullName
- Liberaal Vlaams Studentenverbond
- internalName
- LVSV
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Minos Gent
- internalName
- MINOS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- NSV! Gent
- fullName
- Nationalistische Studentenvereniging
- internalName
- NSV
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Politiek en Filosofisch Konvent
- internalName
- PFKCENTRAAL
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Ronduit N-VA Gent
- internalName
- RNVA
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Socialisme 21 UGent
- internalName
- ROODUG
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- 't Zal Wel Gaan
- internalName
- TZAL
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Vonk, Marxistische Studenten
- internalName
- VMS
- parentAssociation
- PFKCENTRAAL
-
-
- displayName
- Schamperdruk
- internalName
- SCHAMPDRUK
- parentAssociation
- SCHAMPER
-
-
- displayName
- Schamper
- internalName
- SCHAMPER
- parentAssociation
- SCHAMPER
-
-
- displayName
- Vader Aalsterse
- internalName
- AALSTERSE
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Antwerpen Boven
- internalName
- AB
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Brugse Universitaire Kring
- internalName
- BUK
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Deliria
- internalName
- DELIRIA
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- HSC De Dijlebrassers
- internalName
- DIJLEBRASSERS
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Dionysus
- internalName
- DIONYSUS
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Moeder Domper
- internalName
- DOMPER
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Moeder Egmont
- internalName
- EGMONT
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Geeraard
- internalName
- GEERAARD
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Internia
- internalName
- INTERNIA
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Laetitia
- internalName
- LAETITIA
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Limburgia
- internalName
- LIMBURGIA
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Moeder Oilsjterse
- internalName
- OILSJTERSE
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Payottenland
- internalName
- PAYOTTEN
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Rodenbach
- internalName
- RODENBACH
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Scaldis
- internalName
- SCALDIS
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Sd'A Gent
- internalName
- SDA
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Senioren Konvent
- internalName
- SKCENTRAAL
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- 't Stropke
- internalName
- STROPKE
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Wase Club
- internalName
- WASE
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Westlandia
- internalName
- WESTLANDIA
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- 't Wielke
- internalName
- WIELKE
- parentAssociation
- SKCENTRAAL
-
-
- displayName
- Urgent.fm
- internalName
- URGENT
- parentAssociation
- URGENT
-
-
- displayName
- UGent AAPG Studentchapter
- internalName
- AAPGSC
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- 180DC
- internalName
- OEDC
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Archeologische Werkgroep
- internalName
- AW
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- BeMSA
- internalName
- BEMSA
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Capitant Gent
- internalName
- CAPITANT
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- CenEka
- internalName
- CENEKA
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- De Loeiende Koe
- internalName
- DLK
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- FLUX
- internalName
- FLUX
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- FLYSE
- fullName
- Flanders Youth Society for Entrepreneurship
- internalName
- FLYSE
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Groene Kring
- internalName
- GK
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- IEEE SB
- fullName
- IEEE Student Branch Gent
- internalName
- IEEE
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Kajira
- internalName
- KAJIRA
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Klassieke Kring
- internalName
- KK
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- MaCht
- internalName
- MACHT
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Moeder Theepot
- internalName
- THEEPOT
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Noord-Zuid Studenten
- internalName
- ONZ
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- PKarus
- internalName
- PKARUS
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Poutrix
- internalName
- POUTRIX
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- PRIME
- internalName
- PRIME
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Sense
- internalName
- SENSE
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Verkeerd Geparkeerd
- internalName
- VG
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Vereniging Voor Natuurkunde
- internalName
- VVN
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Werkgroepen & Verenigingen Konvent
- internalName
- WVKCENTRAAL
- parentAssociation
- WVKCENTRAAL
-
-
- displayName
- Zeus WPI
- fullName
- Zeus WerkgroeP Informatica
- internalName
- ZEUS
- parentAssociation
- WVKCENTRAAL
-
-
-
diff --git a/iOS/RestoMenuToday/DecimalNumberExtension.swift b/iOS/RestoMenuToday/DecimalNumberExtension.swift
index 99c39a8d..d7f96cab 100644
--- a/iOS/RestoMenuToday/DecimalNumberExtension.swift
+++ b/iOS/RestoMenuToday/DecimalNumberExtension.swift
@@ -16,11 +16,11 @@ extension NSDecimalNumber {
*/
convenience init(euroString : String) {
// Replace the comma by a point since the NSDecimalNumber expects a point as decimal separator
- var euroString = euroString.stringByReplacingOccurrencesOfString(",", withString: ".", options: nil, range: nil)
+ var euroString = euroString.stringByReplacingOccurrencesOfString(",", withString: ".", options: [], range: nil)
// Remove any non-numerical characters
let charactersToRemove = NSCharacterSet(charactersInString: "0123456789.").invertedSet
- euroString = "".join(euroString.componentsSeparatedByCharactersInSet(charactersToRemove))
+ euroString = euroString.componentsSeparatedByCharactersInSet(charactersToRemove).joinWithSeparator("")
self.init(string: euroString)
}
diff --git a/iOS/RestoMenuToday/Info.plist b/iOS/RestoMenuToday/Info.plist
index 4e8a6df2..4a25f152 100644
--- a/iOS/RestoMenuToday/Info.plist
+++ b/iOS/RestoMenuToday/Info.plist
@@ -3,7 +3,7 @@
CFBundleDevelopmentRegion
- en
+ nl
CFBundleDisplayName
Resto Menu
CFBundleExecutable
@@ -21,11 +21,26 @@
CFBundlePackageType
XPC!
CFBundleShortVersionString
- 1.2
+ 2.0.1
CFBundleSignature
????
CFBundleVersion
- 1.2.2
+ 2.0.15
+ NSAppTransportSecurity
+
+ NSExceptionDomains
+
+ zeus.ugent.be
+
+ NSIncludesSubdomains
+
+ NSTemporaryExceptionMinimumTLSVersion
+ TLSv1.0
+ NSTemporaryExceptionRequiresForwardSecrecy
+
+
+
+
NSExtension
NSExtensionMainStoryboard
diff --git a/iOS/RestoMenuToday/MainInterface.storyboard b/iOS/RestoMenuToday/MainInterface.storyboard
index 12dc433e..bece2591 100644
--- a/iOS/RestoMenuToday/MainInterface.storyboard
+++ b/iOS/RestoMenuToday/MainInterface.storyboard
@@ -1,7 +1,8 @@
-
+
-
+
+
@@ -22,18 +23,20 @@
+
+
-
-
-
-
-
-
diff --git a/iOS/RestoMenuToday/Menu.swift b/iOS/RestoMenuToday/Menu.swift
index d21f45de..fdb8e6cc 100644
--- a/iOS/RestoMenuToday/Menu.swift
+++ b/iOS/RestoMenuToday/Menu.swift
@@ -8,7 +8,7 @@
import UIKit
-class Menu: NSObject, Printable {
+class Menu: NSObject {
// MARK: Properties
diff --git a/iOS/RestoMenuToday/MenuItem.swift b/iOS/RestoMenuToday/MenuItem.swift
index 294e31a4..ef15a787 100644
--- a/iOS/RestoMenuToday/MenuItem.swift
+++ b/iOS/RestoMenuToday/MenuItem.swift
@@ -21,7 +21,7 @@ enum MenuItemType {
case Soup
}
-class MenuItem: NSObject, Printable {
+class MenuItem: NSObject {
// MARK: Properties
diff --git a/iOS/RestoMenuToday/MenuItemTableViewCell.swift b/iOS/RestoMenuToday/MenuItemTableViewCell.swift
index 711fccec..12215ae8 100644
--- a/iOS/RestoMenuToday/MenuItemTableViewCell.swift
+++ b/iOS/RestoMenuToday/MenuItemTableViewCell.swift
@@ -35,7 +35,7 @@ class MenuItemTableViewCell: UITableViewCell {
// MARK: Initialization
- required init(coder aDecoder: NSCoder) {
+ required init?(coder aDecoder: NSCoder) {
self.numberFormatter.numberStyle = .CurrencyStyle
self.numberFormatter.locale = NSLocale(localeIdentifier: "nl_BE")
diff --git a/iOS/RestoMenuToday/RestoManager.swift b/iOS/RestoMenuToday/RestoManager.swift
index 0b650534..d8b0a3b6 100644
--- a/iOS/RestoMenuToday/RestoManager.swift
+++ b/iOS/RestoMenuToday/RestoManager.swift
@@ -23,7 +23,7 @@ class RestoManager: NSObject {
/**
Returns the shared Resto manager object for the process.
- :returns: The shared RestoManager object.
+ - returns: The shared RestoManager object.
*/
class var sharedManager : RestoManager {
struct Static {
@@ -51,17 +51,17 @@ class RestoManager: NSObject {
Retrieves the menu for the given date in the background and caches it.
If the menu is already in the cache, the cached menu is used and no request is made.
- :param: date The date of the menu you want to retrieve.
+ - parameter date: The date of the menu you want to retrieve.
- :param: completionHandler A block that is executed on the main queue when the request has succeeded or failed.
+ - parameter completionHandler: A block that is executed on the main queue when the request has succeeded or failed.
The optional menu parameter holds the eventually retrieved menu.
The optional error parameter holds any error that caused the request to fail.
Either the menu or the error is not nil.
*/
func retrieveMenuForDate(date: NSDate, completionHandler: (menu: Menu?, error: NSError?) -> ()) {
// Construct the URL for the API request based on the year and week of the given date
- let dateComponents = NSCalendar.currentCalendar().components(.WeekOfYearCalendarUnit | .YearCalendarUnit, fromDate: date)
- let URL = NSURL(string: "http://zeus.ugent.be/hydra/api/1.0/resto/menu/\(dateComponents.year)/\(dateComponents.weekOfYear).json")
+ let dateComponents = NSCalendar.currentCalendar().components([.NSWeekOfYearCalendarUnit, .NSYearCalendarUnit], fromDate: date)
+ let URL = NSURL(string: "https://zeus.ugent.be/hydra/api/1.0/resto/menu/\(dateComponents.year)/\(dateComponents.weekOfYear).json")
// We're relying on NSURLCache to cache the data for us when the user is offline
let URLRequest = NSURLRequest(URL: URL!, cachePolicy: .ReturnCacheDataElseLoad, timeoutInterval: 0)
@@ -73,7 +73,12 @@ class RestoManager: NSObject {
completionHandler(menu: nil, error: error)
} else {
if data != nil {
- completionHandler(self.menuForDate(date, withData: data))
+ do {
+ try completionHandler(self.menuForDate(date, withData: data!))
+ } catch _ {
+ let error = NSError(domain: RestoKitErrorDomain, code: RestoKitError.NoData.rawValue, userInfo: nil)
+ completionHandler(menu: nil, error: error)
+ }
} else {
let error = NSError(domain: RestoKitErrorDomain, code: RestoKitError.NoData.rawValue, userInfo: nil)
completionHandler(menu: nil, error: error)
@@ -87,16 +92,14 @@ class RestoManager: NSObject {
/**
Creates a Menu for the given date based on the given JSON data.
- :param: date The date of the menu you want to parse.
- :param: data The NSData representation of the JSON containing the menu for the given date.
+ - parameter date: The date of the menu you want to parse.
+ - parameter data: The NSData representation of the JSON containing the menu for the given date.
- :returns: A tuple consisting of an optional menu and an optional error.
+ - returns: A tuple consisting of an optional menu and an optional error.
Either the menu or the error is not nil.
*/
- private func menuForDate(date : NSDate, withData data : NSData) -> (menu: Menu?, error : NSError?) {
- var error : NSError?
- let JSONDictionary = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error) as? [String : AnyObject]
-
+ private func menuForDate(date : NSDate, withData data : NSData) throws -> (menu: Menu?, error : NSError?) {
+ let JSONDictionary = try NSJSONSerialization.JSONObjectWithData(data, options: []) as? [String : AnyObject]
if let JSONDictionary = JSONDictionary {
// Create a date string from the given date
let dateFormatter = NSDateFormatter()
@@ -143,12 +146,11 @@ class RestoManager: NSObject {
let menu = Menu(date: date, menuItems: menuItems, open: JSONMenu["open"] as! Bool)
return (menu, nil)
} else {
- let menu = Menu(date: date, menuItems: [], open: false)
+ let menu = Menu(date: date, menuItems: [], open: false)
return (menu, nil)
}
- } else {
- return (nil, error)
}
+ return (nil, nil) //TODO: shouldn't be reached, and needs to be rewritten to use standard hydra resto items
}
}
diff --git a/iOS/RestoMenuToday/String.swift b/iOS/RestoMenuToday/String.swift
index 69f3d236..fc6df25b 100644
--- a/iOS/RestoMenuToday/String.swift
+++ b/iOS/RestoMenuToday/String.swift
@@ -13,7 +13,7 @@ extension String {
A representation of the receiver with the first character capitalized. (read-only)
*/
var sentenceCapitalizedString : NSString {
- if count(self) > 0 {
+ if self.characters.count > 0 {
return (self as NSString).substringToIndex(1).uppercaseString.stringByAppendingString((self as NSString).substringFromIndex(1))
} else {
return self
diff --git a/iOS/RestoMenuToday/TodayViewController.swift b/iOS/RestoMenuToday/TodayViewController.swift
index fd974609..07336208 100644
--- a/iOS/RestoMenuToday/TodayViewController.swift
+++ b/iOS/RestoMenuToday/TodayViewController.swift
@@ -89,7 +89,7 @@ class TodayViewController: UIViewController, UITableViewDataSource, UITableViewD
let calendar = NSCalendar.currentCalendar()
// Call the completion with no data as update result when we already have a menu for the given date
- if self.menu != nil && calendar.ordinalityOfUnit(.DayCalendarUnit, inUnit: .EraCalendarUnit, forDate: self.menu.date) == calendar.ordinalityOfUnit(.DayCalendarUnit, inUnit: .EraCalendarUnit, forDate: NSDate()){
+ if self.menu != nil && calendar.ordinalityOfUnit(.NSDayCalendarUnit, inUnit: .NSEraCalendarUnit, forDate: self.menu.date) == calendar.ordinalityOfUnit(.NSDayCalendarUnit, inUnit: .NSEraCalendarUnit, forDate: NSDate()){
completionHandler(.NoData)
return
}