Преглед изворни кода

Merge branch 'Location' into BaseProject

Iñigo Valentin пре 9 година
родитељ
комит
dbdad4f2f1
5 измењених фајлова са 207 додато и 1 уклоњено
  1. 4 0
      app.xcodeproj/project.pbxproj
  2. 81 0
      app/FetchLocation.swift
  3. 92 0
      app/LocationView.swift
  4. 14 1
      app/LocationView.xib
  5. 16 0
      app/ViewController.swift

+ 4 - 0
app.xcodeproj/project.pbxproj

@@ -19,6 +19,7 @@
 		9326C4F61EA5279D007DF2A4 /* RowLablancaDay.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9326C4F51EA5279D007DF2A4 /* RowLablancaDay.swift */; };
 		93294FF81E336FA000FDAF50 /* Entry.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93294FF71E336FA000FDAF50 /* Entry.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 */; };
 		935AE18A1EC6138D0055E71F /* SyncController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 935AE1891EC6138D0055E71F /* SyncController.swift */; };
 		935AE18C1ECE162C0055E71F /* RowLablancaOffer.xib in Resources */ = {isa = PBXBuildFile; fileRef = 935AE18B1ECE162B0055E71F /* RowLablancaOffer.xib */; };
@@ -100,6 +101,7 @@
 		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>"; };
 		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>"; };
 		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>"; };
@@ -247,6 +249,7 @@
 				93075C711E59D06900396389 /* RowBlog.xib */,
 				93075C6F1E59D04A00396389 /* RowBlog.swift */,
 				93D9EA751DE3ACBB00089002 /* Sync.swift */,
+				9357460F1EE20B99005DED61 /* FetchLocation.swift */,
 				931AA5881E1AFF8C003A2290 /* String.swift */,
 				93D9EA671DE342AC00089002 /* UIView.swift */,
 				935892CF1E493C2300E1CD5F /* UIImageView.swift */,
@@ -440,6 +443,7 @@
 				93E0C5E41EB7E94300905811 /* ActivitiesView.swift in Sources */,
 				93B408031D9ED44C000FBC99 /* MenuCollectionViewCell.swift in Sources */,
 				93B9113F1ED7582B0061BA71 /* LocationView.swift in Sources */,
+				935746101EE20B99005DED61 /* FetchLocation.swift in Sources */,
 				93E0C5E61EBDEF2B00905811 /* RowFutureActivity.swift in Sources */,
 				935D6E2F1E86792000CED3A1 /* GalleryView.swift in Sources */,
 			);

+ 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()
+	}
+}

+ 92 - 0
app/LocationView.swift

@@ -29,10 +29,23 @@ class LocationView: UIView {
 	
 	@IBOutlet var container: UIView!
 	@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 locationTimer: Timer? = nil
+	
 	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)
 	}
 	
@@ -42,6 +55,10 @@ class LocationView: UIView {
 	*/
 	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)
 		
 		// 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)
 		let camera: GMSCameraPosition = GMSCameraPosition.camera(withLatitude: 42.846399, longitude: -2.673365, zoom: 12.0)
 		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) {
 		if !didFindMyLocation {
 			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">
             <connections>
                 <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"/>
             </connections>
         </placeholder>
@@ -42,7 +45,7 @@
                                     <color key="textColor" red="0.1529411765" green="0.33333333329999998" blue="0.45098039220000002" alpha="1" colorSpace="calibratedRGB"/>
                                     <nil key="highlightedColor"/>
                                 </label>
-                                <label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="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"/>
                                     <constraints>
                                         <constraint firstAttribute="height" constant="21" id="ann-h3-NzS"/>
@@ -51,6 +54,12 @@
                                     <nil key="textColor"/>
                                     <nil key="highlightedColor"/>
                                 </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">
                                     <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"/>
@@ -71,9 +80,13 @@
                             <constraints>
                                 <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="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="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="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="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"/>

+ 16 - 0
app/ViewController.swift

@@ -51,6 +51,9 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	var didFindMyLocation = false
 	
 	
+	var locationTimer: Timer? = nil
+	
+	
 	/**
 	Controller initializer.
 	:param: coder Coder.
@@ -58,6 +61,11 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 	required init?(coder aDecoder: NSCoder) {
 		NSLog(":CONTROLLER:DEBUG: Init!")
 		super.init(coder: aDecoder)
+		
+	}
+	
+	func getLocation() -> CLLocationCoordinate2D {
+		return (locationManager.location?.coordinate)!
 	}
 	
 	
@@ -171,6 +179,10 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		self.containerViewActivities.alpha = 0
 		self.containerViewBlog.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()
@@ -185,6 +197,10 @@ class ViewController: UIViewController, UICollectionViewDataSource, UICollection
 		super.viewDidLoad()
 		
 	}
+	
+	func fetchLocation(){
+		FetchLocation()
+	}
 
 	/**
 	Actually populates all sections.