用C#完成Swift远程推送通知
admin
2023-02-10 11:20:16
0

开发环境xcode7.1 运行环境 IOS9.1

IOS的信送简单就是在开开发者管理门户中创建推送证书,然后生成服务器推送证书(服务端代码可以是任意的,我们采用C#来写),App中嵌入推送代码,App安装后允许推送后就可以收到服务端的推送消息了,关于更进一步的原理说明,可以查看官方文档。

 

前提是你已经开通购买了apple的开发者帐户,并且已经有开发证书,能正常创建运行项目到你的iphone上了,如果以前条件不具备,请先参完成以上步骤。

导出证书

打开Mac系统的“钥匙串访问”-“证书助理”-“从证书颁发机构请求证书

用C#完成Swift远程推送通知

输入邮箱和名称,选择“存储到磁盘”

用C#完成Swift远程推送通知

在弹出框中***的名字为RemotePush_CertificateSigningRequest.certSigningRequest请注意,这记住这个名字和保存路径,马上在创建App ID时会用到。

添加App ID

登录apple的开发者门户,进入到“MemberCenter-Certificates,Identifiers&Profiles”-IOSApps下的“Certificates”-Identifiers”-“AppIDs”

用C#完成Swift远程推送通知

这时,还有没在xcode下创建自己的项目,所以App IDs下还无法添加对应的App ID,现在先在xcode下创建一个项目,名字叫RemotePushDemo

用C#完成Swift远程推送通知

现在添加一个App ID

用C#完成Swift远程推送通知

用C#完成Swift远程推送通知

用C#完成Swift远程推送通知



然后提交

用C#完成Swift远程推送通知

提交成功后,在App IDs中选择刚添加的RemotePush,点击Edit

用C#完成Swift远程推送通知

找到Push Notifications节点,点击CreateCertificate(如果是发布,就先Production SSL Certificate下的Create Certificate)

 用C#完成Swift远程推送通知

选择继续,直到选择上传证书页面,点击选择证书

用C#完成Swift远程推送通知

这是找到文章开始先择导出的证书RemotePush_CertificateSigningRequest.certSigningRequest,然后点击Generate生成证书

 用C#完成Swift远程推送通知


这时,就可以下载生成的证书了,下载完成后双击安装证书。

用C#完成Swift远程推送通知

安装完成后可以钥匙串访问的“登录”下,类型为证书下看到安装的证书了。

用C#完成Swift远程推送通知

选中这张证书,右键,选择导出证书选项,然后在弹出框中输入证书名称,要使用.p12格式,同时,需要输入证书密码,这时一定要记住自己设定的证书密码,这个证书和密码将要在服务端使用。在最后,导出证书时需要系统登录密码,以作验证。

配置Provisioning Profiles,选择Development添加,选择IOS App Development

用C#完成Swift远程推送通知

要选择自己创建的App ID,然后保存下载,双击安装即可(安装后会自动打开xcode,可以在项目的Build Settings中搜Provisioning Profile的选项目中查看是否安装成功)。

用C#完成Swift远程推送通知

同时,在设置项目的Capabilities开启Remotenotifications

用C#完成Swift远程推送通知

接下来就开始写swiftapp中的代码了,打开项目的AppDelegate活加如下代码:

 func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        
        UIApplication.sharedApplication().applicationIconBadgeNumber=0;
        
        application.registerUserNotificationSettings(UIUserNotificationSettings(forTypes: [UIUserNotificationType.Alert,UIUserNotificationType.Sound,UIUserNotificationType.Badge], categories: nil));
        
        return true
    }
    
    // 8.0 
之后 收到远程推送通知
    func application(application: UIApplication , didReceiveRemoteNotification userInfo: [ NSObject : AnyObject ], fetchCompletionHandler completionHandler: ( UIBackgroundFetchResult ) -> Void ) {
   
    }
    func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
     
    }
    // 注册通知 alert 、 sound 、 badge ( 8.0 之后,必须要添加下面这段代码,否则注册失败)
    func application(application: UIApplication , didRegisterUserNotificationSettings notificationSettings: UIUserNotificationSettings ) {
        application.registerForRemoteNotifications();
    }    
    
    func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
 
         print(deviceToken);//在输入窗口中查看此值
    }
    func application(application: UIApplication, didFailToRegisterForRemoteNotificationsWithError error: NSError) {
    
    }


注意认识印的倒数第二个方法的deviceToken,这个值要作为服务端推送的设备值使用,每个设备,每次安装后都有一个唯一的值,同样设备卸载再次安装,此值会变化。

 

接下来是用C#写服务端了:

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Security;
using System.Net.Sockets;
using System.Security.Authentication;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
 
namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            while (true)
            {
                pushMessage(Console.ReadLine());
            }
        }
        public static void pushMessage(string content)
        {         
            string deviceID = "deviceToken替换掉这里";
            int port = 2195;
            var hostname = "gateway.sandbox.push.apple.com";
 
             var certificatePath = @"还记得.p12的证书文件吗?替换这里";
        
            X509Certificate2 clientCertificate = new X509Certificate2(System.IO.File.ReadAllBytes(certificatePath), "还记得证书密码吗?你设定的,替换这里");
 
            X509Certificate2Collection certificatesCollection = new X509Certificate2Collection(clientCertificate);
 
            TcpClient client = new TcpClient(hostname, port);
            SslStream sslStream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateServerCertificate), null);
 
            try
            {
                sslStream.AuthenticateAsClient(hostname, certificatesCollection, SslProtocols.Tls, false);
                MemoryStream memoryStream = new MemoryStream();
                BinaryWriter writer = new BinaryWriter(memoryStream);
                writer.Write((byte)0);
                writer.Write((byte)0);
                writer.Write((byte)32);
 
                writer.Write(HexStringToByteArray(deviceID.ToUpper()));
  
                String payload = "{\"aps\":{\"alert\":\"" + content + "\",\"badge\":10,\"sound\":\"default\"}}";
                var payloadlength = System.Text.Encoding.UTF8.GetBytes(payload).Length;
                writer.Write((byte)0);
                //writer.Write((byte)payload.Length);
                writer.Write((byte)payloadlength);
                byte[] b1 = System.Text.Encoding.UTF8.GetBytes(payload);
                writer.Write(b1);
                writer.Flush();
                byte[] array = memoryStream.ToArray();
                sslStream.Write(array);
                sslStream.Flush();
                client.Close();
            }
            catch (System.Security.Authentication.AuthenticationException ex)
            {
                client.Close();
            }
            catch (Exception e)
            {
                client.Close();
            }
        }
 
        private static bool ValidateServerCertificate(object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {     
            Console.WriteLine(certificate.Subject);         
            return true;
        }
 
        public static byte[] HexStringToByteArray(string hex) 
        {
            return Enumerable.Range(0, hex.Length)
                              .Where(x => x % 2 == 0)
                              .Select(x => Convert.ToByte(hex.Substring(x, 2), 16))
                              .ToArray();
        }
 
    }
}


相关内容

热门资讯

德国总理:美国正在被伊朗羞辱 德国之声4月27日报道,德国总理默茨在访问一所学校时表示,在当前的持续冲突中,伊朗领导层正试图羞辱美...
理响中国|“长”歌以行,风云激... 光阴如梭,东方潮阔。这里是中国的长三角,世界的长三角。无论过去、现在还是未来,这片土地都因时代而生,...
白宫:特朗普及其国安团队开会讨... 新华社华盛顿4月27日电 美国白宫新闻秘书莱维特27日在记者会上证实,总统特朗普及其国家安全团队当天...
人民日报刊文:日本放开杀伤性武... 日本放开杀伤性武器出口推高地缘冲突风险(国际论坛)常思纯《人民日报》(2026年04月28日 第 0...
医疗保障法草案二审:明确生育保... 满足多样化健康保障需求本报记者 彭 波4月27日,医疗保障法草案二审稿提请十四届全国人大常委会第二十...
天津一景区发生自转旋翼机事故1... 澎湃新闻记者 吕新文中国民用航空华北地区管理局4月22日公布《豪客通航“10•1”天津长芦汉盐旅游区...
卡塔尔埃米尔与美国总统特朗普通... 当地时间24日,卡塔尔埃米尔塔米姆与美国总统特朗普通电话,重点就中东地区局势以及伊朗与美国谈判问题交...
男子30年前被扣押2859克黄... 澎湃新闻记者 王鑫家住辽宁省大连市的潘永嘉近日向澎湃新闻反映称,三十年前,他在大连周水子机场被盖州市...
商务部:取消反制欧盟两家金融机... 中华人民共和国商务部令二〇二六年 第1号鉴于欧盟已取消对中国两家金融机构的制裁措施,现公布《关于取消...
过去24小时共有5艘船只通过霍... 总台记者当地时间24日获悉,过去24小时内,共有5艘船只通过霍尔木兹海峡,其中包括一艘伊朗油轮。(总...