JPush APNs Auth Key Token 验证模式 Token Authentication 配置

新的APNs协议基于HTTP/2,一种是使用Universal Push Notification Client SSL 证书,一种是使用Token。

基于HTTP/2与Token的 APNs 协议

2199840-c3887f0a51fbd5e6.png

APNs Provider(即,APP的后台) API 允许您向您的 iOS,macOS 设备上的应用程序和 Apple Watch 发送远程通知。API 基于 HTTP/2 网络协议。每个交互通过一个 POST 请求,包含 JSON 的有效Payload负载,通过服务器使用Auth Key生成服务端token连接APNs服务器,并且通过设备token发送负载。APNs然后转发给特定设备的指定应用程序。
Request 和 Response 使用JSON通信APNs支持状态码和返回 error 信息APNs推送成功时 Response 将返回状态码200APNs推送失败时,Response 将返回 JSON 格式的 Error 信息。最大推送长度提升到4096字节(4Kb)可以通过 “HTTP/2 PING ” 心跳包功能检测当前 APNs 连接是否可用,并能维持当前长连接。支持为不同的APP定义 “topic”(其实就是App Bundle ID)多个推送App,只需要一个Apple Push APNs Auth Key

Apple Push Notification Authentication Key

2016年9月,苹果悄悄上线了token验证的推送方式,通过获得一个认证密钥(APNs Auth Key)去生成服务器端token,并且token非常容易生成,可以使用这些token令牌代替推送证书。一个认证密钥可用于多个应用程序并且永远不过期。每一个需要推送的App都需要配置推送证书的时代过去了。but,大部分第三方推送服务商,目前都没有升级到APNs Auth Key Token模式。

APNs Auth Key.JPEG
  • 通过 APNs Auth Key 鉴权
    开发者网站证书页面:开发者网站
1.点击左侧列表 “Keys” 中的 “All”,看账户中是否已有 auth key,没有则点击 “+” 新建。
authkey_1_addAuthKey.png
2.填写该 key 的描述并选择服务,如下图。 (注:在开发和生产环境均可使用,且不会过期。)
authkey_2_createAuthKey.png
3.点击 “Continue” 让你确认信息,再点击 “confirm”,就可以下载该 key了。(.p8 密钥文件)

(注意:记下 key id(.p8 密钥文件),而且只可以下载一次,请妥善保存。)

authkey_3_downloadAuthKey.png
4.获取你之前创建过的应用的 Bundle ID
authkey_4_getBundleId.png
5.在开发者账户的 “Membership” 页面获取 Team ID
authkey_5_getTeamId.png
6.在推送平台控制台上,进入你应用的应用设置中 iOS 的鉴权方式选择 “Token Authentication”,上传 auth key 文件,并填写你的 KEY ID,TeamID,和指定应用的 BundleID。推送平台会在后台为你的应用进行鉴权。
authkey_6_addInfoToPortal.png

权限和使用期限

新的token验证推送,一个认证密钥可用于多个App服务,没有时效性。不用为每个App需要单独配置两个(开发环境和生产环境)证书,还要注意过没过期。

作者:husky_duang
链接:https://www.jianshu.com/p/b700f0237b0e
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

iOS APP设置启动图片LaunchImages

关于设置launchImage:
这里写图片描述

工程配置信息中设置显示launchImage:
1、删除Launch Screen File
2、在Launch Images Source中设置你在Assets.xcassets中设置的启动页

这里写图片描述

如果你发现:项目运行并没有显示设置的图片,那么试试下面这种方法
1、转到LaunchScreen.storyboard
2、取消勾选配置信息中的Use as Launch Screen选项

这里写图片描述

1.点击工程目录中的Images.xcassets,点击左侧边栏的LaunchImages
2.然后在xcode最右侧的边栏处选择你的APP是否要对ipad、横竖屏、以及低版本的iOS系统做支持。

这里写图片描述

当你再次启动程序时,如果你发现,这一切并没有什么luan用!好吧,请在模拟器中卸载/删除你的APP,然后再重新运行即可

关于 LaunchImage 图片 命名 以及其 尺寸:

iPhone Portrait iOS 11 (1125×2436) @3x
iPhone Portrait iOS 8-Retina HD 5.5 (1242×2208) @3x
iPhone Portrait iOS 8-Retina HD 4.7 (750×1334) @2x
iPhone Portrait iOS 7,8-2x (640×960) @2x
iPhone Portrait iOS 7,8-Retina 4 (640×1136) @2x
iPhone Portrait iOS 5,6-1x (320×480) @1x
iPhone Portrait iOS 5,6-2x (640×960) @2x
iPhone Portrait iOS 5,6-Retina4 (640×1136) @2x

iPad Portrait iPad2 and iPad mini (768×1024) @1x
iPad and iPad mini (1536×2048) @2x
iPad Pro (2048×2732) @2x

IOS打包app到appstore,一直在Authenticating with the iTunes Store…状态的解决办法

不过很常见的错误,非常容易就解决了,但是很常见很常见,解决办法可以:

1、在网络环境好的时候多尝试几次,也许行,也许不行;

2、打开终端,输入

cd ~

mv .itmstransporter/ .old_itmstransporter/

“/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/itms/bin/iTMSTransporter”

swift语言coredata第三方库MagicalRecord最简洁教程

cocoapods
MagicalRecord

pod ‘MagicalRecord’安装MagicalRecord

/*************************以下为教程****************************/

AppDelegate.swift
import MagicalRecord

func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
        MagicalRecord.setupCoreDataStack()//只加这句话初始化
        return true
    }

ViewController.swift
import MagicalRecord

override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        /*创建*/
        let admin = Admin.MR_createEntity()//创建
        admin?.token = "1234"//编辑
        print("创建")
        NSManagedObjectContext.MR_defaultContext().MR_saveToPersistentStoreAndWait()//保存
        /*创建结束*/
        /*查询*/
        let admins = Admin.MR_findAll()//查询
        for a in admins as! [Admin]{
            print(a.token)
            a.token = "liuman"//编辑
            //a.MR_deleteEntity()//删除
        }
        print("条件查询token值为liuman的")
        let liuman = Admin.MR_findFirstByAttribute("token", withValue: "liuman")
        print(liuman!.token)
        /*查询结束*/
        //Admin.MR_truncateAll()//删除所有
        NSManagedObjectContext.MR_defaultContext().MR_saveToPersistentStoreAndWait()//创建编辑删除之后都要保存,原save方法,被取代了。
        //MagicalRecord.cleanUp()//app退出前操作,关闭coredata
    }

coredata:CRED

import CoreData

//添加数据
    func saveCoreDate(){
        //加载AppDelegate
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        //获取管理的上下文
        let context = app.managedObjectContext
        var error:NSError?
        //创建一个实例并给属性赋值
        let admin = NSEntityDescription.insertNewObjectForEntityForName("Admin", inManagedObjectContext: context) as! Admin
        admin.token = "1"
        //保存数据
        do {
            try context.save()
            print("success!")
        }catch let error{
            print("context can't save!, Error:\(error)")
        }
    }
    func fetchCoreData (){
        //加载AppDelegate
        let app = UIApplication.sharedApplication().delegate as! AppDelegate
        //获取管理的上下文
        let context = app.managedObjectContext
        // 声明数据请求实体
        let fetchRequest = NSFetchRequest(entityName: "Admin")
        let predicate = NSPredicate(format:"token='1'")
        //fetchRequest.predicate=predicate//设置查询条件按照id查找不设置查询条件,则默认全部查找
        //执行查询操作
        do {
            let list =
                try context.executeFetchRequest(fetchRequest) as! [NSManagedObject]
            print("打印查询结果")
            for i in list as! [Admin] {
                print(i)
                //修改操作:将查询到的结果修改后,再调用context.save()保存即可
                i.token = "1"
                //删除操作:将查询到的额结果删除后,再调用context.save()保存即可
                context.deleteObject(i)
            }
        }catch let error{
            print("context can't fetch!, Error:\(error)")
        }
        do {
            try context.save()
            print("success!")
        }catch let error{
            print("context can't save!, Error:\(error)")
        }
        
    }

ios笔记

iOS9 隐藏状态栏方法

1.在Info.plist中增加 Status bar is initially hidden一行,选择为 YES,

2.还需增加 View controller-based status bar appearance 一行,选择为 NO。

这个方法支持iOS7及以后的系统,iOS9以后,通过[UIApplication sharedApplication] 取得app的单例,然后调用setStatusBarHidden方法隐藏 Status Bar的方法作废!

swift隐藏键盘

view.endEditing(true)
textfield.resignFirstResponder()

下一项

    func textFieldShouldReturn(textField: UITextField) -> Bool {
        if textfield.isFirstResponder() {
            textfield1.becomeFirstResponder()
        } else if textfield1.isFirstResponder() {
            textfield.becomeFirstResponder()
        } else {
            view.endEditing(true)
        }
        return true
    }

App Transport Security

在Info.plist中添加NSAppTransportSecurity类型Dictionary。
在NSAppTransportSecurity下添加NSAllowsArbitraryLoads类型Boolean,值设为YES