iOS

By admin in 亚洲必赢app在哪下载 on 2018年12月14日

序言:闲在商家混日子一段时间,就上斯维夫特(Swift),学学iOS8,碰巧遇上这首小说,一个早上做下来发现这么些轻亮,就尝试翻译并享受下。顺便求推荐都德国首都的iOS工作~~~~

接触这里看原稿
点这里看 onevcat
大神的课

以下正文,表达一下,并无是逐字翻译,同时流程和情发生改动。

  • 假诺看官太懒了直看就结果,可以触发这里下载就后的工程,存放于dropbox,记得自备VPN。
  • 并且及时篇教程是swift
    1.0底当儿写的,打开项目后会报语法错误,按指示修改就足以。

Step 0:

在iOS
8碰到,苹果集团生产的应用程序扩张Extension技术,可以给你的APP增加原有职能到外界面(通告栏,分享拦),或受不同APP间可以举办数量交互,同时不会晤距离时页面。
iOS 8系统出6只辅助增加的体系区域,分别是Today、Share、Action、Photo
Editing、Storage Provider、Custom
keyboard。辅助扩充的系区域啊被叫作增加点。
脚是以IOS的延伸点的列表:

  • Today –
    对于赛事比分,股票、天气、快递这仿佛需要实时获取同时以简约的音,可以于通报中央的Today视图中开创一个Today扩张实现。Today扩大又称作Widget。

  • Share –
    在系统的享用拦中创建于定义分享,可以分享内容,分享网站要发布音讯。

  • Action –
    action在有着辅助之壮大点吃扩大性最强的一个。它可兑现转移另一个app上下文中的情。苹果在WWDC大会上演示了一个Bing翻译动作扩张,它可以在Safari中当选的文件翻译成不同之言语。

  • Photo Editing – 以iOS
    8在此以前,假使你想啊汝的影添加一个奇特之滤镜,你待进入第三方app中,那个历程是一对一繁琐的。在iOS
    8吃,你得从来当Photos中以第三方app,如Instagram,VSCO
    cam、Aviary提供的Photo
    Editing扩张完成对图纸的修,而无论是需离开时之app。

  • Document Provider – 也给Storage
    Provider,可以吃领先多单文本存储服务中的治本变得重复简便易行。类似Dropbox、GoogleDrive等储存提供商经当iOS 8遭到提供一个Storage
    Provider扩展,app直接可以以那么些扩大检索和贮文件要不再需要创设不必要的正片。

  • Custom Keyboard – 自定义键盘输入法可以被用户以周系统范围外动。

假如就首随笔,将集中授课 Today Extention 部分。

图片 1

Extention是怎工作之?

当我们起头选取Today
Extensions在此以前,先为咱看看Extensions的一部分定义,以便精晓之后的学科。

  • 第一,Extensions不是独的应用程序。Extensions必须凭让一个host
    app,下边一律吃作宿主APP,同时他们之生命周期相互独立,并且可相互接触事件。一个宿主APP可以蕴涵多独Extensions。

  • 当一个Extensions运行的上,宿主APP不会合同时运转。每个Extensions都生自己之单独进程(十分给一个有点的APP)。同时,可以基本上个Extensions同时运行,互相间不被影响。每便运行Extensions都是更启航之(重复的运相同Extensions并无会晤用相同片内存)。

  • Extensions与宿主APP间不克间接通讯,但足尝尝通过OpenURL()来开辟宿主APP或使用NSUserDefaults存储和朗诵博通用的数。

The Today Extension

哼了,现在大家准备开创一个widget,为了节约不必要之首准备,
这里好下载到旧状态的工程,记得使用VPN和修改swift
1.2 导致的语法错误。
那些本来工程是一个简单的气象数据展示下,so……它是用互联网连接和一个天数据得到之API。
假诺我们的气象数据将从今
forecast.io以此网站取得,它提供天天1000长条免费查询,所以在起头勾画代码前,最好先去报并将到属您的API
key。
Oh,还有还有,要取得天气虽用所在城市的地理地点音讯,所以我们还得而CoreLocation来博地理音信。(原文略过了立即步,并提供了一个教程
,但以分外简单用自己当此处就增长了 (.) )

Step 1:

总体准备好后,我们运行工程后该会盼底的界面:

图片 2

这就是是宿主APP现在底状态了,城市名跟坐标写深了 (=.=)。
然后,起头首先步咯!

Embedded Frameworks and Code Reuse 嵌入式框架和代码用

Extensions
的生命周期是单身于宿主APP的,同时Extensions的效能应是宿主的片段机能的拉开,Extensions与宿主应有相同的效用有,即其将会合动用相似甚至同的代码和逻辑。
故而,制作Extensions的率先步,就是管通用的代码块放到一个宿主APP与Extensions都可以“拿到”的地点。
iOS 8的自制Framwork就得帮到你!

以下是手续:

  1. 于Project
    Navigator中,点击project,然后于起的面板左下方点击”+”按钮(或选用Editor,然后AddTarget)。
![](https://upload-images.jianshu.io/upload_images/6775-d0667493f8973805.png)

这里是已经完成了状态
  1. 于打开的面板中,拔取 iOS > Framework & Library > Cocoa Touch
    Framework,然后您相会盼:
![](http://www.appcoda.com/wp-content/uploads/2014/10/weather_data_kit.png)
App Extension - Weather Data Kit



名字叫 WeatherDataKit 不要搞错了,其他按项目填,然后点一下 Finish。

完成地方的步子后,你碰面发觉多少个一个吃WeatherData基特的folder和target。展开WeatherData基特,会盼只有暴发一个
WeatherData基特(Kit).h 在这边,这个 .h 文件之凡当您的型又采纳 Obj-C 和
Swift的早晚以的,功能是桥接Obj-C的头文件,当然那类型里永不做任何操作。

以此我们要顾,Extension并无是会完全援助具有Cocoa Touch
APIs的,比如下边的几点:

  • 语音输入和视频头调用
  • 自AirDrop接收数据(但亦可发送数据)
  • 常驻后台(Extensions的可用内存是充分没有之,同时系统内存紧张的下也率先拿Extensions开刀)
  • 免克应用另外带有 NS_EXTENSION_UNAVAILABLE 或近似宏定义 的近乎, 或
    伊芙(Eve)nt基特 和 Health基特 这种无协助Extensions的 framework
  • Access a sharedApplication object, and so cannot use any of the
    methods on that object(不领会就词)

现今大家编译的时段要下上述的API将会碰着有告诫,可以经过勾选”Allow
app extension API
only”来虽然得避那些警告。(这里生只列表能够参照哪些不克就此当Extension上)

图片 3

记得勾上

哼了,接下去要召开的很简短,把原本在 Weather folder 中的 “Weather Data”
移动到 WeatherData基特(Kit) folder
中,记得去改变叫移位文件的target(四只都要)。

图片 4

App Extension – Weather Group

图片 5

即便是此处

Extra Part!

尚记下面提过,要拿走天气音讯,首先要拿走到地理地点音讯。原科目是因而固定坐标的,这里吧,我们就好写一个。
要么在 WeatherData基特 folder,新建一个受 WeatherLocation 的 swift
文件。然后,在 WeatherData基特 的 target 里补充加 CoreLocation framework。

图片 6

丰裕必要之 framework

日后就足以描绘代码啦:

  1. 以 WeatherLocation.swift 里,注解 WeatherLocation 的 class,它继续和
    NSObject,并且会发出 CoreLocation 的 delegate(记得先 import
    CoreLocation)。
  2. 下一场注解 CLLocationManager 对象
    ‘manager’,它好扶持我们一定又拿到到祥的地理消息。
  3. 继之补上 CLLocationManagerDelegate 的办法:
  • locationManager(manager: CLLocationManager!, didUpdateLocations
    locations: [AnyObject]!)
  • locationManager(manager: CLLocationManager!, didFailWithError error:
    NSError!)
    其一个当更新当前底地理地方音讯,一个顶住告诉你出错的情节。
  1. 末段在 init() 方法里受 manager 启动。(记得上上 manager 的装置与指定
    delegate 对象)

出这粗略也?
本来没有。Apple对于用户的难言之隐分外重视,像地理地方这种随时出卖你的信息,当然如若落用户许可才会运用!
那么我们先行回去 Weather 那一个target,找到 info 面板(或者以 Weather folder
下找到 info.plist)。
接下来上加少单价值:(在iOS 7
或事先就待一个,若是用协理原本本子则要开系统版本判断来做不同处理)

  • NSLocationAlwaysUsageDescription
  • NSLocationWhenInUseUsageDescription
    图片 7
    以 info.plist 为例
类型记得要为 String
,内容根据自己需要填。补充完这两项后,当项目启动并在第一次使用地理位置信息的时候,系统就会自动弹出
Alert 要求获取授权,这是上面你填的信息就会显示在这个 Alert
里。(关于这两个 String
的使用场景,可以参考[Develop](https://link.jianshu.com?t=https://developer.apple.com/library/prerelease/ios/documentation/General/Reference/InfoPlistKeyReference/Articles/CocoaKeys.html))

吓了,接下去贴一下代码:

import Foundation
import CoreLocation

class WeatherLocation : NSObject, CLLocationManagerDelegate {

typealias WeatherLocationCompletionBlock = (latLong: String?, cityName: String?, error: NSError?) -> ()

let manager = CLLocationManager()
var latAndLong : String?
var city : String?
var block : WeatherLocationCompletionBlock?

class var sharedInstance: WeatherLocation {
    struct Singleton {
        static let instance = WeatherLocation()
    }
    return Singleton.instance
}

override init() {

    super.init()

    manager.delegate = self
    manager.desiredAccuracy = kCLLocationAccuracyBest
    manager.requestAlwaysAuthorization()
}

 // MARK: 看这里看这里
func updateLocation(completion: WeatherLocationCompletionBlock) {
    if CLLocationManager.locationServicesEnabled() {
        manager.startUpdatingLocation()
        block = completion
    }
}

// MARK: CoreLocation
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {

    manager.stopUpdatingLocation()

    var location:CLLocation = locations[0] as! CLLocation
    latAndLong = "\(location.coordinate.latitude),\(location.coordinate.longitude)"

    CLGeocoder().reverseGeocodeLocation(location, completionHandler: { (placemarks, error) -> Void in
        if (error != nil) {
            self.block!(latLong: "", cityName: "", error: error)
            println("Reverse geocoder failed with error" + error.localizedDescription)
        } else {
            if placemarks.count > 0 {
                let pm:CLPlacemark = placemarks[0] as! CLPlacemark
                if (pm.locality != nil) {
                    self.city = pm.locality
                    self.block!(latLong: self.latAndLong, cityName: self.city, error: nil)
                }
            } else {
                var otherError : NSError?
                otherError = NSError(domain: "Problem with the data received from geocoder", code: -9999, userInfo: nil)
                self.block!(latLong: "", cityName: "", error: otherError)
                println("Problem with the data received from geocoder")
            }
        }
    })
}

    func locationManager(manager: CLLocationManager!, didFailWithError error: NSError!) {
        println("\(error)")
    }
}

好了,我们应该发现,除了当上头列有得使贯彻的法和对象以外,我还补充加了一个初的计
updateLocation(completion:blockName) 和一个 block
,它的来意是询问地理地点而通过 block 的花样重返结果于调用者。
欲注意的是 updateLocation
方法并无兢兢业业,它并不曾处理结果的状态再次回到给调用者,那当实际开支被以会晤遭受题目(比如你无可以确保用户机器会每趟都询问到结果)。

下一场,在 WeatherDataViewController.swift 文件被上加一个办法

func loadLocation(completionLocdLocation:(city: NSString?)->()) {
    WeatherLocation.sharedInstance.updateLocation { (latLong, cityName, error) -> () in
        weak var weakSelf = self as WeatherDataViewController
    WeatherLocation.sharedInstance.updateLocation { (latLong, cityName, error) -> () in
        WeatherService.sharedInstance.fetchWeatherData(latLong!, completion: { (data, error) -> () in
            dispatch_async(dispatch_get_main_queue()) {
                weakSelf?.weatherData = data
                weakSelf?.updateData()
                completionLocdLocation(city: cityName)
            }
        })
    }
}

loadLocation
方法里第一查询地理地方,得到结果后查询天气消息,得到气象详情后更新数据并拿当下城名重返给调用者,因为嵌套了
block 的干,记得使用 weak 来吧 self 变成弱引用,避免 retain cycle
问题。

最终,我们以 ViewController.swift 里测试一下,import WeatherData基特(WeatherDataViewController 的 target 改变了,需要打表引入,记得加上
framework),在 viewDidAppear 方法里增长:

weak var weakSelf = self
loadLocation { (city) -> () in
        weakSelf?.locationLabel.text = city as? String
}

运转,等 API 重临结果,UI
更新!(假如模拟器下边世谬误,记得调整模拟器地理地点的挑三拣四项,或者指定一个地理地方)

图片 8

呵呵呵呵

Step 2:

Creating the Widget

顶梁柱登场~~~继续累加 target,然后命名也 Weather Widget 。

图片 9

就是者

创造好后,我们会发觉大多了一个 Weather Widget 的 floder 和多矣一个
Scheme:

图片 10

连logo都不同

兹大家来看望一个初创制的 Today widget 会发生什么东西:

  • TodayViewController.swift
  • MainInterface.storyboard

以及一般的 ViewController 没什区别嘛~~~~但其实 TodayViewController
里已经补充加了 NCWidgetProviding 这么些protocol,乖乖的依据要求上了便好。还有久违的 didReceiveMemoryWarning
方法,看来 widget 是只每一天惨死的命,我们想做的花俏的口舌记得做懒加载与以
didReceiveMemoryWarning 里做释放,不然因为 widget 体验不佳就将 APP
删掉就得无尝试了。

摸索运行一下,弹出来的面板直接选 Today 就得了,然后会晤到底的效果:

图片 11

她曾经拉你写好 Hello World 了

坐 Extension 和 宿主APP 都待用同样的代码,所以其一样假设补偿加
framework:

图片 12

App Extension – 添加 Framework

补加了晚就是可当 TodayViewController 里继承的 ViewController 改也
WeatherDataViewController ,这样就是能够使用 WeatherDataViewController
的章程了。
搭下,大家设改 MainInterface.storyboard 里的UI,使 widget
看到的信可以同 宿主APP 的同。

图片 13

拿原来的 Hello World 界面改成为这样

根据 Apple Extensions
Guide

的提议,widget最好是于小之,对于详细信息要来只可适配的莫大去显示或隐匿。
从而棕色字体的一部分会因用户之消来显示会隐藏,这部分在 stroyboard
里叫一个晶莹剔透底 view 所蕴涵,大家把它定义也 MoreDetailsContainer
,等下会为此到。
下一场再次来到 TodayViewController ……

非正常,漏了同一步,大家在继承写代码前,需要对 storyboard 或 xib 里的 UI
做适配。大家是项目不过补助 iOS 8,所以可以放心的使用 AutoLayout 跟
SizeClass。

  1. 接触开 MainInterface.storyboard ,点击
    MoreDetailsContainer,大家得它们维持一定的中度并且连接以底部的岗位,我们可如此设置:
![](https://upload-images.jianshu.io/upload_images/6775-f5bedeace434ac47.png)

点点这里



![](http://www.appcoda.com/wp-content/uploads/2014/10/container_view_constraints.png)
注意不要勾选 Contrain to margins
  1. 选择 Cupertino, CA
![](http://www.appcoda.com/wp-content/uploads/2014/10/cupertino_constraints.png)
改成这样
  1. 选择 100
![](http://www.appcoda.com/wp-content/uploads/2014/10/temperature_constraint.png)
改成这样
  1. 择小箭头按钮
![](http://www.appcoda.com/wp-content/uploads/2014/10/caret_constraints.png)
改成这样
  1. 于 Mostly Cloudy 这种不确定长度的
    label,我们得给它们自动依照仿改变长度,同时假使同 Summy 对联合。
    右键按停 Summy ,然后拖动到 Mostly Cloudy,拔取 Horizontal Spacing。
![](http://www.appcoda.com/wp-content/uploads/2014/10/modify_option_a.png)
这样配置



或者在 Mostly Coudy 的 constraint 面板中,找到 Leading Space to
SUMMARY 的 contraint ,修改为 20。



![](http://www.appcoda.com/wp-content/uploads/2014/10/modify_option_b.png)
modify\_option\_b
  1. 旁有参考第5步。

哼,运行一下。

图片 14

当下是假数据

想必您会师发现左边会暴发一样截空白空间,我们得据此脚的代码把她填满:

func widgetMarginInsetsForProposedMarginInsets
    (defaultMarginInsets: UIEdgeInsets) -> (UIEdgeInsets) {
    return UIEdgeInsetsZero
}

实际效能自己尝试看。

随后我们若实例化 UI 上边的元素:

  1. 返 TodayViewController,添加一个按钮和按钮方法:
    @IBOutlet weak var showMoreButton: UIButton!
    @IBAction func showMore(sender: UIButton) {
    }
  2. 增长一个可变的 contraint:
    @IBOutlet weak var moreDetailsContainerHeightConstraint :
    NSLayoutConstraint!
  3. 末段定义一个 BOOL 变量,标记 moreDetailsContainer 是否出示:
    var widgetExpanded = false

概念了后,开端写相关逻辑:

  1. Widget 先导化的时段是绝非数的,所以同样先导 moreDetailsContainer
    应该是隐形的状态:
    moreDetailsContainerHeightConstraint.constant = 0

  2. 以 showMore 方法里添加代码:
    @IBAction func showMore(sender: UIButton) {
    if widgetExpanded {
    moreDetailsContainerHeightConstraint.constant = 0
    showMoreButton.transform = CGAffineTransformMakeRotation(0)
    widgetExpanded = false
    } else {
    moreDetailsContainerHeightConstraint.constant = 220
    showMoreButton.transform =
    CGAffineTransformMakeRotation(CGFloat(180.0 * M_PI/180.0))
    widgetExpanded = true
    }
    }
    记在 sotryboar 里将多少箭头按钮跟代码连接起来。

  3. 终极当 ViewDidLoad 方法里充足:
    temperatureLabel.text = “–“
    summaryLabel.text = “–“
    timeLabel.text = “–“
    humidityLabel.text = “–“
    precipitationLabel.text = “–“

     loadLocation { (city) -> () in
         self.locationLabel.text = city as? String
     }
    

然widget启动的时候虽然相会活动获取信息。

运行吧!

图片 15

容这么些箭头

后续

首先不善翻译还有写教程呢(基本上就于胡说了),没悟出要是考虑的物仍旧颇多之。
即首教程最后还有跟 宿主APP 通过 UserDefault
来开展数量交互的一些,可是她都是故写深的多寡,这里虽无布置了,看看后续能无克充分又实用的办法来做。

分外感谢能看出最终。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 亚洲必赢app官方下载 版权所有