2017-03-17 11:42:29 qq_31927785 阅读数 512

最近在写一个纯的swift项目,虽然swift还是非常的完美,但是由于对它不够熟悉,遇到了很多的坑,这一次分享一下极光的推送的使用的,
关于极光推送的自定义消息,我也解释过的,在我之前的博客中,这一次主要分享一下,如何用swift3.0实现极光推送和自定义的消息
关于极光SDK的集成,和OC的没有区别,官方的资料也很详细,我在这里不讲了,
直接上代码代码

//  Created by 段振轩 on 2016/12/26.
//  Copyright © 2016年 段振轩. All rights reserved.
//

import UIKit

@UIApplicationMain

class AppDelegate: UIResponder, UIApplicationDelegate,BMKGeneralDelegate,UIAlertViewDelegate {


    var window: UIWindow?
    var _mapManager: BMKMapManager?


    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {


        // 要使用百度地图,请先启动BaiduMapManager
        _mapManager = BMKMapManager()
        // 如果要关注网络及授权验证事件,请设定generalDelegate参数
        let ret = _mapManager?.start("RXn7z14wXaiX82uG6VzxnSIhMSoYzeRt", generalDelegate: self)
        if ret == false {
            NSLog("manager start failed!")
        }








        //UINavigationBar.appearance().titleTextAttributes=NSDictionary(object:UIColor.white, forKey:NSForegroundColorAttributeName as NSCopying) as? [String : AnyObject];
        //UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white,NSFontAttributeName:UIFont.boldSystemFont(ofSize: 20)]




        UINavigationBar.appearance().titleTextAttributes = [NSForegroundColorAttributeName:UIColor.white,NSFontAttributeName:UIFont.systemFont(ofSize: 19)]

        //极光推送;

       JPUSHService.register(forRemoteNotificationTypes: (UIUserNotificationType.badge.union(UIUserNotificationType.sound).union(UIUserNotificationType.alert)).rawValue, categories:nil)


        JPUSHService.setup(withOption: launchOptions, appKey:"6a9350d7afdda858e41f59f9", channel:"", apsForProduction:true)


//        let center : UNUserNotificationCenter = UNUserNotificationCenter
        //注册一个通知,我们从通知拿到registID
        NotificationCenter.default.addObserver(self, selector: #selector(AppDelegate.self.networkDidLogin(notification:)), name: NSNotification.Name.jpfNetworkDidLogin, object: nil)
        return true
    }
    //在这里拿到divieToken 向极光注册拿到registID;拿到registID后可能需要上传到您的应用服务器,
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {

        print("divceToken"+"\(deviceToken)");

        JPUSHService.registerDeviceToken(deviceToken)


    }

    //在这个通知的方法中,就可以拿到我们想要的registID
    public func networkDidLogin(notification:NSNotification){

        if (JPUSHService.registrationID() != nil) {


            let str:String = JPUSHService.registrationID()

            print("registId:"+str);

            if UserAccount.isLogin() {

                saveDivce(registid: str)
            }



        }



    }







    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {


        print("接到通知")

        JPUSHService.handleRemoteNotification(userInfo)

        application.applicationIconBadgeNumber=0

        JPUSHService.resetBadge()

        if(application.applicationState == .active) {

            //在前台活动do nothing

            let alertView = UIAlertView(title: "消息", message: "您有一条新的消息", delegate: self, cancelButtonTitle: "取消", otherButtonTitles: "查看")

            alertView.show()

        }else{

            //后台或者没有活动

        }




    }




    func applicationWillResignActive(_ application: UIApplication) {
        // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
        // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game.
    }

    func applicationDidEnterBackground(_ application: UIApplication) {
        // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
        // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
    }

    func applicationWillEnterForeground(_ application: UIApplication) {
        // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background.
    }

    func applicationDidBecomeActive(_ application: UIApplication) {
        // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
    }

    func applicationWillTerminate(_ application: UIApplication) {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }


}


//极光推送的代理方法

extension AppDelegate:JPUSHRegisterDelegate{


    @available(iOS 10.0, *)
    public func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {

    }
    public func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {

    }


}





extension AppDelegate{

    func saveDivce(registid:String) {

        let paramers = ["plateform":1,"registrationId":registid] as [String : Any]

        NetworkToolRequest.SaveDivice(params: paramers as [String : AnyObject]) { (response) in
            print("上传结果"+"\(response)")

            self.DivceRelation(registid: registid)

        }

    }

    func DivceRelation(registid:String) {

        let paramers = ["memberId":UserAccount.account?.id ?? 0,"registrationId":registid] as [String : Any]

        NetworkToolRequest.RelationDivice(params: paramers as [String : AnyObject]) { (response) in
             print("绑定结果"+"\(response)")

        }

    }


}

//下面的代码是接受一个自定义消息的,自定义的消息,只能在前台运行,为了能够接受到自定义消息,建议还写自己的根控制器中,tabbar,这种不会销毁的控制器中。

接收自定义消息,通过注册通知,接受到消息的内容,其实被套了一层壳,如果直接通过key的方式,拿到这个字典的key是不行的。必须要将通知的内容,转成data.再通过反序列化为为字典,这个坑,我也被坑了一下午的。

//  Created by 段振轩 on 2017/2/23.
//  Copyright © 2017年 段振轩. All rights reserved.
//

import UIKit

let identifier = "MainCell"

class GrabOrderTableViewController: UITableViewController {


    var orders :[GrabOrder] = [GrabOrder]()


    override func viewDidLoad() {
        super.viewDidLoad()

//        self.view.backgroundColor = UIColor.red;

        NotificationCenter.default.addObserver(self, selector: #selector(self.networkDidReceiveMessage(notification:)), name: NSNotification.Name.jpfNetworkDidReceiveMessage, object: nil)


        setUpTableView()

    }
    func networkDidReceiveMessage(notification:NSNotification){


        //注意拿到通知的内容,一定要转成二进制。
        var userInfo =  notification.userInfo!
        //获取推送内容
        let content =  userInfo["content"] as! String

        let data = content.data(using: .utf8)
        let dic = try? JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions.mutableContainers)

        //将这个字典转成模型,显示到我们的界面,这个功能就完成。
        let order = GrabOrder.init(Dic: dic as! [String : AnyObject])

        orders.append(order)


        tableView.reloadData()






    }

就写这么多吧,swift的路上,坑很多,有时间和大家一起分享。

2019-04-02 17:55:50 sinat_36206255 阅读数 542

iOS 集成极光推送 (swift版)

1、使用cocoapods安装极光推送SDK

之前项目使用的是信鸽推送,但是后面不知怎么地,就是收不到推送消息了,安卓,iOS都是,然后就换成了极光;
我用的是cocoapods安装,也可以在官网下载SDK拖拽进你的工程里
cocoapods安装及使用[https://www.jianshu.com/p/265d8e4dd73a]

在Podfile添加JPush

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
target '******' do
pod 'JPush' #极光推送
use_frameworks!
end

然后在终端进入你的项目目录,执行 pod install

2、注册及配置极光推送相关

在Header.h引入相关文件

#ifndef Header_h
#define Header_h
/*极光推送*/
#import "JPUSHService.h"
// iOS10注册APNs所需头文件
//#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
#endif /* Header_h */

AppDelegate.swift

class AppDelegate: UIResponder, UIApplicationDelegate,JPUSHRegisterDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
		//注册极光推送
		registerJPush()
		return true
	}
	func registerJPush(){
		//注册极光推送
        let entity = JPUSHRegisterEntity()
        entity.types = 1 << 0 | 1 << 1 | 1 << 2
        JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)
        //需要IDFA 功能,定向投放广告功能
        //let advertisingId = ASIdentifierManager.shared().advertisingIdentifier.uuidString
        //通知类型(这里将声音、消息、提醒角标都给加上)
        let userSettings = UIUserNotificationSettings(types: [.alert, .badge, .sound],
                                                      categories: nil)
        if ((UIDevice.current.systemVersion as NSString).floatValue >= 8.0) {
            //可以添加自定义categories
            JPUSHService.register(forRemoteNotificationTypes: userSettings.types.rawValue,
                                  categories: nil)
        }
        else {
            //categories 必须为nil
            JPUSHService.register(forRemoteNotificationTypes: userSettings.types.rawValue,
                                  categories: nil)
        }
        
        //监听自定义消息的接收
        //let defaultCenter =  NotificationCenter.default
        //defaultCenter.addObserver(self, selector: #selector(networkDidReceiveMessage(notification:)),
        //                          name:Notification.Name.jpfNetworkDidReceiveMessage, object: nil)
        
        JPUSHService.setup(withOption: launchOptions, appKey: "appKey", channel: "App Store", apsForProduction: false, advertisingIdentifier: nil)
	}
	
	//极光推送需要实现的代理方法
	// MARK: -JPUSHRegisterDelegate
    // iOS 10.x 需要
    @available(iOS 10.0, *)
    func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {
        
        let userInfo = notification.request.content.userInfo
        if notification.request.trigger is UNPushNotificationTrigger {
            JPUSHService.handleRemoteNotification(userInfo)
        }
        // 需要执行这个方法,选择是否提醒用户,有Badge、Sound、Alert三种类型可以选择设置
        completionHandler(Int(UNNotificationPresentationOptions.alert.rawValue))
    }
    
    @available(iOS 10.0, *)
    func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {
        let userInfo = response.notification.request.content.userInfo
        if response.notification.request.trigger is UNPushNotificationTrigger {
            JPUSHService.handleRemoteNotification(userInfo)
        }
        // 系统要求执行这个方法
        completionHandler()
    }
    
    //点推送进来执行这个方法
    func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
        JPUSHService.handleRemoteNotification(userInfo)
        completionHandler(UIBackgroundFetchResult.newData)
        
    }
    //系统获取Token
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        UserDefaults.standard.set(deviceToken, forKey: "deviceToken")
        JPUSHService.registerDeviceToken(deviceToken)
    }
    //获取token 失败
    func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) { //可选
        print("did Fail To Register For Remote Notifications With Error: \(error)")
    }
    @available(iOS 10.0, *)
    func jpushNotificationCenter(_ center: UNUserNotificationCenter!, openSettingsFor notification: UNNotification?) {
        
    }

	func applicationDidEnterBackground(_ application: UIApplication) {
		//在应用进入后台时清除推送消息角标
        application.applicationIconBadgeNumber = 0
        JPUSHService.setBadge(0)
    }
}

appKey在极光推送开发者服务平台里找,注册一个应用的时候会自动生成
在这里插入图片描述

3、使用别名做唯一标识推送到指定用户的设备

我这里使用的是登陆成功后接口返回的用户手机号做别名,seq是序列号,随便填,我这里用的是用户id

JPUSHService.setAlias("user\(loginInfo.telephone!)", completion: { (iResCode, iAlias, seq) in
                        print("iResCode---\(iResCode)")
                        print("iAlias---\(iAlias ?? "")")
                        print("seq---\(seq)")
                    }, seq: loginInfo.id!)

用户退出登录后移除别名,避免用户使用其他设备登录后当前设备依然还能收到推送消息

	JPUSHService.deleteAlias({ (iResCode, iAlias, seq) in
                print("iResCode---\(iResCode)")
                print("iAlias---\(iAlias ?? "")")
                print("seq---\(seq)")
            }, seq: Int(UserDefaults.standard.string(forKey: "userId")))

搞定!!!

2018-02-08 21:36:40 average17 阅读数 2426

JPushDemo

github项目地址
需要导入JPush框架,可以使用cocoapod导入,也可以手动导入

环境配置

配置环境可以参考极光推送的官方文档:

iOS 证书设置指南

iOS SDK 集成指南

iOS SDK API

使用说明

待环境配置好了之后,就可以进入极光推送开始推送消息了

极光推送首页

推送使用示例如下:

发送通知

这里写图片描述

发送自定义消息

这里写图片描述

代码转换

因为极光推送文档里的环境配置使用的是OC代码,如果对OC不熟悉的话,可以参考以下翻译成Swift的代码,如果你是OC大牛,那就忽略这里

添加头文件

因为极光推送的框架JPush是OC写的框架,Swift不能直接使用,所以需要创建一个桥接文件,会创建桥接文件的直接复制代码即可,不会创建桥接文件的,并且工程下没有OC文件(.m文件的)可以直接File->New->File->Objective-C File,然后任意输入一个文件名,这时会提示你是否自动创建桥接文件,选择是,就会创建一个桥接文件了,然后我们把下面的代码复制到xxx-Bridging-Header.h文件中

// 引入JPush功能所需头文件
#import "JPUSHService.h"
// iOS10注册APNs所需头文件
#ifdef NSFoundationVersionNumber_iOS_9_x_Max
#import <UserNotifications/UserNotifications.h>
#endif
// 如果需要使用idfa功能所需要引入的头文件(可选)
#import <AdSupport/AdSupport.h>

添加Delegate

为AppDelegate添加Delegate。

参考代码:

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, JPUSHRegisterDelegate {

}

添加初始化代码

添加初始化APNs代码

请将以下代码添加到func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

let entity = JPUSHRegisterEntity()
entity.types = 1 << 0 | 1 << 1 | 1 << 2
JPUSHService.register(forRemoteNotificationConfig: entity, delegate: self)

添加初始化JPush代码

请将以下代码添加到func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

let advertisingId = ASIdentifierManager.shared().advertisingIdentifier.uuidString
JPUSHService.setup(withOption: launchOptions, appKey: "a8cc62546a2407102cf484b6", channel: "App Store", apsForProduction: false, advertisingIdentifier: advertisingId)

(参数说明请看文档)

注册APNs成功并上报DeviceToken

请在AppDelegate.swift实现该回调方法并添加回调方法中的代码

func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    //注册 DeviceToken
    JPUSHService.registerDeviceToken(deviceToken)
}

实现注册APNs失败接口(可选)

func application(_ application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: Error) {
    func application(_ application: UIApplication,
                     didFailToRegisterForRemoteNotificationsWithError error: Error) {
        //可选
        NSLog("did Fail To Register For Remote Notifications With Error: \(error)")
    }
}

添加处理APNs通知回调方法

请在AppDelegate.swift实现该回调方法并添加回调方法中的代码

// MARK: JPUSHRegisterDelegate
// iOS 10 Support
func jpushNotificationCenter(_ center: UNUserNotificationCenter!, willPresent notification: UNNotification!, withCompletionHandler completionHandler: ((Int) -> Void)!) {
    let userInfo = notification.request.content.userInfo
    if notification.request.trigger is UNPushNotificationTrigger {
        JPUSHService.handleRemoteNotification(userInfo)
    }
    // 需要执行这个方法,选择是否提醒用户,有BadgeSoundAlert三种类型可以选择设置
    completionHandler(Int(UNNotificationPresentationOptions.alert.rawValue))
}

// iOS 10 Support
func jpushNotificationCenter(_ center: UNUserNotificationCenter!, didReceive response: UNNotificationResponse!, withCompletionHandler completionHandler: (() -> Void)!) {
    let userInfo = response.notification.request.content.userInfo
    if response.notification.request.trigger is UNPushNotificationTrigger {
        JPUSHService.handleRemoteNotification(userInfo)
    }
    // 系统要求执行这个方法
    completionHandler()
}

func application(_ application: UIApplication, didReceiveRemoteNotification userInfo: [AnyHashable : Any], fetchCompletionHandler completionHandler: @escaping (UIBackgroundFetchResult) -> Void) {
    JPUSHService.handleRemoteNotification(userInfo)
    completionHandler(UIBackgroundFetchResult.newData)
}

添加处理JPush自定义消息回调方法

在iOS SDK集成指南中并没有直接给出处理JPush自定义消息的回调方法,需要你自己到API中去寻找,这里,我直接把它抽出来写在下面

功能说明

1、只有在前端运行的时候才能收到自定义消息的推送。

2、从jpush服务器获取用户推送的自定义消息内容和标题以及附加字段等。

实现方法

请将以下代码添加到func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool

NotificationCenter.default.addObserver(self, selector: #selector(networkDidReceiveMessage(notification:)), name: NSNotification.Name.jpfNetworkDidReceiveMessage, object: nil)

实现回调方法 networkDidReceiveMessage

@objc func networkDidReceiveMessage(notification: Notification) {
    let userInfo = notification.userInfo
    if let extras = userInfo?["extras"] as? Dictionary<String, String> {
        NSLog("extras: \(extras)")
    }
    // 将自定义消息的内容转换成本地推送
    if let con = userInfo?["content"] as? String {
        //设置推送内容
        let content = UNMutableNotificationContent()
        content.body = con

        //设置通知触发器
        let trigger = UNTimeIntervalNotificationTrigger(timeInterval: 0.01, repeats: false)

        //设置请求标识符
        let requestIdentifier = "com.average.Demo"

        //设置一个通知请求
        let request = UNNotificationRequest(identifier: requestIdentifier,
                                            content: content, trigger: trigger)

        //将通知请求添加到发送中心
        UNUserNotificationCenter.current().add(request) { error in
            if error == nil {
                print("Time Interval Notification scheduled: \(requestIdentifier)")
            }
        }
    }
}

这里我跟官方的处理方式不同,官方的API中,获取到content和extras之后直接打印出来,我这里只输出extras,而将content作为本地推送的消息body推送出去,有关本地推送的相关知识,可以参考这篇博客

Swift - UserNotifications框架使用详解2(发送本地通知)

还有朋友对AppDelegate.swift中的

UNUserNotificationCenter.current()
    .requestAuthorization(options: [.alert, .sound, .badge]) {
        (accepted, error) in
        if !accepted {
            print("用户不允许消息通知。")
        }
}

和ViewController.swift中的

// 判断权限
UNUserNotificationCenter.current().getNotificationSettings {
    settings in
    switch settings.authorizationStatus {
    // 已获取到通知权限
    case .authorized:
        break
    // 还未获取权限
    case .notDetermined:
        //请求授权
        UNUserNotificationCenter.current()
            .requestAuthorization(options: [.alert, .sound, .badge]) {
                (accepted, error) in
                if !accepted {
                    print("用户不允许消息通知。")
                }
        }
    // 用户关闭通知权限
    case .denied:
        DispatchQueue.main.async(execute: { () -> Void in
            let alertController = UIAlertController(title: "消息推送已关闭",
                                                    message: "想要及时获取消息。点击“设置”,开启通知。",
                                                    preferredStyle: .alert)

            let cancelAction = UIAlertAction(title:"取消", style: .cancel, handler:nil)

            let settingsAction = UIAlertAction(title:"设置", style: .default, handler: {
                (action) -> Void in
                let url = URL(string: UIApplicationOpenSettingsURLString)
                if let url = url, UIApplication.shared.canOpenURL(url) {
                    if #available(iOS 10, *) {
                        UIApplication.shared.open(url, options: [:],
                                                  completionHandler: {
                                                    (success) in
                        })
                    } else {
                        UIApplication.shared.openURL(url)
                    }
                }
            })

            alertController.addAction(cancelAction)
            alertController.addAction(settingsAction)

            self.present(alertController, animated: true, completion: nil)
        })
    }
}

感兴趣,想要仔细了解,也可以参考下面这篇博客

Swift - UserNotifications框架使用详解1(基本介绍,权限的申请与判断)

2017-02-16 14:10:15 wwc455634698 阅读数 1619


//添加监听者

    NSNotificationCenter *defaultCenter = [NSNotificationCenter defaultCenter];

    [defaultCenter addObserver:self selector:@selector(networkDidReceiveMessage:)

                          name:kJPFNetworkDidReceiveMessageNotification object:nil];


//在APP打开的情况下,接收自定义的方法

- (void)networkDidReceiveMessage:(NSNotification *)notification {

    //处理通知的方法

NSDictionary *userInfo = [notification userInfo];

}


2016-03-10 14:04:44 saw471 阅读数 1779

由于自定义通知声音还是由 iOS 系统来播放的,所以对音频数据格式有限制,可以是如下四种之一:

  1. Linear PCM
  2. MA4 (IMA/ADPCM)
  3. µLaw
  4. aLaw

对应音频文件格式是 aiffwavcaf 文件,文件也必须放到 app 的 mainBundle 目录中。

自定义通知声音的播放时间必须在 30s 内,如果超过这个限制,则将用系统默认通知声音替代。

可以使用 afconvert 工具来处理音频文件格式,在终端中敲入如下命令就可以将一个 mp3 文件转换成 caf 文件:

afconvert unbelievable.mp3 unbelievable.caf -d ima4 -f caff -v

转换完成后就可以将 unbelievable.caf 这个文件拖入 Xcode 工程中,编译运行项目在真机上。


将 unbelievable.caf 文件拖入工程中

发送推送通知时,只需配置 sound 字段的值为导入到工程中的音频文件名,这里即就是 unbelievable.caf

测试~~,完美!!!收到推送时,通知声音就是我们自定义的声音了。


收到推送信息

Demo 地址

没有更多推荐了,返回首页