顯示具有 iOS 標籤的文章。 顯示所有文章
顯示具有 iOS 標籤的文章。 顯示所有文章

2018年2月20日 星期二

[iOS]使用Google Map

使用GOOGLE的API,萬法不離宗,就是要申請API KEY,

所以到Google Cloud Platform 新增專案
https://console.developers.google.com

















建立完成後畫面如下,接下來點選啟用API和服務



















點選Google Map for iOS



















啟用


建立憑證

點選"我需要那些憑證?"



點選"為金鑰新增限制"保護你的KEY不被預期之外的程序呼叫

如果你有要限定某一款iOS APP 才能呼叫,記得在com.example.MyAPP填入

 金鑰這樣就申請好囉


接下來記住你的金鑰,進入軟體部份了,如果您沒安裝過CocoaPods 需要先安裝,否則

請跳過安裝這一步,記得要是Xcode 8 or 9 ,請在終端機打上以下內容

sudo gem install cocoapods

等待安裝完成。

接下來我們要開啟一個Xcode專案


當專案建立完畢後,關閉專案及Xcode,回到終端機,進入專案根目錄下

cd MapDemo/

接下來要安裝GOOGLE MAP SDK,首先初始化一下cocoa pods 需要的設定檔
pod init

接下來編輯設定檔
vi Podfile

設定檔一開始長這樣
# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'MapDemo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MapDemo

  target 'MapDemoTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'MapDemoUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end
~      

加入GOOGLE MAP SDK,主要有三行
source 'https://github.com/CocoaPods/Specs.git'

pod 'GoogleMaps'
pod 'GooglePlaces' 


# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'
source 'https://github.com/CocoaPods/Specs.git'
target 'MapDemo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!
  pod 'GoogleMaps'
  pod 'GooglePlaces' 
  # Pods for MapDemo

  target 'MapDemoTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'MapDemoUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end




# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'MapDemo' do
  # Comment the next line if you're not using Swift and don't want to use dynamic frameworks
  use_frameworks!

  # Pods for MapDemo

  target 'MapDemoTests' do
    inherit! :search_paths
    # Pods for testing
  end

  target 'MapDemoUITests' do
    inherit! :search_paths
    # Pods for testing
  end

end
~      

接下來存檔,然候開始安裝SDK囉,視網路情況,可能需要一點時間喔。
pod install
安裝過程如下

Analyzing dependencies
Downloading dependencies
Installing GoogleMaps (2.5.0)
Installing GooglePlaces (2.5.0)
Generating Pods project
Integrating client project

[!] Please close any current Xcode sessions and use `MapDemo.xcworkspace` for this project from now on.
Sending stats
Pod installation complete! There are 2 dependencies from the Podfile and 2 total pods installed.

[!] Automatically assigning platform ios with version 10.2 on target MapDemo because no platform was specified. Please specify a platform for this target in your Podfile. See `https://guides.cocoapods.org/syntax/podfile.html#platform`.



接下來用指令啟動xocde
open MapDemo.xcworkspace

安裝成功的話你會發現專案多了一個Pods


在AppDelegate.swift 加入import GoogleMaps



接下來在application(_:didFinishLaunchingWithOptions:) 方法中填入你的API KEY(金鑰)

GMSServices.provideAPIKey("YOUR_API_KEY")









接下來把Main.storyboard的View的Class改成GMSMapView


接著在ViewController.swift中加入import GoogleMaps 以及以下程式碼

  override func loadView() {
        // Create a GMSCameraPosition that tells the map to display the
        // coordinate -33.86,151.20 at zoom level 6.
        let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6.0)
        let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        mapView.isMyLocationEnabled = true
        view = mapView
        
        // Creates a marker in the center of the map.
        let marker = GMSMarker()
        marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)
        marker.title = "Sydney"
        marker.snippet = "Australia"
        marker.map = mapView

    }


完整ViewController.swift如下


接著在Info.plist中加入Google Maps SDK for iOS 使用的 URL 配置


或是用UI介面編輯


接下來就可以開啟模擬器執行看看地圖會不會出來囉,地點會在雪梨


接下來我們試著顯示自己位置看看,此時我們會需要再加入一個NSLocationAlwaysUsageDescription 到Info.plis 提示用戶需要位置權限的字串



接下來我們改一下程式碼如下
import UIKit import GoogleMaps class YourViewController: UIViewController {   // You don't need to modify the default init(nibName:bundle:) method.   override func loadView() {     // Create a GMSCameraPosition that tells the map to display the     // coordinate -33.86,151.20 at zoom level 6.     let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6.0)     let mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)     mapView.isMyLocationEnabled = true     view = mapView     // Creates a marker in the center of the map.     let marker = GMSMarker()     marker.position = CLLocationCoordinate2D(latitude: -33.86, longitude: 151.20)     marker.title = "Sydney"     marker.snippet = "Australia"     marker.map = mapView   } }

//
//  ViewController.swift
//  MapDemo
//
//  Created by boywhy chen on 2018/2/20.
//  Copyright © 2018年 qq. All rights reserved.
//

import UIKit
import GoogleMaps

class ViewController: UIViewController,CLLocationManagerDelegate {
    var locationManager = CLLocationManager()
    var currentLocation: CLLocation?
    var mapView: GMSMapView!
    var zoomLevel: Float = 15.0
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    
    override func loadView() {
        locationManager = CLLocationManager()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestAlwaysAuthorization()
        locationManager.distanceFilter = 50
        locationManager.startUpdatingLocation()
        locationManager.delegate = self
        
     
        
        //init MapView
        let camera = GMSCameraPosition.camera(withLatitude: -33.86, longitude: 151.20, zoom: 6.0)
        
        mapView = GMSMapView.map(withFrame: CGRect.zero, camera: camera)
        
        mapView.isMyLocationEnabled = true
        
        view = mapView
    }
    
    // Handle incoming location events.
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let location: CLLocation = locations.last!
        print("Location: \(location)")
        
        let camera = GMSCameraPosition.camera(withLatitude: location.coordinate.latitude,
                                              longitude: location.coordinate.longitude,
                                              zoom: zoomLevel)
        
        if mapView.isHidden {
            mapView.isHidden = false
            mapView.camera = camera
        } else {
            mapView.animate(to: camera)
        }
        
      
    }
    
    // Handle authorization for the location manager.
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        switch status {
        case .restricted:
            print("Location access was restricted.")
        case .denied:
            print("User denied access to location.")
            // Display the map using the default location.
            mapView.isHidden = false
        case .notDetermined:
            print("Location status not determined.")
        case .authorizedAlways: fallthrough
        case .authorizedWhenInUse:
            print("Location status is OK.")
        }
    }
    
    // Handle location manager errors.
    func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
        locationManager.stopUpdatingLocation()
        print("Error: \(error)")
    }
}

主要是增加定位功能,接下來執行會要求權限,按下Allow


如果是用模擬器的話,可以選置以下幾種方式模擬位置

APPLE ,定位在APPLE總部




Custom Location 則是自己輸入經緯度



City Bike Ride ,City Run

其實是類似功能,只是移動速度不太一樣以及移動路徑不太相同


Freeway Driver 則是模擬在高速公路開車




參考文件

https://developers.google.com/maps/documentation/ios-sdk/map?hl=zh-tw

https://developers.google.com/maps/documentation/ios-sdk/current-places-tutorial?hl=zh-tw

https://stackoverflow.com/questions/24062509/location-services-not-working-in-ios-8

2017年12月18日 星期一

「iOS」[Firebase] iOS存取Firebase Realtime Database(1)

紀錄一下自己用iOS來存取Firebase Realtime Database

首先到進入到Firebase
https://console.firebase.google.com/u/2/

















新增專案



















點選iOS











先開啟xcode,建立一個iOS專案














重點在於紅框框中那一行,先記下等等有妙用














按下Next把專案建立好,再來回到Firebase



















把剛才記下的 Bundle Identifier填入,註冊應用程式
















下載GoogleService-Info.plist並放到專案目錄下



















接下來會用到CocoaPods ,如果沒安裝過,請先安裝,

不知道cocoaPods是什麼可以參考這一篇 , 安裝只需要在終端機輸入

sudo gem install cocoapods


接下來要進到專案根目錄下,開啟終端機並進入專案目錄

cd iOSDemo

初始化cocoaPods

pod init

此時目錄下會出現Podfile ,表示初始化cocoaPods成功






編輯Podfile 

vi Podfile

並在# Pods for iOSDemo下方加入二行

pod 'Firebase/Core'
pod 'Firebase/Database'





















存檔後,先裝Xcode關掉(很重要)

輸入下列指令開始安裝插件

pod install














接下來在輸入以下指令,開啟剛剛的專案

open iOSDemo.xcworkspace

此時會發現專案中多了一個Pods表示Firebase SDK安裝成功囉~


接下來是初始化Firebase ,打開AppDelegate.swift

import Firebase

並在
func application(_ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions

中加入

FirebaseApp.configure()

先Build一次看看,如果編譯成功,可以開啟模擬器執行,會有Firebase Log輸出。

下一篇會介紹如何新增,修改,刪除,讀取




2017年12月16日 星期六

[名詞定義][iOS]COCOAPODS

CocoaPods,它是一種支援 Swift 和 Objective-C 程式開發的

第三方庫資源相依性管理工具。



例如iOS APP使用如Firebase SDK , ,所以需要滙入包括Firebase本身及所需相關的類別

庫。開發者如果手動去處理,是一個很麻煩且易出錯的過程,日後如果Firebase SDK 或相關

的類別庫有更新時,就必須手動一個一個處理,且容易遇到版本相依性問題。

為了方便管理類別庫,因而𧗠生不少相依性管理工具 ,透過此工具解決開發者必須手動處理

類別庫更新問題。

OS X安裝方式

sudo gem install cocoapods


















安裝會需要一點點時間,東西有點多。

之後使用方式則如下,進入到專案根目錄

cd myiOSProgram

初始化cocoappods

vi Podfile

在檔案中加入所需要的類別庫,例如firebase



接下來安裝相關類別庫

pod install

參考來源:

https://www.appcoda.com.tw/cocoapods/


2017年10月16日 星期一

[iOS] Signing for "Map" requires a development team.


初用MapKit,編譯時遇到這個錯誤

Signing for "Map" requires a development team.


解法如下:

1.登入APPLE ID


2.在Signing設定Team即可(我的APPLE ID是沒有交99鎂的)

3.重新Builder



2016年12月27日 星期二

「iOS」Web View

Web View是讓APP可以造訪網頁,下載圖片,顯示地方等等功能的元件,

它就像是一個小小瀏覽器,也可以顯示圖片、GIF動畫,GOOGLE MAP等等。


Web View常用的方法如下:

loadRequest(request:NSURLResuest)  載入URL請求以顯示網頁

loadHTMLString(string:String!,baseURL:NSURL!) 載入網頁內容

loadData(file:NSData!,MIMEType:String!,textEncodingName:String!,baseURL:NSURL!)

reload()  重新載入

stropLoading() 停止載入

goBack() 在歷史紀錄中回到上一頁,如果沒有上一頁則不會有任何處理。

goForware() 在歷史紀錄中進到下一頁,如果沒有下一頁則不會有任何處理


以下是範例

載入Yahoo新聞 https://tw.news.yahoo.com/

先拉一個WebView元件出來,與程式碼建立連結

























這裡注意一件事,Storage必須選擇Strong,否則你會無法找到loadRequest之類的方法。

俺在這裡吃了一個晚上的悶虧。


程式碼如下:


  override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
            let url = NSURL(string:"https://tw.news.yahoo.com/")
            let request = NSURLRequest(URL:url!)
            myWebView.loadRequest(request);
        
          }

執行結果











































接下來我試Load一個HTTP網站(沒有SSL認證)是不行的,一片空白,並出現警告訊息




爬文後發現:

在 iOS 9 之後,應用程式內的 UIWebView 預設為只能載入 https 的網頁

(也就是加密過的),如果是普通 http 的網頁會無法開啟。

如果要允許開啟HTTP網頁,需要額外設定。

(1)打開info.plist




















(2)空白處按右鍵 Add Row









































輸入NSAppTransportSecurity 後按下Enter


























然候點一下這一行,讓箭頭向下,再按右鍵Add Row





























輸入NSAllowsArbitraryLoads 後按下Enter,型別為Boolean,值為Yes






再重新Build一次程式就可以Run一般的網頁了。

程式碼如下,我們來開一下蕃薯藤網站,沒有HTTPS的入口網頁之一,也沒有RWD。


 @IBOutlet var myWebView: UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
            let url = NSURL(string:"http://www.yam.com/")
            let request = NSURLRequest(URL:url!)
            myWebView.loadRequest(request);
        
          }
















































接下來示範另一個有用的功能,讀取HTML字串(或者稱為HTML原始碼)。

例如我有一個網頁的原始碼長這樣。


<html>
<head>
<title>Test Read HTML String</title>
</head>
<body>
<h1>test h1</h1><br><h2>test h2</h2>
</body>
</html>

我們用loadHTMLString方法來顯示這段程式碼

   @IBOutlet var myWebView: UIWebView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        
        let source:String = "<html><head><title>Test Read HTML String</title></head><body><h1>test h1</h1><br><h2>test h2</h2></body></html>"
              myWebView.loadHTMLString(source, baseURL: nil)
          }

執行畫面如下































參考資料:



網頁 UIWebView