机器学习-CoreML入门 结合ARKit


ARKit:

iOS11引入的全新的框架,允许开发者轻松地为 iPhone 和 iPad 创建无与伦比的增强现实体验。通过将虚拟对象和虚拟信息同用户周围的环境相互融合,ARKit 使得应 用跳出屏幕的限制,让它们能够以全新的方式与现实世界进行交互。

  • 所谓的增强现实 (Augmented Reality, AR),指的是向设备摄像头产生的实时动态视图中,添加 2D 或者 3D 元素,然后用某种方法让这些元素看起来就处于现实世界当中,所产生的一种用户体验。ARKit 提供设备动作追踪、相机场景捕获和高级场景处理,并让AR元素的展示变得极为便利,从而大大简化了建立 AR用户体验的工作难度。

  • ARSession类:
    这是一个单例, 是ARKit的核心类,用于控制设备摄像头,处理传感器数据,对捕获的图像进行分析等

  • ARSessionConfiguration类:
    跟踪设备 向的 个基本配置, 在运行时,需要指定AR运行的配置

  • ARWorldTrackingSessionConfiguration类:
    配置跟踪设备的方向和位置,以及检测设备摄像头所看到的现实世界的表面

  • ARSCNView类:
    用来增强相机通过 3D SceneKit 所捕捉到的内容并展示 AR 效果的一个 view

  • ARSKView类:
    用来增强相机通过 2D SpriteKit 所捕捉到的内容并展示AR 效果的一个 view

  • ARAnchor类:
    真实世界的位置和方向,用于在一个AR场景中放置一个物体

  • ARPlaneAnchor类:
    在一个AR Session会话中检测一个真实世界中平面的位置和方向的相关信息

  • ARHitTestResult类:
    在一个AR Session会话中通过检测相机视图中的一个点来获取真实世界中表面的相关信息

  • ARFrame类:
    捕获一个视频图像和位置追踪信息作为一个AR会话的一部分

  • ARCamera类:
    在一个AR会话中摄像机的位置和成像特征信息为捕获视频帧

  • ARLightEstimate类
    在一个AR会话中估计场景照明信息关联到一个捕获的视频帧

coreML

iOS11引入的一个全新的机器学习框架,同时伴随着Vision框架。Core ML 是特定框架功能的基础,支持用于用户图像分析的 Vision,用于自然语言处理的 Foundation (如 NSLinguisticTagger 类)和用于评估已经学习到的决策树 GamePlayKit。Core ML 本身构建于低层面的原语上,比如 Accelerate、BNNS、Metal Performance Shaders。coreML让我们更容易在App中使用训练过的模型, 而Vision让我们轻松访问苹果的模型,用于面部检测、面部特征点、文字、矩形、条形码和物体等。Vision模型中可以包装任意的图像分析coreML模型。Vision框架其实就是对coreML框架的一层封装,使用起来更加方便。根据官方文档提供的图像可以看出,这两个框架的作用,就是将一个ML模型,转换成我们的app工程可以直接使用的对象。

  • 机器学习(ML:Machine Learning):
    是一种人工智能,计算机会“学习”而不是被明确编程。不用编写算法,机器学习工具通过在大量数据中寻找模式,使计算机能够开发和优化算法。机器学习(ML)是人工智能(AI)的一个分支,深度学习(DL)又是更小分一个分支,大概关系如图所示

Demo:

  1. 建立一个工程,选择Augmented Reality App, 会帮我们创建一个ARSCNView视图

2.到官网下载一个模型 模型下载, 每个模型的作用都有对应的解释,能识别的图像种类也不尽相同,根据不同需求下载不同模型

3.将模型拖入工程中,可能需要加载一会才会显示,如下图所示。选中模型,会出现模型相关信息,大小、功能、类型等。Model Class下会有一个箭头,点击进入会看到模型的源码。Model Evaluation Parameter下会有模型的输入(input)输出(outPuts)信息。输入的需要时大小为224*224的图片,而返回的结果一个是classLabelProbs,即信任度或百分比,而classLabel即得到的结果。不同模型的输输出并不相同。注意右下角的Target Members在Xcode9中默认不会勾选,需要手动选中。

4.创建模型并声明相关变量

1
2
3
4
5
var resentModel = Resnet50()

var hitTestResult: ARHitTestResult!

var visionRequests = [VNRequest]()

5.给当前场景添加一个手势

1
2
3
4
func registerGestureRecognizers() {
let tapGesture = UITapGestureRecognizer(target:self, action:#selector(tapped))
sceneView.addGestureRecognizer(tapGesture)
}

6.点击场景

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@objc func tapped(tapGesture:UITapGestureRecognizer) {
let sceneView = tapGesture.view as! ARSCNView
let touchLocation = tapGesture.location(in: self.sceneView)
guard let currentFrame = sceneView.session.currentFrame else {
fatalError("no pixel")
}

let hitTestResults = sceneView.hitTest(touchLocation, types: .featurePoint)
if hitTestResults.isEmpty { return }
guard let hitTestResult = hitTestResults.first else {
fatalError("not first object")
}

self.hitTestResult = hitTestResult;
// image->pixel
let pixelBuffer = currentFrame.capturedImage;

// Vision
performVisonRequest(pixelBuffer: pixelBuffer)
}

7.通过Vision处理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
func performVisonRequest(pixelBuffer:CVPixelBuffer) {
let visionModel = try! VNCoreMLModel(for:self.resentModel.model)
let request:VNCoreMLRequest = VNCoreMLRequest(model:visionModel) { request,error in
if error != nil { return }
guard let observations = request.results else {
fatalError("no result")
}

let observation = observations.first as! VNClassificationObservation
print("name is \(observation.identifier) \n confidence is \(observation.confidence)")

DispatchQueue.main.async {
self.displayPredictions(text: observation.identifier)
}
}
request.imageCropAndScaleOption = .centerCrop;
visionRequests = [request]
let imageRequestHandler:VNImageRequestHandler = VNImageRequestHandler(cvPixelBuffer:pixelBuffer,orientation:.upMirrored,options:[:])

DispatchQueue.global().async {
try? imageRequestHandler.perform(self.visionRequests)
}
}

8.展示预测结果

func displayPredictions(text:String) {
let parentNode = SCNNode()

    // 1cm
    let sphere = SCNSphere(radius:0.01)
    let sphereMaterial = SCNMaterial()
    sphereMaterial.diffuse.contents = UIColor.orange
    sphere.firstMaterial = sphereMaterial

    let sphereNode = SCNNode(geometry:sphere)
    parentNode.addChildNode(sphereNode)

    // text
    let textGeo = SCNText(string:text,extrusionDepth:0)
    textGeo.alignmentMode = kCAAlignmentCenter
    textGeo.firstMaterial?.diffuse.contents = UIColor.orange
    textGeo.firstMaterial?.specular.contents = UIColor.white
    textGeo.firstMaterial?.isDoubleSided = true
    textGeo.font = UIFont(name:"Futura",size:0.20)

    let textNode = SCNNode(geometry:textGeo)
    textNode.position = SCNVector3(x:self.hitTestResult.worldTransform.columns.3.x,
                                   y:self.hitTestResult.worldTransform.columns.3.y,
                                   z:self.hitTestResult.worldTransform.columns.3.z)
    textNode.scale = SCNVector3Make(0.2,0.2,0.2)
    parentNode.addChildNode(textNode)

    parentNode.position = SCNVector3(x:self.hitTestResult.worldTransform.columns.3.x,
                                     y:self.hitTestResult.worldTransform.columns.3.y,
                                     z:self.hitTestResult.worldTransform.columns.3.z)
    // show AR resutl
    self.sceneView.scene.rootNode.addChildNode(parentNode)
}

9.结果展示

运行项目,将真机对准物体,距离适中。注意苹果AR仅支持搭载A9/A10及更先进处理器的iOS 11设备,接下来新出的苹果设备,也同样会支持苹果AR功能。目前支持机型如下:

  • iPhone6s和6S Plus
  • iPhone7和7 Plu
  • iPhone SE
  • iPad Pro (9.7, 10.5和12.9)
  • iPad (2017

最终展示效果如下,结果其实可能并不准确,但是提供了一个可能性。展示结果也可以呈现多样性,比如显示百分比,显示可信度排名前几的分析对象等


Demo下载

如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

机器学习-将第三方模型转换成Core ML或自己训练模型环境配置


机器学习中使用到的模型,除了使用苹果官方提供到的一些模型以外,还可以将第三方训练好的模型转成coreML model,甚至可以自己训练模型。苹果官方给出了一些支持第三方模型的工具和版本

配置环境

1.安装Anaconda

选择2.7版本,然后一路安装,Anconda是一个python的IDE,安装成功后打开终端更新Python版本,现在Mac内置的Python版本是2.7,而苹果要求的版本至少是是2.7.13

1
conda install python=2.7.13

安装成功后查看Python版本

2.安装pip

pip是Python种安装和管理包的工具,是easy_install的替代品

1
easy_install pip

3.安装coremlTools

1
pip install -U coremltools

判断是否安装成功,可通过导入模块是否成功来判断

4.安装keras、tensorflow、scikit-learn

1
2
3
pip install keras==1.2.2
pip install tensorflow
pip install -U scikit-learn

判断是否安装成功依然可用上述方法

或者,打开Anconda, 选择3.1.4版本的Spyder

运行,如果没报错说明引入成功

5.安装caffe依赖包

1
2
3
4
5
6
7
8
9
brew install -vd snappy leveldb giflags glog szip lmdb

for x in snappy leveldb gflags glog szip hdf5 lmdb homebrew/science/opencv; do brew uninstall $x; brew install --fresh -vd $x
done
brew uninstall --force protobuf; brew install --with-python --fresh -vd protobuf brew uninstall boost boost-python; brew install --fresh -vd boost boost-python

brew tap homebrew/science

brew install hdf5 opencv

6.修改opencv

1
brew edit opencv

找到下图标注的两行

替换成:

1
DPYTHON_LIBRARY=#{py_prefi x}/lib/libpython2.7.dylib
DPYTHON_INCLUDE_DIR=#{py _prefix}/include/python2.7

替换后的效果是:

7.加入依赖包

1
brew install --build-from-source --with-python -vd protobuf
brew install --build-from-source -vd boost boost-python

8.检查是否有缺失

1
2
brew doctor
brew missing

上述安装过程中可能并非一帆风顺,如有错误应按照提示修改。苹果对版本要求较为严格,安装时注意版本控制。


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

机器学习-CoreML基于图像处理


Vision是建立在Core ML上层的Framework。Vision专门用来处理视觉。Vison可以进行多种应用场景的机器学习处理,使用场景:

  • 人脸检测:支持检测笑脸、侧脸、局部遮挡脸部、戴眼镜和帽子等场景,可以标记出人脸的矩形区域
  • 人脸特征点:可以标记出人脸和眼睛、眉毛、鼻子、嘴、牙齿的轮廓,以及人脸的中轴线
  • 图像配准
  • 矩形检测
  • 二维码/条形码检测
  • 文字检测
  • 目标跟踪

Vision是将各种功能的Request提供给一个 RequestHandler,Handler持有图片信息,并将处理结果分发给每个Request的completion Block中。可以从 results 属性中得到 Observation 数组,然后进行更新 UI 等操作。Vision中包含的重要类:

  • VNImageRequestHandler: 处理单张图片的分析请求的类
  • VNSequenceRequestHandler: 处理连续图片的分析请求的类
  • VNDetectFaceRectanglesRequest: 图片中人脸的分析请求类
  • VNDetectFaceLandmarksRequest: 图片中人脸特征(眼睛、嘴)的分析请求类
  • VNFaceObservation: 通过图片分析请求得到的人脸信息
  • VNDetectBarcodesRequest: 查找图片中二维码的请求
  • VNBarcodeObservation: 图片请求获取的二维码的信息
  • VNCoreMLRequest: 使用 Core ML 处理图片生成的请求类
  • VNClassificationObservation: 图片分析请求获取的场景分类信息
  • VNPixelBufferObservation:Core ML图片分析请求输出的图片信息
  • VNCoreMLFeatureValueObservation: Core ML 图片分析请求获取的一系列 key-value 信息

Vision支持的图片类型包括:

  • CVPixelBufferRef
  • CGImageRef
  • CIImage
  • NSURL
  • NSData

关联关系如下:

到官网先下载一个模型,比如GoogLeNetPlaces(链接),一个识别场景的模型,创建一个Single View App工程,拖入下载好的模型 ,搭建基本的UI页面

使用两种方式分析图片场景,coreML和Vision。

Vision处理图片

1
2
3
4
5
6
func coreMLprocessImage(image:UIImage) {
let hander = VNImageRequestHandler(cgImage:image.cgImage!)
let model = try! VNCoreMLModel(for:modelFile.model)
let request = VNCoreMLRequest(model:model,completionHandler:completionHandler)
try? hander.perform([request])
}

处理结果

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
func completionHandler(request:VNRequest,error:Error?) {
guard let results = request.results as? [VNClassificationObservation] else {
fatalError("no result")
}

// result
var bestPredication = ""
var bestConfidence:VNConfidence = 0

for classIdentifier in results {
if classIdentifier.confidence > bestConfidence {
bestPredication = classIdentifier.identifier
bestConfidence = classIdentifier.confidence
}
}
DispatchQueue.main.async {
self.resultLabel.text = "Predication:\(bestPredication) Confidence:\(lroundf(bestConfidence * 100))%"
}
}

coreML处理图片

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func coreMLAndVisionProcessImage(image:UIImage) {
let imageWidth:CGFloat = 224.0
let imageHeight:CGFloat = 224.0
UIGraphicsBeginImageContext(CGSize(width:imageWidth, height:imageHeight))
image.draw(in:CGRect(x:0, y:0, width:imageHeight, height:imageHeight))
let resizedImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
guard resizedImage != nil else {
fatalError("resized Image fail")
}

// image->CVPixelBuffer
guard let pixelBuffer = imageCovertToPixelBuffer(from: resizedImage!) else {
fatalError("UIImage->CVPixelBuffer failed")
}

guard let outPut = try? modelFile.prediction(sceneImage: pixelBuffer) else {
fatalError("failed")
}

DispatchQueue.main.async {
self.resultLabel.text = "Predication:\(outPut.sceneLabel) Confidence:\(lroundf(Float(outPut.sceneLabelProbs[outPut.sceneLabel]! * 100)))%"
}
}

将UIImage转成CVPixelBuffer

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
func imageCovertToPixelBuffer(from image: UIImage) -> CVPixelBuffer? {
let attrs = [kCVPixelBufferCGImageCompatibilityKey: kCFBooleanTrue, kCVPixelBufferCGBitmapContextCompatibilityKey: kCFBooleanTrue] as CFDictionary
var pixelBuffer : CVPixelBuffer?
let status = CVPixelBufferCreate(kCFAllocatorDefault, Int(image.size.width), Int(image.size.height), kCVPixelFormatType_32ARGB, attrs, &pixelBuffer)
guard (status == kCVReturnSuccess) else {
return nil
}

CVPixelBufferLockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))
let pixelData = CVPixelBufferGetBaseAddress(pixelBuffer!)

let rgbColorSpace = CGColorSpaceCreateDeviceRGB()
let context = CGContext(data: pixelData, width: Int(image.size.width), height: Int(image.size.height), bitsPerComponent: 8, bytesPerRow: CVPixelBufferGetBytesPerRow(pixelBuffer!), space: rgbColorSpace, bitmapInfo: CGImageAlphaInfo.noneSkipFirst.rawValue)

context?.translateBy(x: 0, y: image.size.height)
context?.scaleBy(x: 1.0, y: -1.0)

UIGraphicsPushContext(context!)
image.draw(in: CGRect(x: 0, y: 0, width: image.size.width, height: image.size.height))
UIGraphicsPopContext()
CVPixelBufferUnlockBaseAddress(pixelBuffer!, CVPixelBufferLockFlags(rawValue: 0))

return pixelBuffer
}

结果演示

上图可以看到,同样的场景图片,coreML和Vision预测的结果并不一样,同一场景或图片,coreML预测的结果可信度更高,Vision可能在封装coreML时做了一些其他操作,具体不得而知。但是使用coreML处理过程较Vision更为繁琐,首先需要将图片裁剪成模型需要的指定大小,而后需要将图片格式转化为模型需要的CVPixelBuffer类型。选择哪种模式需根据具体需求而定。

Demo下载


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

机器学习-将第三方模型转换成Core ML或自己训练模型


苹果官方提供的model功能有限,我们可以自己训练模型或者将第三方模型转化成苹果可以识别的模型。

将第三方模型转化成苹果可以识别的模型

这里以苹果给出的参考为例,也可以下载Caffee model

其中.txt文件是所有预测结果,.prototxt是模型结构文件。

打开Anaconda的spyder, 使用coremltools转换

1
2
3
4
5
6
7
8
9
coreml_model = coremltools.converters.caffe.convert(('./caffee model/bvlc_alexnet.caffemodel', 
'./caffee model/deploy.prototxt'),
predicted_feature_name='./caffee model/class_labels.txt')

coreml_model.author = "Fish News"
coreml_model.license = "BSD"
coreml_model.short_description = "this is a test description"

coreml_model.save('BVLCObjectClassifier.mlmodel')

上图的model的author、short_description、输入输出等属性可自行设置。

转换成功后会得到一个mlmodel文件,拖入工程后即可使用

自己训练模型

我们使用sklearn库内置的iris数据,或者使用自己提供的csv格式的数据进行训练

1
2
3
4
5
6
7
8
9
10
11
from sklearn import datasets
from sklearn.linear_model import LogisticRegression
import coremltools

iris = datasets.load_iris()
model = LogisticRegression()
model.fit(iris.data,iris.target)
print iris.target_names[model.predict([ [1.0 ,2.0, 2.0, 3.0] ])]
print iris.data.shape
coreml_model = coremltools.converters.sklearn.convert(model,iris.feature_names, 'iris class')
coreml_model.save('iris.mlmodel')

训练好后会生成iris.mlmodel模型,拖入工程进行测试

测试已训练好的模型

  • 搭建UI,iris.mlmodel需要四个参数,分别是speal length,speal width,petal length,petal width

  • 结果展示

Demo下载


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

十月

选择在周日下午午睡实在不是明智的选择,记不清多少次一觉醒来都临近晚上了。仿佛穿越时空,片刻间不知道自己在哪、什么时间,拉上的窗帘依然能透过夕阳的影子,恍惚间会觉得有点低落。往常可能会在这个时候给久未联系的朋友打个电话,也不知道何时这个习惯莫名终止了。

忙碌的生活可能并不容易,但是颓废的生活果然是这么轻松惬意,身为并不愿意承认重度拖延症患者的我,想做点什么并不容易,这种感觉很糟糕。今年几个熟悉的人从公司离职,感觉是更糟糕。想想也是有趣,大概每天至少会有三分之一的时间是在职场度过,然而一旦离职这种体系基本会随之崩塌,仿佛从未认识过一样,然后变成社交软件上的一个ID,然后变成不远的将来后偶尔想起的曾经。越来越不喜欢建立这种随时会被打破的社交关系,费时费力,仅点头之交的关系,不要也罢。

四年前的这个时候初到上海,离开了我非常喜欢的泉州厦门,四年过去了,不仔细回想,都不知道这几年是怎么过的。以前希望一天变成12小时,而现在却希望一天是48小时。变得和以前难以置信的不一样,我经常会怀念过去无形装逼放浪不羁的我。朋友圈慢慢屏蔽了几十个人,今天突然之间想全部都解除屏蔽了,想想也挺有趣,没有这些人的每天鸡汤、软文、自拍,那朋友圈还有什么意思,如果生活不用来装逼,那还有什么意义?

都是需要诗和远方的人,当然可能需要的还有money。从沉迷于空虚之中,彷徨于温饱之际,到房产两三套,资产过千万的城市小资产阶级,他们理解这个世界在发生什么,然而却并不关心身边的人,他们自私而苦闷,幸福而纠结,安然而焦虑,在单位有一官半职,在社会上有一定地位,这是被时间和岁月吞噬的一类人,尚未发光却即将熄灭,尚未年轻却迅速老去,而我们,却都在希望变成这一类人!

很难不忧伤,尽管忧伤,是生活的一部分!


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

Xcode免证书免数据线调试

一. 免证书

Xcode7之后,开发者调试终于可以不需要证书了,之前越狱后免除证书不算在内

  • 步骤如上图所示
  • 注意,Bundle Inentifier最好使用之前没用过的,否则可能不成功
  • 上图步骤之后,钥匙串中已经自动生成了一个供本机使用的调试证书
  • 如果App ID已经是开发者账号或者属于某个已付费的账号组里,会给该账号自动生成一个证书,可登陆苹果开发者中心查看。勾选Automatically manage signing后会自动生成Provisioning Prifile描述文件,当然可能会生成失败,会提示更换Bundle Identifier。如果该账号不是开发者账号,则仅会在本机生成一个可供调试的证书
  • 如果有多个工程需要调试,调试时可修改Bundle Identifier为同一个值,否则可能会对频繁更改Bundle Identifier的App Id进行限制。
  • 运行后依然会报错,会提示需要打开手机设置->通用->描述文件与设备管理中添加信任
二.免数据线

Xcode9之后,终于可以免数据线调试了。这里说的免数据线并非完全脱离数据线,而是第一次使用数据线启动之后才可以脱离使用

  • 步骤如上图所示,注意勾选Connect via network,即通过网络连接
  • 注意,手机系统要求iOS11及以上
  • 第一次启动需要连接数据线,并且手机和电脑需处于同一无线网环境下。第一次启动后,拔出数据线,这时候会发现设备依然连接着,选中运行即可
  • 可以同时支持多台设备

以上,即可实现免证书免数据线,平时方便自己调试,还随时可以给测试人员安装开发包临时测试


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

六月

又到六一了,去年的这个时候和老大请了半天假,陪伴另一个儿童。今年那个儿童又长大了一岁,应该也不需要我再请假陪伴了。端午这三天假才刚准备进入状态就火速结束了(此处没有事后烟),可怜那个儿童连着三天都上班,我也不能挥霍的太过分,简直了。

七年过去了,七年是什么概念,可能当时你身体都可以进入的人现在连朋友圈都进不了了。还有一周又要高考了,我记得那会最后一门英语考的时候外面乌黑一片,山雨欲来风满楼,仿佛是为了我考试灾难性的结果买下伏笔,根本无心静下来思考,虽然不知道填的啥但就觉得填的是对的,这想法也是没谁了,这也是整个高考期间的缩影。我记得第一天考试正是NBA总决赛湖人VS绿军的第七场,晚上我竟然丧心病狂的去网吧看了下比赛回放,这把我激动的,晚上觉都没睡好。事后想了下,这可能也是为了衬托我考试灾难性的后果,毕竟以乐景写哀更见其哀。这一年又一年过去了,每年都会想起,无法释怀,又怎么去释怀。多说有泪,不能再说了~

现在又逢NBA总决赛及欧冠决赛了,借此预测一波,勇士4:1骑士 or 4:2夺冠,皇马1:0尤文 or 2:1夺冠,坐等被证实。现在我还记得13年那个夏天我预测好声音汪峰组张恒远夺冠,结果很明显。

都说爱笑的女生运气不会太差,而JJ长的男生,亦是如此,然而运气不错,但也架不住明目张胆的折腾。这几天中金某领导潜规则实习生,据说此人年薪千万,然而掩盖不了low穿地心的本质。今年互联网平均年薪据调查首次超过金融业位居榜首,为十二万多,值得恭喜一波,讲真,我也不知道有啥值得恭喜的。《欢乐颂》最近这么火,里面的应勤又给广大IT男招黑了,其实不觉得有什么问题考虑到应勤自身的状况。一开始我还以为给IT男洗白了呢,谁知道闹了这么一出,平心而论,应勤配得上邱莹莹,但是否配得上邱莹莹的爱,仁者见仁了。好在最后两人又和好了,感情中这事没道理可讲,还是应了那句话,你说要敬往事一杯酒,再爱也不回头,然而就算你醉到黄昏独自愁,如果那人伸出手,你还是会跟他走!

金三银四铜五过去了,铁六锡七铝八就要来了。这一晃17年快过一半了,这一天天过得,纸醉金迷,酒肉池林。想做点什么,应该做点什么。于我而言,六月份是个比较独特的月份。要是有的选,我愿意牺牲点什么,换回之前几年的六月份,重新来过的机会。事实是,没有机会!

不打扰,我似乎很难做到,然而我似乎又做到了。是否有人知道我在说什么,谁知道呢,会有人的!


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

2016

16年永久性的成为了过往!

一如既往,朋友圈充满了各种过去一年的总结汇报以及来年的心愿展望,什么新的一年要成功脱单、加薪升职、胸再大点腰再细点、JJ再长点个子再高点之类的,像我这种只阅不发的人简直是一股清流。也不知道是男票女票不好玩还是不好用,竟然还有力气还有时间发动态,真是难得。微信各种群都是些骚乱的人们,当然可能并不乱。红包发个不停,抢了半天不够再发一个出去的,真是蛋疼,现在基本都不抢了。但是有个群例外,爱得威技术部,是我喜欢的氛围,要么不发,要发就数额不菲,都自觉的轮着来。想想离职快两年了也没退群,基本是装死的状态,一直也心系爱得威。那是我职业生涯的第一站,对我之后的各种装逼也产生了深远影响。现在想来,当时老大给的各种排期都比较宽松充裕,而年轻人总是急于冒进,每次都强行装逼觉得分分钟可以搞定,几次意外发生后也就吸取教训了。后来又来个新人,又在走我之前的老路,总是眼高于顶,你说给一天时间他说一小时足矣,结果很明显,脸打得啪啪响。时至今日,我的做事风格也归咎于此,需要一天的时间我可能会要两天,无他,只因可能会面临各种意外,而且提前搞定了还皆大欢喜。当时学到的各种基础对我后来也都起了极大的帮助,现在我所掌握的几门语言也都是在那段时间学习的,虽然有的现在已经仅剩点概念了。那会还学了半年日语,以至于每次看岛国爱情动作片的时候我都会下意识的去拼写日语单词,并尝试去纠正语法和发音,也学到了些许,是的。那也是我至今为止最为上进的一段时间吧,早上坐地铁全是背日语单词和课文,而现在我早上坐地铁关注的全tm是谁又偷我能量了,谁的能量又可以偷了,我罗是否又进球了,我科是不是又有什么记录被破了,偶尔心情好的话还会关注下周围妹子的罩杯大小,定期锻炼下眼力,真是堕落!

这几天又被余太逼着做饭了,我内心是拒绝的。这种属于细水长流的活岂是一朝一夕之事,想我16年全年厨艺都进步寥寥,也不知何时能大成!在上海的这几年,是真切的感受到了上海女人在家里的话语权实在太大,严重带坏了那些来上海工作的妹子们。开始来上海时都是妹子,后来都成了汉子,这些人最大的毛病就是妄图改造自己的另一半,自己却拒绝被改造。感情中最难能可贵的是什么,从来不是那些,彼此送的手表和项链,甚至也不是那些甜蜜的短信和合照,甚至都不是毫无保留的付出,而是彼此留在对方身上的,如同河流留给山川的,那些你对我,造成的改变。付出并不难,改变才是!也不知道何时才能顿悟,依然任重道远啊。

16年年初定的几个目标基本都完成了一半,希望自己稳重些,的确是重了不少;希望一年存款30万,结果果然存了有3万大概;希望在技术上有更多积累,所以微信上收藏了少说也有几百篇从未打开过的技术文章。一切都进展的难以置信的顺利,也不知道17年是个什么鸟样!

但是生活,最重要的是开心!


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

毕业前夕,我曾发出宏愿,走遍心中向往的风景,沿途拜访每一位江湖旧友,参加每一场好朋友的婚礼。可是去过很多地方,大多匆匆而过,旧友也早已消弭与江湖,没有参加的婚礼,也远比参加的要多。

我十分肯定想去的,却竟然始终也没有去。这几年变化的也不仅仅是心态,逐渐增多的赘肉和日益稀少的头发也都在见证着这一切。几年前一天动辄可以给予几次高潮的身体也一去不复返了,挺怀念的。毕竟一被子和谐才能一辈子和谐,这是刚需,做人不能太颓废,偶尔锻炼还是要有的。

这几天和余太从上海回来,走了下婚前流程。有些形式总是要走一遍的,毕竟人总是需要一种仪式感的。以前这些繁杂的流程,现在的年轻人基本都不甚了解,讲真,有点羞愧。谁知道会不会若干年后传到国外申请个文化遗产啥的,到时候再各种撕逼谁说的清呢。这些年在外上学家里这些娃都迫不及待的冒出来不少,这样一代代繁衍生息挺奇妙的,尽管很多时候初衷只是享受制造过程。想抱抱他们,到叔叔这里来,然而基本只给我留了一个背影。以前看中的妹子也不知道现在嫁到哪去了,曾经和我在学校并肩作战走南闯北的发小还是没有音信,如果你能看到,给家里报个平安吧。那些我熟悉的岁月印记越来越少了,然而一切依然进行着,他们也依然幸福的生活着。这么多年的学习后,似乎学到了很多,然而失去的也许更多,让我仿佛变成了一无所知的傻×,挺好的。

永乐的通知,一切都如预料般的猝不及防。我早没有那么放荡不羁了,然而你一如既往的不着调。上次来沪连做个啥保健的时间都没有,挺遗憾的。不过好在你的所在地也随时都可以。不过我还是劝你从良吧,尽管我知道的你一直都是优。昔日顶风尿三丈,如今顺风尿湿鞋,现在的年轻人还是要多注意,少年不知精子贵都是有历史教训的,下联我就不说了。讲真,坚持几年的感情实在不易,现在的女性都打着磨合的幌子渐渐的把男人磨平了,尤其是知识女性,女权思想太盛。看来书读得多也未必是好事。个人酸楚也就自己体验的最为真切了。婚姻怎么选都是错的,长久婚姻就是将错就错,修成正果这种事对男人来说尤其不易,毕竟会被要求太多,自行体会下。哥听到消息高兴的把旁边的雪花一饮而尽,算是隔空祝福了。

上段时间宝强的事霸屏很多天,讲真,看你们没事骂来骂去的挺没意思的。对一些没啥底线的人能动手就别吵吵。现在每天都在发生那么多的事,几乎每个事件下面的评论都是键盘侠的粗言秽语,妄图去骂醒别人的认知。一个成年人的认知基本无法改变,这种争论毫无意义,言论背后是多年生活方方面面的折射,岂会因为你一段话而改变。郎平在里约女排夺冠前一直被骂为叛徒,夺冠后各大媒体又各种跪舔将其捧上神坛。脸打的啪啪响,人至贱真是无敌。义愤填膺的是网民,冷漠无情的是路人,到底是网民不上街还是路人不上网,这种畸形网络文化也不知何时能终结,仿佛看不到曙光。

假期要结束了,这和余太还没来得及思念就又相见了,爽的飞起,这仿佛像是在尿裤子,很多人都能看到,但是只有自己才能体会到那种温暖。希望接下来的一段日子里我可以沉迷于工作无法自拔,其实内心是拒绝的。这段时间加的班比之前几年加的都多,仿佛看不到诗和远方,并且受到了从业以来仅有的能力质疑,酸爽!这种事情觉得只要说点啥基本都是在给自己找借口,还是默默承受比较好,毕竟也没人在意发生了啥。之前带的项目现在想来有些也是不应该,是否唯结果论并不重要,一切都要看人,没错,是看人。最重要的是,如果位置互换,未必会做的更好。但是这些谁会去在乎呢。工作是为了更好的生活,不应该本末倒置。我依然坚信,不能直接了当的判断一个人,信息量太大!

挺想到阳台上抽根烟的,考虑到安安宝贝还小,还是算了,我这一年抽一包的速度着实慢了点,谁让咱是三好青年呢。这中秋过的,以前小时候,嫦娥的故事根本听不下去,心里想着月饼,那个馋啊。而现在,月饼根本吃不下去,心里想着嫦娥,那个馋啊。成年人的世界也就剩想想了,放在心里,也许就成为了梦想!

讲真,感觉很是蛋疼!


如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

控雨片段



如有任何疑问或问题请联系我:fishnewsdream@gmail.com,欢迎交流,共同提高!

Objective-C/Swift技术开发交流群201556264,讨论何种技术并不受限,欢迎各位大牛百家争鸣!

微信公众号OldDriverWeekly,欢迎关注并提出宝贵意见

老司机iOS周报,欢迎关注或订阅

刚刚在线工作室,欢迎关注或提出建设性意见!

刚刚在线论坛, 欢迎踊跃提问或解答!

如有转载,请注明出处,谢谢!

本站总访问量 本文总阅读量