iOS推送

从极光推送的实现原理概括iOS和Andriod推送原理 推送是手机中非常常见的功能了。可是在实现上iOS和Andriod却有很大的差别。       因为iOS有强大的产品生态体系,APP从研发到审核上架,再到最后在手机端运行,都有严格的把关。所以推送功能在它这里实现起来比较简单。每个时候只要保持一个与APNs的常链接,服务器将要推送的消息发送给APNs,APNs再将消息转发到响应的手机APP,就能很好的实现推送功能。由于手机APP所有的推送功能有统 阅读详情

http://www.cocoachina.com/industry/20130321/5862.html

原文太常了,就不转了。可以去原文看。写的很全面。

ios8中的推送,看下文

http://blog.youkuaiyun.com/apple_app/article/details/39228221

上边的文章讲的是使用php的,下边这个是使用pyhton的一个第三方库实现的。

另一个python推送,applepush:http://python.jobbole.com/86847/

pip install applepush

http://www.tuicool.com/articles/aqYBna

pip install pyapns

或者使用

easy_install pyapns

如果上边两个下载twistd有问题,可以从下边的地址下载twistd

https://pypi.python.org/packages/18/85/eb7af503356e933061bf1220033c3a85bad0dbc5035dfd9a97f1e900dfcb/Twisted-16.2.0.tar.bz2

或者直接在服务器终端里输入:

curl -O https://pypi.python.org/packages/18/85/eb7af503356e933061bf1220033c3a85bad0dbc5035dfd9a97f1e900dfcb/Twisted-16.2.0.tar.bz2

下载好之后,使用

tar -xvjf Twisted-16.2.0.tar.bz2

解压后,进入目录,使用sudo python setup.py install安装

启动twisted

#linux
twistd -r epoll web --class=pyapns.server.APNSServer --port=7077

#mac os
twistd -r kqueue web --class=pyapns.server.APNSServer --port=7077

我在运行这个的时候出了些问题,在mac上运行时发现少了一个叫libffi的库,要安装上这个才能运行。安装之后一,又少service-identity,再后来说openssl的库找不到.使用下边方法

sudo ln -s /Users/username/anaconda/lib/libssl.1.0.0.dylib  /usr/lib/libssl.1.0.0.dylib

sudo ln -s  /Users/username/anaconda/lib/libcrypto.1.0.0.dylib  /usr/lib/libcrypto.1.0.0.dylib

在ubuntu linux上发现用pip安装的twistd没有web的这个命令,后来使用

sudo apt-get install python-twisted python-libxml2 python-simplejson

使用上边的命令安装好了twistd之后运行web命令又说少了service-identity,使用pip install service-identity进行安装时又说pyopenssl的版本不对。

再使用sudo pip install openssl进行openssl安装,接着运行twistd,发现已经有一个进程在运行了。这时找到twistd进程,使用。

kill pid

终止进程后,再运行

#linux
twistd -r epoll web --class=pyapns.server.APNSServer --port=7077

#mac os
twistd -r kqueue web --class=pyapns.server.APNSServer --port=7077

没有报错,这时就可以新建下边的push.py文件了,如果运气好,你的手机应该会收到推送消息。但是也有可能你在生成pem文件时使用了密码。而pyapns默认是不使用密码的。这个时候用下边的方法重新生成一个没有安装密码的ck.pem文件。

openssl rsa -in PushChatKey.pem -out PushChatKey-noenc.pem。
cat PushChatCert.pem PushChatKey-noenc.pem > ck.pem

新建push.py文件输入下面内容

#!/usr/bin/python
# -*- coding: utf-8 -*
# Filename: push.py

from pyapns import configure, provision, notify

tokens = ["token1" ,
          "token2"]

notifications = [
    {'aps' :{'alert': 'Hello token 1', 'badge': 0, 'sound': 'flynn.caf'}},
]

configure({'HOST': 'http://localhost:7077/'})
provision('myapp', open('developent.pem').read(), 'sandbox')
notify('myapp', tokens, notifications)

pyapns推送消息  需要一个pem格式的证书文件,跟 Parse 里要求一个.p12文件不同啊。我看看怎么搞到这文件。从苹果下载的证书是.cer格式的,在苹果的KeyChain程序中,选择导出,可是,只能选择导出成.cer和.p12文件,.pem的选项被禁用了,好桑心。通过搜索export pem from keychain找到 Creating .pem file for APNS? ,简单说,就是在KeyChain里导出.p12格式的,再通过下面的命令转换成.pem的。搞定。

openssl pkcs12 -in Development.p12 -out developent.pem -nodes -clcerts

python push.py

推送成功

完成

pyapns源码:

https://github.com/samuraisam/pyapns

具体的.pem文件生成:

处理证书

打开终端.

cd到桌面,我们那三个文件所在的位置

三个文件:

一个是CSR请求文件,一个是aps_development .cer的SSL证书文件,还有一个刚才生成的Push.p12秘钥文件


1、把.cer的SSL证书转换为.pem文件,执行命令:

openssl x509 -in aps_development.cer -inform der -out PushChatCert.pem


在桌面上会生成一个PushChatCert.pem文件

localhost:Desktop oukoumine$ openssl x509 -in ps_development.cer -inform der -out PushChatCert.pem

localhost:Desktop oukoumine$

2、把私钥Push.p12文件转化为.pem文件:

openssl pkcs12 -nocerts -out PushChatKey.pem -in Push.p12

这里需要我们输入密码,这个密码也就是我们导出p12文件时的密码,也就是我们上面设置的abcabc。然后,需要我们对生成的pem文件设置一个密语,这里我们推荐还是用上面这个abcabc,防止混乱(当然你也可以设置成别的更有意义的密语),这里的密语是要告诉我们服务器的。这样,桌面上又会生成一个PushChatKey.pem文件


 

3、对生成的这两个pem文件再生成一个pem文件,来把证书和私钥整合到一个文件里:

cat PushChatCert.pem PushChatKey.pem > ck.pem
生成ck.pem文件


这样,我们的文件就制作完了

项目测试

建立我们的推送的项目(注意BundleIdentifier必须和我们推送应用的App id一致)

在AppDelegate里didFinishLaunchingWithOptions函数里写

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

{

……

  //推送的形式:标记,声音,提示


   [[UIApplication sharedApplication] registerForRemoteNotificationTypes: UIRemoteNotificationTypeBadge |UIRemoteNotificationTypeSound | UIRemoteNotificationTypeAlert];

//上边的方法在ios8以上的版本不能用了。ios8以后要使用新的方法

iOS推送 - ♂苹果 - 眼睛想旅行

 

   return YES;

}

 

- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken {

   NSLog(@"regisger success:%@",pToken);

   //注册成功,将deviceToken保存到应用服务器数据库中

}

- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{

    // 处理推送消息

    NSLog(@"userinfo:%@",userInfo);

   

    NSLog(@"收到推送消息:%@",[[userInfo objectForKey:@"aps"] objectForKey:@"alert"]);

}

- (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error {

   NSLog(@"Registfail%@",error);

}

我们运行程序的时候会有提示,说我们的程序要发送推送通知。


C++推送服务器端:

转自:http://www.cocoachina.com/bbs/read.php?tid=74676

SSLCOMM_H文件

#ifndef SSLCOMM_H

#define SSLCOMM_H

 

#ifdef linux

#include <assert.h>

#include "openssl/pem.h"

#include "openssl/rsa.h"

#include "openssl/crypto.h"

#include "openssl/x509.h"

#include "openssl/ssl.h"

#include "openssl/err.h"

#include "openssl/rand.h"

 

#include "errno.h"

#include "sys/socket.h"

#include "netinet/in.h"

#include "unistd.h"

#include <arpa/inet.h>

#include <netdb.h>

 

#include "Utility.h"

 

#define APNS_DEV

#if defined(APNS_DEV)

 

#define CA_CERT_PATH    "./pem"

#define RSA_CLIENT_CERT     "./pem/a.pem"

#define RSA_CLIENT_KEY      "./pem/a.pem"

/* Development Connection Infos */

#define APPLE_HOST          "gateway.sandbox.push.apple.com"

#define APPLE_PORT          2195

 

#define APPLE_FEEDBACK_HOST "feedback.sandbox.push.apple.com"

#define APPLE_FEEDBACK_PORT 2196

 

#else

#define CA_CERT_PATH    "./pem"

#define RSA_CLIENT_CERT     "./pem/b.pem"

#define RSA_CLIENT_KEY      "./pem/b.pem"

#define APPLE_HOST          "gateway.push.apple.com"

#define APPLE_PORT          2195

#define APPLE_FEEDBACK_HOST "feedback.push.apple.com"

#define APPLE_FEEDBACK_PORT 2196

#endif

 

 

class CSSLComm

{

 public:

    CSSLComm();

    ~CSSLComm();

 

    bool connected();

    bool ssl_connect(const char *host, int port, const char *certfile, const char *keyfile, const char* capath);

    void PushNotification(const char *pToken,const char *pMsg);

 

    void GenPushData(const char *pToken);

    int GenPayloadData(int badgeNum,const char *pMsg = NULL);

 

    private:

    void Reset();

 

    private:

 

    SSL_CTX         *m_pctx;

    SSL             *m_pssl;

    const SSL_METHOD      *m_pmeth;

    X509            *m_pserver_cert;

    EVP_PKEY        *m_pkey;

 

    /* Socket Communications */

    struct sockaddr_in   m_server_addr;

    struct hostent      *m_phost_info;

 

    int                  m_sockfd;

    uint16 m_tokenLen;

    struct PUSHDATA

    {

        char szToken[1+2+32];

        char szPayload[2+256];

    }m_data;

 

    CSyncCritical m_lock;

};

 

#endif

 

#endif // SSLCOMM_H


SSLComm.cpp

#ifdef linux

 

#include "SSLComm.h"

 

CSSLComm::CSSLComm()

{

    //ctor

    m_sockfd = -1;

    m_pctx = NULL;

    m_pssl = NULL;

    m_pmeth = NULL;

    m_pserver_cert = NULL;

    m_pkey = NULL;

 

    m_tokenLen = htons(32);

    memset((void*)&m_data,0,sizeof(m_data));

 

}

 

CSSLComm::~CSSLComm()

{

    //dtor

    Reset();

 

}

void CSSLComm::Reset()

{

 

    if(m_pssl)

    {

        SSL_shutdown(m_pssl);

        SSL_free(m_pssl);

        m_pssl = NULL;

    }

    if(m_pctx)

    {

        SSL_CTX_free(m_pctx);

        m_pctx = NULL;

    }

    if(m_sockfd > 2)

    {

        close(m_sockfd);

        m_sockfd = -1;

    }

 

}

 

 

bool CSSLComm::connected()

{

    if(m_sockfd < 2) return false;

 

    struct timeval timeout;

    timeout.tv_sec = 0;

    timeout.tv_usec = 0;

    fd_set fdwrite;

    fd_set fdexcept;

    FD_ZERO(&fdwrite);

    FD_ZERO(&fdexcept);

    FD_SET(m_sockfd,&fdwrite);

    FD_SET(m_sockfd,&fdexcept);

    int ret = select(m_sockfd+1,NULL,&fdwrite,&fdexcept,&timeout);

    if(ret == -1)

        return false;

    if(ret > 0)

    {

        if(FD_ISSET(m_sockfd,&fdexcept))

            return false;

        else if(FD_ISSET(m_sockfd,&fdwrite))

        {

            int err = 0;

            socklen_t len = sizeof(err);

            int result = getsockopt(m_sockfd,SOL_SOCKET,SO_ERROR,(char*)&err,&len);

            if(result < 0 || err != 0)

                return false;

            return true;

        }

    }

    return false;

}

 

 

bool CSSLComm::ssl_connect(const char *host, int port, const char *certfile, const char *keyfile, const char* capath)

{

    Reset();

 

    int err;

 

    /* Load encryption & hashing algorithms for the SSL program */

    SSL_library_init();

 

    /* Load the error strings for SSL & CRYPTO APIs */

    SSL_load_error_strings();

 

    /* Create an SSL_METHOD structure (choose an SSL/TLS protocol version) */

    m_pmeth = SSLv3_method();

 

    /* Create an SSL_CTX structure */

    m_pctx = SSL_CTX_new(m_pmeth);

    if(!m_pctx)

    {

        printf("Could not get SSL Context\n");

        return false;

    }

 

    /* Load the CA from the Path */

    if(SSL_CTX_load_verify_locations(m_pctx, NULL, capath) <= 0)

    {

        /* Handle failed load here */

        printf("Failed to set CA location...\n");

        ERR_print_errors_fp(stderr);

        return false;

    }

 

    /* Load the client certificate into the SSL_CTX structure */

    if (SSL_CTX_use_certificate_file(m_pctx, certfile, SSL_FILETYPE_PEM) <= 0)

    {

        printf("Cannot use Certificate File\n");

        ERR_print_errors_fp(stderr);

        return false;

    }

 

    /* Load the private-key corresponding to the client certificate */

    if (SSL_CTX_use_PrivateKey_file(m_pctx, keyfile, SSL_FILETYPE_PEM) <= 0)

    {

        printf("Cannot use Private Key\n");

        ERR_print_errors_fp(stderr);

        return false;

    }

 

    /* Check if the client certificate and private-key matches */

    if (!SSL_CTX_check_private_key(m_pctx))

    {

        printf("Private key does not match the certificate public key\n");

        return false;

    }

 

    /* Set up a TCP socket */

    m_sockfd = socket (PF_INET, SOCK_STREAM, IPPROTO_TCP);

    if(m_sockfd == -1)

    {

        printf("Could not get Socket\n");

        return false;

    }

 

    memset (&m_server_addr, '\0', sizeof(m_server_addr));

    m_server_addr.sin_family      = AF_INET;

    m_server_addr.sin_port        = htons(port);       /* Server Port number */

    m_phost_info = gethostbyname(host);

    if(m_phost_info)

    {

        /* Take the first IP */

        struct in_addr *address = (struct in_addr*)m_phost_info->h_addr_list[0];

        m_server_addr.sin_addr.s_addr = inet_addr(inet_ntoa(*address)); /* Server IP */

 

    }

    else

    {

        printf("Could not resolve hostname %s\n", host);

        return false;

    }

 

    /* Establish a TCP/IP connection to the SSL client */

    err = connect(m_sockfd, (struct sockaddr*) &m_server_addr, sizeof(m_server_addr));

    if(err == -1)

    {

        printf("Could not connect\n");

        return false;

    }

 

    /* An SSL structure is created */

    m_pssl = SSL_new(m_pctx);

    if(!m_pssl)

    {

        printf("Could not get SSL Socket\n");

        return false;

    }

 

    /* Assign the socket into the SSL structure (SSL and socket without BIO) */

    SSL_set_fd(m_pssl, m_sockfd);

 

    /* Perform SSL Handshake on the SSL client */

    err = SSL_connect(m_pssl);

    if(err == -1)

    {

        printf("Could not connect to SSL Server\n");

        return false;

    }

    return true;

 

}

 

void CSSLComm::PushNotification(const char *pToken,const char *pMsg)

{

    CMyLock lock(&m_lock);

    if(!connected())

    {

        ssl_connect(APPLE_HOST, APPLE_PORT, RSA_CLIENT_CERT, RSA_CLIENT_KEY, CA_CERT_PATH);

    }

    int paylen = GenPayloadData(1,pMsg);

    GenPushData(pToken);

    int ret = SSL_write(m_pssl, (void*)&m_data, 35 + paylen);

    //printf("ret = %d \n",ret);

}

 

void CSSLComm::GenPushData(const char *pToken)

{

    char *ptr = m_data.szToken;

    *ptr++ = 0;

    memcpy(ptr,&m_tokenLen,2);

    ptr += 2;

    memcpy(ptr,pToken,32);

}

 

int CSSLComm::GenPayloadData(int badgeNum,const char *pMsg)

{

    char buf[256] = {0};

    char badgeBuf[3] = {0};

    strcpy(&m_data.szPayload[2], "{\"aps\":{");

    if(pMsg != NULL)

    {

        strcat(&m_data.szPayload[2], "\"alert\":");

        snprintf(buf, sizeof(buf)-1,"\"%s\",", pMsg);

        strcat(&m_data.szPayload[2],buf);

    }

    if(badgeNum > 99 || badgeNum < 0) badgeNum = 1;

    snprintf(badgeBuf, sizeof(badgeBuf)-1,"%d", badgeNum);

    strcat(&m_data.szPayload[2], "\"badge\":");

    strcat(&m_data.szPayload[2], badgeBuf);

    strcat(&m_data.szPayload[2], ",\"sound\":\"msg.wav\"}");

    /*

        int i = 0;

        while(payload->dictKey<i> != NULL && i < 5)

        {

            sprintf(tmpBuff, "\"%s\":\"%s\"", payload->dictKey<i>, payload->dictValue<i>);

            strcat(messageBuff, tmpBuff);

            if(i < 4 && payload->dictKey[i + 1] != NULL)

            {

                strcat(messageBuff, ",");

            }

            i++;

        }

    */

 

    snprintf(buf, sizeof(buf)-1,",\"%s\":\"%d\"", "forum_id",88);

    strcat(&m_data.szPayload[2],buf);

 

    snprintf(buf, sizeof(buf)-1,",\"%s\":\"%d\"", "topic_id",999);

    strcat(&m_data.szPayload[2],buf);

 

    strcat(&m_data.szPayload[2],"}");

    int len = strlen(&m_data.szPayload[2]);

    assert(len <= 256);

    uint16_t payload_len = htons(len);

    memcpy(m_data.szPayload,&payload_len,sizeof(payload_len));

    return len + 2;

}

 

#endif

另外还有一些第三方的推送平台,用第三方平台的好处就是操作简单,不同系统的设备推送接口统一。缺点只有一个,就是推送数据的全安性,以及到一定量时要收费。 Python新版本升级方法:
Linux系统登陆密码忘了怎么办:
使用系统安装盘,进入修复模式,输入
 passwd <用户名>
就可以输入新密码了。我是在ubuntu 14.04上试的。
iOS平台推送原理 iOS平台推送原理       由于我们在开发过程中用到远程推送相对比较频繁,本篇博文我们将以介绍iOS远程推送原理为基础,展开我们的下面的话题。       我们先要明确至关重要的一点:所有的iOS设备收到的远程推送消息都是通过苹果的服务器发出来的。不管是公司的服务器,还是第三方的推送服务器都是将要发送给我们的推送消息先推给苹果的服务器,然后再由苹果的服务器发送给我们。       所以远程推送... 阅读详情

相关推荐

U3d WebGL使用ToLua

首先我们在编辑器模式下加入Tolua插件,然后配置修改到在编辑器模式下能够正常的运行。 同个U3d 插件Build出WebGL的工程,运行的时候你会发现(有些需要把这个WebGL工程放在一个HttpServer下面,直接本地访问index.html会被拒绝,让你使用http的格式)。 当要加载完的时候会出现 To use dlopen, you need to use Emscripten'...

qq_35267906的博客 2947

#ifdef 跨平台宏定义

// IOS平台 #ifdef __APPLE__ #include #ifdef TARGET_OS_IPHONE #define ZS_PLATFORM_IOS #endif #endif // ANDROID平台 #ifdef __ANDROID__ #define ZS_PLATFORM_ANDROID #endif // WIN32平台 #ifdef WIN32 #def

朱韦刚(zhuweigangzwg)的技术博客 5507

“傻瓜”stata入门——熟悉操作界面

小白开始学习stata和matlab,零基础上手

nnpersistent的博客 4457

twisted 的 epoll 爽歪歪

<br /><br />from twisted.internet import epollreactor<br />epollreactor.install()<br />from twisted.internet import reactor<br />from twisted.internet.protocol import Protocol,Factory<br />from twisted.protocols.basic import LineReceiver<br /> <br />class

逆雪寒的天坑 2705

如何使用superpowers

"这个 bug 帮我修一下" → 我会自动走 systematic-debugging → TDD → verify 流程。- "帮我添加一个登录功能" → 我会自动走 brainstorming → plan → TDD → verify 流程。只要任务有 1% 的可能性适用某个技能,我就会先调用它再行动。→ TDD(测试驱动开发)→ verification(验证)→ code review(代码审查)提出需求 → brainstorming(头脑风暴)→ writing-plans(编写计划)

xiaojingjianqiang的博客 612

形位公差标注的常见误区与优化策略

本文深入解析机械设计中形位公差标注的常见误区与优化策略,特别针对NX2406用户提供实用技巧。从标注冗余、基准选择到公差值设定等五大误区入手,结合工程图实例展示如何提升标注精度与效率,帮助工程师避免常见错误,优化设计流程,确保零件功能实现与制造可行性。

info6的博客 245

iOS开发资源:推送通知相关开源项目--PushSharp、APNS-PHP以及Pyapns等

iOS开发资源:推送通知相关开源项目--PushSharp、APNS-PHP以及Pyapns等 “” 阅读器 PushSharp  (github) PushSharp是一个实现了由服务器端向移动客户端推送消息的开源C#库,支持 iOS (iPhone/iPad APNS)、 Android (C2DM/GCM - Google Cloud Message)、Windows Ph

billfanggs的专栏 2199

2万字长文:海豚调度器(DolphinScheduler)面试题深入了解

DAG图(有向无环图)是海豚调度器中表示工作流任务依赖关系的一种方式。在DolphinScheduler中,每个任务是一个节点,任务之间的依赖关系通过有向边连接这些节点来表示。无环:保证了工作流的执行顺序是确定的,避免了无限循环的问题。有向:箭头指示了任务的执行方向,即上一个任务的输出可以作为下一个任务的输入。依赖表示:通过图形化界面,用户可以通过拖拽连接线来定义任务之间的先后顺序和依赖关系。并行处理:DAG图可以表示出任务的并行关系,允许多个任务在没有直接依赖关系的情况下同时执行。条件分支。

大模型大数据攻城狮的专栏 1331

iOS推送通知

推送通知,也被叫做远程通知,是在iOS 3.0以后被引入的功能。是当程序没有启动或不在前台运行时,告诉用户有新消息的一种途径,是从外部服务器发送到应用程序上的。一般说来,当要显示消息或下载数据的时候,通知是由远程服务器(程序的提供者)发送,然后通过苹果的推送通知服务(Apple Push Notification Service,简称APNS)推送到设备的程序上。直接由应用程序(程序中写入对应代码)给用户发出通知本地通知需要用到一个重要的类:本地通知的实现步骤:(1)创建本地通知。

旭日的博客 4285

把大表拆成更好用的“小仓库”:SAP HANA 表分区设计、分区裁剪与内存代价全解析

摘要:本文深入解析SAP HANA分区技术的核心价值与实现策略。作为内存数据库的"手术刀",分区通过将逻辑表横向切分为独立物理容器,显著提升并行计算能力与查询效率。重点探讨了三种分区类型(Range、Hash、Round-robin)的适用场景,以及分区裁剪的优化原理与前提条件。特别指出分区设计需要平衡查询模式与数据分布,并揭示了分区对内存占用的双向影响机制:既可能因字典复制增加消耗,也可能因数据纯度提升压缩率。通过电商订单表等实际案例,展示了合理分区如何将分钟级报表优化至秒级响应。文章

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 1650

【MATLAB代码】蚁群算法(Ant Colony Optimization, ACO)路径规划(避障)仿真程序,订阅专栏后可直接查看完整源代码

基于蚁群算法的路径规划系统。可自定义起点、终点和障碍物地图,系统通过蚁群算法自动计算最优路径,并输出路径坐标、障碍物地图和收敛曲线。完整MATLAB源代码直接运行。适用于复杂障碍环境下的路径优化问题。

985工科博士毕业,专攻定位、导航和滤波等算法研究。从业10年,主要使用MATLAB 3091

IOS推送

IOS推送 推送 ●iOS不允许App常驻后台 ●提供服务器主动与用户相互的功能 ●新闻类(热点新闻的推送) ●本地推送 ●由本地应用触发(闹铃/待办事项) ●无需网络数据,提供和远程推送统一的交互 ●远程推送 ●普通远程推送 ●静默推送 UserNotifications UserNotifications ●iOS10之后统一UserNotificatiohsframework ●需要兼容低版本机型 ●UNUserNotificationCenter单例管理全部推送 ●统一的权限的申请

weixin_45363671的博客 1394

本文将详细介绍如何在 Qt (C++) 应用程序中集成 osgEarth,加载三维数字地球,并在指定经纬度添加三维模型(如飞机、建筑等)。

OSG 与 Qt 的交互通常需要处理 OpenGL 上下文。osgEarth 3.x 提供了对 Qt 的较好支持,或者可以使用。在普通 OSG 程序中,你需要手动处理坐标系转换将经纬度转为笛卡尔坐标 (XYZ)。这是实现的关键,将 OSG 的渲染循环集成到 Qt 的事件循环中。第三方库,但在本教程中,我们将展示一种通过继承。,将 Qt 的输入事件转换为 OSG 理解的。事件,这是实现交互(旋转地球、缩放)的基础。来嵌入 OSG 视图的标准方法。在这里我们初始化地球并添加模型。节点简化了这一过程。

qq_45859163的博客 1045

IOS 推送(本地推送、远程推送、三方推送[极光推送])

1.本地推送 关于本地推送的作用及意义:【后期完善】 实现步骤 大致4步:1创建通知、2注册通知、3实现函数、4删除通知 注意! 下面的内容中没有提到:在使用通知的时候,为了避免重复注册:最好在生命周期的函数中进行 注册 和 删除通知 如下: //注册通知 - (void)viewWillAppear:(BOOL)animated {     、、、、、 }

kenshin的专栏 3626

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

iOS 推送通知

引言: 推送通知是移动终端保持永远在线概念的一个核心方式,当人们离开桌面互联网以后想在第一时间收到与之相关的信息时.推送通知的出现就再好不过了. 但是,要注意不可滥用,繁多的非必要性推送消息会给用户造成非常烦躁的心理.作为用户体验的一部分,那就已经在往失败的方向走了. 推送通知共为两种类型,分别是本地推送通知和远程推送通知. 本文将对这两类通知的使用展开详细讨论. 参考资料:

余书懿 1万+

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

iOS推送小结

iOS推送小结(吐槽,md的代码编辑功能不知道是不会用还是确实不好用)1.推送配置1.1证书配置请自己谷百.1.2注册推送 //代码来源:环信Demo //In method application:(UIApplication *)application didFinishLaunchingWithOptions: UIApplication *application = [U

谁令骑马客京华 1426

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

ios推送php,php如何实现ios推送

php实现ios推送的方法:首先把要发送的消息以及iPhone标识打包,并发送给APNS;然后查找有相应标识的iPhone,并把消息发送到iPhone;最后把发来的消息传递给相应的应用程序,并且按照设定弹出Push通知即可。IOS推送消息是许多IOS应用都具备的功能,最近也在研究这个功能,参考了很多资料终于搞定了,下面就把步骤拿出来分享下:iOS消息推送的工作机制可以简单的用下图来概括:Provi...

weixin_39624094的博客 475

iOS 推送(苹果原生)

来自:https://www.jianshu.com/p/3fc46a8764ed 前言 推送对App的重要性不言而喻,是每一个iOS开发者必修的技能。网上的资料对于初学者并不友好(至少对于我来说),其中有许多坑。并且由于要配置证书,只能真机调试等,学起来更是难上加难。这篇文章是从刚开始接触推送的起点写起。最近有点忙,有些地方没有细究,只是暂时知道了能实现什么,并且贴出了一些文章的链接,方便进...

LANGZI7758521的专栏 1187

[IOS开发]IOS开发之推送

最近的项目中使用到了推送,第一次搞推送,遇到了不少坑,所以记录下来。 参考:手把手教你做IOS推送 首先是一些基础知识 APNS的推送机制 首先我们看一下苹果官方给出的对iOS推送机制的解释。如下图 Provider就是我们自己程序的后台服务器,APNS是Apple Push Notification Service的缩写,也就是苹果的推送

风飘絮 1536

IOS 普通推送和静默推送

在IOS推送服务中,Apple提供了两种不同方式的推送形式,一种是在通知栏上面显示的推送;另一种则是不带消息提醒的推送,俗称“静默消息”。1.普通推送模板:ios10以前的模板:{ "aps":{ "alert":"内容", "badge":1, "sound":"default", "userinfo":{

双手成就你的梦想 7755

iOS远程推送之极光推送

极光推送

buildSetting的博客 1425

iOS 推送要点整合

本文旨在对 iOS 推送(以下简称 推送)进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解。以下是 pikacode 使用 iOS 推送的一些经验,欢迎互相交流,指出错漏之处。 推送服务 可以说是所有 App 的标配,不论是哪种类型的 App,推送都从很大程度上决定了 App 的 打开率、使用率、存活率 。因此

COOL_BEAR_XX的专栏 1242

iOS —— 推送

本文旨在对 iOS 推送进行一个完整的剖析,如果你之前对推送一无所知,那么在你认真地阅读了全文后必将变成一个推送老手,你将会对其中的各种细节和原理有充分的理解。以下是 pikacode 使用 iOS 推送的一些经验,欢迎互相交流,指出错漏之处。 推送服务可以说是所有 App 的标配,不论是哪种类型的 App,推送都从很大程度上决定了 App 的 打开率、使用率、存活率 。因此,熟知并掌握推送

会飞の马 630

iOS9 和iOS10远程推送通知的总结

iOS10开始推送通知的变化比较大,之前对推送的处理没太注意,一直没太明白推送前台、后台、杀死状态,点击通知栏走的具体方法是什么。这次有时间重新整理测试了一下关于推送的几个代理方法。下面都是我是实测的结果,iOS9.3和iOS10和iOS12的测试机,没有iOS8的,不过iOS8和iOS9效果应该是一样的。 先说苹果原生的方法,我用的是极光的推送,所以也要说说极光升级后的方法: 我们对推送的处理主...

wangqiuwei07的专栏 1583
上一篇: python中Decorators的用法
下一篇: python查看进程是否运行
woodcol
博客等级 码龄19年 288粉丝 429原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值