Explorar o código

Event extended info screen. Language fixes. Code cleanup.

Iñigo Valentin %!s(int64=9) %!d(string=hai) anos
pai
achega
3b1d4eb554

+ 6 - 0
.gitignore

@@ -0,0 +1,6 @@
+GoogleMaps.framework/Versions/.DS_Store
+GoogleMaps.framework/Versions/A/.DS_Store
+app.xcodeproj/project.xcworkspace/xcuserdata/
+app.xcodeproj/xcuserdata/seavenois.xcuserdatad/xcdebugger/
+app/.DS_Store
+app/Assets.xcassets/.DS_Store

+ 5 - 1
app.xcodeproj/project.pbxproj

@@ -19,6 +19,7 @@
 		9326C4F61EA5279D007DF2A4 /* RowLablancaDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9326C4F51EA5279D007DF2A4 /* RowLablancaDay.swift */; };
 		9326C4F61EA5279D007DF2A4 /* RowLablancaDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9326C4F51EA5279D007DF2A4 /* RowLablancaDay.swift */; };
 		93294FF81E336FA000FDAF50 /* Entry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93294FF71E336FA000FDAF50 /* Entry.swift */; };
 		93294FF81E336FA000FDAF50 /* Entry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93294FF71E336FA000FDAF50 /* Entry.swift */; };
 		93294FFA1E337D0D00FDAF50 /* RowHomePastActivities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93294FF91E337D0D00FDAF50 /* RowHomePastActivities.swift */; };
 		93294FFA1E337D0D00FDAF50 /* RowHomePastActivities.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93294FF91E337D0D00FDAF50 /* RowHomePastActivities.swift */; };
+		93348A611EF4273F0093503A /* EventController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93348A601EF4273F0093503A /* EventController.swift */; };
 		935746101EE20B99005DED61 /* FetchLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9357460F1EE20B99005DED61 /* FetchLocation.swift */; };
 		935746101EE20B99005DED61 /* FetchLocation.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9357460F1EE20B99005DED61 /* FetchLocation.swift */; };
 		935892D01E493C2300E1CD5F /* UIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935892CF1E493C2300E1CD5F /* UIImageView.swift */; };
 		935892D01E493C2300E1CD5F /* UIImageView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935892CF1E493C2300E1CD5F /* UIImageView.swift */; };
 		935AE18A1EC6138D0055E71F /* SyncController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935AE1891EC6138D0055E71F /* SyncController.swift */; };
 		935AE18A1EC6138D0055E71F /* SyncController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935AE1891EC6138D0055E71F /* SyncController.swift */; };
@@ -107,6 +108,7 @@
 		9326C4F51EA5279D007DF2A4 /* RowLablancaDay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowLablancaDay.swift; sourceTree = "<group>"; };
 		9326C4F51EA5279D007DF2A4 /* RowLablancaDay.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowLablancaDay.swift; sourceTree = "<group>"; };
 		93294FF71E336FA000FDAF50 /* Entry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Entry.swift; sourceTree = "<group>"; };
 		93294FF71E336FA000FDAF50 /* Entry.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Entry.swift; sourceTree = "<group>"; };
 		93294FF91E337D0D00FDAF50 /* RowHomePastActivities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowHomePastActivities.swift; sourceTree = "<group>"; };
 		93294FF91E337D0D00FDAF50 /* RowHomePastActivities.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowHomePastActivities.swift; sourceTree = "<group>"; };
+		93348A601EF4273F0093503A /* EventController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EventController.swift; sourceTree = "<group>"; };
 		9357460F1EE20B99005DED61 /* FetchLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchLocation.swift; sourceTree = "<group>"; };
 		9357460F1EE20B99005DED61 /* FetchLocation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FetchLocation.swift; sourceTree = "<group>"; };
 		935892CF1E493C2300E1CD5F /* UIImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageView.swift; sourceTree = "<group>"; };
 		935892CF1E493C2300E1CD5F /* UIImageView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageView.swift; sourceTree = "<group>"; };
 		935AE1891EC6138D0055E71F /* SyncController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncController.swift; sourceTree = "<group>"; };
 		935AE1891EC6138D0055E71F /* SyncController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SyncController.swift; sourceTree = "<group>"; };
@@ -233,9 +235,10 @@
 		93B84B981D9C31AB006C0F67 /* app */ = {
 		93B84B981D9C31AB006C0F67 /* app */ = {
 			isa = PBXGroup;
 			isa = PBXGroup;
 			children = (
 			children = (
-				93D8B0931EF1A64C008BD946 /* Notifications.swift */,
+				93348A601EF4273F0093503A /* EventController.swift */,
 				93B84BA81D9C31AB006C0F67 /* Info.plist */,
 				93B84BA81D9C31AB006C0F67 /* Info.plist */,
 				93B84BA31D9C31AB006C0F67 /* Assets.xcassets */,
 				93B84BA31D9C31AB006C0F67 /* Assets.xcassets */,
+				93D8B0931EF1A64C008BD946 /* Notifications.swift */,
 				93B84BA01D9C31AB006C0F67 /* app.xcdatamodeld */,
 				93B84BA01D9C31AB006C0F67 /* app.xcdatamodeld */,
 				93B84BA51D9C31AB006C0F67 /* LaunchScreen.storyboard */,
 				93B84BA51D9C31AB006C0F67 /* LaunchScreen.storyboard */,
 				93B84B991D9C31AB006C0F67 /* AppDelegate.swift */,
 				93B84B991D9C31AB006C0F67 /* AppDelegate.swift */,
@@ -460,6 +463,7 @@
 				93075C6C1E59CB6B00396389 /* BlogView.swift in Sources */,
 				93075C6C1E59CB6B00396389 /* BlogView.swift in Sources */,
 				93B84B9A1D9C31AB006C0F67 /* AppDelegate.swift in Sources */,
 				93B84B9A1D9C31AB006C0F67 /* AppDelegate.swift in Sources */,
 				93D8B0961EF1B98E008BD946 /* FutureActivityViewController.swift in Sources */,
 				93D8B0961EF1B98E008BD946 /* FutureActivityViewController.swift in Sources */,
+				93348A611EF4273F0093503A /* EventController.swift in Sources */,
 				93B84BA21D9C31AB006C0F67 /* app.xcdatamodeld in Sources */,
 				93B84BA21D9C31AB006C0F67 /* app.xcdatamodeld in Sources */,
 				935D6E331E867C7E00CED3A1 /* RowGallery.swift in Sources */,
 				935D6E331E867C7E00CED3A1 /* RowGallery.swift in Sources */,
 				93EB2F0C1EBF5AEB00F64186 /* RowSchedule.swift in Sources */,
 				93EB2F0C1EBF5AEB00F64186 /* RowSchedule.swift in Sources */,

+ 4 - 1
app/ActivitiesView.swift

@@ -23,7 +23,7 @@ import CoreData
 import UIKit
 import UIKit
 
 
 /**
 /**
-Class to handle the home view.
+Class to handle the activities view.
 */
 */
 class ActivitiesView: UIView {
 class ActivitiesView: UIView {
 	
 	
@@ -41,6 +41,9 @@ class ActivitiesView: UIView {
 	var context: NSManagedObjectContext? = nil
 	var context: NSManagedObjectContext? = nil
 	
 	
 	
 	
+	/**
+	Default contstructor for the interface builder.
+	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
 	}
 	}

+ 3 - 2
app/AlbumViewController.swift

@@ -22,7 +22,7 @@ import UIKit
 import CoreData
 import CoreData
 
 
 /**
 /**
-The view controller of the app.
+The view controller to show albums.
 */
 */
 class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 	
 	
@@ -209,7 +209,8 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 	
 	
 	/**
 	/**
 	Shows a photo.
 	Shows a photo.
-	:param: id The album id.
+	:param: album The album id.
+	:param: photo The photo id.
 	*/
 	*/
 	func showPhoto(album: Int, photo: Int){
 	func showPhoto(album: Int, photo: Int){
 		self.passAlbum = album
 		self.passAlbum = album

+ 17 - 7
app/AppDelegate.swift

@@ -23,6 +23,9 @@ import CoreData
 import GoogleMaps
 import GoogleMaps
 import UserNotifications
 import UserNotifications
 
 
+/**
+Application delegate.
+*/
 @UIApplicationMain
 @UIApplicationMain
 class AppDelegate: UIResponder, UIApplicationDelegate {
 class AppDelegate: UIResponder, UIApplicationDelegate {
 
 
@@ -30,37 +33,44 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 	var controller: ViewController?
 	var controller: ViewController?
 	var albumController: AlbumViewController?
 	var albumController: AlbumViewController?
 	var syncController: SyncController?
 	var syncController: SyncController?
-
+	var scheduleController: ScheduleViewController?
+	var futureActivityController: FutureActivityViewController?
+	
 	
 	
+	/**
+	Application opened normally. Request permissions amd defines some settings.
+	*/
 	func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
 	func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
-		// Override point for customization after application launch.
 		
 		
 		// Google Mapas API KEY
 		// Google Mapas API KEY
 		GMSServices.provideAPIKey("AIzaSyBfIiBM_YSBlxybmI_Uz_fGoUFN4wacR80")
 		GMSServices.provideAPIKey("AIzaSyBfIiBM_YSBlxybmI_Uz_fGoUFN4wacR80")
 		
 		
-		// Background mode.
+		// Enable background mode.
 		UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
 		UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
 		
 		
+		// Enable notifications (for iOS 10)
 		if #available(iOS 10.0, *) {
 		if #available(iOS 10.0, *) {
 			let center = UNUserNotificationCenter.current()
 			let center = UNUserNotificationCenter.current()
 			center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
 			center.requestAuthorization(options: [.alert, .sound]) { (granted, error) in
-				// Enable or disable features based on authorization.
+				// Notification authorization granted
 			}
 			}
 		} else {
 		} else {
-			// Fallback on earlier versions
+			// No notifications for iOS < 10
 		}
 		}
 		
 		
-		
 		return true
 		return true
 	}
 	}
 	
 	
 
 
+	/**
+	Application run in the background. Fectches notifications and syncs with the server.
+	*/
 	func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
 	func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
 		NSLog(":BACKGROUND:LOG: Start bg sync...")
 		NSLog(":BACKGROUND:LOG: Start bg sync...")
 		Notifications()
 		Notifications()
 		Sync()
 		Sync()
 		
 		
-		let when = DispatchTime.now() + 120 // 2 minutes to perform the sync.
+		let when = DispatchTime.now() + 180 // 3 minutes to perform the sync.
 		DispatchQueue.main.asyncAfter(deadline: when) {
 		DispatchQueue.main.asyncAfter(deadline: when) {
 			completionHandler(UIBackgroundFetchResult.newData)
 			completionHandler(UIBackgroundFetchResult.newData)
 		}
 		}

+ 206 - 3
app/Base.lproj/Main.storyboard

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="3o1-ab-AT4">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16F73" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="3o1-ab-AT4">
     <device id="retina4_7" orientation="portrait">
     <device id="retina4_7" orientation="portrait">
         <adaptation id="fullscreen"/>
         <adaptation id="fullscreen"/>
     </device>
     </device>
     <dependencies>
     <dependencies>
         <deployment identifier="iOS"/>
         <deployment identifier="iOS"/>
-        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
         <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
         <capability name="Aspect ratio constraints" minToolsVersion="5.1"/>
         <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
         <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
@@ -16,7 +16,7 @@
         <scene sceneID="e3W-6Z-Jyk">
         <scene sceneID="e3W-6Z-Jyk">
             <objects>
             <objects>
                 <navigationController title="Gasteizko Margolariak" id="cgF-cq-ysf" sceneMemberID="viewController">
                 <navigationController title="Gasteizko Margolariak" id="cgF-cq-ysf" sceneMemberID="viewController">
-                    <navigationBar key="navigationBar" contentMode="scaleToFill" id="lgI-h9-O0s">
+                    <navigationBar key="navigationBar" contentMode="scaleToFill" misplaced="YES" id="lgI-h9-O0s">
                         <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                         <rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
                         <autoresizingMask key="autoresizingMask"/>
                         <autoresizingMask key="autoresizingMask"/>
                         <color key="backgroundColor" red="0.4079896717" green="1" blue="0.34807942549999998" alpha="1" colorSpace="calibratedRGB"/>
                         <color key="backgroundColor" red="0.4079896717" green="1" blue="0.34807942549999998" alpha="1" colorSpace="calibratedRGB"/>
@@ -964,6 +964,7 @@
                         <outlet property="lbToolbarTitle" destination="RJE-Hu-oDM" id="nCW-fh-Pst"/>
                         <outlet property="lbToolbarTitle" destination="RJE-Hu-oDM" id="nCW-fh-Pst"/>
                         <outlet property="lbWindowTitle" destination="663-n7-Jwn" id="0p7-02-Veb"/>
                         <outlet property="lbWindowTitle" destination="663-n7-Jwn" id="0p7-02-Veb"/>
                         <outlet property="svScheduleList" destination="bHp-Km-KNL" id="aSi-lC-w6H"/>
                         <outlet property="svScheduleList" destination="bHp-Km-KNL" id="aSi-lC-w6H"/>
+                        <segue destination="Uh5-wZ-ogP" kind="modal" identifier="SegueEvent" modalPresentationStyle="currentContext" modalTransitionStyle="coverVertical" id="0Qp-db-Qb0"/>
                     </connections>
                     </connections>
                 </viewController>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="rq0-MV-vyl" userLabel="First Responder" sceneMemberID="firstResponder"/>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="rq0-MV-vyl" userLabel="First Responder" sceneMemberID="firstResponder"/>
@@ -1489,16 +1490,218 @@
                         <outlet property="barTitle" destination="v7W-BZ-qle" id="aQB-IA-P19"/>
                         <outlet property="barTitle" destination="v7W-BZ-qle" id="aQB-IA-P19"/>
                         <outlet property="itineraryContainer" destination="HZX-gN-1YI" id="1lZ-0m-TwZ"/>
                         <outlet property="itineraryContainer" destination="HZX-gN-1YI" id="1lZ-0m-TwZ"/>
                         <outlet property="itineraryList" destination="3lO-kN-Y0S" id="Vf3-t6-l0Y"/>
                         <outlet property="itineraryList" destination="3lO-kN-Y0S" id="Vf3-t6-l0Y"/>
+                        <segue destination="Uh5-wZ-ogP" kind="popoverPresentation" identifier="SegueItinerary" popoverAnchorView="Tll-v9-w0T" id="zCO-aN-4xt">
+                            <popoverArrowDirection key="popoverArrowDirection" up="YES" down="YES" left="YES" right="YES"/>
+                        </segue>
                     </connections>
                     </connections>
                 </viewController>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="IHt-fO-2Q0" userLabel="First Responder" sceneMemberID="firstResponder"/>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="IHt-fO-2Q0" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
             </objects>
             <point key="canvasLocation" x="1302" y="-403"/>
             <point key="canvasLocation" x="1302" y="-403"/>
         </scene>
         </scene>
+        <!--Event-->
+        <scene sceneID="CJp-1C-D1Z">
+            <objects>
+                <viewController title="Event" id="Uh5-wZ-ogP" customClass="EventController" customModule="app" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="oTc-Dn-jSp"/>
+                        <viewControllerLayoutGuide type="bottom" id="GQn-fc-wCY"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleAspectFill" id="Whe-r6-tkx" userLabel="Section">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Pzh-mM-oRb">
+                                <rect key="frame" x="14.5" y="14.5" width="345" height="637"/>
+                                <subviews>
+                                    <textView clipsSubviews="YES" multipleTouchEnabled="YES" userInteractionEnabled="NO" contentMode="scaleToFill" bounces="NO" scrollEnabled="NO" showsHorizontalScrollIndicator="NO" showsVerticalScrollIndicator="NO" editable="NO" text="Localizacion" textAlignment="natural" translatesAutoresizingMaskIntoConstraints="NO" id="TdI-Mq-pQ8" userLabel="Title">
+                                        <rect key="frame" x="0.0" y="0.0" width="345" height="33"/>
+                                        <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                        <textInputTraits key="textInputTraits" autocapitalizationType="sentences"/>
+                                    </textView>
+                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="p9X-b1-qyz" userLabel="Entry">
+                                        <rect key="frame" x="10" y="43" width="325" height="584"/>
+                                        <subviews>
+                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Time" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="uS1-ic-OaV" userLabel="Time">
+                                                <rect key="frame" x="10" y="10" width="305" height="22"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="22" id="d1L-1Q-VmO"/>
+                                                </constraints>
+                                                <fontDescription key="fontDescription" type="boldSystem" pointSize="18"/>
+                                                <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                                <nil key="highlightedColor"/>
+                                            </label>
+                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Text" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="3" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hVJ-CB-Hgq">
+                                                <rect key="frame" x="9.5" y="42" width="305" height="70"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="70" id="fcs-jf-hAG"/>
+                                                </constraints>
+                                                <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                <nil key="textColor"/>
+                                                <nil key="highlightedColor"/>
+                                            </label>
+                                            <imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Pinpoint" translatesAutoresizingMaskIntoConstraints="NO" id="V1S-rW-K5b">
+                                                <rect key="frame" x="20" y="142" width="30" height="50"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="width" constant="30" id="Vzh-tD-dAp"/>
+                                                    <constraint firstAttribute="height" constant="50" id="gsL-Ww-tn3"/>
+                                                </constraints>
+                                            </imageView>
+                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Place asdaskldkjas  askjdhasjhk asdkjh" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Dae-xA-1hx" userLabel="Place">
+                                                <rect key="frame" x="70" y="122" width="235" height="40"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="40" id="Gbn-tP-CDH"/>
+                                                </constraints>
+                                                <fontDescription key="fontDescription" type="system" pointSize="15"/>
+                                                <nil key="textColor"/>
+                                                <nil key="highlightedColor"/>
+                                            </label>
+                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Address dsajhfjkdsfkl asfdioadsjkfdsndsf djdsj" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="2" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="YgS-fT-YvY">
+                                                <rect key="frame" x="80" y="162" width="215" height="35"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="35" id="N0Q-U8-hfI"/>
+                                                </constraints>
+                                                <fontDescription key="fontDescription" type="italicSystem" pointSize="14"/>
+                                                <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
+                                                <nil key="highlightedColor"/>
+                                            </label>
+                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LsE-aH-N1R" customClass="GMSMapView">
+                                                <rect key="frame" x="10" y="242" width="305" height="277"/>
+                                                <color key="backgroundColor" red="1" green="0.20334201390000001" blue="0.32001410590000001" alpha="1" colorSpace="calibratedRGB"/>
+                                                <userDefinedRuntimeAttributes>
+                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                        <color key="value" white="0.0" alpha="1" colorSpace="calibratedWhite"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                        <real key="value" value="1"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                        <real key="value" value="3"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                </userDefinedRuntimeAttributes>
+                                            </view>
+                                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="mGX-dR-mu2">
+                                                <rect key="frame" x="65" y="529" width="195" height="45"/>
+                                                <color key="backgroundColor" red="0.070588235289999995" green="0.27058823529999998" blue="0.4039215686" alpha="1" colorSpace="calibratedRGB"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="45" id="mty-PM-ITe"/>
+                                                </constraints>
+                                                <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                                <state key="normal" title="Cerrar">
+                                                    <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                </state>
+                                                <userDefinedRuntimeAttributes>
+                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                        <color key="value" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                        <real key="value" value="2"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                        <real key="value" value="4"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                </userDefinedRuntimeAttributes>
+                                            </button>
+                                        </subviews>
+                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <constraints>
+                                            <constraint firstItem="hVJ-CB-Hgq" firstAttribute="top" secondItem="uS1-ic-OaV" secondAttribute="bottom" constant="10" id="0Xx-dX-W67"/>
+                                            <constraint firstItem="YgS-fT-YvY" firstAttribute="top" secondItem="Dae-xA-1hx" secondAttribute="bottom" id="5F1-QH-ldA"/>
+                                            <constraint firstItem="Dae-xA-1hx" firstAttribute="top" secondItem="V1S-rW-K5b" secondAttribute="top" constant="-20" id="99i-3d-OrW"/>
+                                            <constraint firstItem="V1S-rW-K5b" firstAttribute="leading" secondItem="p9X-b1-qyz" secondAttribute="leading" constant="20" id="Ehc-g1-4vU"/>
+                                            <constraint firstItem="mGX-dR-mu2" firstAttribute="centerX" secondItem="p9X-b1-qyz" secondAttribute="centerX" id="FQH-JN-a4w"/>
+                                            <constraint firstItem="uS1-ic-OaV" firstAttribute="width" secondItem="p9X-b1-qyz" secondAttribute="width" constant="-20" id="KAS-74-SkE"/>
+                                            <constraint firstItem="mGX-dR-mu2" firstAttribute="width" secondItem="p9X-b1-qyz" secondAttribute="width" multiplier="0.6" id="LNw-p9-1Ps"/>
+                                            <constraint firstItem="Dae-xA-1hx" firstAttribute="trailing" secondItem="p9X-b1-qyz" secondAttribute="trailing" constant="-20" id="Le1-3C-kRK"/>
+                                            <constraint firstItem="LsE-aH-N1R" firstAttribute="top" secondItem="V1S-rW-K5b" secondAttribute="bottom" constant="50" id="MCp-6n-v4V"/>
+                                            <constraint firstItem="hVJ-CB-Hgq" firstAttribute="width" secondItem="uS1-ic-OaV" secondAttribute="width" id="NKz-Nb-pVn"/>
+                                            <constraint firstItem="LsE-aH-N1R" firstAttribute="centerX" secondItem="p9X-b1-qyz" secondAttribute="centerX" id="QgF-Lt-FhS"/>
+                                            <constraint firstItem="YgS-fT-YvY" firstAttribute="width" secondItem="Dae-xA-1hx" secondAttribute="width" constant="-20" id="RYS-JN-ifV"/>
+                                            <constraint firstItem="LsE-aH-N1R" firstAttribute="bottom" secondItem="mGX-dR-mu2" secondAttribute="top" constant="-10" id="Sn5-V9-5D9"/>
+                                            <constraint firstItem="hVJ-CB-Hgq" firstAttribute="centerX" secondItem="uS1-ic-OaV" secondAttribute="centerX" id="Uut-4g-fU7"/>
+                                            <constraint firstAttribute="bottom" secondItem="mGX-dR-mu2" secondAttribute="bottom" constant="10" id="c1g-0m-IAv"/>
+                                            <constraint firstItem="uS1-ic-OaV" firstAttribute="top" secondItem="p9X-b1-qyz" secondAttribute="top" constant="10" id="esJ-Dq-yAN"/>
+                                            <constraint firstItem="LsE-aH-N1R" firstAttribute="width" secondItem="p9X-b1-qyz" secondAttribute="width" constant="-20" id="mHY-j9-73b"/>
+                                            <constraint firstItem="uS1-ic-OaV" firstAttribute="centerX" secondItem="p9X-b1-qyz" secondAttribute="centerX" id="mbE-Hi-ycL"/>
+                                            <constraint firstItem="Dae-xA-1hx" firstAttribute="leading" secondItem="V1S-rW-K5b" secondAttribute="trailing" constant="20" id="nSZ-b4-vsW"/>
+                                            <constraint firstItem="YgS-fT-YvY" firstAttribute="centerX" secondItem="Dae-xA-1hx" secondAttribute="centerX" id="qoJ-AG-kYy"/>
+                                            <constraint firstItem="V1S-rW-K5b" firstAttribute="top" secondItem="hVJ-CB-Hgq" secondAttribute="bottom" constant="30" id="xld-5s-PKk"/>
+                                        </constraints>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                <color key="value" red="0.42745098040000001" green="0.41176470590000003" blue="0.56470588239999997" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            </userDefinedRuntimeAttribute>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                <integer key="value" value="1"/>
+                                            </userDefinedRuntimeAttribute>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                <integer key="value" value="3"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </view>
+                                </subviews>
+                                <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstAttribute="bottom" secondItem="p9X-b1-qyz" secondAttribute="bottom" constant="10" id="8Ft-cW-Vzq"/>
+                                    <constraint firstItem="p9X-b1-qyz" firstAttribute="width" secondItem="Pzh-mM-oRb" secondAttribute="width" constant="-20" id="8aS-wx-yQR"/>
+                                    <constraint firstItem="p9X-b1-qyz" firstAttribute="centerX" secondItem="Pzh-mM-oRb" secondAttribute="centerX" id="LUQ-uT-amE"/>
+                                    <constraint firstItem="TdI-Mq-pQ8" firstAttribute="width" secondItem="Pzh-mM-oRb" secondAttribute="width" id="ZZb-OS-ppR"/>
+                                    <constraint firstItem="TdI-Mq-pQ8" firstAttribute="top" secondItem="Pzh-mM-oRb" secondAttribute="top" id="Zwb-ch-MpX"/>
+                                    <constraint firstItem="TdI-Mq-pQ8" firstAttribute="centerX" secondItem="Pzh-mM-oRb" secondAttribute="centerX" id="eqQ-i9-kAX"/>
+                                    <constraint firstItem="p9X-b1-qyz" firstAttribute="top" secondItem="TdI-Mq-pQ8" secondAttribute="bottom" constant="10" id="ezI-gR-vy7"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                        <real key="value" value="1"/>
+                                    </userDefinedRuntimeAttribute>
+                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                        <real key="value" value="8"/>
+                                    </userDefinedRuntimeAttribute>
+                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                        <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <constraints>
+                            <constraint firstItem="Pzh-mM-oRb" firstAttribute="centerY" secondItem="Whe-r6-tkx" secondAttribute="centerY" id="JIZ-Dq-7XP"/>
+                            <constraint firstItem="Pzh-mM-oRb" firstAttribute="height" secondItem="Whe-r6-tkx" secondAttribute="height" constant="-30" id="ZqF-ZH-E1R"/>
+                            <constraint firstItem="Pzh-mM-oRb" firstAttribute="centerX" secondItem="Whe-r6-tkx" secondAttribute="centerX" id="cOh-nb-Sp4"/>
+                            <constraint firstItem="Pzh-mM-oRb" firstAttribute="width" secondItem="Whe-r6-tkx" secondAttribute="width" constant="-30" id="g05-vA-bat"/>
+                        </constraints>
+                        <userDefinedRuntimeAttributes>
+                            <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                <real key="value" value="0.0"/>
+                            </userDefinedRuntimeAttribute>
+                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                <real key="value" value="0.0"/>
+                            </userDefinedRuntimeAttribute>
+                        </userDefinedRuntimeAttributes>
+                    </view>
+                    <connections>
+                        <outlet property="btClose" destination="mGX-dR-mu2" id="ldW-4y-Rkd"/>
+                        <outlet property="eventAddress" destination="YgS-fT-YvY" id="w0Y-CG-Cc5"/>
+                        <outlet property="eventLocation" destination="Dae-xA-1hx" id="iQo-Tg-jJ5"/>
+                        <outlet property="eventMap" destination="LsE-aH-N1R" id="3Hq-Ig-SmJ"/>
+                        <outlet property="eventText" destination="hVJ-CB-Hgq" id="Mx7-6n-d2u"/>
+                        <outlet property="eventTime" destination="uS1-ic-OaV" id="CyB-ua-P1g"/>
+                        <outlet property="eventTitle" destination="TdI-Mq-pQ8" id="Qjv-Cn-HLQ"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="iqH-Ju-whF" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+            <point key="canvasLocation" x="-1570" y="277"/>
+        </scene>
     </scenes>
     </scenes>
     <resources>
     <resources>
         <image name="GM" width="120" height="120"/>
         <image name="GM" width="120" height="120"/>
         <image name="Logo" width="83" height="83"/>
         <image name="Logo" width="83" height="83"/>
         <image name="PhotoPlaceholder" width="170" height="108"/>
         <image name="PhotoPlaceholder" width="170" height="108"/>
+        <image name="Pinpoint" width="10" height="13"/>
     </resources>
     </resources>
+    <inferredMetricsTieBreakers>
+        <segue reference="0Qp-db-Qb0"/>
+    </inferredMetricsTieBreakers>
 </document>
 </document>

+ 5 - 1
app/BlogView.swift

@@ -22,7 +22,7 @@ import Foundation
 import CoreData
 import CoreData
 import UIKit
 import UIKit
 /**
 /**
-Class to handle the home view.
+Class to handle the blog view.
 */
 */
 class BlogView: UIView {
 class BlogView: UIView {
 	
 	
@@ -39,6 +39,10 @@ class BlogView: UIView {
 	var context: NSManagedObjectContext? = nil;
 	var context: NSManagedObjectContext? = nil;
 	var lang: String? = nil
 	var lang: String? = nil
 	
 	
+
+	/**
+	Default constructor for the interface builder.
+	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
 	}
 	}

+ 1 - 1
app/Entry.swift

@@ -22,7 +22,7 @@ import Foundation
 import UIKit
 import UIKit
 
 
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as entries or rows.
 */
 */
 class Entry: UIView {
 class Entry: UIView {
 	
 	

+ 212 - 0
app/EventController.swift

@@ -0,0 +1,212 @@
+// Copyright (C) 2016 Inigo Valentin
+//
+// This file is part of the Gasteizko Margolariak IOS app.
+//
+// The Gasteizko Margolariak IOS app is free software: you can
+// redistribute it and/or modify it under the terms of the
+// GNU General Public License as published by the Free Software
+// Foundation, either version 3 of the License, or (at your
+// option) any later version.
+//
+// The Gasteizko Margolariak IOS app is distributed in the
+// hope that it will be useful, but WITHOUT ANY WARRANTY;
+// without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
+// Public License for more details.
+//
+// You should have received a copy of the GNU General Public
+// License along with the Gasteizko Margolariak IOS app.
+// If not, see <http://www.gnu.org/licenses/>.
+
+import UIKit
+import CoreData
+import GoogleMaps
+
+/**
+The view controller of the app.
+*/
+class EventController: UIViewController, UIGestureRecognizerDelegate {
+
+	@IBOutlet weak var eventTitle: UITextView!
+	@IBOutlet weak var eventText: UILabel!
+	@IBOutlet weak var eventTime: UILabel!
+	@IBOutlet weak var eventLocation: UILabel!
+	@IBOutlet weak var eventMap: GMSMapView!
+	@IBOutlet weak var btClose: UIButton!
+	@IBOutlet weak var eventAddress: UILabel!
+	
+	var id: Int = -1
+	var passId: Int = -1
+	var delegate: AppDelegate?
+	
+	
+	/**
+	Gets the application context.
+	:return: The application context.
+	*/
+	func getContext () -> NSManagedObjectContext {
+		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
+	}
+	
+	
+	/**
+	Run when the app loads. Sets everything up.
+	*/
+	override func viewDidLoad() {
+		
+		// Populate photo array.
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Festival_event> = Festival_event.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			var name: String = ""
+			var text: String = ""
+			var start: NSDate
+			var placeId: Int = -1
+			var place: [Any]
+			var placeName: String = ""
+			var placeAddress: String = ""
+			var lat: Double = 0.0
+			var lon: Double = 0.0
+			if searchResults.count > 0{
+				let r = searchResults[0]
+				
+				name = r.value(forKey: "title_\(lang)")! as! String
+				text = r.value(forKey: "description_\(lang)")! as! String
+				start = r.value(forKey: "start")! as! NSDate
+				placeId = r.value(forKey: "place")! as! Int
+				place = getPlace(place: placeId, lang: getLanguage(), context: context)
+				placeName = place[0] as! String
+				placeAddress = place[1] as! String
+				lat = place[2] as! Double
+				lon = place[3] as! Double
+				
+				// Set labels
+				eventTitle.text = " \(name.decode().stripHtml())"
+				if text.length > 0{
+					eventText.text = " \(text.decode().stripHtml())"
+				}
+				else{
+					self.eventText.isHidden = true
+				}
+				self.eventTime.text = formatTime(date: start)
+				self.eventLocation.text = placeName.decode().stripHtml()
+				if placeAddress.length == 0 || placeAddress == placeName{
+					self.eventAddress.isHidden = true
+				}
+				else{
+					self.eventAddress.text = placeAddress.decode().stripHtml()
+				}
+				
+				// Set map marker
+				let marker = GMSMarker()
+				marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lon)
+				marker.title = name
+				marker.map = self.eventMap
+				
+				// Center map
+				eventMap.isMyLocationEnabled = true
+				let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: lat, longitude: lon, zoom: 12.0)
+				self.eventMap.camera = camera
+				
+			}
+			
+		}
+		catch {
+			NSLog(":EVENT:ERROR: Error getting info from event \(id): \(error)")
+		}
+		
+		super.viewDidLoad()
+		
+		// Set button action
+		self.btClose.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+	}
+	
+	
+	/**
+	Dismisses the controller.
+	*/
+	func back() {
+		self.dismiss(animated: true, completion: nil)
+	}
+	
+	
+	/**
+	Dispose of any resources that can be recreated.
+	*/
+	override func didReceiveMemoryWarning() {
+		super.didReceiveMemoryWarning()
+	}
+	
+	/**
+	Extracts the time from a date to a string.
+	:param: text The date.
+	:return: Time, in string format.
+	*/
+	func formatTime(date: NSDate) -> String{
+
+		let calendar = Calendar.current
+		let hour: Int = calendar.component(.hour, from: date as Date)
+		let minute: Int = calendar.component(.minute, from: date as Date)
+		
+		var strTime = ""
+		if minute <= 9{
+			strTime = "\(hour):0\(minute)"
+		}
+		else{
+			strTime = "\(hour):\(minute)"
+		}
+		
+		return strTime
+	}
+	
+	
+	/**
+	Gets info about a place in the device language.
+	:param: place Place id.
+	:param: lang Device language (only 'es', 'en', or 'eu').
+	:param: context Application context.
+	:return: String array. 0-index item contains the place name. The 1-index one contains the address.
+	*/
+	func getPlace(place: Int, lang: String, context: NSManagedObjectContext) -> [Any]{
+		var placeName: String = ""
+		var placeAddress: String = ""
+		var lat: Double = 0.0
+		var lon: Double = 0.0
+		let fetchRequest: NSFetchRequest<Place> = Place.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", place)
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			let r: NSManagedObject = searchResults[0]
+			placeName = r.value(forKey: "name_\(lang)")! as! String
+			placeAddress = r.value(forKey: "address_\(lang)")! as! String
+			lat = r.value(forKey: "lat")! as! Double
+			lon = r.value(forKey: "lon")! as! Double
+		}
+		catch{
+			NSLog(":FUTUREACTIVITY:ERROR: Error getting infor about place \(place): \(error)")
+		}
+		return [placeName, placeAddress, lat, lon]
+	}
+	
+	
+	/**
+	Gets the device language. The only recognized languages are Spanish, English and Basque.
+	If the device has another language, Spanish will be selected by default.
+	:return: Two-letter language code.
+	*/
+	func getLanguage() -> String{
+		let pre = NSLocale.preferredLanguages[0].subStr(start: 0, end: 1)
+		if(pre == "es" || pre == "en" || pre == "eu"){
+			return pre
+		}
+		else{
+			return "es"
+		}
+	}
+}
+

+ 4 - 1
app/FetchLocation.swift

@@ -28,13 +28,16 @@ class FetchLocation{
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
 	*/
 	*/
 	init(){
 	init(){
 		fetch()
 		fetch()
 	}
 	}
 	
 	
 	
 	
+	/**
+	Fetches location reports form the server in the background.
+	*/
 	func fetch(){
 	func fetch(){
 		NSLog(":LOCATION:LOG: Fetching location...")
 		NSLog(":LOCATION:LOG: Fetching location...")
 		
 		

+ 26 - 0
app/FutureActivityViewController.swift

@@ -88,6 +88,7 @@ class FutureActivityViewController: UIViewController, UIGestureRecognizerDelegat
 		
 		
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		let appDelegate = UIApplication.shared.delegate as! AppDelegate
 		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		appDelegate.futureActivityController = self
 		let lang : String = getLanguage()
 		let lang : String = getLanguage()
 		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
 		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
 		let fetchRequest: NSFetchRequest<Activity> = Activity.fetchRequest()
 		let fetchRequest: NSFetchRequest<Activity> = Activity.fetchRequest()
@@ -289,6 +290,31 @@ class FutureActivityViewController: UIViewController, UIGestureRecognizerDelegat
 	}
 	}
 	
 	
 	
 	
+	/**
+	Shows an itinerary dialog.
+	:param: id The itinerary id.
+	*/
+	func showItinerary(id: Int){
+		self.passId = id
+		// TODO
+		NSLog(":FUTUREACTIVITY:TODO: Implement segue")
+		//performSegue(withIdentifier: "SegueItinerary", sender: nil)
+	}
+	
+	
+	/**
+	Run before performing a segue.
+	Assigns id if neccessary.
+	:param: segue The segue to perform.
+	:sender: The calling view.
+	*/
+	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
+		if segue.identifier == "SegueItinerary"{
+			(segue.destination as! EventController).id = passId
+		}
+	}
+	
+	
 	/**
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	If the device has another language, Spanish will be selected by default.
 	If the device has another language, Spanish will be selected by default.

+ 7 - 13
app/GalleryView.swift

@@ -21,8 +21,10 @@
 import Foundation
 import Foundation
 import CoreData
 import CoreData
 import UIKit
 import UIKit
+
+
 /**
 /**
-Class to handle the home view.
+Class to handle the gallery view.
 */
 */
 class GalleryView: UIView {
 class GalleryView: UIView {
 	
 	
@@ -39,7 +41,7 @@ class GalleryView: UIView {
 	
 	
 	
 	
 	/**
 	/**
-	Run when the view is started.
+	Default constructor for the interface builder.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -139,19 +141,11 @@ class GalleryView: UIView {
 				// Add to the rows array
 				// Add to the rows array
 				self.rows.append(row)
 				self.rows.append(row)
 			}
 			}
-		} catch {
-			NSLog(":GALLERY:ERROR: Error with request: \(error)")
 		}
 		}
-		
-		//Always at the end: update scrollview
-		var h: Int = 0
-		for view in scrollView.subviews {
-			//contentRect = contentRect.union(view.frame);
-			h = h + Int(view.frame.height) + 30 // TODO Why 30?
+		catch {
+			NSLog(":GALLERY:ERROR: Error with request: \(error)")
 		}
 		}
-		// TODO: Calculate at the end
-		self.scrollView.contentSize.height = 2500 //CGFloat(h);
-		
+				
 		self.setUpRowsTapRecognizers()
 		self.setUpRowsTapRecognizers()
 	}
 	}
 	
 	

+ 7 - 4
app/HomeView.swift

@@ -21,6 +21,8 @@
 import Foundation
 import Foundation
 import CoreData
 import CoreData
 import UIKit
 import UIKit
+
+
 /**
 /**
  Class to handle the home view.
  Class to handle the home view.
  */
  */
@@ -63,7 +65,8 @@ class HomeView: UIView {
 	
 	
 	
 	
 	/**
 	/**
-	 Run when the view is started.
+	Run when the view is started.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		
 		
@@ -138,7 +141,6 @@ class HomeView: UIView {
 	If no location is reported, it hiddes the section.
 	If no location is reported, it hiddes the section.
 	*/
 	*/
 	func setUpLocation(){
 	func setUpLocation(){
-		// TODO: Also set up tap recognizer.
 		let defaults = UserDefaults.standard
 		let defaults = UserDefaults.standard
 		if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
 		if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
 			let lat = defaults.value(forKey: "GMLocLat") as! Double
 			let lat = defaults.value(forKey: "GMLocLat") as! Double
@@ -228,7 +230,7 @@ class HomeView: UIView {
 					
 					
 				}
 				}
 				catch {
 				catch {
-					NSLog(":LABLANCA:ERROR: Error getting festivals info: \(error)")
+					NSLog(":HOME:ERROR: Error getting setting the La Blanca section up: \(error)")
 				}
 				}
 			}
 			}
 			else{
 			else{
@@ -438,7 +440,8 @@ class HomeView: UIView {
 				parent.addArrangedSubview(row)
 				parent.addArrangedSubview(row)
 				
 				
 			}
 			}
-		} catch {
+		}
+		catch {
 			NSLog(":HOME:ERROR: Error loading past activities: \(error)")
 			NSLog(":HOME:ERROR: Error loading past activities: \(error)")
 		}
 		}
 	}
 	}

+ 6 - 7
app/LablancaView.swift

@@ -21,8 +21,10 @@
 import Foundation
 import Foundation
 import CoreData
 import CoreData
 import UIKit
 import UIKit
+
+
 /**
 /**
-Class to handle the home view.
+Class to handle the La Blanca view.
 */
 */
 class LablancaView: UIView {
 class LablancaView: UIView {
 
 
@@ -37,13 +39,13 @@ class LablancaView: UIView {
 	@IBOutlet weak var fOfferList: UIStackView!	// Stack view to hold the offer list.
 	@IBOutlet weak var fOfferList: UIStackView!	// Stack view to hold the offer list.
 	@IBOutlet weak var fDayList: UIStackView!	// Stack view to hold the single days price list.
 	@IBOutlet weak var fDayList: UIStackView!	// Stack view to hold the single days price list.
 	
 	
-	
 	// App delegate
 	// App delegate
 	var delegate: AppDelegate? = nil
 	var delegate: AppDelegate? = nil
 	
 	
 	
 	
 	/**
 	/**
-	Run when the view is started.
+	Default constructor for the interface builder.
+	:param: frame Window frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -77,6 +79,7 @@ class LablancaView: UIView {
 		}
 		}
 	}
 	}
 
 
+
 	/**
 	/**
 	Displays the section to be shown while (and near) the La Blanca festivals.
 	Displays the section to be shown while (and near) the La Blanca festivals.
 	*/	
 	*/	
@@ -131,7 +134,6 @@ class LablancaView: UIView {
 		let tapRecognizerGMSchedule = UITapGestureRecognizer(target: self, action: #selector(openGMSchedule(_:)))
 		let tapRecognizerGMSchedule = UITapGestureRecognizer(target: self, action: #selector(openGMSchedule(_:)))
 		fBtGMSchedule.isUserInteractionEnabled = true
 		fBtGMSchedule.isUserInteractionEnabled = true
 		fBtGMSchedule.addGestureRecognizer(tapRecognizerGMSchedule)
 		fBtGMSchedule.addGestureRecognizer(tapRecognizerGMSchedule)
-
 		
 		
 		// Get info about the days and offers.
 		// Get info about the days and offers.
 		let dateFormatter = DateFormatter()
 		let dateFormatter = DateFormatter()
@@ -243,13 +245,11 @@ class LablancaView: UIView {
 	func showNoFestivals(){
 	func showNoFestivals(){
 		NSLog(":LABLANCA:LOG: Showing no festivals section.")
 		NSLog(":LABLANCA:LOG: Showing no festivals section.")
 		self.fWindow.isHidden = true
 		self.fWindow.isHidden = true
-		// Nothing else to be done.
 	}
 	}
 	
 	
 
 
 	/**
 	/**
 	Commands the view controller to show the city schedule view.
 	Commands the view controller to show the city schedule view.
-	:param: sender The view that triggered the event.
 	*/
 	*/
 	func openSchedule(_ sender:UITapGestureRecognizer? = nil){
 	func openSchedule(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
@@ -259,7 +259,6 @@ class LablancaView: UIView {
 
 
 	/**
 	/**
 	Commands the view controller to show the Gasteizko Margolariak schedule view.
 	Commands the view controller to show the Gasteizko Margolariak schedule view.
-	:param: sender The view that triggered the event.
 	*/
 	*/
 	func openGMSchedule(_ sender:UITapGestureRecognizer? = nil){
 	func openGMSchedule(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate

+ 28 - 4
app/LocationView.swift

@@ -22,8 +22,10 @@ import Foundation
 import CoreData
 import CoreData
 import UIKit
 import UIKit
 import GoogleMaps
 import GoogleMaps
+
+
 /**
 /**
-Class to handle the home view.
+Class to handle the location view.
 */
 */
 class LocationView: UIView {
 class LocationView: UIView {
 	
 	
@@ -40,6 +42,11 @@ class LocationView: UIView {
 	
 	
 	var locationTimer: Timer? = nil
 	var locationTimer: Timer? = nil
 	
 	
+
+	/**
+	Default constructor for the interface builder.
+	:param: frame View frame.
+	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		
 		
 		// Set controller
 		// Set controller
@@ -79,7 +86,9 @@ class LocationView: UIView {
 	
 	
 	
 	
 	/**
 	/**
-	I am not sure what does this do...
+	Enables the user location dot in the map, checking for permission.
+	:param: manager Location manager used to get the location.
+	:param: didChangeAuthorizationStatus status Permission status
 	*/
 	*/
 	func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
 	func locationManager(manager: CLLocationManager!, didChangeAuthorizationStatus status: CLAuthorizationStatus) {
 		if status == CLAuthorizationStatus.authorizedWhenInUse {
 		if status == CLAuthorizationStatus.authorizedWhenInUse {
@@ -89,7 +98,7 @@ class LocationView: UIView {
 	
 	
 	
 	
 	/**
 	/**
-	Get new location
+	Get new user location and recalculates distance to GM .
 	*/
 	*/
 	func getNewLocation(){
 	func getNewLocation(){
 		let defaults = UserDefaults.standard
 		let defaults = UserDefaults.standard
@@ -132,11 +141,24 @@ class LocationView: UIView {
 	}
 	}
 
 
 
 
+	/**
+	Converts degrees to radians.
+	:param: degrees Angle in degrees.
+	:return: Angle in radiands.
+	*/
 	func degreesToRadians(degrees: Double) -> Double {
 	func degreesToRadians(degrees: Double) -> Double {
 		return degrees * Double.pi / 180;
 		return degrees * Double.pi / 180;
 	}
 	}
 
 
 
 
+	/**
+	Calculates the distance, in integer meters, between two coordinates.
+	:param: lat1 Latitude component of the first point.
+	:param: lon1 Longitude component of the first point.
+	:param: lat2 Latitude component of the second point.
+	:param: lon2 Longitude component of the second point.
+	:return: Distance, in integer meters, between the points.
+	*/
 	func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Int {
 	func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Int {
 		let eRadius: Double = 6371
 		let eRadius: Double = 6371
 
 
@@ -152,7 +174,9 @@ class LocationView: UIView {
 		return Int(m)
 		return Int(m)
 	}
 	}
 	
 	
-	/*func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutableRawPointer) {
+	/*
+	// TODO: Whato does this do?
+	func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutableRawPointer) {
 		if !didFindMyLocation {
 		if !didFindMyLocation {
 			let myLocation: CLLocation = change[NSKeyValueChangeNewKey] as CLLocation
 			let myLocation: CLLocation = change[NSKeyValueChangeNewKey] as CLLocation
 			map.camera = GMSCameraPosition.camera(withTarget: myLocation.coordinate, zoom: 10.0)
 			map.camera = GMSCameraPosition.camera(withTarget: myLocation.coordinate, zoom: 10.0)

+ 36 - 12
app/Notifications.swift

@@ -23,8 +23,9 @@ import CoreData
 import UIKit
 import UIKit
 import UserNotifications
 import UserNotifications
 
 
+
 /**
 /**
-Class to handle server sync.
+Class to fetch notifications from the server.
 */
 */
 class Notifications{
 class Notifications{
 	
 	
@@ -45,13 +46,12 @@ class Notifications{
 	func buildUrl() -> URL{
 	func buildUrl() -> URL{
 		
 		
 		let url = URL(string: "https://margolariak.com/API/v1/notifications.php")
 		let url = URL(string: "https://margolariak.com/API/v1/notifications.php")
-		
 		return url!
 		return url!
 	}
 	}
 	
 	
 	
 	
 	/**
 	/**
-	Performs an asynchronous sync.
+	Performs an asynchronous request.
 	It fetches the info from the server and stores as Core Data
 	It fetches the info from the server and stores as Core Data
 	:param: url The url to sync.
 	:param: url The url to sync.
 	*/
 	*/
@@ -186,12 +186,23 @@ class Notifications{
 						if #available(iOS 10.0, *) {
 						if #available(iOS 10.0, *) {
 							let content = UNMutableNotificationContent()
 							let content = UNMutableNotificationContent()
 							
 							
-							// TODO Select language.
-							content.title = title_es
-							content.body = text_es
+							let lang = getLanguage()
+							switch lang{
+								case "en":
+									content.title = title_en
+									content.body = text_en
+									break;
+								case "eu":
+									content.title = title_eu
+									content.body = text_eu
+									break;
+								default:
+									content.title = title_es
+									content.body = text_es
+							}
 							content.sound = UNNotificationSound.default()
 							content.sound = UNNotificationSound.default()
 							let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1, repeats: false)
 							let trigger = UNTimeIntervalNotificationTrigger.init(timeInterval: 1, repeats: false)
-							let request = UNNotificationRequest.init(identifier: "Not", content: content, trigger: trigger)
+							let request = UNNotificationRequest.init(identifier: "Not\(id)", content: content, trigger: trigger)
 							
 							
 							// Schedule the notification.
 							// Schedule the notification.
 							let center = UNUserNotificationCenter.current()
 							let center = UNUserNotificationCenter.current()
@@ -199,10 +210,10 @@ class Notifications{
 								(error) in
 								(error) in
 								NSLog(":NOTIFICATION:ERROR: Error showing notification \(String(describing: error))")
 								NSLog(":NOTIFICATION:ERROR: Error showing notification \(String(describing: error))")
 							}
 							}
-						} else {
-							// Fallback on earlier versions
 						}
 						}
-						// TODO Get language
+						else {
+							NSLog(":NOTIFICATION:ERROR: Can't send notifications in iOS versions lower than 10. Not showing notification \(id)")
+						}
 						
 						
 					}
 					}
 					catch let error as NSError  {
 					catch let error as NSError  {
@@ -218,6 +229,19 @@ class Notifications{
 			}
 			}
 		}
 		}
 	}
 	}
-	
-	
+
+	/**
+	Gets the device language. The only recognized languages are Spanish, English and Basque.
+	If the device has another language, Spanish will be selected by default.
+	:return: Two-letter language code.}
+	*/
+	func getLanguage() -> String{
+		let pre = NSLocale.preferredLanguages[0].subStr(start: 0, end: 1)
+		if(pre == "es" || pre == "en" || pre == "eu"){
+			return pre
+		}
+		else{
+			return "es"
+		}
+	}
 }
 }

+ 4 - 2
app/PastActivityViewController.swift

@@ -19,6 +19,7 @@
 // If not, see <http://www.gnu.org/licenses/>.
 // If not, see <http://www.gnu.org/licenses/>.
 
 
 import UIKit
 import UIKit
+
 import CoreData
 import CoreData
 
 
 /**
 /**
@@ -78,8 +79,8 @@ class PastActivityViewController: UIViewController, UIGestureRecognizerDelegate
 	
 	
 	
 	
 	/**
 	/**
-	Loads the selected post.
-	:param: id Post id.
+	Loads the selected activity.
+	:param: id Activity id.
 	*/
 	*/
 	public func loadActivity(id: Int){
 	public func loadActivity(id: Int){
 		
 		
@@ -187,6 +188,7 @@ class PastActivityViewController: UIViewController, UIGestureRecognizerDelegate
 		
 		
 		return strDate
 		return strDate
 	}
 	}
+
 	
 	
 	/**
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	Gets the device language. The only recognized languages are Spanish, English and Basque.

+ 5 - 4
app/PhotoViewController.swift

@@ -21,8 +21,9 @@
 import UIKit
 import UIKit
 import CoreData
 import CoreData
 
 
+
 /**
 /**
-The view controller of the app.
+The controller to show photos.
 */
 */
 class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
 class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
 
 
@@ -90,7 +91,7 @@ class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
 				self.albumTitle = r.value(forKey: "title_\(lang)")! as! String
 				self.albumTitle = r.value(forKey: "title_\(lang)")! as! String
 			}
 			}
 			catch {
 			catch {
-				NSLog(":GALLERYCONTROLLER:ERROR: Error getting album info: \(error)")
+				NSLog(":PHOTO:ERROR: Error getting album info: \(error)")
 			}
 			}
 			
 			
 		} catch {
 		} catch {
@@ -149,7 +150,7 @@ class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
 	
 	
 	/**
 	/**
 	Loads a photo in the viewer.
 	Loads a photo in the viewer.
-	:param: id
+	:param: id Photo id.
 	*/
 	*/
 	public func loadPhoto(id: Int){
 	public func loadPhoto(id: Int){
 		
 		
@@ -217,12 +218,12 @@ class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
 		}
 		}
 	}
 	}
 	
 	
-
 	
 	
 	/**
 	/**
 	Formats a date to the desired language.
 	Formats a date to the desired language.
 	:param: text The date.
 	:param: text The date.
 	:param: lang Device language (only 'es', 'en', or 'eu').
 	:param: lang Device language (only 'es', 'en', or 'eu').
+	:return: Human readable string in the required language.
 	*/
 	*/
 	func formatDate(date: NSDate, lang: String) -> String{
 	func formatDate(date: NSDate, lang: String) -> String{
 		
 		

+ 19 - 6
app/PostViewController.swift

@@ -21,8 +21,9 @@
 import UIKit
 import UIKit
 import CoreData
 import CoreData
 
 
+
 /**
 /**
-The view controller of the app.
+View controller to show a post.
 */
 */
 class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	
 	
@@ -37,6 +38,11 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	var passId: Int = -1
 	var passId: Int = -1
 	var delegate: AppDelegate?
 	var delegate: AppDelegate?
 	
 	
+
+	/**
+	Gets the application context.
+	:return: Application context.
+	*/
 	func getContext () -> NSManagedObjectContext {
 	func getContext () -> NSManagedObjectContext {
 		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
 		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
 	}
 	}
@@ -55,6 +61,9 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	}
 	}
 		
 		
 	
 	
+	/**
+	Dismisses the controller, efectively going to the previous section.
+	*/
 	func back() {
 	func back() {
 		self.dismiss(animated: true, completion: nil)
 		self.dismiss(animated: true, completion: nil)
 	}
 	}
@@ -67,6 +76,11 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		super.didReceiveMemoryWarning()
 		super.didReceiveMemoryWarning()
 	}
 	}
 	
 	
+
+	/**
+	Actually loads the post.
+	:param: id Post id.
+	*/
 	public func loadPost(id: Int){
 	public func loadPost(id: Int){
 		
 		
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
@@ -77,14 +91,12 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
 		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
 		
 		
 		do {
 		do {
-			//go get the results
 			let searchResults = try context.fetch(fetchRequest)
 			let searchResults = try context.fetch(fetchRequest)
 			
 			
 			var sTitle: String
 			var sTitle: String
 			var sText: String
 			var sText: String
 			var image: String
 			var image: String
 			
 			
-			//You need to convert to NSManagedObject to use 'for' loops
 			for r in searchResults as [NSManagedObject] {
 			for r in searchResults as [NSManagedObject] {
 				
 				
 				sTitle = r.value(forKey: "title_\(lang)")! as! String
 				sTitle = r.value(forKey: "title_\(lang)")! as! String
@@ -100,7 +112,6 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 				imgFetchRequest.sortDescriptors = imgSortDescriptors
 				imgFetchRequest.sortDescriptors = imgSortDescriptors
 				imgFetchRequest.predicate = NSPredicate(format: "post == %i", id)
 				imgFetchRequest.predicate = NSPredicate(format: "post == %i", id)
 				imgFetchRequest.fetchLimit = 1
 				imgFetchRequest.fetchLimit = 1
-				//TODO get more images
 				do{
 				do{
 					let imgSearchResults = try context.fetch(imgFetchRequest)
 					let imgSearchResults = try context.fetch(imgFetchRequest)
 					for imgR in imgSearchResults as [NSManagedObject]{
 					for imgR in imgSearchResults as [NSManagedObject]{
@@ -113,12 +124,14 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 							self.postImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 							self.postImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 						}
 						}
 					}
 					}
-				} catch {
+				}
+				catch {
 					NSLog(":POST:ERROR: Error getting image for post \(id): \(error)")
 					NSLog(":POST:ERROR: Error getting image for post \(id): \(error)")
 				}
 				}
 				
 				
 			}
 			}
-		} catch {
+		}
+		catch {
 			NSLog(":POST:ERROR: Error with request: \(error)")
 			NSLog(":POST:ERROR: Error with request: \(error)")
 		}
 		}
 	}
 	}

+ 23 - 9
app/RowAlbum.swift

@@ -21,8 +21,9 @@
 import Foundation
 import Foundation
 import UIKit
 import UIKit
 
 
+
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as a row of an album.
 */
 */
 @IBDesignable class RowAlbum: UIView {
 @IBDesignable class RowAlbum: UIView {
 	
 	
@@ -41,11 +42,13 @@ Extension of UIView to be formatted as sections.
 	var preview: [UIImageView] = []
 	var preview: [UIImageView] = []
 
 
 	/**
 	/**
-	Default constructor
+	Default constructor.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
 	}
 	}
+
 	
 	
 	/**
 	/**
 	Loads the view from the xib with the same name as the class.
 	Loads the view from the xib with the same name as the class.
@@ -83,25 +86,30 @@ Extension of UIView to be formatted as sections.
 		//Populate review array
 		//Populate review array
 		self.preview = [self.photo0, self.photo1]
 		self.preview = [self.photo0, self.photo1]
 		
 		
-		// Set tap recognizers
-		// TODO
-		//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowAlbum.openPhoto(_:)))
-		//tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		//self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
+
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: frame View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
 	}
 	}
 	
 	
+
+	/**
+	Opens the photo in the left side in a new controller.
+	*/
 	func openLeftPhoto(_ sender:UITapGestureRecognizer? = nil){
 	func openLeftPhoto(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.albumController?.showPhoto(album: self.id, photo: self.photoIds[0])
 		delegate.albumController?.showPhoto(album: self.id, photo: self.photoIds[0])
 	}
 	}
-	
+
+
+	/**
+	Opens the photo in the right side in a new controller.
+	*/
 	func openRightPhoto(_ sender:UITapGestureRecognizer? = nil){
 	func openRightPhoto(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		delegate.albumController?.showPhoto(album: self.id, photo: self.photoIds[1])
 		delegate.albumController?.showPhoto(album: self.id, photo: self.photoIds[1])
@@ -137,7 +145,13 @@ Extension of UIView to be formatted as sections.
 			}
 			}
 		}
 		}
 	}
 	}
+
 	
 	
+	/**
+	Set the image id for both photos.
+	:param: left Id of the photo in the left.
+	:param: right Id of the photo on the right.
+	*/
 	func setIds(left: Int, right: Int){
 	func setIds(left: Int, right: Int){
 		self.photoIds[0] = left
 		self.photoIds[0] = left
 		self.photoIds[1] = right
 		self.photoIds[1] = right

+ 4 - 2
app/RowBlog.swift

@@ -38,7 +38,8 @@ Extension of UIView to be formatted as post rows.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
@@ -80,7 +81,8 @@ Extension of UIView to be formatted as post rows.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: frame View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)

+ 6 - 4
app/RowFutureActivity.swift

@@ -21,6 +21,7 @@
 import Foundation
 import Foundation
 import UIKit
 import UIKit
 
 
+
 /**
 /**
 Extension of UIView to be formatted as future activity rows.
 Extension of UIView to be formatted as future activity rows.
 */
 */
@@ -40,7 +41,7 @@ Extension of UIView to be formatted as future activity rows.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
 	:param: coder Coder.
 	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
@@ -83,7 +84,8 @@ Extension of UIView to be formatted as future activity rows.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: frame View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -184,7 +186,7 @@ Extension of UIView to be formatted as future activity rows.
 	
 	
 	/**
 	/**
 	Changes the image of the activity.
 	Changes the image of the activity.
-	If null or empty, the igage is hidden.
+	If null or empty, the image is hidden.
 	:param: path The new text.
 	:param: path The new text.
 	*/
 	*/
 	func setImage(filename: String){
 	func setImage(filename: String){
@@ -200,7 +202,7 @@ Extension of UIView to be formatted as future activity rows.
 	
 	
 	
 	
 	/**
 	/**
-	Opens an activity.
+	Opens an activity in a new controller.
 	*/
 	*/
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate

+ 5 - 3
app/RowGallery.swift

@@ -42,7 +42,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
@@ -89,7 +90,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: frame View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -97,7 +99,7 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Opens an album.
+	Opens an album in other controller.
 	*/
 	*/
 	func openAlbum(_ sender:UITapGestureRecognizer? = nil){
 	func openAlbum(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate

+ 9 - 6
app/RowHomeBlog.swift

@@ -21,8 +21,9 @@
 import Foundation
 import Foundation
 import UIKit
 import UIKit
 
 
+
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as a row on the blog section of the home view.
 */
 */
 @IBDesignable class RowHomeBlog: UIView {
 @IBDesignable class RowHomeBlog: UIView {
 
 
@@ -38,7 +39,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
@@ -80,7 +82,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: frame View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -97,7 +100,7 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Changes the text of the text. Decodes HTML.
+	Changes the text of the post. Decodes HTML.
 	:param: text The new text.
 	:param: text The new text.
 	*/
 	*/
 	func setText(text: String){
 	func setText(text: String){
@@ -106,7 +109,7 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Changes the image of the activity.
+	Changes the image of the post.
 	If null or empty, the igage is hidden.
 	If null or empty, the igage is hidden.
 	:param: path The new text.
 	:param: path The new text.
 	*/
 	*/
@@ -123,7 +126,7 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Opens a post.
+	Opens a post in a controller.
 	*/
 	*/
 	func openPost(_ sender:UITapGestureRecognizer? = nil){
 	func openPost(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate

+ 7 - 4
app/RowHomeFutureActivities.swift

@@ -21,8 +21,9 @@
 import Foundation
 import Foundation
 import UIKit
 import UIKit
 
 
+
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as a future activity in the home screen.
 */
 */
 @IBDesignable class RowHomeFutureActivities: UIView {
 @IBDesignable class RowHomeFutureActivities: UIView {
 	
 	
@@ -38,7 +39,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
@@ -80,7 +82,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: fraom View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -123,7 +126,7 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Opens an activity.
+	Opens an activity in a controller.
 	*/
 	*/
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
 		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate

+ 8 - 7
app/RowHomeGallery.swift

@@ -21,8 +21,9 @@
 import Foundation
 import Foundation
 import UIKit
 import UIKit
 
 
+
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as a the gallery section in the home view.
 */
 */
 @IBDesignable class RowHomeGallery: UIView {
 @IBDesignable class RowHomeGallery: UIView {
 	
 	
@@ -39,7 +40,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor
+	Default constructor.
+	:param: coder Coder.
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
@@ -74,9 +76,6 @@ Extension of UIView to be formatted as sections.
 		self.addSubview(container)
 		self.addSubview(container)
 		
 		
 		self.photos = [photo0, photo1, photo2, photo3]
 		self.photos = [photo0, photo1, photo2, photo3]
-		
-
-		//TODO Set click listeners
 	}
 	}
 	
 	
 	
 	
@@ -117,7 +116,8 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Default constructor for the interface builder
+	Default constructor for the interface builder.
+	:param: frame View frame.
 	*/
 	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
@@ -127,7 +127,8 @@ Extension of UIView to be formatted as sections.
 	/**
 	/**
 	Changes the preview image.
 	Changes the preview image.
 	If null or empty, the igage is hidden.
 	If null or empty, the igage is hidden.
-	:param: path The new text.
+	:param: path idx Index of the image (0-3).
+	:filename: path to the image.
 	*/
 	*/
 	func setImage(idx: Int, filename: String){
 	func setImage(idx: Int, filename: String){
 		if (filename == ""){
 		if (filename == ""){

+ 8 - 0
app/RowItinerary.swift

@@ -35,6 +35,7 @@ Extension of UIView to be formatted an activity itinerary.
 	@IBOutlet weak var lbLocation: UILabel!
 	@IBOutlet weak var lbLocation: UILabel!
 	
 	
 	var id: Int = -1
 	var id: Int = -1
+	var type: String = ""
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -71,6 +72,11 @@ Extension of UIView to be formatted an activity itinerary.
 		
 		
 		container.frame = self.bounds
 		container.frame = self.bounds
 		self.addSubview(container)
 		self.addSubview(container)
+		
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowItinerary.openItinerary(_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
 	
 	
@@ -164,5 +170,7 @@ Extension of UIView to be formatted an activity itinerary.
 	func openItinerary(_ sender:UITapGestureRecognizer? = nil){
 	func openItinerary(_ sender:UITapGestureRecognizer? = nil){
 		// TODO implement openItinerary.
 		// TODO implement openItinerary.
 		NSLog(":ROWITINERARY:DEBUG: Open Itinerary")
 		NSLog(":ROWITINERARY:DEBUG: Open Itinerary")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.futureActivityController?.showItinerary(id: self.id)
 	}
 	}
 }
 }

+ 13 - 4
app/RowSchedule.swift

@@ -34,6 +34,8 @@ Extension of UIView to be formatted as sections.
 	@IBOutlet weak var lbText: UILabel!
 	@IBOutlet weak var lbText: UILabel!
 	@IBOutlet weak var lbLocation: UILabel!
 	@IBOutlet weak var lbLocation: UILabel!
 	
 	
+	var id: Int = -1
+	
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -70,6 +72,12 @@ Extension of UIView to be formatted as sections.
 		
 		
 		container.frame = self.bounds
 		container.frame = self.bounds
 		self.addSubview(container)
 		self.addSubview(container)
+		
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowSchedule.openSchedule(_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
+
 	}
 	}
 	
 	
 	
 	
@@ -154,10 +162,11 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Opens an event dialog.
+	Opens an schedule dialog.
 	*/
 	*/
-	func openEvent(_ sender:UITapGestureRecognizer? = nil){
-		// TODO implement openEvent.
-		NSLog(":ROWSCHEDULE:DEBUG: Open Event")
+	func openSchedule(_ sender:UITapGestureRecognizer? = nil){
+		NSLog(":ROWSCHEDULE:DEBUG: Open schedule")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.scheduleController?.showEvent(id: self.id)
 	}
 	}
 }
 }

+ 31 - 2
app/ScheduleViewController.swift

@@ -19,8 +19,6 @@
 // If not, see <http://www.gnu.org/licenses/>.
 // If not, see <http://www.gnu.org/licenses/>.
 
 
 
 
-// TODO: Barely working. City schedule not working, GM is shown but events times are mixed.
-
 import UIKit
 import UIKit
 import CoreData
 import CoreData
 
 
@@ -51,6 +49,8 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 	var days: [NSDate] = [NSDate]()
 	var days: [NSDate] = [NSDate]()
 	var selectedDay: Int = 0
 	var selectedDay: Int = 0
 
 
+	// Id of event to open.
+	var passId: Int = -1
 	
 	
 	/**
 	/**
 	Gets the application context.
 	Gets the application context.
@@ -107,6 +107,7 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 		
 		
 		self.context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		self.context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
+		self.delegate?.scheduleController = self
 		self.lang = getLanguage()
 		self.lang = getLanguage()
 		self.context?.persistentStoreCoordinator = self.delegate?.persistentStoreCoordinator
 		self.context?.persistentStoreCoordinator = self.delegate?.persistentStoreCoordinator
 
 
@@ -233,6 +234,7 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 		
 		
 		var rowcount = 0
 		var rowcount = 0
 		var row: RowSchedule
 		var row: RowSchedule
+		var id: Int
 		var start: NSDate
 		var start: NSDate
 		var title: String
 		var title: String
 		var text: String
 		var text: String
@@ -258,6 +260,8 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 			
 			
 			for r in searchResults! {
 			for r in searchResults! {
 				
 				
+				id = r.value(forKey: "id") as! Int
+				
 				title = r.value(forKey: "title_\(lang!)") as! String
 				title = r.value(forKey: "title_\(lang!)") as! String
 				if r.value(forKey: "description_\(lang!)") != nil{
 				if r.value(forKey: "description_\(lang!)") != nil{
 					text = r.value(forKey: "description_\(lang!)") as! String
 					text = r.value(forKey: "description_\(lang!)") as! String
@@ -272,6 +276,7 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 				row.setTitle(text: title)
 				row.setTitle(text: title)
 				row.setText(text: text)
 				row.setText(text: text)
 				row.setTime(dtime: start)
 				row.setTime(dtime: start)
+				row.id = id
 				
 				
 				// Get location info from Place entity
 				// Get location info from Place entity
 				let locationFetchRequest: NSFetchRequest<Place> = Place.fetchRequest()
 				let locationFetchRequest: NSFetchRequest<Place> = Place.fetchRequest()
@@ -336,6 +341,30 @@ class ScheduleViewController: UIViewController, UIGestureRecognizerDelegate {
 	}
 	}
 	
 	
 	
 	
+	/**
+	Shows an event dialog.
+	:param: id The event id.
+	*/
+	func showEvent(id: Int){
+		NSLog(":SCHEDULECONTROLLER:DEBUG: Show event \(id)")
+		self.passId = id
+		performSegue(withIdentifier: "SegueEvent", sender: nil)
+	}
+	
+	
+	/**
+	Run before performing a segue.
+	Assigns id if neccessary.
+	:param: segue The segue to perform.
+	:sender: The calling view.
+	*/
+	override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
+		if segue.identifier == "SegueEvent"{
+			(segue.destination as! EventController).id = passId
+		}
+	}
+	
+	
 	/**
 	/**
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	Gets the device language. The only recognized languages are Spanish, English and Basque.
 	If the device has another language, Spanish will be selected by default.
 	If the device has another language, Spanish will be selected by default.

+ 30 - 57
app/ViewController.swift

@@ -31,9 +31,6 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	
 	
 	//The menu collection.
 	//The menu collection.
 	var sectionCollection: UICollectionView!
 	var sectionCollection: UICollectionView!
-	
-	// Need to save the sync segue.
-	var syncSegue: UIStoryboardSegue?
 
 
 	//Each of the sections of the app.
 	//Each of the sections of the app.
 	@IBOutlet var containerViewGallery: GalleryView!
 	@IBOutlet var containerViewGallery: GalleryView!
@@ -43,6 +40,11 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	@IBOutlet var containerViewLocation: LocationView!
 	@IBOutlet var containerViewLocation: LocationView!
 	@IBOutlet var containerViewHome: HomeView!
 	@IBOutlet var containerViewHome: HomeView!
 	
 	
+	//Menu items.
+	let reuseIdentifier = "cell"
+	var selected = 0
+	var items = ["Inicio", "Localización", "La Blanca", "Actividades", "Blog", "Galería"]
+	
 	// Passed id to perform segues.
 	// Passed id to perform segues.
 	var passId: Int = -1
 	var passId: Int = -1
 	var passAlbum: Int = -1
 	var passAlbum: Int = -1
@@ -50,8 +52,6 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	// Location-related variables.
 	// Location-related variables.
 	var locationManager = CLLocationManager()
 	var locationManager = CLLocationManager()
 	var didFindMyLocation = false
 	var didFindMyLocation = false
-	
-	
 	var locationTimer: Timer? = nil
 	var locationTimer: Timer? = nil
 	
 	
 	
 	
@@ -65,6 +65,9 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		
 		
 	}
 	}
 	
 	
+	/**
+	Gets the device-reported location.
+	*/
 	func getLocation() -> CLLocationCoordinate2D {
 	func getLocation() -> CLLocationCoordinate2D {
 		return (locationManager.location?.coordinate)!
 		return (locationManager.location?.coordinate)!
 	}
 	}
@@ -147,20 +150,6 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	}
 	}
 	
 	
 	
 	
-	/** 
-	Handles the initial sync process.
-	It can start it, showing the sync screen, or finish it, hidding the screen.
-	:param: showScreen True to start the sync, false to end it.
-	*/
-	func initialSync(showScreen: Bool){
-		if showScreen == true{
-			Sync(synchronous: true)
-		}
-		else{
-			syncSegue?.destination.dismiss(animated: true, completion: nil)
-		}
-	}
-	
 	/**
 	/**
 	Run before performing a segue.
 	Run before performing a segue.
 	Assigns id if neccessary.
 	Assigns id if neccessary.
@@ -186,9 +175,6 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 				(segue.destination as! ScheduleViewController).margolari = false
 				(segue.destination as! ScheduleViewController).margolari = false
 			}
 			}
 		}
 		}
-		if segue.identifier == "SegueSync"{
-			self.syncSegue = segue
-		}
 		if segue.identifier == "SeguePastActivity"{
 		if segue.identifier == "SeguePastActivity"{
 			(segue.destination as! PastActivityViewController).id = passId
 			(segue.destination as! PastActivityViewController).id = passId
 		}
 		}
@@ -197,9 +183,6 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		}
 		}
 	}
 	}
 	
 	
-	override func viewWillAppear(_ animated: Bool) {
-		super.viewWillAppear(animated)
-	}
 	
 	
 	/**
 	/**
 	Run when the app loads.
 	Run when the app loads.
@@ -220,44 +203,22 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		// Start the location schedule
 		// Start the location schedule
 		fetchLocation()
 		fetchLocation()
 		self.locationTimer = Timer.scheduledTimer(timeInterval: 90, target: self, selector: #selector(fetchLocation), userInfo: nil, repeats: true)
 		self.locationTimer = Timer.scheduledTimer(timeInterval: 90, target: self, selector: #selector(fetchLocation), userInfo: nil, repeats: true)
-				
-		NSLog(":CONTROLLER:DEBUG: Don't skyp sync")
-		//NSLog(":CONTROLLER:DEBUG: Skyp sync")
-		//Notifications()
-		//Sync()
-
 		
 		
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.delegate?.controller = self
 		self.delegate?.controller = self
 		
 		
-		//self.sectionCollection.visibleCells[0].isSelected = true
-		
 		super.viewDidLoad()
 		super.viewDidLoad()
 		
 		
 	}
 	}
 	
 	
+	/**
+	Asynchronously gets a location report from the server.
+	*/
 	func fetchLocation(){
 	func fetchLocation(){
 		FetchLocation()
 		FetchLocation()
 	}
 	}
 	
 	
 	
 	
-	/**
-	Executed when the view is actually shown.
-	Performs the initial sync in the first run.
-	It also generates a user id if none exists.
-	:param: animated Wether the controller appearance must be animated or not.
-	*/
-	override func viewDidAppear(_ animated: Bool) {
-		super.viewDidAppear(animated)
-		/*if UserDefaults.standard.object(forKey: "userId") == nil{
-			let newUid = randomString(length: 16)
-			let defaults = UserDefaults.standard
-			defaults.set(newUid, forKey: "userId")
-			initialSync(showScreen: true)
-		}*/
-		
-	}
-	
 	/**
 	/**
 	Generates a random string to be used as a user identifier.
 	Generates a random string to be used as a user identifier.
 	:param: length The length of the generated string.
 	:param: length The length of the generated string.
@@ -278,7 +239,8 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		
 		
 		return randomString
 		return randomString
 	}
 	}
-
+	
+	
 	/**
 	/**
 	Dispose of any resources that can be recreated.
 	Dispose of any resources that can be recreated.
 	*/
 	*/
@@ -287,13 +249,9 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	}
 	}
 	
 	
 	
 	
-	//Menu items.
-	let reuseIdentifier = "cell"
-	var selected = 0
-	var items = ["Home", "Location", "La Blanca", "Actividades", "Blog", "Gallery"]
-	
 	// MARK: - UICollectionViewDataSource protocol
 	// MARK: - UICollectionViewDataSource protocol
 	
 	
+	
 	/**
 	/**
 	Sets a collection of menu items.
 	Sets a collection of menu items.
 	:param: numberOfItemsInSection The number of entries of the menu.
 	:param: numberOfItemsInSection The number of entries of the menu.
@@ -303,7 +261,11 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		return self.items.count
 		return self.items.count
 	}
 	}
 	
 	
-	//Make a cell for each section
+	
+	/**
+	Sets up the menu bar.
+	:param: cellForItemAt indexPath One cell of the menu.
+	*/
 	func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 	func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
 		
 		
 		//Get a reference to our storyboard cell
 		//Get a reference to our storyboard cell
@@ -322,16 +284,27 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	
 	
 	// MARK: - UICollectionViewDelegate protocol
 	// MARK: - UICollectionViewDelegate protocol
 	
 	
+	
+	/**
+	Inits items in the menu bar.
+	:paramm: didSelectItemAt item index
+	*/
 	func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
 	func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
 		sectionCollection = collectionView
 		sectionCollection = collectionView
 		showComponent(selected: indexPath.item)
 		showComponent(selected: indexPath.item)
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Caled when an item of the menu bar is selected.
 	Caled when an item of the menu bar is selected.
 	:param: selected Index of the selected item.
 	:param: selected Index of the selected item.
 	*/
 	*/
 	@IBAction func showComponent(selected: Int) {
 	@IBAction func showComponent(selected: Int) {
+	
+		// Reverts the style of the first tab.
+		if selected != 0{
+			self.sectionCollection.visibleCells[0].isSelected = false
+		}
 				
 				
 		//Show the view
 		//Show the view
 		if selected == 0 {
 		if selected == 0 {