Przeglądaj źródła

Merge branch 'BaseProject'

Iñigo Valentin 9 lat temu
rodzic
commit
7f90cde70c

+ 18 - 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 */; };
+		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 */; };
 		935AE18C1ECE162C0055E71F /* RowLablancaOffer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 935AE18B1ECE162B0055E71F /* RowLablancaOffer.xib */; };
 		935AE18C1ECE162C0055E71F /* RowLablancaOffer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 935AE18B1ECE162B0055E71F /* RowLablancaOffer.xib */; };
@@ -83,8 +84,10 @@
 		93E0C5EE1EBE25BD00905811 /* RowLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E0C5ED1EBE25BC00905811 /* RowLabel.swift */; };
 		93E0C5EE1EBE25BD00905811 /* RowLabel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E0C5ED1EBE25BC00905811 /* RowLabel.swift */; };
 		93E0C5F21EBE264F00905811 /* RowLabel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93E0C5F11EBE264F00905811 /* RowLabel.xib */; };
 		93E0C5F21EBE264F00905811 /* RowLabel.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93E0C5F11EBE264F00905811 /* RowLabel.xib */; };
 		93E0C5F41EBE306900905811 /* ScheduleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E0C5F31EBE306900905811 /* ScheduleViewController.swift */; };
 		93E0C5F41EBE306900905811 /* ScheduleViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E0C5F31EBE306900905811 /* ScheduleViewController.swift */; };
+		93E5058F1EEB0DCC00560B4A /* PhotoViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E5058E1EEB0DCC00560B4A /* PhotoViewController.swift */; };
 		93EB2F0C1EBF5AEB00F64186 /* RowSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93EB2F0B1EBF5AEB00F64186 /* RowSchedule.swift */; };
 		93EB2F0C1EBF5AEB00F64186 /* RowSchedule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93EB2F0B1EBF5AEB00F64186 /* RowSchedule.swift */; };
 		93EB2F0E1EBF5BF500F64186 /* RowSchedule.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93EB2F0D1EBF5BF500F64186 /* RowSchedule.xib */; };
 		93EB2F0E1EBF5BF500F64186 /* RowSchedule.xib in Resources */ = {isa = PBXBuildFile; fileRef = 93EB2F0D1EBF5BF500F64186 /* RowSchedule.xib */; };
+		93EE9ECB1EE9B87100288F6E /* PastActivityViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93EE9ECA1EE9B87100288F6E /* PastActivityViewController.swift */; };
 /* End PBXBuildFile section */
 /* End PBXBuildFile section */
 
 
 /* Begin PBXFileReference section */
 /* Begin PBXFileReference section */
@@ -100,6 +103,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>"; };
+		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>"; };
 		935AE18B1ECE162B0055E71F /* RowLablancaOffer.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowLablancaOffer.xib; sourceTree = "<group>"; };
 		935AE18B1ECE162B0055E71F /* RowLablancaOffer.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowLablancaOffer.xib; sourceTree = "<group>"; };
@@ -167,8 +171,10 @@
 		93E0C5ED1EBE25BC00905811 /* RowLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowLabel.swift; sourceTree = "<group>"; };
 		93E0C5ED1EBE25BC00905811 /* RowLabel.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowLabel.swift; sourceTree = "<group>"; };
 		93E0C5F11EBE264F00905811 /* RowLabel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowLabel.xib; sourceTree = "<group>"; };
 		93E0C5F11EBE264F00905811 /* RowLabel.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowLabel.xib; sourceTree = "<group>"; };
 		93E0C5F31EBE306900905811 /* ScheduleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduleViewController.swift; sourceTree = "<group>"; };
 		93E0C5F31EBE306900905811 /* ScheduleViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ScheduleViewController.swift; sourceTree = "<group>"; };
+		93E5058E1EEB0DCC00560B4A /* PhotoViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PhotoViewController.swift; sourceTree = "<group>"; };
 		93EB2F0B1EBF5AEB00F64186 /* RowSchedule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowSchedule.swift; sourceTree = "<group>"; };
 		93EB2F0B1EBF5AEB00F64186 /* RowSchedule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RowSchedule.swift; sourceTree = "<group>"; };
 		93EB2F0D1EBF5BF500F64186 /* RowSchedule.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowSchedule.xib; sourceTree = "<group>"; };
 		93EB2F0D1EBF5BF500F64186 /* RowSchedule.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = RowSchedule.xib; sourceTree = "<group>"; };
+		93EE9ECA1EE9B87100288F6E /* PastActivityViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PastActivityViewController.swift; sourceTree = "<group>"; };
 /* End PBXFileReference section */
 /* End PBXFileReference section */
 
 
 /* Begin PBXFrameworksBuildPhase section */
 /* Begin PBXFrameworksBuildPhase section */
@@ -226,8 +232,8 @@
 				93B84B991D9C31AB006C0F67 /* AppDelegate.swift */,
 				93B84B991D9C31AB006C0F67 /* AppDelegate.swift */,
 				93B84B9D1D9C31AB006C0F67 /* Main.storyboard */,
 				93B84B9D1D9C31AB006C0F67 /* Main.storyboard */,
 				93B84B9B1D9C31AB006C0F67 /* ViewController.swift */,
 				93B84B9B1D9C31AB006C0F67 /* ViewController.swift */,
-				93B408021D9ED44C000FBC99 /* MenuCollectionViewCell.swift */,
 				93BEB6D11E7E878300C68DE5 /* PostViewController.swift */,
 				93BEB6D11E7E878300C68DE5 /* PostViewController.swift */,
+				93B408021D9ED44C000FBC99 /* MenuCollectionViewCell.swift */,
 				93D9EA5F1DE271E700089002 /* Section.xib */,
 				93D9EA5F1DE271E700089002 /* Section.xib */,
 				93D9EA631DE273FD00089002 /* Section.swift */,
 				93D9EA631DE273FD00089002 /* Section.swift */,
 				931AA5AD1E218D0D003A2290 /* Entry.xib */,
 				931AA5AD1E218D0D003A2290 /* Entry.xib */,
@@ -247,6 +253,7 @@
 				93075C711E59D06900396389 /* RowBlog.xib */,
 				93075C711E59D06900396389 /* RowBlog.xib */,
 				93075C6F1E59D04A00396389 /* RowBlog.swift */,
 				93075C6F1E59D04A00396389 /* RowBlog.swift */,
 				93D9EA751DE3ACBB00089002 /* Sync.swift */,
 				93D9EA751DE3ACBB00089002 /* Sync.swift */,
+				9357460F1EE20B99005DED61 /* FetchLocation.swift */,
 				931AA5881E1AFF8C003A2290 /* String.swift */,
 				931AA5881E1AFF8C003A2290 /* String.swift */,
 				93D9EA671DE342AC00089002 /* UIView.swift */,
 				93D9EA671DE342AC00089002 /* UIView.swift */,
 				935892CF1E493C2300E1CD5F /* UIImageView.swift */,
 				935892CF1E493C2300E1CD5F /* UIImageView.swift */,
@@ -281,6 +288,8 @@
 				93B9113C1ED7567B0061BA71 /* LocationView.xib */,
 				93B9113C1ED7567B0061BA71 /* LocationView.xib */,
 				93B9113E1ED7582B0061BA71 /* LocationView.swift */,
 				93B9113E1ED7582B0061BA71 /* LocationView.swift */,
 				93B9115E1ED765510061BA71 /* app-Bridging-Header.h */,
 				93B9115E1ED765510061BA71 /* app-Bridging-Header.h */,
+				93EE9ECA1EE9B87100288F6E /* PastActivityViewController.swift */,
+				93E5058E1EEB0DCC00560B4A /* PhotoViewController.swift */,
 			);
 			);
 			path = app;
 			path = app;
 			sourceTree = "<group>";
 			sourceTree = "<group>";
@@ -345,6 +354,11 @@
 						DevelopmentTeam = 9F9ER4X7TG;
 						DevelopmentTeam = 9F9ER4X7TG;
 						LastSwiftMigration = 0830;
 						LastSwiftMigration = 0830;
 						ProvisioningStyle = Automatic;
 						ProvisioningStyle = Automatic;
+						SystemCapabilities = {
+							com.apple.BackgroundModes = {
+								enabled = 1;
+							};
+						};
 					};
 					};
 				};
 				};
 			};
 			};
@@ -424,6 +438,7 @@
 				93D9EA761DE3ACBB00089002 /* Sync.swift in Sources */,
 				93D9EA761DE3ACBB00089002 /* Sync.swift in Sources */,
 				93E0C5EA1EBDFFB400905811 /* RowPastActivity.swift in Sources */,
 				93E0C5EA1EBDFFB400905811 /* RowPastActivity.swift in Sources */,
 				93BAD2F41E585EE6009DF853 /* RowHomeFutureActivities.swift in Sources */,
 				93BAD2F41E585EE6009DF853 /* RowHomeFutureActivities.swift in Sources */,
+				93E5058F1EEB0DCC00560B4A /* PhotoViewController.swift in Sources */,
 				931AA5891E1AFF8C003A2290 /* String.swift in Sources */,
 				931AA5891E1AFF8C003A2290 /* String.swift in Sources */,
 				935AE18A1EC6138D0055E71F /* SyncController.swift in Sources */,
 				935AE18A1EC6138D0055E71F /* SyncController.swift in Sources */,
 				93B84B9C1D9C31AB006C0F67 /* ViewController.swift in Sources */,
 				93B84B9C1D9C31AB006C0F67 /* ViewController.swift in Sources */,
@@ -432,6 +447,7 @@
 				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 */,
+				93EE9ECB1EE9B87100288F6E /* PastActivityViewController.swift in Sources */,
 				936966ED1E98445200A11055 /* AlbumViewController.swift in Sources */,
 				936966ED1E98445200A11055 /* AlbumViewController.swift in Sources */,
 				93D9EA681DE342AC00089002 /* UIView.swift in Sources */,
 				93D9EA681DE342AC00089002 /* UIView.swift in Sources */,
 				938D211F1EA2306300C47EC3 /* LablancaView.swift in Sources */,
 				938D211F1EA2306300C47EC3 /* LablancaView.swift in Sources */,
@@ -440,6 +456,7 @@
 				93E0C5E41EB7E94300905811 /* ActivitiesView.swift in Sources */,
 				93E0C5E41EB7E94300905811 /* ActivitiesView.swift in Sources */,
 				93B408031D9ED44C000FBC99 /* MenuCollectionViewCell.swift in Sources */,
 				93B408031D9ED44C000FBC99 /* MenuCollectionViewCell.swift in Sources */,
 				93B9113F1ED7582B0061BA71 /* LocationView.swift in Sources */,
 				93B9113F1ED7582B0061BA71 /* LocationView.swift in Sources */,
+				935746101EE20B99005DED61 /* FetchLocation.swift in Sources */,
 				93E0C5E61EBDEF2B00905811 /* RowFutureActivity.swift in Sources */,
 				93E0C5E61EBDEF2B00905811 /* RowFutureActivity.swift in Sources */,
 				935D6E2F1E86792000CED3A1 /* GalleryView.swift in Sources */,
 				935D6E2F1E86792000CED3A1 /* GalleryView.swift in Sources */,
 			);
 			);

+ 7 - 31
app/ActivitiesView.swift

@@ -21,11 +21,13 @@
 import Foundation
 import Foundation
 import CoreData
 import CoreData
 import UIKit
 import UIKit
+
 /**
 /**
 Class to handle the home view.
 Class to handle the home view.
 */
 */
 class ActivitiesView: UIView {
 class ActivitiesView: UIView {
 	
 	
+	// Outlets.
 	@IBOutlet var container: ActivitiesView!
 	@IBOutlet var container: ActivitiesView!
 	@IBOutlet weak var futureSection: Section!
 	@IBOutlet weak var futureSection: Section!
 	@IBOutlet weak var pastSection: Section!
 	@IBOutlet weak var pastSection: Section!
@@ -38,6 +40,7 @@ class ActivitiesView: UIView {
 	var pastList: UIStackView? = nil
 	var pastList: UIStackView? = nil
 	var context: NSManagedObjectContext? = nil
 	var context: NSManagedObjectContext? = nil
 	
 	
+	
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
 	}
 	}
@@ -119,6 +122,7 @@ class ActivitiesView: UIView {
 					row.setPrice(price: price)
 					row.setPrice(price: price)
 					row.setCity(text: city)
 					row.setCity(text: city)
 					row.setDate(date: date, lang: lang!)
 					row.setDate(date: date, lang: lang!)
+					row.id = id
 				
 				
 					// Get main image
 					// Get main image
 					image = ""
 					image = ""
@@ -139,15 +143,10 @@ class ActivitiesView: UIView {
 					}
 					}
 				
 				
 					self.futureList?.addArrangedSubview(row)
 					self.futureList?.addArrangedSubview(row)
-					
-					// TODO: Do this on the row didLoad method
-					// Set tap recognizer
-					//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openActivity(_:)))
-					//row.isUserInteractionEnabled = true
-					//row.addGestureRecognizer(tapRecognizer)
 				}
 				}
 				self.futureList?.setNeedsLayout()
 				self.futureList?.setNeedsLayout()
 				self.futureList?.layoutIfNeeded()
 				self.futureList?.layoutIfNeeded()
+				
 			}
 			}
 		}
 		}
 		catch {
 		catch {
@@ -155,7 +154,6 @@ class ActivitiesView: UIView {
 		}
 		}
 		
 		
 		
 		
-		
 		// Show past activities
 		// Show past activities
 		fetchRequest = Activity.fetchRequest()
 		fetchRequest = Activity.fetchRequest()
 		sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
 		sortDescriptor = NSSortDescriptor(key: "date", ascending: false)
@@ -183,6 +181,7 @@ class ActivitiesView: UIView {
 				text = r.value(forKey: "text_\(lang!)")! as! String
 				text = r.value(forKey: "text_\(lang!)")! as! String
 				row.setTitle(text: title)
 				row.setTitle(text: title)
 				row.setText(text: text)
 				row.setText(text: text)
+				row.id = id
 				
 				
 				// Get main image
 				// Get main image
 				image = ""
 				image = ""
@@ -205,38 +204,15 @@ class ActivitiesView: UIView {
 				
 				
 				
 				
 				self.pastList?.addArrangedSubview(row)
 				self.pastList?.addArrangedSubview(row)
-				
-				// TODO: Do this on the row didLoad method
-				// Set tap recognizer
-				//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openActivity(_:)))
-				//row.isUserInteractionEnabled = true
-				//row.addGestureRecognizer(tapRecognizer)
 			}
 			}
 			self.pastList?.setNeedsLayout()
 			self.pastList?.setNeedsLayout()
 			self.pastList?.layoutIfNeeded()
 			self.pastList?.layoutIfNeeded()
+			
 		} catch {
 		} catch {
 			NSLog(":ACTIVITIES:ERROR: Error with request: \(error)")
 			NSLog(":ACTIVITIES:ERROR: Error with request: \(error)")
 		}
 		}
-		NSLog(":ACTIVITIES:DEBUG: Finished loading ActivitiesView")
 	}
 	}
 	
 	
-	
-	/*func openActivity(){//(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ACTIVITIES:DEBUG: getting delegate and showing activity.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showActivity(id: 4)
-		NSLog(":ACTIVITIES:DEBUG: Activity should be shown.")
-	}
-	
-	
-	func openActivity(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ACTIVITIES:DEBUG: getting delegate and showing activity.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showActivity(id: 4)
-		NSLog(":ACTIVITIES:DEBUG: Activity should be shown.")
-	}*/
-	
-	
 	/**
 	/**
 	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.

+ 3 - 3
app/ActivitiesView.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <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="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     </dependencies>
     <objects>
     <objects>
@@ -24,7 +24,7 @@
                 <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xyM-cc-W1r">
                 <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xyM-cc-W1r">
                     <rect key="frame" x="0.0" y="0.0" width="375" height="666"/>
                     <rect key="frame" x="0.0" y="0.0" width="375" height="666"/>
                     <subviews>
                     <subviews>
-                        <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" misplaced="YES" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="gvi-ij-s5Q">
+                        <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" translatesAutoresizingMaskIntoConstraints="NO" id="gvi-ij-s5Q">
                             <rect key="frame" x="0.0" y="0.0" width="375" height="306"/>
                             <rect key="frame" x="0.0" y="0.0" width="375" height="306"/>
                             <subviews>
                             <subviews>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jdf-74-tJS" customClass="Section" customModule="app">
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Jdf-74-tJS" customClass="Section" customModule="app">

+ 7 - 1
app/AlbumViewController.swift

@@ -108,8 +108,11 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 				
 				
 				var r = searchResults[i]
 				var r = searchResults[i]
 				var photoId = r.value(forKey: "photo")! as! Int
 				var photoId = r.value(forKey: "photo")! as! Int
+				var leftId: Int = -1
+				var rightId: Int = -1
 				
 				
 				row = RowAlbum.init(s: "rowAlbum\(i)", i: i)
 				row = RowAlbum.init(s: "rowAlbum\(i)", i: i)
+				row.id = id
 				
 				
 				// Get photo info from Photo entity
 				// Get photo info from Photo entity
 				let imgFetchRequest: NSFetchRequest<Photo> = Photo.fetchRequest()
 				let imgFetchRequest: NSFetchRequest<Photo> = Photo.fetchRequest()
@@ -122,17 +125,20 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 					var imgSearchResults = try context.fetch(imgFetchRequest)
 					var imgSearchResults = try context.fetch(imgFetchRequest)
 					var imgR = imgSearchResults[0]
 					var imgR = imgSearchResults[0]
 					image = imgR.value(forKey: "file")! as! String
 					image = imgR.value(forKey: "file")! as! String
+					leftId = imgR.value(forKey: "id")! as! Int
 					NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) left: \(image)")
 					NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) left: \(image)")
 					row.setImage(idx: 0, filename: image)
 					row.setImage(idx: 0, filename: image)
 					if i + 1 < searchResults.count {
 					if i + 1 < searchResults.count {
 						r = searchResults[i + 1]
 						r = searchResults[i + 1]
 						photoId = r.value(forKey: "photo")! as! Int
 						photoId = r.value(forKey: "photo")! as! Int
+						
 						imgFetchRequest.predicate = NSPredicate(format: "id == %i", photoId)
 						imgFetchRequest.predicate = NSPredicate(format: "id == %i", photoId)
 						imgSearchResults = try context.fetch(imgFetchRequest)
 						imgSearchResults = try context.fetch(imgFetchRequest)
 						
 						
 						
 						
 						imgR = imgSearchResults[0]
 						imgR = imgSearchResults[0]
 						image = imgR.value(forKey: "file")! as! String
 						image = imgR.value(forKey: "file")! as! String
+						rightId = imgR.value(forKey: "id")! as! Int
 						NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) right: \(image)")
 						NSLog(":GALLERYCONTROLLER:LOG: Image Row \(i) right: \(image)")
 						row.setImage(idx: 1, filename: image)
 						row.setImage(idx: 1, filename: image)
 					}
 					}
@@ -145,7 +151,7 @@ class AlbumViewController: UIViewController, UIGestureRecognizerDelegate {
 					NSLog(":GALLERYCONTROLLER:ERROR: Error getting image for post \(id): \(error)")
 					NSLog(":GALLERYCONTROLLER:ERROR: Error getting image for post \(id): \(error)")
 				}
 				}
 				
 				
-				NSLog(":GALLERYCONTROLLER:DEBUG: Adding row: height: \(row.frame.height)")
+				row.setIds(left: leftId, right: rightId)
 				albumContainer.addArrangedSubview(row)
 				albumContainer.addArrangedSubview(row)
 				
 				
 				rowcount = rowcount + 1
 				rowcount = rowcount + 1

+ 27 - 0
app/AppDelegate.swift

@@ -32,12 +32,39 @@ class AppDelegate: UIResponder, UIApplicationDelegate {
 	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.
 		// Override point for customization after application launch.
 		
 		
+		// Google Mapas API KEY
 		GMSServices.provideAPIKey("AIzaSyBfIiBM_YSBlxybmI_Uz_fGoUFN4wacR80")
 		GMSServices.provideAPIKey("AIzaSyBfIiBM_YSBlxybmI_Uz_fGoUFN4wacR80")
 		
 		
+		// Background mode.
+		UIApplication.shared.setMinimumBackgroundFetchInterval(UIApplicationBackgroundFetchIntervalMinimum)
+		
 		return true
 		return true
 	}
 	}
 	
 	
 
 
+	func application(_ application: UIApplication, performFetchWithCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
+		NSLog(":BACKGROUND:LOG: Start bg sync...")
+		Sync()
+		
+		let when = DispatchTime.now() + 120 // 2 minutes to perform the sync.
+		DispatchQueue.main.asyncAfter(deadline: when) {
+			NSLog(":BACKGROUND:LOG: Calling completion handler.")
+			completionHandler(UIBackgroundFetchResult.newData)
+		}
+		
+		/*if let tabBarController = window?.rootViewController as? UITabBarController, let viewControllers = tabBarController.viewControllers {
+			for viewController in viewControllers {
+				if let fetchViewController = viewController as? FetchViewController {
+					fetchViewController.fetch {
+						fetchViewController.updateUI()
+						completionHandler(.newData)
+					}
+				}
+			}
+		}*/
+	}
+
+
 	/**
 	/**
 	Sent when the application is about to move from active to inactive state.
 	Sent when the application is about to move from active to inactive state.
 	This can occur for certain types of temporary interruptions
 	This can occur for certain types of temporary interruptions

+ 422 - 0
app/Base.lproj/Main.storyboard

@@ -199,6 +199,8 @@
                         <segue destination="k0M-Sk-DZM" kind="show" identifier="SegueAlbum" id="Puc-tv-vaD"/>
                         <segue destination="k0M-Sk-DZM" kind="show" identifier="SegueAlbum" id="Puc-tv-vaD"/>
                         <segue destination="zJF-Mh-CNb" kind="show" identifier="SegueSchedule" id="A70-jo-yAP"/>
                         <segue destination="zJF-Mh-CNb" kind="show" identifier="SegueSchedule" id="A70-jo-yAP"/>
                         <segue destination="3o1-ab-AT4" kind="show" identifier="SegueSync" id="E96-mK-gE9"/>
                         <segue destination="3o1-ab-AT4" kind="show" identifier="SegueSync" id="E96-mK-gE9"/>
+                        <segue destination="jfx-Q2-RtY" kind="show" identifier="SeguePastActivity" id="MmG-k2-wHn"/>
+                        <segue destination="hRA-2q-Tv9" kind="show" identifier="SeguePhoto" id="XIb-zK-EYd"/>
                     </connections>
                     </connections>
                 </viewController>
                 </viewController>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
@@ -1032,6 +1034,426 @@
                 <placeholder placeholderIdentifier="IBFirstResponder" id="fRm-1Y-Xmm" userLabel="First Responder" sceneMemberID="firstResponder"/>
                 <placeholder placeholderIdentifier="IBFirstResponder" id="fRm-1Y-Xmm" userLabel="First Responder" sceneMemberID="firstResponder"/>
             </objects>
             </objects>
         </scene>
         </scene>
+        <!--Past Activity View Controller-->
+        <scene sceneID="0of-i7-sd6">
+            <objects>
+                <viewController id="jfx-Q2-RtY" customClass="PastActivityViewController" customModule="app" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="u2P-so-lU7"/>
+                        <viewControllerLayoutGuide type="bottom" id="Lav-1c-S51"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="SdM-pu-zm3">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="BxO-VS-eP5" userLabel="Toolbar">
+                                <rect key="frame" x="0.0" y="20" width="375" height="30"/>
+                                <subviews>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Loj-Ff-gNj">
+                                        <rect key="frame" x="0.0" y="0.0" width="56.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                        <state key="normal" title="&lt;">
+                                            <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                    </button>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gasteizko Margolariak" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="xf1-tl-98b">
+                                        <rect key="frame" x="56.5" y="0.0" width="262.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="height" secondItem="BxO-VS-eP5" secondAttribute="height" id="A9Y-Fw-3wT"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="width" secondItem="BxO-VS-eP5" secondAttribute="width" multiplier="0.15" id="JAK-Wn-RB0"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="leading" secondItem="BxO-VS-eP5" secondAttribute="leading" id="KWZ-5M-JBT"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="height" secondItem="BxO-VS-eP5" secondAttribute="height" id="PRz-QI-LGC"/>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="width" secondItem="BxO-VS-eP5" secondAttribute="width" multiplier="0.7" id="cAg-nR-WRl"/>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="centerY" secondItem="BxO-VS-eP5" secondAttribute="centerY" id="cCD-R8-57d"/>
+                                    <constraint firstItem="xf1-tl-98b" firstAttribute="centerX" secondItem="BxO-VS-eP5" secondAttribute="centerX" id="ltM-gK-avh"/>
+                                    <constraint firstItem="Loj-Ff-gNj" firstAttribute="centerY" secondItem="BxO-VS-eP5" secondAttribute="centerY" id="rUy-8N-1cq"/>
+                                </constraints>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="JgN-DW-xUZ">
+                                <rect key="frame" x="0.0" y="50" width="375" height="617"/>
+                                <subviews>
+                                    <scrollView clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="scaleToFill" bounces="NO" alwaysBounceVertical="YES" showsHorizontalScrollIndicator="NO" translatesAutoresizingMaskIntoConstraints="NO" id="3SZ-u2-ZIb">
+                                        <rect key="frame" x="0.0" y="0.0" width="375" height="617"/>
+                                        <subviews>
+                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="xi6-iq-IpA" userLabel="Section">
+                                                <rect key="frame" x="10" y="10" width="355" height="995"/>
+                                                <subviews>
+                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" restorationIdentifier="Title" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="cWR-TU-0Za" userLabel="Title">
+                                                        <rect key="frame" x="0.0" y="0.0" width="355" height="30"/>
+                                                        <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                        <constraints>
+                                                            <constraint firstAttribute="height" constant="30" id="s4L-e0-U96"/>
+                                                        </constraints>
+                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                        <nil key="highlightedColor"/>
+                                                    </label>
+                                                    <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="riK-xb-Vls" userLabel="Content">
+                                                        <rect key="frame" x="0.0" y="30" width="355" height="965"/>
+                                                        <subviews>
+                                                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="Omg-cP-uvF" userLabel="Activity">
+                                                                <rect key="frame" x="8" y="8" width="339" height="949"/>
+                                                                <subviews>
+                                                                    <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="8Jn-h7-TSJ" userLabel="Image">
+                                                                        <rect key="frame" x="0.0" y="10" width="339" height="71"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="71" id="lZg-2O-4LP"/>
+                                                                        </constraints>
+                                                                    </imageView>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Text" textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Usd-Rm-Tq2" userLabel="Text">
+                                                                        <rect key="frame" x="17" y="91" width="305.5" height="826"/>
+                                                                        <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                                                        <nil key="textColor"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="LmH-0o-Hku" userLabel="Separator">
+                                                                        <rect key="frame" x="17" y="917" width="305.5" height="2"/>
+                                                                        <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="2" id="X7n-cL-6Hk"/>
+                                                                        </constraints>
+                                                                    </view>
+                                                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="254" text="Date" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="dvg-B2-xmI" userLabel="Date">
+                                                                        <rect key="frame" x="17" y="929" width="305.5" height="20"/>
+                                                                        <constraints>
+                                                                            <constraint firstAttribute="height" constant="20" id="8LF-YM-5Cn"/>
+                                                                        </constraints>
+                                                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                                                        <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
+                                                                        <nil key="highlightedColor"/>
+                                                                    </label>
+                                                                </subviews>
+                                                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                                <constraints>
+                                                                    <constraint firstItem="Usd-Rm-Tq2" firstAttribute="top" secondItem="8Jn-h7-TSJ" secondAttribute="bottom" constant="10" id="1oO-Iq-tff"/>
+                                                                    <constraint firstItem="LmH-0o-Hku" firstAttribute="top" secondItem="Usd-Rm-Tq2" secondAttribute="bottom" id="7Du-au-fft"/>
+                                                                    <constraint firstItem="8Jn-h7-TSJ" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="H9k-8U-X4o"/>
+                                                                    <constraint firstItem="dvg-B2-xmI" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" multiplier="0.9" id="LcU-3f-pz6"/>
+                                                                    <constraint firstItem="Usd-Rm-Tq2" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" multiplier="0.9" id="MQd-UV-3Ee"/>
+                                                                    <constraint firstItem="dvg-B2-xmI" firstAttribute="top" secondItem="LmH-0o-Hku" secondAttribute="bottom" constant="10" id="QrH-eq-mXV"/>
+                                                                    <constraint firstItem="Usd-Rm-Tq2" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="SHM-nk-s9u"/>
+                                                                    <constraint firstItem="dvg-B2-xmI" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="XBR-sR-Yqg"/>
+                                                                    <constraint firstItem="LmH-0o-Hku" firstAttribute="centerX" secondItem="Omg-cP-uvF" secondAttribute="centerX" id="a8v-br-EaA"/>
+                                                                    <constraint firstItem="8Jn-h7-TSJ" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" id="gm5-CU-FKw"/>
+                                                                    <constraint firstItem="8Jn-h7-TSJ" firstAttribute="top" secondItem="Omg-cP-uvF" secondAttribute="top" constant="10" id="js6-Fg-pg1"/>
+                                                                    <constraint firstAttribute="bottom" secondItem="dvg-B2-xmI" secondAttribute="bottom" id="lta-H9-CYI"/>
+                                                                    <constraint firstItem="LmH-0o-Hku" firstAttribute="width" secondItem="Omg-cP-uvF" secondAttribute="width" multiplier="0.9" id="xmH-tU-ZFp"/>
+                                                                </constraints>
+                                                                <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                                <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">
+                                                                        <real key="value" value="1"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                                        <real key="value" value="3"/>
+                                                                    </userDefinedRuntimeAttribute>
+                                                                </userDefinedRuntimeAttributes>
+                                                            </view>
+                                                        </subviews>
+                                                        <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                        <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                    </stackView>
+                                                </subviews>
+                                                <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="bottom" secondItem="riK-xb-Vls" secondAttribute="bottom" id="Cx5-Kf-8OE"/>
+                                                    <constraint firstItem="cWR-TU-0Za" firstAttribute="width" secondItem="xi6-iq-IpA" secondAttribute="width" id="FVH-in-wHT"/>
+                                                    <constraint firstItem="riK-xb-Vls" firstAttribute="top" secondItem="cWR-TU-0Za" secondAttribute="bottom" id="Hn5-9l-iCk"/>
+                                                    <constraint firstItem="riK-xb-Vls" firstAttribute="centerX" secondItem="xi6-iq-IpA" secondAttribute="centerX" id="KR9-e1-CPc"/>
+                                                    <constraint firstItem="cWR-TU-0Za" firstAttribute="centerX" secondItem="xi6-iq-IpA" secondAttribute="centerX" id="eMS-XG-Mee"/>
+                                                    <constraint firstItem="riK-xb-Vls" firstAttribute="width" secondItem="xi6-iq-IpA" secondAttribute="width" id="g6A-Nh-o8X"/>
+                                                    <constraint firstItem="cWR-TU-0Za" firstAttribute="top" secondItem="xi6-iq-IpA" secondAttribute="top" id="yuP-2e-AdF"/>
+                                                </constraints>
+                                                <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                                <userDefinedRuntimeAttributes>
+                                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                        <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                        <real key="value" value="1"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                    <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                        <real key="value" value="8"/>
+                                                    </userDefinedRuntimeAttribute>
+                                                </userDefinedRuntimeAttributes>
+                                            </view>
+                                        </subviews>
+                                        <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                        <constraints>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="top" secondItem="3SZ-u2-ZIb" secondAttribute="top" constant="10" id="DOt-pc-3eb"/>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="centerX" secondItem="3SZ-u2-ZIb" secondAttribute="centerX" id="IFM-jn-576"/>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="trailing" secondItem="3SZ-u2-ZIb" secondAttribute="trailing" constant="10" id="SAk-SF-xVS"/>
+                                            <constraint firstAttribute="bottom" secondItem="xi6-iq-IpA" secondAttribute="bottom" constant="10" id="Xdk-K7-KDJ"/>
+                                            <constraint firstItem="xi6-iq-IpA" firstAttribute="leading" secondItem="3SZ-u2-ZIb" secondAttribute="leading" constant="10" id="wud-Ff-5hQ"/>
+                                        </constraints>
+                                        <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                <real key="value" value="0.0"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </scrollView>
+                                </subviews>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="3SZ-u2-ZIb" firstAttribute="width" secondItem="JgN-DW-xUZ" secondAttribute="width" id="31P-4U-Pt1"/>
+                                    <constraint firstAttribute="bottom" secondItem="3SZ-u2-ZIb" secondAttribute="bottom" id="Eou-gG-0WN"/>
+                                    <constraint firstItem="3SZ-u2-ZIb" firstAttribute="centerX" secondItem="JgN-DW-xUZ" secondAttribute="centerX" id="JzA-TZ-T6w"/>
+                                    <constraint firstItem="3SZ-u2-ZIb" firstAttribute="top" secondItem="JgN-DW-xUZ" secondAttribute="top" id="T5M-NN-rUZ"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                        <color key="value" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="BxO-VS-eP5" firstAttribute="centerX" secondItem="SdM-pu-zm3" secondAttribute="centerX" id="0eo-Jq-yKG"/>
+                            <constraint firstItem="JgN-DW-xUZ" firstAttribute="centerX" secondItem="SdM-pu-zm3" secondAttribute="centerX" id="XMm-11-4Bs"/>
+                            <constraint firstItem="Lav-1c-S51" firstAttribute="top" secondItem="JgN-DW-xUZ" secondAttribute="bottom" id="ai7-fu-CPH"/>
+                            <constraint firstItem="BxO-VS-eP5" firstAttribute="width" secondItem="SdM-pu-zm3" secondAttribute="width" id="d1M-W0-fTO"/>
+                            <constraint firstItem="JgN-DW-xUZ" firstAttribute="width" secondItem="SdM-pu-zm3" secondAttribute="width" id="jJF-ok-Gxw"/>
+                            <constraint firstItem="JgN-DW-xUZ" firstAttribute="top" secondItem="BxO-VS-eP5" secondAttribute="bottom" id="pqm-X9-1Pa"/>
+                            <constraint firstItem="BxO-VS-eP5" firstAttribute="top" secondItem="u2P-so-lU7" secondAttribute="bottom" id="qdC-D0-ERu"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="activityDate" destination="dvg-B2-xmI" id="hyQ-Wm-9J7"/>
+                        <outlet property="activityImage" destination="8Jn-h7-TSJ" id="OtM-Zu-0Qf"/>
+                        <outlet property="activityText" destination="Usd-Rm-Tq2" id="ySl-QS-kOh"/>
+                        <outlet property="activityTitle" destination="cWR-TU-0Za" id="oRe-G1-MMU"/>
+                        <outlet property="barButton" destination="Loj-Ff-gNj" id="0tW-a0-rNG"/>
+                        <outlet property="barTitle" destination="xf1-tl-98b" id="dO8-P5-V8C"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="YKC-ZH-aSz" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
+        <!--Photo-->
+        <scene sceneID="Qxt-8f-I5l">
+            <objects>
+                <viewController title="Photo" id="hRA-2q-Tv9" customClass="PhotoViewController" customModule="app" customModuleProvider="target" sceneMemberID="viewController">
+                    <layoutGuides>
+                        <viewControllerLayoutGuide type="top" id="iD5-7d-BcL"/>
+                        <viewControllerLayoutGuide type="bottom" id="UVa-jE-Gqw"/>
+                    </layoutGuides>
+                    <view key="view" contentMode="scaleToFill" id="zXb-Ja-8dX" userLabel="Container">
+                        <rect key="frame" x="0.0" y="0.0" width="375" height="667"/>
+                        <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
+                        <subviews>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="XUY-te-9PN" userLabel="Toolbar">
+                                <rect key="frame" x="0.0" y="20" width="375" height="30"/>
+                                <subviews>
+                                    <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="4tx-eL-rur">
+                                        <rect key="frame" x="0.0" y="0.0" width="56.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                        <state key="normal" title="&lt;">
+                                            <color key="titleColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        </state>
+                                    </button>
+                                    <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gasteizko Margolariak" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="ifO-mU-TPV">
+                                        <rect key="frame" x="56.5" y="0.0" width="262.5" height="30"/>
+                                        <fontDescription key="fontDescription" type="boldSystem" pointSize="17"/>
+                                        <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                        <nil key="highlightedColor"/>
+                                    </label>
+                                </subviews>
+                                <color key="backgroundColor" red="0.0" green="0.47843137250000001" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                <constraints>
+                                    <constraint firstItem="4tx-eL-rur" firstAttribute="centerY" secondItem="XUY-te-9PN" secondAttribute="centerY" id="AgA-QN-AMl"/>
+                                    <constraint firstItem="4tx-eL-rur" firstAttribute="width" secondItem="XUY-te-9PN" secondAttribute="width" multiplier="0.15" id="C5z-S4-EpK"/>
+                                    <constraint firstItem="ifO-mU-TPV" firstAttribute="centerY" secondItem="XUY-te-9PN" secondAttribute="centerY" id="DDx-b3-3ds"/>
+                                    <constraint firstItem="4tx-eL-rur" firstAttribute="leading" secondItem="XUY-te-9PN" secondAttribute="leading" id="W4J-mY-EF9"/>
+                                    <constraint firstItem="ifO-mU-TPV" firstAttribute="height" secondItem="XUY-te-9PN" secondAttribute="height" id="aKD-k3-Rn6"/>
+                                    <constraint firstItem="4tx-eL-rur" firstAttribute="height" secondItem="XUY-te-9PN" secondAttribute="height" id="msK-d2-NhX"/>
+                                    <constraint firstItem="ifO-mU-TPV" firstAttribute="centerX" secondItem="XUY-te-9PN" secondAttribute="centerX" id="r98-kb-UcD"/>
+                                    <constraint firstItem="ifO-mU-TPV" firstAttribute="width" secondItem="XUY-te-9PN" secondAttribute="width" multiplier="0.7" id="stn-gW-qHw"/>
+                                </constraints>
+                            </view>
+                            <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="dh0-OE-3US">
+                                <rect key="frame" x="0.0" y="50" width="375" height="617"/>
+                                <subviews>
+                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="bqh-wV-GNf" userLabel="Section">
+                                        <rect key="frame" x="10" y="10" width="355" height="597"/>
+                                        <subviews>
+                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" restorationIdentifier="Title" text="Title" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="esM-2C-p2i" userLabel="Title">
+                                                <rect key="frame" x="0.0" y="0.0" width="355" height="30"/>
+                                                <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                                <constraints>
+                                                    <constraint firstAttribute="height" constant="30" id="RzN-hZ-tOL"/>
+                                                </constraints>
+                                                <fontDescription key="fontDescription" type="boldSystem" pointSize="14"/>
+                                                <color key="textColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                                <nil key="highlightedColor"/>
+                                            </label>
+                                            <stackView opaque="NO" contentMode="scaleToFill" axis="vertical" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="78P-mw-WXM" userLabel="Content">
+                                                <rect key="frame" x="0.0" y="30" width="355" height="557"/>
+                                                <subviews>
+                                                    <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="jIN-Yy-3GU" userLabel="Photo">
+                                                        <rect key="frame" x="8" y="8" width="339" height="541"/>
+                                                        <subviews>
+                                                            <imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="PhotoPlaceholder" translatesAutoresizingMaskIntoConstraints="NO" id="2wg-l8-Thi" userLabel="Image">
+                                                                <rect key="frame" x="10" y="10" width="319" height="406"/>
+                                                            </imageView>
+                                                            <label opaque="NO" userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="254" text="Date" textAlignment="right" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Vhb-gI-4I7" userLabel="Date">
+                                                                <rect key="frame" x="10.5" y="451" width="319" height="20"/>
+                                                                <constraints>
+                                                                    <constraint firstAttribute="height" constant="20" id="fXM-sB-Ii7"/>
+                                                                </constraints>
+                                                                <fontDescription key="fontDescription" type="italicSystem" pointSize="16"/>
+                                                                <color key="textColor" white="0.33333333333333331" alpha="1" colorSpace="calibratedWhite"/>
+                                                                <nil key="highlightedColor"/>
+                                                            </label>
+                                                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="Jcy-kv-ggg">
+                                                                <rect key="frame" x="10" y="491" width="149.5" height="40"/>
+                                                                <color key="backgroundColor" red="0.070588235289999995" green="0.27058823529999998" blue="0.4039215686" alpha="1" colorSpace="calibratedRGB"/>
+                                                                <constraints>
+                                                                    <constraint firstAttribute="height" constant="40" id="voU-YV-2ln"/>
+                                                                </constraints>
+                                                                <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                                                <state key="normal" title="&lt;">
+                                                                    <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>
+                                                            <button opaque="NO" contentMode="scaleToFill" contentHorizontalAlignment="center" contentVerticalAlignment="center" buttonType="roundedRect" lineBreakMode="middleTruncation" translatesAutoresizingMaskIntoConstraints="NO" id="HOD-9J-wQK">
+                                                                <rect key="frame" x="179.5" y="491" width="149.5" height="40"/>
+                                                                <color key="backgroundColor" red="0.070588235289999995" green="0.27058823529999998" blue="0.4039215686" alpha="1" colorSpace="calibratedRGB"/>
+                                                                <constraints>
+                                                                    <constraint firstAttribute="height" constant="40" id="6oc-MW-3JE"/>
+                                                                </constraints>
+                                                                <fontDescription key="fontDescription" type="boldSystem" pointSize="15"/>
+                                                                <state key="normal" title="&gt;">
+                                                                    <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="2wg-l8-Thi" firstAttribute="top" secondItem="jIN-Yy-3GU" secondAttribute="top" constant="10" id="D28-DF-HF9"/>
+                                                            <constraint firstAttribute="bottom" secondItem="Jcy-kv-ggg" secondAttribute="bottom" constant="10" id="HPg-ft-VEj"/>
+                                                            <constraint firstItem="2wg-l8-Thi" firstAttribute="centerX" secondItem="jIN-Yy-3GU" secondAttribute="centerX" id="KoA-A3-Ygf"/>
+                                                            <constraint firstItem="Vhb-gI-4I7" firstAttribute="bottom" secondItem="HOD-9J-wQK" secondAttribute="top" constant="-20" id="NVj-fY-b6d"/>
+                                                            <constraint firstAttribute="trailing" secondItem="HOD-9J-wQK" secondAttribute="trailing" constant="10" id="can-PT-Neg"/>
+                                                            <constraint firstAttribute="bottom" secondItem="HOD-9J-wQK" secondAttribute="bottom" constant="10" id="dsJ-0z-vOa"/>
+                                                            <constraint firstItem="Vhb-gI-4I7" firstAttribute="width" secondItem="jIN-Yy-3GU" secondAttribute="width" constant="-20" id="geF-9Y-pxJ"/>
+                                                            <constraint firstItem="Jcy-kv-ggg" firstAttribute="leading" secondItem="jIN-Yy-3GU" secondAttribute="leading" constant="10" id="grR-FP-FE3"/>
+                                                            <constraint firstItem="Vhb-gI-4I7" firstAttribute="centerX" secondItem="jIN-Yy-3GU" secondAttribute="centerX" id="hDr-cv-Tma"/>
+                                                            <constraint firstItem="HOD-9J-wQK" firstAttribute="width" secondItem="jIN-Yy-3GU" secondAttribute="width" multiplier="0.5" constant="-20" id="pQ0-vJ-Uv1"/>
+                                                            <constraint firstItem="Jcy-kv-ggg" firstAttribute="width" secondItem="jIN-Yy-3GU" secondAttribute="width" multiplier="0.5" constant="-20" id="rnQ-m4-XQ0"/>
+                                                            <constraint firstItem="2wg-l8-Thi" firstAttribute="height" secondItem="jIN-Yy-3GU" secondAttribute="height" multiplier="0.75" id="vhz-lJ-2fm"/>
+                                                            <constraint firstItem="2wg-l8-Thi" firstAttribute="width" secondItem="jIN-Yy-3GU" secondAttribute="width" constant="-20" id="wQB-Hs-vSs"/>
+                                                        </constraints>
+                                                        <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                                        <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">
+                                                                <real key="value" value="1"/>
+                                                            </userDefinedRuntimeAttribute>
+                                                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                                <real key="value" value="3"/>
+                                                            </userDefinedRuntimeAttribute>
+                                                        </userDefinedRuntimeAttributes>
+                                                    </view>
+                                                </subviews>
+                                                <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                                <edgeInsets key="layoutMargins" top="8" left="8" bottom="8" right="8"/>
+                                            </stackView>
+                                        </subviews>
+                                        <color key="backgroundColor" red="0.59607843140000005" green="0.7843137255" blue="1" alpha="1" colorSpace="calibratedRGB"/>
+                                        <constraints>
+                                            <constraint firstAttribute="bottom" secondItem="78P-mw-WXM" secondAttribute="bottom" constant="10" id="JdO-O4-mee"/>
+                                            <constraint firstItem="78P-mw-WXM" firstAttribute="width" secondItem="bqh-wV-GNf" secondAttribute="width" id="PpI-M2-bDk"/>
+                                            <constraint firstItem="78P-mw-WXM" firstAttribute="centerX" secondItem="bqh-wV-GNf" secondAttribute="centerX" id="bEw-TV-GOh"/>
+                                            <constraint firstItem="78P-mw-WXM" firstAttribute="top" secondItem="esM-2C-p2i" secondAttribute="bottom" id="muK-Pd-v3M"/>
+                                            <constraint firstItem="esM-2C-p2i" firstAttribute="width" secondItem="bqh-wV-GNf" secondAttribute="width" id="vEo-Fa-qdK"/>
+                                            <constraint firstItem="esM-2C-p2i" firstAttribute="centerX" secondItem="bqh-wV-GNf" secondAttribute="centerX" id="zPh-03-gDc"/>
+                                        </constraints>
+                                        <edgeInsets key="layoutMargins" top="10" left="10" bottom="10" right="10"/>
+                                        <userDefinedRuntimeAttributes>
+                                            <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                                <color key="value" red="0.0" green="0.0" blue="0.066666666669999999" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                            </userDefinedRuntimeAttribute>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
+                                                <real key="value" value="1"/>
+                                            </userDefinedRuntimeAttribute>
+                                            <userDefinedRuntimeAttribute type="number" keyPath="cornerRadius">
+                                                <real key="value" value="8"/>
+                                            </userDefinedRuntimeAttribute>
+                                        </userDefinedRuntimeAttributes>
+                                    </view>
+                                </subviews>
+                                <color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
+                                <constraints>
+                                    <constraint firstItem="bqh-wV-GNf" firstAttribute="width" secondItem="dh0-OE-3US" secondAttribute="width" constant="-20" id="8a3-am-7Ch"/>
+                                    <constraint firstItem="bqh-wV-GNf" firstAttribute="height" secondItem="dh0-OE-3US" secondAttribute="height" constant="-20" id="Tgd-YQ-aEQ"/>
+                                    <constraint firstItem="bqh-wV-GNf" firstAttribute="centerY" secondItem="dh0-OE-3US" secondAttribute="centerY" id="U2v-3X-Ub1"/>
+                                    <constraint firstItem="bqh-wV-GNf" firstAttribute="centerX" secondItem="dh0-OE-3US" secondAttribute="centerX" id="eI3-vW-bvZ"/>
+                                </constraints>
+                                <userDefinedRuntimeAttributes>
+                                    <userDefinedRuntimeAttribute type="color" keyPath="borderColor">
+                                        <color key="value" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                                    </userDefinedRuntimeAttribute>
+                                </userDefinedRuntimeAttributes>
+                            </view>
+                        </subviews>
+                        <color key="backgroundColor" red="0.0" green="0.47058823529999999" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
+                        <constraints>
+                            <constraint firstItem="XUY-te-9PN" firstAttribute="width" secondItem="zXb-Ja-8dX" secondAttribute="width" id="1gg-3z-VTT"/>
+                            <constraint firstItem="XUY-te-9PN" firstAttribute="top" secondItem="iD5-7d-BcL" secondAttribute="bottom" id="6xm-50-tbJ"/>
+                            <constraint firstItem="dh0-OE-3US" firstAttribute="top" secondItem="XUY-te-9PN" secondAttribute="bottom" id="Cwk-RG-Bdj"/>
+                            <constraint firstItem="dh0-OE-3US" firstAttribute="centerX" secondItem="zXb-Ja-8dX" secondAttribute="centerX" id="FEt-9c-pvb"/>
+                            <constraint firstItem="XUY-te-9PN" firstAttribute="centerX" secondItem="zXb-Ja-8dX" secondAttribute="centerX" id="vfQ-Yn-21i"/>
+                            <constraint firstItem="UVa-jE-Gqw" firstAttribute="top" secondItem="dh0-OE-3US" secondAttribute="bottom" id="w47-kr-EXB"/>
+                        </constraints>
+                    </view>
+                    <connections>
+                        <outlet property="barButton" destination="4tx-eL-rur" id="fAC-j7-Kuv"/>
+                        <outlet property="barTitle" destination="ifO-mU-TPV" id="Yba-nJ-MyQ"/>
+                        <outlet property="btNext" destination="HOD-9J-wQK" id="mc4-j1-seA"/>
+                        <outlet property="btPrev" destination="Jcy-kv-ggg" id="L1Q-2X-H43"/>
+                        <outlet property="photoDate" destination="Vhb-gI-4I7" id="pyP-a1-Iz7"/>
+                        <outlet property="photoImage" destination="2wg-l8-Thi" id="xgu-JA-6Zs"/>
+                        <outlet property="photoTitle" destination="esM-2C-p2i" id="ev5-QE-lS6"/>
+                    </connections>
+                </viewController>
+                <placeholder placeholderIdentifier="IBFirstResponder" id="jtA-t8-aan" userLabel="First Responder" sceneMemberID="firstResponder"/>
+            </objects>
+        </scene>
     </scenes>
     </scenes>
     <resources>
     <resources>
         <image name="GM" width="120" height="120"/>
         <image name="GM" width="120" height="120"/>

+ 11 - 35
app/BlogView.swift

@@ -60,19 +60,18 @@ class BlogView: UIView {
 		
 		
 		// Get viewController from StoryBoard
 		// Get viewController from StoryBoard
 		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
 		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
-		self.controller = storyboard?.instantiateViewController(withIdentifier: "GMViewController") as? ViewController
+		self.controller = storyboard?.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
 		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.lang = getLanguage()
 		self.lang = getLanguage()
 		self.context?.persistentStoreCoordinator = delegate?.persistentStoreCoordinator
 		self.context?.persistentStoreCoordinator = delegate?.persistentStoreCoordinator
 		
 		
 		populate()
 		populate()
-		
 	}
 	}
 	
 	
 	
 	
 	/**
 	/**
-	Populates the section.
+	Actually populates the section.
 	*/
 	*/
 	func populate(){
 	func populate(){
 		let fetchRequest: NSFetchRequest<Post> = Post.fetchRequest()
 		let fetchRequest: NSFetchRequest<Post> = Post.fetchRequest()
@@ -87,18 +86,17 @@ class BlogView: UIView {
 			}
 			}
 			
 			
 			// Get the results
 			// Get the results
-			let searchResults = try self.context?.fetch(fetchRequest)			
+			let searchResults = try self.context?.fetch(fetchRequest)
 			
 			
+			var count: Int = 0
 			var row : RowBlog
 			var row : RowBlog
-			var count = 0
 			var id: Int
 			var id: Int
 			var title: String
 			var title: String
 			var text: String
 			var text: String
 			var image: String
 			var image: String
 			
 			
-			for r in searchResults! {
-				count = count + 1
-				
+			for r in searchResults as! [NSManagedObject] {
+								
 				//Create a new row
 				//Create a new row
 				row = RowBlog.init(s: "rowBlog\(count)", i: count)
 				row = RowBlog.init(s: "rowBlog\(count)", i: count)
 				id = r.value(forKey: "id")! as! Int
 				id = r.value(forKey: "id")! as! Int
@@ -106,6 +104,7 @@ class BlogView: UIView {
 				text = r.value(forKey: "text_\(lang!)")! as! String
 				text = r.value(forKey: "text_\(lang!)")! as! String
 				row.setTitle(text: title)
 				row.setTitle(text: title)
 				row.setText(text: text)
 				row.setText(text: text)
+				row.id = id
 				
 				
 				// Get main image
 				// Get main image
 				image = ""
 				image = ""
@@ -117,7 +116,7 @@ class BlogView: UIView {
 				imgFetchRequest.fetchLimit = 1
 				imgFetchRequest.fetchLimit = 1
 				do{
 				do{
 					let imgSearchResults = try context?.fetch(imgFetchRequest)
 					let imgSearchResults = try context?.fetch(imgFetchRequest)
-					for imgR in imgSearchResults!{
+					for imgR in imgSearchResults as! [NSManagedObject]{
 						image = imgR.value(forKey: "image")! as! String
 						image = imgR.value(forKey: "image")! as! String
 						row.setImage(filename: image)
 						row.setImage(filename: image)
 					}
 					}
@@ -127,13 +126,7 @@ class BlogView: UIView {
 				
 				
 				
 				
 				self.postList?.addArrangedSubview(row)
 				self.postList?.addArrangedSubview(row)
-				
-				// TODO: Do this on the row didLoad method
-				// Set tap recognizer
-				//let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector(openPost(_:)))
-				//row.isUserInteractionEnabled = true
-				//row.addGestureRecognizer(tapRecognizer)
-				
+				count = count + 1
 			}
 			}
 
 
 			// Trigger a layout update
 			// Trigger a layout update
@@ -143,25 +136,8 @@ class BlogView: UIView {
 		} catch {
 		} catch {
 			NSLog(":BLOG:ERROR: Error with request: \(error)")
 			NSLog(":BLOG:ERROR: Error with request: \(error)")
 		}
 		}
-		NSLog(":BLOG:DEBUG: Finished populating BlogView")
 	}
 	}
-	
-	
-	/*func openPost(){//(_ sender:UITapGestureRecognizer? = nil){
-		print("BLOG:DEBUG: getting delegate and showing post.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showPost(id: 4)
-		
-	print("BLOG:DEBUG: Post should be shown.")
-	}
-	
-	func openPost(_ sender:UITapGestureRecognizer? = nil){
-		print("BLOG:DEBUG: getting delegate and showing post.")
-		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		delegate.controller?.showPost(id: 4)
-		print("BLOG:DEBUG: Post should be shown.")
-	}*/
-	
+
 	
 	
 	/**
 	/**
 	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.

+ 81 - 0
app/FetchLocation.swift

@@ -0,0 +1,81 @@
+// 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 Foundation
+
+
+/**
+Class to handle Gasteizko Margolariak location updates.
+*/
+class FetchLocation{
+	
+	
+	/**
+	Default constructor
+	*/
+	init(){
+		fetch()
+	}
+	
+	
+	func fetch(){
+		NSLog(":LOCATION:LOG: Fetching location...")
+		
+		let url = URL(string: "https://margolariak.com/API/V1/location.php")
+		
+		let task = URLSession.shared.dataTask(with: url!) { data, response, error in
+			if error != nil {
+				NSLog(":LOCATION:ERROR: Unknown error getting location: \(error.debugDescription)")
+			}
+			let status = (response as! HTTPURLResponse).statusCode
+			
+			NSLog(":LOCATION:LOG: Response code \(status)")
+			if status == 200{
+			
+				guard let data = data else {
+					NSLog(":LOCATION:DEBUG: No data received.")
+					return
+				}
+
+				var strData = String(data: data, encoding: String.Encoding.utf8)
+			
+				// Get fields
+				let lat: Double = Double(strData!.subStr(start : strData!.indexOf(target : "\"lat\":")! + 7, end : strData!.indexOf(target : ",\"")! - 2))!
+			
+			
+				strData = strData?.subStr(start : (strData?.indexOf(target : ",\"")!)! + 1, end : (strData?.length)! - 1)
+				let lon: Double = Double(strData!.subStr(start : strData!.indexOf(target : "\"lon\":")! + 7, end : strData!.indexOf(target : ",\"")! - 2))!
+			
+				strData = strData?.subStr(start : (strData?.indexOf(target : ",\"")!)! + 1, end : (strData?.length)! - 1)
+				let dateFormatter = DateFormatter()
+				dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
+				let dtime = dateFormatter.date(from : (strData?.subStr(start : (strData?.indexOf(target : "\"dtime\":")!)! + 9, end : (strData?.length)! - 4))!)!
+			
+				let defaults = UserDefaults.standard
+				defaults.set(lat, forKey: "GMLocLat")
+				defaults.set(lon, forKey: "GMLocLon")
+				defaults.set(dtime, forKey: "GMLocTime")
+			
+				NSLog(":LOCATION:LOG: Got location at \(lat), \(lon) at \(dtime)")
+			}
+		}
+		task.resume()
+	}
+}

+ 132 - 60
app/HomeView.swift

@@ -26,10 +26,8 @@ import UIKit
  */
  */
 class HomeView: UIView {
 class HomeView: UIView {
 	
 	
-	//The main scroll view.
+	// Outlets
 	@IBOutlet weak var scrollView: UIScrollView!
 	@IBOutlet weak var scrollView: UIScrollView!
-	
-	//The container of the view.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
 	
 	
 	//Each of the sections of the view.
 	//Each of the sections of the view.
@@ -41,10 +39,22 @@ class HomeView: UIView {
 	@IBOutlet weak var pastActivitiesSection: Section!
 	@IBOutlet weak var pastActivitiesSection: Section!
 	@IBOutlet weak var socialSection: Section!
 	@IBOutlet weak var socialSection: Section!
 	
 	
+	var moc: NSManagedObjectContext? = nil
+	var delegate: AppDelegate? = nil
+	var lang: String? = nil
+	var locationTimer: Timer? = nil
+	
+	
+	/**
+	Default constructor for the storyboard.
+	:param: frame View frame.
+	*/
 	override init(frame: CGRect){
 	override init(frame: CGRect){
 		super.init(frame: frame)
 		super.init(frame: frame)
+		
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	 Run when the view is started.
 	 Run when the view is started.
 	*/
 	*/
@@ -57,45 +67,49 @@ class HomeView: UIView {
 		self.addSubview(container)
 		self.addSubview(container)
 		container.frame = self.bounds
 		container.frame = self.bounds
 		
 		
-
-		
 		//Set titles for each section
 		//Set titles for each section
-		locationSection.setTitle(text: "Encuentranos")
+		locationSection.setTitle(text: "Encuéntranos")
 		lablancaSection.setTitle(text: "La Blanca")
 		lablancaSection.setTitle(text: "La Blanca")
-		futureActivitiesSection.setTitle(text: "Proximas actividades")
-		blogSection.setTitle(text: "Ultimos posts")
-		gallerySection.setTitle(text: "Ultimas fotos")
-		pastActivitiesSection.setTitle(text: "Ultimas actividades")
-		socialSection.setTitle(text: "Siguenos")
+		futureActivitiesSection.setTitle(text: "Próximas actividades")
+		blogSection.setTitle(text: "Últimos posts")
+		gallerySection.setTitle(text: "Últimas fotos")
+		pastActivitiesSection.setTitle(text: "Últimas actividades")
+		socialSection.setTitle(text: "Síguenos")
 		
 		
 		//Get info to populate sections
 		//Get info to populate sections
-		let moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		self.moc = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		
 		
-		let appDelegate = UIApplication.shared.delegate as! AppDelegate
-		moc.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
-		let lang : String = getLanguage()
+		self.delegate = UIApplication.shared.delegate as! AppDelegate
+		self.moc?.persistentStoreCoordinator = self.delegate?.persistentStoreCoordinator
+		self.lang = getLanguage()
 		
 		
-		//Populate sections
-		setUpPastActivities(context: moc, delegate: appDelegate, lang: lang, parent: pastActivitiesSection.getContentStack())
-		setUpBlog(context: moc, delegate: appDelegate, lang: lang, parent: blogSection.getContentStack())
-		setUpFutureActivities(context: moc, delegate: appDelegate, lang: lang, parent: futureActivitiesSection.getContentStack())
-		setUpSocial(parent: socialSection.getContentStack())
-		setUpGallery(context: moc, delegate: appDelegate, parent: gallerySection.getContentStack())
 		
 		
+		// Populate section.
+		populate()
 		
 		
-		pastActivitiesSection.expandSection()
 		
 		
-		
-		//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 //Why 30?
-		}
-		// TODO: Calculate at the end
-		self.scrollView.contentSize.height = 1300// CGFloat(h);
+		// Special case: Location
+		// Set up once and start and periodically witha  timer.
+		setUpLocation()
+		Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(setUpLocation), userInfo: nil, repeats: true)
 	}
 	}
 	
 	
+	
+	/**
+	Sets all the sections up
+	*/
+	func populate(){
+	
+		//Populate sections
+		setUpPastActivities(context: self.moc!, delegate: self.delegate!, lang: self.lang!, parent: self.pastActivitiesSection.getContentStack())
+		setUpBlog(context: self.moc!, delegate: self.delegate!, lang: self.lang!, parent: self.blogSection.getContentStack())
+		setUpFutureActivities(context: self.moc!, delegate: self.delegate!, lang: self.lang!, parent: self.futureActivitiesSection.getContentStack())
+		setUpSocial(parent: self.socialSection.getContentStack())
+		setUpGallery(context: self.moc!, delegate: self.delegate!, parent: self.gallerySection.getContentStack())
+		setUpLablanca(context: self.moc!, delegate: self.delegate!, self.lang!)
+	}
+	
+	
 	/**
 	/**
 	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.
@@ -112,8 +126,54 @@ class HomeView: UIView {
 	}
 	}
 	
 	
 	
 	
+	/**
+	Sets up the location section.
+	If no location is reported, it hiddes the section.
+	*/
+	func setUpLocation(){
+		let defaults = UserDefaults.standard
+		if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
+			let time = defaults.value(forKey: "GMLocTime") as! Date
+			let cTime = Date()
+			let minutes = Calendar.current.dateComponents([.minute], from: time, to: cTime).minute
+			if (minutes! < 30){
+				self.locationSection.isHidden = false
+			}
+			else{
+				self.locationSection.isHidden = true
+			}
+		}
+		else{
+			self.locationSection.isHidden = true
+		}
+	}
+	
+	
+	/**
+	Sets up the La Blanca secction.
+	Hiddes it if no current festivals.
+	:param: context App context.
+	:param: delegate App delegate.
+	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
+	*/
+	func setUpLablanca(context : NSManagedObjectContext, delegate: AppDelegate, lang: String){
+		let defaults = UserDefaults.standard
+		if (defaults.value(forKey: "festivals") != nil){
+			let festivals = defaults.value(forKey: "festivals") as! Int
+			if festivals == 1{
+				// TODO Actualy show something
+			}
+			else{
+				self.lablancaSection.isHidden = true
+			}
+		}
+	}
+	
+	
 	/**
 	/**
 	Sets up the future activities section.
 	Sets up the future activities section.
+	If none, it hiddes the section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: delegate App delegate.
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: parent Stack view to load the rows in.
 	:param: parent Stack view to load the rows in.
@@ -136,40 +196,46 @@ class HomeView: UIView {
 			var text: String
 			var text: String
 			var image: String
 			var image: String
 			
 			
-			for r in searchResults as [NSManagedObject] {
-				count = count + 1
+			if searchResults.count == 0{
+				self.futureActivitiesSection.isHidden = true
+			}
+			else{
+				for r in searchResults as [NSManagedObject] {
+					count = count + 1
 				
 				
-				//Create a new row
-				row = RowHomeFutureActivities.init(s: "rowHomeFutureActivities\(count)", i: count)
-				id = r.value(forKey: "id")! as! Int
-				title = r.value(forKey: "title_\(lang)")! as! String
-				text = r.value(forKey: "text_\(lang)")! as! String
-				row.setTitle(text: title)
-				row.setText(text: text.decode())
+					//Create a new row
+					row = RowHomeFutureActivities.init(s: "rowHomeFutureActivities\(count)", i: count)
+					id = r.value(forKey: "id")! as! Int
+					title = r.value(forKey: "title_\(lang)")! as! String
+					text = r.value(forKey: "text_\(lang)")! as! String
+					row.setTitle(text: title)
+					row.setText(text: text)
+					row.id = id
 				
 				
-				// Get main image
-				image = ""
-				let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
-				let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
-				let imgSortDescriptors = [imgSortDescriptor]
-				imgFetchRequest.sortDescriptors = imgSortDescriptors
-				imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
-				imgFetchRequest.fetchLimit = 1
-				do{
-					let imgSearchResults = try context.fetch(imgFetchRequest)
-					for imgR in imgSearchResults as [NSManagedObject]{
-						image = imgR.value(forKey: "image")! as! String
-						row.setImage(filename: image)
+					// Get main image
+					image = ""
+					let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
+					let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
+					let imgSortDescriptors = [imgSortDescriptor]
+					imgFetchRequest.sortDescriptors = imgSortDescriptors
+					imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
+					imgFetchRequest.fetchLimit = 1
+					do{
+						let imgSearchResults = try context.fetch(imgFetchRequest)
+						for imgR in imgSearchResults as [NSManagedObject]{
+							image = imgR.value(forKey: "image")! as! String
+							row.setImage(filename: image)
+						}
+					}
+					catch {
+						NSLog(":HOME:ERROR: Error getting image for activity \(id): \(error)")
 					}
 					}
-				}
-				catch {
-					NSLog(":HOME:ERROR: Error getting image for activity \(id): \(error)")
-				}
-				
-				parent.addArrangedSubview(row)
 				
 				
+					parent.addArrangedSubview(row)
+				}
 			}
 			}
-		} catch {
+		}
+		catch {
 			NSLog(":HOME:ERROR: Error loading future activities: \(error)")
 			NSLog(":HOME:ERROR: Error loading future activities: \(error)")
 		}
 		}
 	}
 	}
@@ -177,6 +243,7 @@ class HomeView: UIView {
 	
 	
 	/**
 	/**
 	Sets up the blog section.
 	Sets up the blog section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: delegate App delegate.
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: parent Stack view to load the rows in.
 	:param: parent Stack view to load the rows in.
@@ -245,6 +312,7 @@ class HomeView: UIView {
 	
 	
 	/**
 	/**
 	Sets up the past activities section.
 	Sets up the past activities section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: delegate App delegate.
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: lang Language code (two letter code, lowercase. Only 'es', 'en' and 'eu' supported).
 	:param: parent Stack view to load the rows in.
 	:param: parent Stack view to load the rows in.
@@ -279,6 +347,7 @@ class HomeView: UIView {
 				
 				
 				row.setTitle(text: title)
 				row.setTitle(text: title)
 				row.setText(text: text)
 				row.setText(text: text)
+				row.id = id
 				
 				
 				// Get main image
 				// Get main image
 				image = ""
 				image = ""
@@ -306,8 +375,10 @@ class HomeView: UIView {
 		}
 		}
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Sets up the future activities section.
 	Sets up the future activities section.
+	:param: context App context.
 	:param: delegate App delegate.
 	:param: delegate App delegate.
 	:param: parent Stack view to load the rows in.
 	:param: parent Stack view to load the rows in.
 	*/
 	*/
@@ -335,6 +406,7 @@ class HomeView: UIView {
 				
 				
 				image = r.value(forKey: "file")! as! String
 				image = r.value(forKey: "file")! as! String
 				row.setImage(idx: i, filename: image)
 				row.setImage(idx: i, filename: image)
+				NSLog(":HOME:DEBUG: Photo \(i)")
 				
 				
 				//TODO Set click listener
 				//TODO Set click listener
 				i = i + 1
 				i = i + 1

+ 11 - 5
app/HomeView.xib

@@ -31,7 +31,7 @@
                     <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                     <rect key="frame" x="0.0" y="0.0" width="320" height="480"/>
                     <subviews>
                     <subviews>
                         <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="gOz-rr-CeQ">
                         <stackView opaque="NO" contentMode="scaleToFill" ambiguous="YES" axis="vertical" alignment="center" spacing="10" translatesAutoresizingMaskIntoConstraints="NO" id="gOz-rr-CeQ">
-                            <rect key="frame" x="0.0" y="0.0" width="320" height="780"/>
+                            <rect key="frame" x="0.0" y="0.0" width="320" height="930"/>
                             <subviews>
                             <subviews>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ljm-NP-c4e" customClass="Section" customModule="app">
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Ljm-NP-c4e" customClass="Section" customModule="app">
                                     <rect key="frame" x="0.0" y="0.0" width="320" height="50"/>
                                     <rect key="frame" x="0.0" y="0.0" width="320" height="50"/>
@@ -46,10 +46,10 @@
                                     <rect key="frame" x="0.0" y="180" width="320" height="50"/>
                                     <rect key="frame" x="0.0" y="180" width="320" height="50"/>
                                 </view>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="v6A-Ya-esA" customClass="Section" customModule="app" customModuleProvider="target">
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="v6A-Ya-esA" customClass="Section" customModule="app" customModuleProvider="target">
-                                    <rect key="frame" x="0.0" y="240" width="320" height="50"/>
+                                    <rect key="frame" x="0.0" y="240" width="320" height="200"/>
                                 </view>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fZk-r1-Tca" customClass="Section" customModule="app">
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="fZk-r1-Tca" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="300" width="320" height="350"/>
+                                    <rect key="frame" x="0.0" y="450" width="320" height="350"/>
                                     <userDefinedRuntimeAttributes>
                                     <userDefinedRuntimeAttributes>
                                         <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
                                         <userDefinedRuntimeAttribute type="number" keyPath="borderWidth">
                                             <real key="value" value="0.0"/>
                                             <real key="value" value="0.0"/>
@@ -57,7 +57,7 @@
                                     </userDefinedRuntimeAttributes>
                                     </userDefinedRuntimeAttributes>
                                 </view>
                                 </view>
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dgk-s8-xje" customClass="Section" customModule="app">
                                 <view contentMode="scaleToFill" ambiguous="YES" translatesAutoresizingMaskIntoConstraints="NO" id="dgk-s8-xje" customClass="Section" customModule="app">
-                                    <rect key="frame" x="0.0" y="660" width="320" height="120"/>
+                                    <rect key="frame" x="0.0" y="810" width="320" height="120"/>
                                 </view>
                                 </view>
                             </subviews>
                             </subviews>
                             <color key="backgroundColor" red="1" green="1" blue="0.42787000868055558" alpha="1" colorSpace="calibratedRGB"/>
                             <color key="backgroundColor" red="1" green="1" blue="0.42787000868055558" alpha="1" colorSpace="calibratedRGB"/>
@@ -73,6 +73,7 @@
                                 <constraint firstItem="FQo-nm-4Mo" firstAttribute="centerX" secondItem="gOz-rr-CeQ" secondAttribute="centerX" id="aWZ-5w-1ke"/>
                                 <constraint firstItem="FQo-nm-4Mo" firstAttribute="centerX" secondItem="gOz-rr-CeQ" secondAttribute="centerX" id="aWZ-5w-1ke"/>
                                 <constraint firstItem="FQo-nm-4Mo" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="azo-MK-F5R"/>
                                 <constraint firstItem="FQo-nm-4Mo" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="azo-MK-F5R"/>
                                 <constraint firstItem="uHa-Mu-U68" firstAttribute="centerX" secondItem="gOz-rr-CeQ" secondAttribute="centerX" id="i5O-1b-eCi"/>
                                 <constraint firstItem="uHa-Mu-U68" firstAttribute="centerX" secondItem="gOz-rr-CeQ" secondAttribute="centerX" id="i5O-1b-eCi"/>
+                                <constraint firstAttribute="bottom" secondItem="dgk-s8-xje" secondAttribute="bottom" id="lUo-Rq-bAi"/>
                                 <constraint firstItem="uHa-Mu-U68" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="ljo-DJ-9M1"/>
                                 <constraint firstItem="uHa-Mu-U68" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="ljo-DJ-9M1"/>
                                 <constraint firstItem="Ljm-NP-c4e" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="s8R-dV-4ju"/>
                                 <constraint firstItem="Ljm-NP-c4e" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="s8R-dV-4ju"/>
                                 <constraint firstItem="9nu-j1-wGI" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="v1C-hQ-R98"/>
                                 <constraint firstItem="9nu-j1-wGI" firstAttribute="width" secondItem="gOz-rr-CeQ" secondAttribute="width" id="v1C-hQ-R98"/>
@@ -80,6 +81,8 @@
                         </stackView>
                         </stackView>
                     </subviews>
                     </subviews>
                     <constraints>
                     <constraints>
+                        <constraint firstAttribute="bottom" secondItem="gOz-rr-CeQ" secondAttribute="bottom" id="1aX-69-rIr"/>
+                        <constraint firstAttribute="trailing" secondItem="gOz-rr-CeQ" secondAttribute="trailing" id="53K-6k-eT3"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="width" secondItem="Poy-ba-9jX" secondAttribute="width" id="Gw0-jw-ldE"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="width" secondItem="Poy-ba-9jX" secondAttribute="width" id="Gw0-jw-ldE"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="top" secondItem="Poy-ba-9jX" secondAttribute="top" id="Hmx-ri-LqQ"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="top" secondItem="Poy-ba-9jX" secondAttribute="top" id="Hmx-ri-LqQ"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="leading" secondItem="Poy-ba-9jX" secondAttribute="leading" id="k5u-hr-4th"/>
                         <constraint firstItem="gOz-rr-CeQ" firstAttribute="leading" secondItem="Poy-ba-9jX" secondAttribute="leading" id="k5u-hr-4th"/>
@@ -89,7 +92,10 @@
             <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
             <color key="backgroundColor" red="0.70980392160000005" green="0.82745098039999998" blue="0.8980392157" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
             <constraints>
             <constraints>
                 <constraint firstItem="Poy-ba-9jX" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="9SN-Tf-raC"/>
                 <constraint firstItem="Poy-ba-9jX" firstAttribute="width" secondItem="iN0-l3-epB" secondAttribute="width" id="9SN-Tf-raC"/>
-                <constraint firstItem="Poy-ba-9jX" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="TFG-sf-YY4"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="centerX" secondItem="iN0-l3-epB" secondAttribute="centerX" id="Gar-uI-abW"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="leading" secondItem="iN0-l3-epB" secondAttribute="leading" id="gDS-mJ-c25"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="top" secondItem="iN0-l3-epB" secondAttribute="top" id="k8Z-RL-IVb"/>
+                <constraint firstItem="Poy-ba-9jX" firstAttribute="height" secondItem="iN0-l3-epB" secondAttribute="height" id="xvC-vv-ebb"/>
             </constraints>
             </constraints>
             <point key="canvasLocation" x="26" y="52"/>
             <point key="canvasLocation" x="26" y="52"/>
         </view>
         </view>

+ 4 - 0
app/Info.plist

@@ -24,6 +24,10 @@
 	<true/>
 	<true/>
 	<key>NSLocationWhenInUseUsageDescription</key>
 	<key>NSLocationWhenInUseUsageDescription</key>
 	<string>Permitiendo acceso a tu ubicación, podrás conocer la distancia a la cuadrilla y a determinados eventos.</string>
 	<string>Permitiendo acceso a tu ubicación, podrás conocer la distancia a la cuadrilla y a determinados eventos.</string>
+	<key>UIBackgroundModes</key>
+	<array>
+		<string>fetch</string>
+	</array>
 	<key>UILaunchStoryboardName</key>
 	<key>UILaunchStoryboardName</key>
 	<string>LaunchScreen</string>
 	<string>LaunchScreen</string>
 	<key>UIMainStoryboardFile</key>
 	<key>UIMainStoryboardFile</key>

+ 92 - 0
app/LocationView.swift

@@ -29,10 +29,23 @@ class LocationView: UIView {
 	
 	
 	@IBOutlet var container: UIView!
 	@IBOutlet var container: UIView!
 	@IBOutlet weak var map: GMSMapView!
 	@IBOutlet weak var map: GMSMapView!
+	@IBOutlet weak var lbTitle: UILabel!
+	@IBOutlet weak var lbDistance: UILabel!
+	@IBOutlet weak var lbNo: UILabel!
+	
+	var controller: ViewController
+	var storyboard: UIStoryboard
 	
 	
 	var didFindMyLocation = false
 	var didFindMyLocation = false
 	
 	
+	var locationTimer: Timer? = nil
+	
 	override init(frame: CGRect){
 	override init(frame: CGRect){
+		
+		// Set controller
+		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
+		self.controller = storyboard.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
+		
 		super.init(frame: frame)
 		super.init(frame: frame)
 	}
 	}
 	
 	
@@ -42,6 +55,10 @@ class LocationView: UIView {
 	*/
 	*/
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		
 		
+		// Set controller
+		self.storyboard = UIStoryboard(name: "Main", bundle: nil)
+		self.controller = storyboard.instantiateViewController(withIdentifier: "GMViewController") as! ViewController
+		
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
 		
 		
 		// Load the contents of the HomeView.xib file.
 		// Load the contents of the HomeView.xib file.
@@ -54,6 +71,10 @@ class LocationView: UIView {
 		//map.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.new, context: nil)
 		//map.addObserver(self, forKeyPath: "myLocation", options: NSKeyValueObservingOptions.new, context: nil)
 		let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: 42.846399, longitude: -2.673365, zoom: 12.0)
 		let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: 42.846399, longitude: -2.673365, zoom: 12.0)
 		map.camera = camera
 		map.camera = camera
+		
+		// Schedule location fetches
+		getNewLocation()
+		Timer.scheduledTimer(timeInterval: 60, target: self, selector: #selector(getNewLocation), userInfo: nil, repeats: true)
 	}
 	}
 	
 	
 	
 	
@@ -66,6 +87,77 @@ class LocationView: UIView {
 		}
 		}
 	}
 	}
 	
 	
+	
+	/**
+	Get new location
+	*/
+	func getNewLocation(){
+		NSLog(":LOCATION:DEBUG: Setting marker.")
+		let defaults = UserDefaults.standard
+		if (defaults.value(forKey: "GMLocLat") != nil && defaults.value(forKey: "GMLocLon") != nil){
+			let lat = defaults.value(forKey: "GMLocLat") as! Double
+			let lon = defaults.value(forKey: "GMLocLon") as! Double
+			let time = defaults.value(forKey: "GMLocTime") as! Date
+			let cTime = Date()
+			let minutes = Calendar.current.dateComponents([.minute], from: time, to: cTime).minute
+			if (minutes! < 30){
+				self.map.isHidden = false
+				self.lbTitle.isHidden = false
+				self.lbDistance.isHidden = false
+				self.lbNo.isHidden = true
+				let marker = GMSMarker()
+				marker.position = CLLocationCoordinate2D(latitude: lat, longitude: lon)
+				marker.title = "Gasteizko Margolariak"
+				//marker.snippet = "Australia"
+				marker.map = self.map
+				NSLog(":LOCATION:DEBUG: Marker set.")
+			
+				let location = self.controller.getLocation()
+				if location != nil {
+					let d: Int = calculateDistance(lat1: location.latitude, lon1: location.longitude, lat2: lat, lon2: lon)
+					NSLog(":LOCATION:LOG: Distance (m): \(d)")
+				
+					if d <= 1000 {
+						self.lbDistance.text = "A \(d) metros de ti."
+					}
+					else{
+						self.lbDistance.text = "A \(Int(d/1000)) kilómetros de ti."
+					}
+				}
+			}
+			else{
+				self.map.isHidden = true
+				self.lbTitle.isHidden = true
+				self.lbDistance.isHidden = true
+				self.lbNo.isHidden = false
+			}
+		}
+		else{
+			NSLog(":LOCATION:DEBUG: No location saved yet.")
+		}
+	}
+
+
+	func degreesToRadians(degrees: Double) -> Double {
+		return degrees * Double.pi / 180;
+	}
+
+
+	func calculateDistance(lat1: Double, lon1: Double, lat2: Double, lon2: Double) -> Int {
+		let eRadius: Double = 6371
+
+		let dLat: Double = degreesToRadians(degrees: lat2-lat1)
+		let dLon: Double = degreesToRadians(degrees: lon2-lon1)
+
+		let l1: Double = degreesToRadians(degrees: lat1)
+		let l2: Double = degreesToRadians(degrees: lat2)
+
+		let a: Double = sin(dLat/2) * sin(dLat/2) + sin(dLon/2) * sin(dLon/2) * cos(l1) * cos(l2)
+		let c: Double = 2 * atan2(sqrt(a), sqrt(1-a))
+		let m: Double = eRadius * c * 1000
+		return Int(m)
+	}
+	
 	/*func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutableRawPointer) {
 	/*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

+ 14 - 1
app/LocationView.xib

@@ -12,6 +12,9 @@
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LocationView" customModule="app">
         <placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="LocationView" customModule="app">
             <connections>
             <connections>
                 <outlet property="container" destination="iN0-l3-epB" id="HCq-e3-37n"/>
                 <outlet property="container" destination="iN0-l3-epB" id="HCq-e3-37n"/>
+                <outlet property="lbDistance" destination="lB5-i1-GOe" id="50S-QH-XrM"/>
+                <outlet property="lbNo" destination="hMd-9C-Onm" id="v1m-XE-RIG"/>
+                <outlet property="lbTitle" destination="jwp-Sd-GF5" id="aU9-kg-OHt"/>
                 <outlet property="map" destination="guk-vu-ykd" id="zo6-Wc-NCg"/>
                 <outlet property="map" destination="guk-vu-ykd" id="zo6-Wc-NCg"/>
             </connections>
             </connections>
         </placeholder>
         </placeholder>
@@ -42,7 +45,7 @@
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                     <nil key="highlightedColor"/>
                                 </label>
                                 </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="A X metros de ti." textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lB5-i1-GOe" userLabel="Message">
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="" textAlignment="natural" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lB5-i1-GOe" userLabel="Message">
                                     <rect key="frame" x="11.5" y="42" width="311" height="21"/>
                                     <rect key="frame" x="11.5" y="42" width="311" height="21"/>
                                     <constraints>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="21" id="ann-h3-NzS"/>
                                         <constraint firstAttribute="height" constant="21" id="ann-h3-NzS"/>
@@ -51,6 +54,12 @@
                                     <nil key="textColor"/>
                                     <nil key="textColor"/>
                                     <nil key="highlightedColor"/>
                                     <nil key="highlightedColor"/>
                                 </label>
                                 </label>
+                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gasteizko Margolariak no está reportando localización." textAlignment="natural" lineBreakMode="tailTruncation" numberOfLines="0" baselineAdjustment="alignBaselines" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="hMd-9C-Onm" userLabel="MessageNo">
+                                    <rect key="frame" x="12" y="10" width="311" height="53"/>
+                                    <fontDescription key="fontDescription" type="system" pointSize="17"/>
+                                    <nil key="textColor"/>
+                                    <nil key="highlightedColor"/>
+                                </label>
                                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="guk-vu-ykd" customClass="GMSMapView">
                                 <view contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="guk-vu-ykd" customClass="GMSMapView">
                                     <rect key="frame" x="10" y="73" width="315" height="492"/>
                                     <rect key="frame" x="10" y="73" width="315" height="492"/>
                                     <color key="backgroundColor" red="1" green="0.20334201390000001" blue="0.32001410590000001" alpha="1" colorSpace="calibratedRGB"/>
                                     <color key="backgroundColor" red="1" green="0.20334201390000001" blue="0.32001410590000001" alpha="1" colorSpace="calibratedRGB"/>
@@ -71,9 +80,13 @@
                             <constraints>
                             <constraints>
                                 <constraint firstItem="jwp-Sd-GF5" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="6vZ-Ex-Gdp"/>
                                 <constraint firstItem="jwp-Sd-GF5" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="6vZ-Ex-Gdp"/>
                                 <constraint firstItem="lB5-i1-GOe" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="8VC-kx-sMo"/>
                                 <constraint firstItem="lB5-i1-GOe" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="8VC-kx-sMo"/>
+                                <constraint firstItem="hMd-9C-Onm" firstAttribute="top" secondItem="jwp-Sd-GF5" secondAttribute="top" id="DMM-cd-pay"/>
+                                <constraint firstItem="hMd-9C-Onm" firstAttribute="bottom" secondItem="lB5-i1-GOe" secondAttribute="bottom" id="IYr-qB-csg"/>
                                 <constraint firstItem="lB5-i1-GOe" firstAttribute="width" secondItem="3aZ-8G-e8X" secondAttribute="width" constant="-24" id="MQn-K0-SK5"/>
                                 <constraint firstItem="lB5-i1-GOe" firstAttribute="width" secondItem="3aZ-8G-e8X" secondAttribute="width" constant="-24" id="MQn-K0-SK5"/>
                                 <constraint firstItem="jwp-Sd-GF5" firstAttribute="top" secondItem="3aZ-8G-e8X" secondAttribute="top" constant="10" id="Ni3-zk-KAJ"/>
                                 <constraint firstItem="jwp-Sd-GF5" firstAttribute="top" secondItem="3aZ-8G-e8X" secondAttribute="top" constant="10" id="Ni3-zk-KAJ"/>
                                 <constraint firstItem="guk-vu-ykd" firstAttribute="width" secondItem="3aZ-8G-e8X" secondAttribute="width" constant="-20" id="OK6-Tx-KhU"/>
                                 <constraint firstItem="guk-vu-ykd" firstAttribute="width" secondItem="3aZ-8G-e8X" secondAttribute="width" constant="-20" id="OK6-Tx-KhU"/>
+                                <constraint firstItem="hMd-9C-Onm" firstAttribute="width" secondItem="3aZ-8G-e8X" secondAttribute="width" constant="-24" id="Pg4-Ng-sSd"/>
+                                <constraint firstItem="hMd-9C-Onm" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="Pw4-7b-hDi"/>
                                 <constraint firstItem="guk-vu-ykd" firstAttribute="top" secondItem="lB5-i1-GOe" secondAttribute="bottom" constant="10" id="Q8e-BQ-NFd"/>
                                 <constraint firstItem="guk-vu-ykd" firstAttribute="top" secondItem="lB5-i1-GOe" secondAttribute="bottom" constant="10" id="Q8e-BQ-NFd"/>
                                 <constraint firstItem="lB5-i1-GOe" firstAttribute="top" secondItem="jwp-Sd-GF5" secondAttribute="bottom" constant="10" id="i7u-s7-Fz0"/>
                                 <constraint firstItem="lB5-i1-GOe" firstAttribute="top" secondItem="jwp-Sd-GF5" secondAttribute="bottom" constant="10" id="i7u-s7-Fz0"/>
                                 <constraint firstItem="guk-vu-ykd" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="ifj-50-FJg"/>
                                 <constraint firstItem="guk-vu-ykd" firstAttribute="centerX" secondItem="3aZ-8G-e8X" secondAttribute="centerX" id="ifj-50-FJg"/>

+ 210 - 0
app/PastActivityViewController.swift

@@ -0,0 +1,210 @@
+// 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
+
+/**
+Controller to show a past activity.
+*/
+class PastActivityViewController: UIViewController, UIGestureRecognizerDelegate {
+	
+	@IBOutlet weak var barButton: UIButton!
+	@IBOutlet weak var barTitle: UILabel!
+	@IBOutlet weak var activityTitle: UILabel!
+	@IBOutlet weak var activityImage: UIImageView!
+	@IBOutlet weak var activityText: UILabel!
+	@IBOutlet weak var activityDate: UILabel!
+
+	
+	// Activity id
+	var id: Int = -1
+	
+	var delegate: AppDelegate?
+	
+	var passId: Int = -1
+	
+	/**
+	Get the app context.
+	:return: The app context.
+	*/
+	func getContext () -> NSManagedObjectContext {
+		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
+	}
+	
+	
+	/**
+	Run when the app loads.
+	*/
+	override func viewDidLoad() {
+		super.viewDidLoad()
+		self.loadActivity(id: id)
+		// Set button action
+		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+	}
+	
+	
+	/**
+	Dismisses the controller.
+	*/
+	func back() {
+		NSLog(":FUTUREACTIVITYCONTROLLER:CONTROLLER:DEBUG: Back")
+		self.dismiss(animated: true, completion: nil)
+	}
+	
+	
+	/**
+	Dispose of any resources that can be recreated.
+	*/
+	override func didReceiveMemoryWarning() {
+		super.didReceiveMemoryWarning()
+	}
+	
+	
+	/**
+	Loads the selected post.
+	:param: id Post id.
+	*/
+	public func loadActivity(id: Int){
+		
+		NSLog(":PASTACTIVITYCONTROLLER:DEBUG: Loading past activity \(id)")
+		
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Activity> = Activity.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			var count = 0
+			var sTitle: String
+			var sText: String
+			var image: String
+			var date: NSDate
+			
+			for r in searchResults as [NSManagedObject] {
+				count = count + 1
+				sTitle = r.value(forKey: "title_\(lang)")! as! String
+				if (r.value(forKey: "after_\(lang)")! as! String).length != 0{
+					sText = r.value(forKey: "after_\(lang)")! as! String
+				}
+				else{
+					sText = r.value(forKey: "text_\(lang)")! as! String
+				}
+				date = r.value(forKey: "date")! as! NSDate
+				activityTitle.text = "  \(sTitle.decode().stripHtml())"
+				activityText.text = sText.decode().stripHtml()
+				activityDate.text = formatDate(date: date, lang: lang)
+				
+				// Get main image
+				image = ""
+				let imgFetchRequest: NSFetchRequest<Activity_image> = Activity_image.fetchRequest()
+				let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
+				let imgSortDescriptors = [imgSortDescriptor]
+				imgFetchRequest.sortDescriptors = imgSortDescriptors
+				imgFetchRequest.predicate = NSPredicate(format: "activity == %i", id)
+				imgFetchRequest.fetchLimit = 1
+				do{
+					let imgSearchResults = try context.fetch(imgFetchRequest)
+					for imgR in imgSearchResults as [NSManagedObject]{
+						image = imgR.value(forKey: "image")! as! String
+						let path = "img/actividades/preview/\(image)"
+						self.activityImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+					}
+				} catch {
+					NSLog(":PASTACTIVITYCONTROLLER:DEBUG: Error getting image for post \(id): \(error)")
+				}
+				
+			}
+		} catch {
+			NSLog(":PASTACTIVITYCONTROLLER:DEBUG: Error with request: \(error)")
+		}
+	}
+	
+	
+	/**
+	Formats a date to the desired language.
+	:param: text The date.
+	:param: lang Device language (only 'es', 'en', or 'eu').
+	*/
+	func formatDate(date: NSDate, lang: String) -> String{
+		
+		let months_es = ["0index", "enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"]
+		let months_en = ["0index", "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]
+		let months_eu = ["0index", "urtarrilaren", "otsailaren", "martxoaren", "abrilaren", "maiatzaren", "ekainaren", "ustailaren", "abustuaren", "irailaren", "urriaren", "azaroaren", "abenduaren"]
+		let days_es = ["0index", "Lunes", "Martes", "Miercoles", "Jueves", "Viernes", "Sábado", "Domingo"]
+		let days_en = ["0index", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"]
+		let days_eu = ["0index", "Astelehena", "Asteartea", "Asteazkena", "Osteguna", "Ostirala", "Larumbata", "Igandea"]
+		
+		let calendar = Calendar.current
+		let day = calendar.component(.day, from: date as Date)
+		let month = calendar.component(.month, from: date as Date)
+		let weekday = calendar.component(.weekday, from: date as Date)
+		var strDate = ""
+		
+		switch lang{
+		case "en":
+			
+			var dayNum = ""
+			switch day{
+			case 1:
+				dayNum = "1th"
+				break
+			case 2:
+				dayNum = "2nd"
+				break;
+			case 3:
+				dayNum = "3rd"
+				break;
+			default:
+				dayNum = "\(weekday)th"
+			}
+			
+			strDate = "\(days_en[weekday]), \(months_en[month]) \(dayNum)"
+			break
+		case "eu":
+			strDate = "\(days_eu[weekday]) \(months_eu[month]) \(day)an"
+			break
+		default:
+			strDate = "\(days_es[weekday]) \(day) de \(months_es[month])"
+		}
+		
+		return strDate
+	}
+	
+	/**
+	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"
+		}
+	}
+	
+}
+

+ 172 - 0
app/PhotoViewController.swift

@@ -0,0 +1,172 @@
+// 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
+
+/**
+The view controller of the app.
+*/
+class PhotoViewController: UIViewController, UIGestureRecognizerDelegate {
+	
+	
+	//@IBOutlet weak var barTitle: UILabel!
+	//@IBOutlet weak var barButton: UIButton!
+	//@IBOutlet weak var postText: UILabel!
+	//@IBOutlet weak var postTitle: UILabel!
+	//@IBOutlet weak var postImage: UIImageView!
+	@IBOutlet weak var barButton: UIButton!
+	@IBOutlet weak var barTitle: UILabel!
+	@IBOutlet weak var photoTitle: UILabel!
+	@IBOutlet weak var photoImage: UIImageView!
+	@IBOutlet weak var photoDate: UILabel!
+	@IBOutlet weak var btPrev: UIButton!
+	@IBOutlet weak var btNext: UIButton!
+	
+	var albumId: Int = -1
+	var photoId: Int = -1
+	var photoIds: [Int] = []
+	var passPhotoId: Int = -1
+	var passAlbumId: 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.
+	*/
+	override func viewDidLoad() {
+		NSLog(":PHOTOCONTROLLER:DEBUG: viewDidLoad")
+		
+		super.viewDidLoad()
+		self.loadPhoto(id: photoId)
+		
+		// TODO populate photo array
+		
+		// Set button action
+		// TODO barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
+	}
+	
+	
+	/**
+	Dismisses the controller.
+	*/
+	func back() {
+		NSLog(":PHOTOCONTROLLER:DEBUG: Back")
+		self.dismiss(animated: true, completion: nil)
+	}
+	
+	
+	/**
+	Dispose of any resources that can be recreated.
+	*/
+	override func didReceiveMemoryWarning() {
+		super.didReceiveMemoryWarning()
+	}
+	
+	
+	/**
+	Loads a photo in the viewer.
+	:param: id
+	*/
+	public func loadPhoto(id: Int){
+		
+		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
+		let appDelegate = UIApplication.shared.delegate as! AppDelegate
+		let lang : String = getLanguage()
+		context.persistentStoreCoordinator = appDelegate.persistentStoreCoordinator
+		let fetchRequest: NSFetchRequest<Photo> = Photo.fetchRequest()
+		fetchRequest.predicate = NSPredicate(format: "id = %i", id)
+		
+		do {
+			let searchResults = try context.fetch(fetchRequest)
+			
+			var sTitle: String
+			var sText: String
+			var image: String
+			
+			for r in searchResults as [NSManagedObject] {
+				
+				sTitle = r.value(forKey: "title_\(lang)")! as! String
+				// TODO photoTitle.text = "  \(sTitle.decode().stripHtml())"
+				// TODO date
+				
+				// TODO set photo
+				
+				/*
+				// Get main image
+				image = ""
+				let imgFetchRequest: NSFetchRequest<Post_image> = Post_image.fetchRequest()
+				let imgSortDescriptor = NSSortDescriptor(key: "idx", ascending: true)
+				let imgSortDescriptors = [imgSortDescriptor]
+				imgFetchRequest.sortDescriptors = imgSortDescriptors
+				imgFetchRequest.predicate = NSPredicate(format: "post == %i", id)
+				imgFetchRequest.fetchLimit = 1
+				//TODO get more images
+				do{
+					let imgSearchResults = try context.fetch(imgFetchRequest)
+					for imgR in imgSearchResults as [NSManagedObject]{
+						image = imgR.value(forKey: "image")! as! String
+						if image == ""{
+							self.postImage.isHidden = true
+						}
+						else{
+							let path = "img/actividades/thumb/\(image)"
+							self.postImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+						}
+					}
+				} catch {
+					NSLog(":POST:ERROR: Error getting image for post \(id): \(error)")
+				}*/
+				
+			}
+		} catch {
+			NSLog(":PHOTO:ERROR: Error setting up photo \(id): \(error)")
+		}
+	}
+	
+	
+	// TODO Buttons
+	
+	
+	/**
+	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"
+		}
+	}
+}
+

+ 22 - 22
app/PostViewController.swift

@@ -26,20 +26,17 @@ The view controller of the app.
 */
 */
 class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	
 	
+	
 	@IBOutlet weak var barTitle: UILabel!
 	@IBOutlet weak var barTitle: UILabel!
 	@IBOutlet weak var barButton: UIButton!
 	@IBOutlet weak var barButton: UIButton!
 	@IBOutlet weak var postText: UILabel!
 	@IBOutlet weak var postText: UILabel!
 	@IBOutlet weak var postTitle: UILabel!
 	@IBOutlet weak var postTitle: UILabel!
 	@IBOutlet weak var postImage: UIImageView!
 	@IBOutlet weak var postImage: UIImageView!
-	var id: Int = -1
-	var delegate: AppDelegate?
 	
 	
+	var id: Int = -1
 	var passId: Int = -1
 	var passId: Int = -1
+	var delegate: AppDelegate?
 	
 	
-	/**
-	Get the app context.
-	:return: The app context.
-	*/
 	func getContext () -> NSManagedObjectContext {
 	func getContext () -> NSManagedObjectContext {
 		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
 		return NSManagedObjectContext(concurrencyType: .mainQueueConcurrencyType)
 	}
 	}
@@ -49,16 +46,17 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 	Run when the app loads.
 	Run when the app loads.
 	*/
 	*/
 	override func viewDidLoad() {
 	override func viewDidLoad() {
+		
 		super.viewDidLoad()
 		super.viewDidLoad()
 		self.loadPost(id: id)
 		self.loadPost(id: id)
+		
 		// Set button action
 		// Set button action
 		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
 		barButton.addTarget(self, action: #selector(self.back), for: .touchUpInside)
 	}
 	}
 	
 	
+	//TODO implement all the logic for post loading here, including iboutlts
+	
 	
 	
-	/**
-	Dismisses the controller.
-	*/
 	func back() {
 	func back() {
 		print("POSTCONTROLLER:DEBUG: Back")
 		print("POSTCONTROLLER:DEBUG: Back")
 		self.dismiss(animated: true, completion: nil)
 		self.dismiss(animated: true, completion: nil)
@@ -72,15 +70,8 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		super.didReceiveMemoryWarning()
 		super.didReceiveMemoryWarning()
 	}
 	}
 	
 	
-	
-	/**
-	Loads the selected post.
-	:param: id Post id.
-	*/
 	public func loadPost(id: Int){
 	public func loadPost(id: Int){
 		
 		
-		NSLog(":POSTCONTROLLER:DEBUG: Loading post \(id)")
-		
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		let context = NSManagedObjectContext(concurrencyType: .privateQueueConcurrencyType)
 		let appDelegate = UIApplication.shared.delegate as! AppDelegate
 		let appDelegate = UIApplication.shared.delegate as! AppDelegate
 		let lang : String = getLanguage()
 		let lang : String = getLanguage()
@@ -89,18 +80,20 @@ 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 count = 0
+			
 			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] {
-				count = count + 1
+				
 				sTitle = r.value(forKey: "title_\(lang)")! as! String
 				sTitle = r.value(forKey: "title_\(lang)")! as! String
 				sText = r.value(forKey: "text_\(lang)")! as! String
 				sText = r.value(forKey: "text_\(lang)")! as! String
-				postTitle.text = "  \(sTitle)"
-				postText.text = sText.stripHtml()
+				postTitle.text = "  \(sTitle.decode().stripHtml())"
+				postText.text = sText.decode().stripHtml()
 				
 				
 				// Get main image
 				// Get main image
 				image = ""
 				image = ""
@@ -110,12 +103,18 @@ 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]{
 						image = imgR.value(forKey: "image")! as! String
 						image = imgR.value(forKey: "image")! as! String
-						let path = "img/blog/preview/\(image)"
-						self.postImage.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+						if image == ""{
+							self.postImage.isHidden = true
+						}
+						else{
+							let path = "img/actividades/thumb/\(image)"
+							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)")
@@ -127,6 +126,7 @@ class PostViewController: UIViewController, UIGestureRecognizerDelegate {
 		}
 		}
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	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.

+ 34 - 6
app/RowAlbum.swift

@@ -34,6 +34,9 @@ Extension of UIView to be formatted as sections.
 	// Album ID
 	// Album ID
 	var id = -1
 	var id = -1
 	
 	
+	// Photo ids
+	var photoIds: [Int] = [-1, -1]
+	
 	// Array with the imageviews
 	// Array with the imageviews
 	var preview: [UIImageView] = []
 	var preview: [UIImageView] = []
 
 
@@ -95,29 +98,54 @@ Extension of UIView to be formatted as sections.
 		super.init(frame: frame)
 		super.init(frame: frame)
 	}
 	}
 	
 	
-	func openPhoto(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ROWALBUM:DEBUG: Getting delegate and showing photo.")
-		// TODO
-		//let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
-		//delegate.controller?.showAlbum(id: self.id)
+	func openLeftPhoto(_ sender:UITapGestureRecognizer? = nil){
+		NSLog(":ROWALBUM:DEBUG: Getting delegate and showing left photo.")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPhoto(album: self.id, photo: self.photoIds[0])
+	}
+	
+	func openRightPhoto(_ sender:UITapGestureRecognizer? = nil){
+		NSLog(":ROWALBUM:DEBUG: Getting delegate and showing right photo.")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPhoto(album: self.id, photo: self.photoIds[1])
 	}
 	}
 	
 	
 	
 	
 	/**
 	/**
 	Changes the preview image of the photos.
 	Changes the preview image of the photos.
 	If null or empty, the igage is hidden.
 	If null or empty, the igage is hidden.
+	It also sets the tap listener to show the photo.
 	:param: idx Id of the image in the row. 0 for left, 1 for right.
 	:param: idx Id of the image in the row. 0 for left, 1 for right.
 	:param: filename Filename of the image.
 	:param: filename Filename of the image.
 	*/
 	*/
 	func setImage(idx: Int, filename: String){
 	func setImage(idx: Int, filename: String){
 		if (filename == ""){
 		if (filename == ""){
 			self.preview[idx].isHidden = true
 			self.preview[idx].isHidden = true
-			//TODO hide the imageview
 		}
 		}
 		else{
 		else{
 			let path = "img/galeria/thumb/\(filename)"
 			let path = "img/galeria/thumb/\(filename)"
 			self.preview[idx].setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 			self.preview[idx].setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+			// Set tap listener
+			if idx == 0 {
+				let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowAlbum.openLeftPhoto(_:)))
+				tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+				self.preview[idx].isUserInteractionEnabled = true
+				NSLog(":ROWALBUM:DEBUG: Setting tap recognizer for left photo.")
+				self.preview[idx].addGestureRecognizer(tapRecognizer)
+			}
+			else{
+				let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowAlbum.openRightPhoto(_:)))
+				tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+				self.preview[idx].isUserInteractionEnabled = true
+				NSLog(":ROWALBUM:DEBUG: Setting tap recognizer for right photo.")
+				self.preview[idx].addGestureRecognizer(tapRecognizer)
+			}
 		}
 		}
 	}
 	}
 	
 	
+	func setIds(left: Int, right: Int){
+		self.photoIds[0] = left
+		self.photoIds[1] = right
+	}
+	
 }
 }

+ 17 - 20
app/RowBlog.swift

@@ -22,25 +22,20 @@ import Foundation
 import UIKit
 import UIKit
 
 
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as post rows.
 */
 */
 @IBDesignable class RowBlog: UIView {
 @IBDesignable class RowBlog: UIView {
 	
 	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
 	@IBOutlet weak var entry: UIView!
-
-	//The post title.
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var title: UILabel!
-	
-	//The post description.
 	@IBOutlet weak var descrip: UILabel!
 	@IBOutlet weak var descrip: UILabel!
-
-	//The post image.
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var image: UIImageView!
 	
 	
+	// Post ID.
+	var id = -1
+	
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -51,14 +46,15 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Loads the view in the xib file with the same name.
+	Loads the view from the xib with the same name as the class.
 	*/
 	*/
 	private func loadViewFromNib() {
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil).first as! UIView
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Default constructor.
 	Default constructor.
 	:param: s Custom identifier
 	:param: s Custom identifier
@@ -77,10 +73,9 @@ Extension of UIView to be formatted as sections.
 		self.addSubview(self.container)
 		self.addSubview(self.container)
 		
 		
 		// Set tap recognizer
 		// Set tap recognizer
-		/*print("ROW_BLOG:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openPost (_:)))
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowBlog.openPost (_:)))
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
 	
 	
@@ -97,7 +92,7 @@ Extension of UIView to be formatted as sections.
 	:param: text The new title.
 	:param: text The new title.
 	*/
 	*/
 	func setTitle(text: String){
 	func setTitle(text: String){
-		self.title.text = text.decode().stripHtml()
+		title.text = text.decode().stripHtml()
 	}
 	}
 	
 	
 	
 	
@@ -106,10 +101,11 @@ Extension of UIView to be formatted as sections.
 	:param: text The new text.
 	:param: text The new text.
 	*/
 	*/
 	func setText(text: String){
 	func setText(text: String){
-		self.descrip.text = text.decode()
+		descrip.text = text.decode().stripHtml()
 	}
 	}
 	
 	
 	
 	
+	
 	/**
 	/**
 	Changes the image of the post.
 	Changes the image of the post.
 	If null or empty, the igage is hidden.
 	If null or empty, the igage is hidden.
@@ -128,10 +124,11 @@ Extension of UIView to be formatted as sections.
 	
 	
 	
 	
 	/**
 	/**
-	Opens a post.
+	Opens an activity.
 	*/
 	*/
 	func openPost(_ sender:UITapGestureRecognizer? = nil){
 	func openPost(_ sender:UITapGestureRecognizer? = nil){
-		// TODO implement openPost.
-		NSLog(":ROW_BLOG:DEBUG: openpost")
+		NSLog(":ROWBLOG:DEBUG: Getting delegate and showing post \(self.id).")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPost(id: self.id)
 	}
 	}
 }
 }

+ 29 - 14
app/RowFutureActivity.swift

@@ -22,11 +22,11 @@ import Foundation
 import UIKit
 import UIKit
 
 
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as future activity rows.
 */
 */
 @IBDesignable class RowFutureActivity: UIView {
 @IBDesignable class RowFutureActivity: UIView {
 
 
-	// Outlets
+	// Outlets.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var image: UIImageView!
@@ -35,6 +35,9 @@ Extension of UIView to be formatted as sections.
 	@IBOutlet weak var city: UILabel!
 	@IBOutlet weak var city: UILabel!
 	@IBOutlet weak var price: UILabel!
 	@IBOutlet weak var price: UILabel!
 	
 	
+	// Activity ID.
+	var id = -1
+	
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -45,13 +48,16 @@ Extension of UIView to be formatted as sections.
 	}
 	}
 	
 	
 	
 	
-	
+	/**
+	Loads the view from the xib with the same name as the class.
+	*/
 	private func loadViewFromNib() {
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
 		nib.instantiate(withOwner: self, options: nil).first
 		nib.instantiate(withOwner: self, options: nil).first
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Default constructor.
 	Default constructor.
 	:param: s Custom identifier
 	:param: s Custom identifier
@@ -66,16 +72,16 @@ Extension of UIView to be formatted as sections.
 		container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 		container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 		container.translatesAutoresizingMaskIntoConstraints = true
 		container.translatesAutoresizingMaskIntoConstraints = true
 		
 		
-		container.frame = self.bounds
-		self.addSubview(container)
+		self.container.frame = self.bounds
+		self.addSubview(self.container)
 		
 		
 		// Set tap recognizer
 		// Set tap recognizer
-		/*print("ROW_FUTURE_ACTIVITY:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openActivity (_:)))
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowPastActivity.openActivity (_:)))
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Default constructor for the interface builder
 	Default constructor for the interface builder
 	*/
 	*/
@@ -84,7 +90,6 @@ Extension of UIView to be formatted as sections.
 	}
 	}
 	
 	
 	
 	
-	
 	/**
 	/**
 	Changes the title of the activity. Decodes HTML.
 	Changes the title of the activity. Decodes HTML.
 	:param: text The new title.
 	:param: text The new title.
@@ -93,6 +98,7 @@ Extension of UIView to be formatted as sections.
 		self.title.text = text.decode().stripHtml()
 		self.title.text = text.decode().stripHtml()
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Sets the city of the activity.
 	Sets the city of the activity.
 	:param: text The city.
 	:param: text The city.
@@ -101,6 +107,7 @@ Extension of UIView to be formatted as sections.
 		self.city.text = text.decode().stripHtml()
 		self.city.text = text.decode().stripHtml()
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Sets the price of the activity.
 	Sets the price of the activity.
 	:param: price The price, in Euros. If 0, nothing is shown.
 	:param: price The price, in Euros. If 0, nothing is shown.
@@ -114,6 +121,7 @@ Extension of UIView to be formatted as sections.
 		}
 		}
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Changes the description of the activity. Decodes HTML.
 	Changes the description of the activity. Decodes HTML.
 	:param: text The new text.
 	:param: text The new text.
@@ -122,6 +130,7 @@ Extension of UIView to be formatted as sections.
 		self.descript.text = text.decode().stripHtml()
 		self.descript.text = text.decode().stripHtml()
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	Sets the date of the activity in a human readable format.
 	Sets the date of the activity in a human readable format.
 	:param: text The date.
 	:param: text The date.
@@ -172,6 +181,7 @@ Extension of UIView to be formatted as sections.
 		self.date.text = strDate
 		self.date.text = strDate
 	}
 	}
 	
 	
+	
 	/**
 	/**
 	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 igage is hidden.
@@ -179,17 +189,22 @@ Extension of UIView to be formatted as sections.
 	*/
 	*/
 	func setImage(filename: String){
 	func setImage(filename: String){
 		if (filename == ""){
 		if (filename == ""){
-			NSLog("ROW_FUTURE_ACTIVITY:DEBUG: No image")
-			//TODO hide the imageview
+			// Hide the imageview
+			self.image.isHidden = true
 		}
 		}
 		else{
 		else{
-			NSLog(":ROW_FUTURE_ACTIVITY:DEBUG: Set image \(filename)")
 			let path = "img/actividades/thumb/\(filename)"
 			let path = "img/actividades/thumb/\(filename)"
-			image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
+			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 		}
 	}
 	}
 	
 	
+	
+	/**
+	Opens an activity.
+	*/
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
-		NSLog(":ROW_FUTURE_ACTIVITY:DEBUG: open activity")
+		NSLog(":ROWFUTUREACTIVITY:DEBUG: Getting delegate and showing past activity \(self.id).")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPastActivity(id: self.id)
 	}
 	}
 }
 }

+ 2 - 2
app/RowGallery.xib

@@ -1,11 +1,11 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <?xml version="1.0" encoding="UTF-8"?>
-<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
+<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="12120" systemVersion="16E195" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES">
     <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="11757"/>
+        <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12088"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="Constraints with non-1.0 multipliers" minToolsVersion="5.1"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
         <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
     </dependencies>
     </dependencies>

+ 25 - 17
app/RowHomeBlog.swift

@@ -26,23 +26,16 @@ Extension of UIView to be formatted as sections.
 */
 */
 @IBDesignable class RowHomeBlog: UIView {
 @IBDesignable class RowHomeBlog: UIView {
 
 
-	var id: Int!
-	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
 	@IBOutlet weak var entry: UIView!
-	
-	//The post title.
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var title: UILabel!
-	
-	//The post text.
 	@IBOutlet weak var descrip: UILabel!
 	@IBOutlet weak var descrip: UILabel!
-	
-	//The image.
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var image: UIImageView!
 	
 	
+	// Post ID.
+	var id: Int!
+	
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -58,7 +51,7 @@ Extension of UIView to be formatted as sections.
 	private func loadViewFromNib() {
 	private func loadViewFromNib() {
 		let bundle = Bundle(for: type(of: self))
 		let bundle = Bundle(for: type(of: self))
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
 		let nib = UINib(nibName: String(describing: type(of: self)), bundle: bundle)
-		nib.instantiate(withOwner: self, options: nil).first
+		nib.instantiate(withOwner: self, options: nil).first as! UIView
 	}
 	}
 	
 	
 	
 	
@@ -73,11 +66,16 @@ Extension of UIView to be formatted as sections.
 		self.frame = self.bounds
 		self.frame = self.bounds
 		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
 		self.translatesAutoresizingMaskIntoConstraints = true
 		self.translatesAutoresizingMaskIntoConstraints = true
-		container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
-		container.translatesAutoresizingMaskIntoConstraints = true
+		self.container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.container.translatesAutoresizingMaskIntoConstraints = true
+		
+		self.container.frame = self.bounds
+		self.addSubview(self.container)
 		
 		
-		container.frame = self.bounds
-		self.addSubview(container)
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeBlog.openPost (_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
 	
 	
@@ -115,11 +113,21 @@ Extension of UIView to be formatted as sections.
 	func setImage(filename: String){
 	func setImage(filename: String){
 		if (filename == ""){
 		if (filename == ""){
 			// Hide the imageview
 			// Hide the imageview
-			self.image.isHidden = true
+			self.image.isHidden = true;
 		}
 		}
 		else{
 		else{
 			let path = "img/blog/thumb/\(filename)"
 			let path = "img/blog/thumb/\(filename)"
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 		}
 	}
 	}
+	
+	
+	/**
+	Opens a post.
+	*/
+	func openPost(_ sender:UITapGestureRecognizer? = nil){
+		NSLog(":ROWHOMEBLOG:DEBUG: Getting delegate and showing post \(self.id).")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPost(id: self.id)
+	}
 }
 }

+ 19 - 9
app/RowHomeFutureActivities.swift

@@ -26,21 +26,16 @@ Extension of UIView to be formatted as sections.
 */
 */
 @IBDesignable class RowHomeFutureActivities: UIView {
 @IBDesignable class RowHomeFutureActivities: UIView {
 	
 	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
 	@IBOutlet weak var entry: UIView!
-	
-	//The activity title.
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var title: UILabel!
-	
-	//The activity description.
 	@IBOutlet weak var descrip: UILabel!
 	@IBOutlet weak var descrip: UILabel!
-	
-	//The activity image.
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var image: UIImageView!
 	
 	
+	// Activity ID.
+	var id: Int = -1;
+	
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -76,6 +71,11 @@ Extension of UIView to be formatted as sections.
 		
 		
 		self.container.frame = self.bounds
 		self.container.frame = self.bounds
 		self.addSubview(container)
 		self.addSubview(container)
+		
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomeFutureActivities.openActivity (_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
 	
 	
@@ -120,4 +120,14 @@ Extension of UIView to be formatted as sections.
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 		}
 	}
 	}
+	
+	
+	/**
+	Opens an activity.
+	*/
+	func openActivity(_ sender:UITapGestureRecognizer? = nil){
+		NSLog(":ROWFUTUREACTIVITY:DEBUG: Getting delegate and showing past activity \(self.id).")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showFutureActivity(id: self.id)
+	}
 }
 }

+ 8 - 1
app/RowHomeGallery.swift

@@ -61,7 +61,14 @@ Extension of UIView to be formatted as sections.
 	init(s: String, i: Int) {
 	init(s: String, i: Int) {
 		super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
 		super.init(frame: CGRect(x: 0, y: 0, width: 0, height: 0))
 		loadViewFromNib()
 		loadViewFromNib()
-		self.addSubview(self.container)
+		
+		self.frame = self.bounds
+		self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.translatesAutoresizingMaskIntoConstraints = true
+		self.container.autoresizingMask = [.flexibleWidth, .flexibleHeight]
+		self.container.translatesAutoresizingMaskIntoConstraints = true
+		self.container.frame = self.bounds
+		self.addSubview(container)
 		
 		
 		self.photos = [photo0, photo1, photo2, photo3]
 		self.photos = [photo0, photo1, photo2, photo3]
 		
 		

+ 20 - 10
app/RowHomePastActivities.swift

@@ -22,25 +22,20 @@ import Foundation
 import UIKit
 import UIKit
 
 
 /**
 /**
-Extension of UIView to be formatted as sections.
+Extension of UIView to be formatted as past activity rows.
 */
 */
 @IBDesignable class RowHomePastActivities: UIView {
 @IBDesignable class RowHomePastActivities: UIView {
 	
 	
-	//The container.
+	// Outlets.
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
-	
-	//The entry
 	@IBOutlet weak var entry: UIView!
 	@IBOutlet weak var entry: UIView!
-	
-	//The activity title.
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var title: UILabel!
-	
-	//The activity description.
 	@IBOutlet weak var descrip: UILabel!
 	@IBOutlet weak var descrip: UILabel!
-	
-	//The activity image.
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var image: UIImageView!
 	
 	
+	// Activity ID.
+	var id: Int = -1;
+	
 	
 	
 	/**
 	/**
 	Default constructor
 	Default constructor
@@ -76,6 +71,11 @@ Extension of UIView to be formatted as sections.
 
 
 		self.container.frame = self.bounds
 		self.container.frame = self.bounds
 		self.addSubview(container)
 		self.addSubview(container)
+		
+		// Set tap recognizer
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowHomePastActivities.openActivity (_:)))
+		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
 	
 	
@@ -120,4 +120,14 @@ Extension of UIView to be formatted as sections.
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 			self.image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 		}
 	}
 	}
+	
+	
+	/**
+	Opens an activity.
+	*/
+	func openActivity(_ sender:UITapGestureRecognizer? = nil){
+		NSLog(":ROWPASTACTIVITY:DEBUG: Getting delegate and showing past activity \(self.id).")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPastActivity(id: self.id)
+	}
 }
 }

+ 10 - 10
app/RowPastActivity.swift

@@ -26,15 +26,15 @@ Extension of UIView to be formatted as sections.
 */
 */
 @IBDesignable class RowPastActivity: UIView {
 @IBDesignable class RowPastActivity: UIView {
 	
 	
-	//This view
-	var v: UIView!
-	
 	// Outlets
 	// Outlets
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var container: UIView!
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var title: UILabel!
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var image: UIImageView!
 	@IBOutlet weak var descript: UILabel!
 	@IBOutlet weak var descript: UILabel!
 	
 	
+	// Activity ID.
+	var id = -1
+	
 	/**
 	/**
 	Default constructor
 	Default constructor
 	*/
 	*/
@@ -71,10 +71,9 @@ Extension of UIView to be formatted as sections.
 		self.addSubview(self.container)
 		self.addSubview(self.container)
 		
 		
 		// Set tap recognizer
 		// Set tap recognizer
-		/*print("ROW_PAST_ACTIVITY:DEBUG: set tap recognizer")
-		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (self.openActivity (_:)))
+		let tapRecognizer = UITapGestureRecognizer(target: self, action: #selector (RowPastActivity.openActivity (_:)))
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
 		tapRecognizer.delegate = (UIApplication.shared.delegate as! AppDelegate).controller
-		addGestureRecognizer(tapRecognizer)*/
+		self.addGestureRecognizer(tapRecognizer)
 	}
 	}
 	
 	
 	
 	
@@ -119,13 +118,14 @@ Extension of UIView to be formatted as sections.
 			image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 			image.setImage(localPath: path, remotePath: "https://margolariak.com/\(path)")
 		}
 		}
 	}
 	}
-	
-	
+
+
 	/**
 	/**
 	Opens an activity.
 	Opens an activity.
 	*/
 	*/
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
 	func openActivity(_ sender:UITapGestureRecognizer? = nil){
-		// TODO: Implement openActivity.
-		NSLog(":ROW_PAST_ACTIVITY:DEBUG: open activity")
+		NSLog(":ROWPASTACTIVITY:DEBUG: Getting delegate and showing past activity \(self.id).")
+		let delegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
+		delegate.controller?.showPastActivity(id: self.id)
 	}
 	}
 }
 }

+ 107 - 54
app/Sync.swift

@@ -28,6 +28,11 @@ Class to handle server sync.
 class Sync{
 class Sync{
 	
 	
 	var initial: Bool = false
 	var initial: Bool = false
+	var vBlog: Int = 0
+	var vActivities: Int = 0
+	var vGallery: Int = 0
+	var vBlanca: Int = 0
+	var vAll: Int = 0
 	
 	
 	/**
 	/**
 	Starts the sync process.
 	Starts the sync process.
@@ -56,14 +61,34 @@ class Sync{
 	:returns: The URL.
 	:returns: The URL.
 	*/
 	*/
 	func buildUrl() -> URL{
 	func buildUrl() -> URL{
-		let url = URL(string: "https://margolariak.com/API/v1/sync.php?client=com.margolariak.app")
-		//TODO add parameters
+		let defaults = UserDefaults.standard
+		var uId: String = "unknown"
+		if defaults.value(forKey: "versionAll") != nil{
+			self.vAll = defaults.value(forKey: "versionAll") as! Int
+		}
+		if defaults.value(forKey: "versionBlog") != nil{
+			self.vAll = defaults.value(forKey: "versionBlog") as! Int
+		}
+		if defaults.value(forKey: "versionActivities") != nil{
+			self.vActivities = defaults.value(forKey: "versionActivities") as! Int
+		}
+		if defaults.value(forKey: "versionGallery") != nil{
+			self.vGallery = defaults.value(forKey: "versionGallery") as! Int
+		}
+		if defaults.value(forKey: "versionBlanca") != nil{
+			self.vBlanca = defaults.value(forKey: "versionBlanca") as! Int
+		}
+		if defaults.value(forKey: "userId") != nil{
+			uId = defaults.value(forKey: "userId") as! String
+		}
+		let url = URL(string: "https://margolariak.com/API/v1/sync.php?client=com.margolariak.app&user=\(uId)&action=sync&version=\(self.vAll)")
+		
 		return url!
 		return url!
 	}
 	}
 	
 	
 	/**
 	/**
 	Performs an asynchronous sync.
 	Performs an asynchronous sync.
-	It fethes 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.
 	*/
 	*/
 	func sync(url: URL){
 	func sync(url: URL){
@@ -82,66 +107,94 @@ class Sync{
 			}
 			}
 			
 			
 			NSLog(":SYNC:LOG: Data received.")
 			NSLog(":SYNC:LOG: Data received.")
+			let defaults = UserDefaults.standard
 			
 			
 			var strData = String(data:data, encoding: String.Encoding.utf8)
 			var strData = String(data:data, encoding: String.Encoding.utf8)
 			
 			
+			var strVersions = ""
+			if strData != nil{
+				strVersions = (strData?.subStr(start : (strData?.indexOf(target : "\"version\":")!)! + 11, end : (strData?.indexOf(target : "}]}")!)! + 1))!
+			}
+			var vrAll: Int = 0
+			var vrBlog: Int = 0
+			var vrActivities: Int = 0
+			var vrGallery: Int = 0
+			var vrBlanca: Int = 0
+			vrAll = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"all\":")! + 7, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",\"")! + 1, end : strVersions.length - 1)
+			vrBlog = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"blog\":")! + 7, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",\"")! + 1, end : strVersions.length - 1)
+			vrActivities = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"activities\":")! + 13, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",\"")! + 1, end : strVersions.length - 1)
+			vrGallery = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"gallery\":")! + 10, end : strVersions.indexOf(target : "}")!-2))!
+			strVersions = strVersions.subStr(start : strVersions.indexOf(target : ",\"")! + 1, end : strVersions.length - 1)
+			vrBlanca = Int(strVersions.subStr(start : strVersions.indexOf(target : "\"lablanca\":")! + 11, end : strVersions.indexOf(target : "}")!-2))!
+			
 			let dataIdx = strData?.indexOf(target: "{\"data\"")
 			let dataIdx = strData?.indexOf(target: "{\"data\"")
 			strData = strData!.subStr(start: dataIdx!, end: strData!.length - 1)
 			strData = strData!.subStr(start: dataIdx!, end: strData!.length - 1)
 			
 			
-			//TODO: do something with versions
-			
-			//Get tables
-			let dataActivity : [String] = self.getTable(data: strData!, table: "activity")
-			let dataActivityComment : [String] = self.getTable(data: strData!, table: "activity_comment")
-			let dataActivityImage : [String] = self.getTable(data: strData!, table: "activity_image")
-			let dataActivityTag : [String] = self.getTable(data: strData!, table: "activity_tag")
-			let dataActivityItinerary : [String] = self.getTable(data: strData!, table: "activity_itinerary")
-			let dataAlbum : [String] = self.getTable(data: strData!, table: "album")
-			let dataFestival : [String] = self.getTable(data: strData!, table: "festival")
-			let dataFestivalDay : [String] = self.getTable(data: strData!, table: "festival_day")
-			let dataFestivalEvent : [String] = self.getTable(data: strData!, table: "festival_event")
-			//let dataFestivalEventImage : [String] = self.getTable(data: strData!, table: "festival_event_image")
-			let dataFestivalOffer : [String] = self.getTable(data: strData!, table: "festival_offer")
-			let dataPeople : [String] = self.getTable(data: strData!, table: "people")
-			let dataPhoto : [String] = self.getTable(data: strData!, table: "photo")
-			let dataPhotoAlbum : [String] = self.getTable(data: strData!, table: "photo_album")
-			//let dataPhotoComment : [String] = self.getTable(data: strData!, table: "photo_comment")
-			let dataPlace : [String] = self.getTable(data: strData!, table: "place")
-			let dataPost : [String] = self.getTable(data: strData!, table: "post")
-			let dataPostComment : [String] = self.getTable(data: strData!, table: "post_comment")
-			let dataPostImage : [String] = self.getTable(data: strData!, table: "post_image")
-			let dataPostTag : [String] = self.getTable(data: strData!, table: "post_tag")
+			//Get tables and save them
+			if vrActivities > self.vActivities || vrBlanca > self.vBlanca{
+				let dataPlace : [String] = self.getTable(data: strData!, table: "place")
+				self.saveTablePlace(entries: dataPlace)
+			}
+			if vrActivities > self.vActivities {
+				let dataActivity : [String] = self.getTable(data: strData!, table: "activity")
+				self.saveTableActivity(entries : dataActivity)
+				let dataActivityComment : [String] = self.getTable(data: strData!, table: "activity_comment")
+				self.saveTableActivityComment(entries : dataActivityComment)
+				let dataActivityImage : [String] = self.getTable(data: strData!, table: "activity_image")
+				self.saveTableActivityImage(entries : dataActivityImage)
+				let dataActivityTag : [String] = self.getTable(data: strData!, table: "activity_tag")
+				self.saveTableActivityTag(entries : dataActivityTag)
+				let dataActivityItinerary : [String] = self.getTable(data: strData!, table: "activity_itinerary")
+				self.saveTableActivityItinerary(entries : dataActivityItinerary)
+				defaults.set(vrActivities, forKey: "versionActivities")
+			}
+			if vrBlanca > self.vBlanca {
+				let dataPeople : [String] = self.getTable(data: strData!, table: "people")
+				self.saveTablePeople(entries: dataPeople)
+				let dataFestival : [String] = self.getTable(data: strData!, table: "festival")
+				self.saveTableFestival(entries: dataFestival)
+				let dataFestivalDay : [String] = self.getTable(data: strData!, table: "festival_day")
+				self.saveTableFestivalDay(entries: dataFestivalDay)
+				let dataFestivalEvent : [String] = self.getTable(data: strData!, table: "festival_event")
+				self.saveTableFestivalEvent(entries: dataFestivalEvent)
+				//let dataFestivalEventImage : [String] = self.getTable(data: strData!, table: "festival_event_image")
+				//
+				let dataFestivalOffer : [String] = self.getTable(data: strData!, table: "festival_offer")
+				self.saveTableFestivalOffer(entries: dataFestivalOffer)
+				defaults.set(vrBlanca, forKey: "versionBlanca")
+			}
+			if vrGallery > self.vGallery {
+				let dataAlbum : [String] = self.getTable(data: strData!, table: "album")
+				self.saveTableAlbum(entries: dataAlbum)
+				let dataPhoto : [String] = self.getTable(data: strData!, table: "photo")
+				self.saveTablePhoto(entries: dataPhoto)
+				let dataPhotoAlbum : [String] = self.getTable(data: strData!, table: "photo_album")
+				self.saveTablePhotoAlbum(entries: dataPhotoAlbum)
+				//let dataPhotoComment : [String] = self.getTable(data: strData!, table: "photo_comment")
+				//
+				defaults.set(vrGallery, forKey: "versionGallery")
+			}
+			if vrBlog > self.vBlog {
+				let dataPost : [String] = self.getTable(data: strData!, table: "post")
+				self.saveTablePost(entries: dataPost)
+				let dataPostComment : [String] = self.getTable(data: strData!, table: "post_comment")
+				self.saveTablePostComment(entries: dataPostComment)
+				let dataPostImage : [String] = self.getTable(data: strData!, table: "post_image")
+				self.saveTablePostImage(entries: dataPostImage)
+				let dataPostTag : [String] = self.getTable(data: strData!, table: "post_tag")
+				self.saveTablePostTag(entries: dataPostTag)
+				defaults.set(vrBlog, forKey: "versionBlog")
+			}
 			let dataSponsor : [String] = self.getTable(data: strData!, table: "sponsor")
 			let dataSponsor : [String] = self.getTable(data: strData!, table: "sponsor")
-			let dataSettings: [String] = self.getTable(data: strData!, table: "settings")
-			
-			//One by one, save the received data
-			self.saveTableActivity(entries : dataActivity)
-			self.saveTableActivityComment(entries : dataActivityComment)
-			self.saveTableActivityImage(entries : dataActivityImage)
-			self.saveTableActivityTag(entries : dataActivityTag)
-			self.saveTableActivityItinerary(entries : dataActivityItinerary)
-			
-			self.saveTablePost(entries: dataPost)
-			self.saveTablePostComment(entries: dataPostComment)
-			self.saveTablePostImage(entries: dataPostImage)
-			self.saveTablePostTag(entries: dataPostTag)
-			
-			self.saveTablePlace(entries: dataPlace)
-			self.saveTablePeople(entries: dataPeople)
-			
-			self.saveTableAlbum(entries: dataAlbum)
-			self.saveTablePhoto(entries: dataPhoto)
-			self.saveTablePhotoAlbum(entries: dataPhotoAlbum)
-			
-			self.saveTableFestival(entries: dataFestival)
-			self.saveTableFestivalDay(entries: dataFestivalDay)
-			self.saveTableFestivalOffer(entries: dataFestivalOffer)
-			self.saveTableFestivalEvent(entries: dataFestivalEvent)
-			
 			self.saveTableSponsor(entries: dataSponsor)
 			self.saveTableSponsor(entries: dataSponsor)
-			
+			let dataSettings: [String] = self.getTable(data: strData!, table: "settings")
 			self.saveSettings(entries: dataSettings)
 			self.saveSettings(entries: dataSettings)
-			
+			defaults.set(vrAll, forKey: "versionAll")
+				
+
 			// If it's the initial sync, hide the segue
 			// If it's the initial sync, hide the segue
 			if self.initial == true{
 			if self.initial == true{
 				NSLog(":SYNC:LOG: Finishing synchronous sync.")
 				NSLog(":SYNC:LOG: Finishing synchronous sync.")

+ 76 - 7
app/ViewController.swift

@@ -45,12 +45,16 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	
 	
 	// Passed id to perform segues.
 	// Passed id to perform segues.
 	var passId: Int = -1
 	var passId: Int = -1
+	var passAlbum: Int = -1
 	
 	
 	// Location-related variables.
 	// Location-related variables.
 	var locationManager = CLLocationManager()
 	var locationManager = CLLocationManager()
 	var didFindMyLocation = false
 	var didFindMyLocation = false
 	
 	
 	
 	
+	var locationTimer: Timer? = nil
+	
+	
 	/**
 	/**
 	Controller initializer.
 	Controller initializer.
 	:param: coder Coder.
 	:param: coder Coder.
@@ -58,6 +62,11 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	required init?(coder aDecoder: NSCoder) {
 	required init?(coder aDecoder: NSCoder) {
 		NSLog(":CONTROLLER:DEBUG: Init!")
 		NSLog(":CONTROLLER:DEBUG: Init!")
 		super.init(coder: aDecoder)
 		super.init(coder: aDecoder)
+		
+	}
+	
+	func getLocation() -> CLLocationCoordinate2D {
+		return (locationManager.location?.coordinate)!
 	}
 	}
 	
 	
 	
 	
@@ -83,6 +92,29 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	}
 	}
 	
 	
 	
 	
+	/**
+	Shows a past activity.
+	:param: id The activity id.
+	*/
+	func showPastActivity(id: Int){
+		NSLog(":CONTROLLER:DEBUG: Showing past activity \(id)")
+		self.passId = id
+		performSegue(withIdentifier: "SeguePastActivity", sender: nil)
+	}
+	
+	
+	/**
+	Shows a future activity.
+	:param: id The activity id.
+	*/
+	func showFutureActivity(id: Int){
+		NSLog(":CONTROLLER:DEBUG: Showing future activity \(id)")
+		self.passId = id
+		// TODO
+		//performSegue(withIdentifier: "SegueFutureActivity", sender: nil)
+	}
+	
+	
 	/**
 	/**
 	Shows an album.
 	Shows an album.
 	:param: id The album id.
 	:param: id The album id.
@@ -94,6 +126,20 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	}
 	}
 	
 	
 	
 	
+	// TODO: This must go in it AlbumViewController
+	/**
+	Shows a photo.
+	:param: id The album id.
+	*/
+	func showPhoto(album: Int, photo: Int){
+		NSLog(":CONTROLLER:DEBUG: Showing photo \(photo) of album \(album)")
+		self.passAlbum = album
+		self.passId = photo
+		performSegue(withIdentifier: "SeguePhoto", sender: nil)
+		NSLog(":CONTROLLER:DEBUG: PHOTO should be shown")
+	}
+	
+	
 	/**
 	/**
 	Shows a schedule.
 	Shows a schedule.
 	:param: margolari True for the margolari schedule, false for the city one.
 	:param: margolari True for the margolari schedule, false for the city one.
@@ -110,7 +156,7 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	}
 	}
 	
 	
 	
 	
-	/**
+	/** m
 	Handles the initial sync process.
 	Handles the initial sync process.
 	It can start it, showing the sync screen, or finish it, hidding the screen.
 	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.
 	:param: showScreen True to start the sync, false to end it.
@@ -143,6 +189,10 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		if segue.identifier == "SegueAlbum"{
 		if segue.identifier == "SegueAlbum"{
 			(segue.destination as! AlbumViewController).id = passId
 			(segue.destination as! AlbumViewController).id = passId
 		}
 		}
+		if segue.identifier == "SeguePhoto"{
+			(segue.destination as! PhotoViewController).photoId = passId
+			(segue.destination as! PhotoViewController).albumId = passAlbum
+		}
 		if segue.identifier == "SegueSchedule"{
 		if segue.identifier == "SegueSchedule"{
 			if passId == 1{
 			if passId == 1{
 				(segue.destination as! ScheduleViewController).margolari = true
 				(segue.destination as! ScheduleViewController).margolari = true
@@ -154,6 +204,19 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		if segue.identifier == "SegueSync"{
 		if segue.identifier == "SegueSync"{
 			self.syncSegue = segue
 			self.syncSegue = segue
 		}
 		}
+		if segue.identifier == "SeguePastActivity"{
+			(segue.destination as! PastActivityViewController).id = passId
+		}
+		if segue.identifier == "SegueFutureActivity"{
+			// TODO
+			//(segue.destination as! FutureActivityViewController).id = passId
+		}
+	}
+	
+	override func viewWillAppear(_ animated: Bool) {
+		NSLog(":CONTROLLER:DEBUG: Forcing a call to populate")
+		self.populate()
+		super.viewWillAppear(animated)
 	}
 	}
 	
 	
 	/**
 	/**
@@ -171,20 +234,26 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		self.containerViewActivities.alpha = 0
 		self.containerViewActivities.alpha = 0
 		self.containerViewBlog.alpha = 0
 		self.containerViewBlog.alpha = 0
 		self.containerViewGallery.alpha = 0
 		self.containerViewGallery.alpha = 0
+		
+		// Start the location schedule
+		fetchLocation()
+		self.locationTimer = Timer.scheduledTimer(timeInterval: 90, target: self, selector: #selector(fetchLocation), userInfo: nil, repeats: true)
 				
 				
-		NSLog(":CONTROLLER:DEBUG: Don't skyp sync")
-		Sync()
+		//NSLog(":CONTROLLER:DEBUG: Don't skyp sync")
+		NSLog(":CONTROLLER:DEBUG: Skyp sync")
+		//Sync()
 
 
 		
 		
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.delegate = UIApplication.shared.delegate as? AppDelegate
 		self.delegate?.controller = self
 		self.delegate?.controller = self
 		
 		
-		NSLog(":CONTROLLER:DEBUG: NOT Forcing a call to populate")
-		//self.populate()
-		
 		super.viewDidLoad()
 		super.viewDidLoad()
 		
 		
 	}
 	}
+	
+	func fetchLocation(){
+		FetchLocation()
+	}
 
 
 	/**
 	/**
 	Actually populates all sections.
 	Actually populates all sections.
@@ -192,7 +261,7 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	*/
 	*/
 	func populate(){
 	func populate(){
 		if (self.containerViewHome != nil){
 		if (self.containerViewHome != nil){
-			//(self.containerViewHome as HomeView).populate2()
+			//(self.containerViewHome as HomeView).populate()
 			//let ng = self.containerViewHome.dbgTxt
 			//let ng = self.containerViewHome.dbgTxt
 			//NSLog("AAAAA \(ng)")
 			//NSLog("AAAAA \(ng)")
 		}
 		}