APNS和token的那些事

版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Number_One_2015/article/details/88316868

关于deviceToken的改变,有三种情况:

1.在用户在新的设备上登陆

2.更新设备操作系统的时候

3.app卸载重装

解决方法:

我主要在主页进行update token api,但是也有在检测到action payment,解锁APP(输错密码三次之后)之后,登录成功等各种需要接受推送的地方 set isNeedForceUpdateAPN = YES,一旦进入主页,就会根据判断去执行update token api。。

除了以上还会setIsWalletBecomeActiveFromLaunching 判断是否执行update token api

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

    [[PGDataManager sharedInstance] setIsWalletBecomeActiveFromLaunching:YES];

}

 

- (void)applicationDidEnterBackground:(UIApplication *)application {

 

    [[PGDataManager sharedInstance] setIsWalletBecomeActiveFromLaunching:NO];

}

这两个方法会在kill掉app的时候执行,如果只是home键出来,再进入是不会调用 didFinishLaunchingWithOptions的

 

最后:token的获取:::

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

    DDLogDebug(@"<%@> %@ [error:%@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd), error);

    if ([[[UIDevice currentDevice] model] isEqualToString:@"iPhone Simulator"]) {

        [[PGDataManager sharedInstance] setKeychainWithKey:kKeychainKeyAPNToken value:@"token"];

    }

}

 

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

    DDLogDebug(@"<%@> %@ [deviceToken:%@]", NSStringFromClass([self class]), NSStringFromSelector(_cmd), deviceToken);

    NSString *token = [[deviceToken description] stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"<>"]];

    token = [token stringByReplacingOccurrencesOfString:@" " withString:@""];

    [[PGDataManager sharedInstance] setKeychainWithKey:kKeychainKeyAPNToken value:token];

}

OK,今天的解释到这里啦,

展开阅读全文

APNS 错误8 : Invalid token ,求解决

12-22

用c#写的ios消息推送,引用PushSharp.Apple和PushSharp.Core 运行时出现下面错误:n APNS NotificationFailureException -> 8 : Invalid token nn网上有说是token 64位的问题,http://www.cocoachina.com/bbs/read.php?tid=165961 不知道要怎么转成32位的?nn还有.ForDeviceToken(tokenID)方法吧token改成32位 提示 5 : Invalid token size nn求高手指点一下 nn```n n private void Form1_Load(object sender, EventArgs e)n n string token = "8d6c30144e7a93e73cc1fafb0a5000000001a0a0bd1f66c9e0ab857291d00000"; n StarServices("production_identity.p12", "123123");n SendSingleMess(token, "这是通过APNS的推送消息");n n public void StarServices(string keyPath, string keyWord)n n tryn n push.OnNotificationSent += NotificationSent; n push.OnNotificationFailed += NotificationFailed; n push.OnDeviceSubscriptionExpired += DeviceSubscriptionExpired; n push.OnDeviceSubscriptionChanged += DeviceSubscriptionChanged; n push.OnChannelException += ChannelException; n push.OnServiceException += ServiceException; n push.OnChannelCreated += ChannelCreated; //n push.OnChannelDestroyed += ChannelDestroyed; //n var appleCert = File.ReadAllBytes(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, keyPath));n push.RegisterAppleService(new ApplePushChannelSettings(appleCert, keyWord)); n n catch n n public void StopServices()n n tryn n push.StopAllServices();n n catch n n public void SendSingleMess(string tokenID, string message)n n tryn n push.QueueNotification(new AppleNotification()n .ForDeviceToken(tokenID)n .WithAlert(message)n .WithBadge(7)n .WithSound("sound.caf")); n Console.ReadLine(); n n catch (Exception e)n n Console.WriteLine("error:" + e.Message);n n n n public void Test()n n n n static void DeviceSubscriptionChanged(object sender, string oldSubscriptionId, string newSubscriptionId, INotification notification)n n //Currently this event will only ever happen for Android GCMn Console.WriteLine("Device Registration Changed: Old-> " + oldSubscriptionId + " New-> " + newSubscriptionId + " -> " + notification);n nn static void NotificationSent(object sender, INotification notification)n n Console.WriteLine("Sent: " + sender + " -> " + notification);n nn static void NotificationFailed(object sender, INotification notification, Exception notificationFailureException)n n Console.WriteLine("Failure: " + sender + " -> " + notificationFailureException.ToString() + " -> " + notification);n nn static void ChannelException(object sender, IPushChannel channel, Exception exception)n n Console.WriteLine("Channel Exception: " + sender + " -> " + exception);n nn static void ServiceException(object sender, Exception exception)n n Console.WriteLine("Service Exception: " + sender + " -> " + exception);n nn static void DeviceSubscriptionExpired(object sender, string expiredDeviceSubscriptionId, DateTime timestamp, INotification notification)n n Console.WriteLine("Device Subscription Expired: " + sender + " -> " + expiredDeviceSubscriptionId);n nn static void ChannelDestroyed(object sender)n n Console.WriteLine("Channel Destroyed for: " + sender);n nn static void ChannelCreated(object sender, IPushChannel pushChannel)n n Console.WriteLine("Channel Created for: " + sender);n nn```nn 问答

关于android自动化测试的那些事!

12-12

组长叫我对公司的一个框架进行单元测试,该主要是操作图形元素,包括图片、文字、手写笔迹等所有能看得到能显示的东西,其中过程非常复杂,层次结构比较深。rn 看了单元测试相关的东西,几天过去了,感觉还是无从下手。rn 一开始我在公司框架源码src包同目录下建了一个test源码目录,然后针对src里面所有的包,都在test目录下建立了同等的包的结构。rn 叫来组长一看,他说新建一个测试项目,专门用来测试这个框架。rn 于是我重新新建了一个Android test project,然后里面可以指定你要测试哪一个项目,于是选定自己要测试的框架之后,把开始上面建立的test下面的包的结构全部移植到该测试项目中。rn 于是我认为的单元测试开始了,我找到框架最底层的数据层来进行一些测试,比如一些对数据和文件的读写操作,然后我对每个数据类的每个方法都写了一个测试方法,然后都是用一些假数据来进行测试,运行,发现正常。然后就以为这就是单元测试了。rn 数据层的好说,现在碰到了数据层上面的图形渲染和组件交互层,这些里面大都都是对一些基本图形元素的处理,里面的逻辑以及关系我看不懂,只知道大概的架构。rn 现在得问题是,对于这些图形组件之类的东西?用这种单元测试的方式,该如何来进行测试呢?该测试什么呢?求高人指导! 论坛

Java 内存的那些

02-22

虽然Java屏蔽了一下内存细节,但是有时候,了解一下这些常识还是有好处的,特别是一些面试,总是盯着这些玩意不放手。把最近看的一些总结一下,欢迎跟帖拍砖。rnrnJVM启动以后,会分配两类内存区域,一类用于开发人员使用,比如保存一些变量,对象等,一类JVM自己使用,比如存放一些class类和描述。rnrn1,第一类内存区域又可以分为栈(stack)、堆(heap),还有一些静态存储区域,这部分的内存在JVM启动的时候,可以用参数进行配置:rnrn-Xms 初始堆大小,这个值不能太小,其初始空间(即-Xms)是物理内存的1/64,这个值不能太小,比如 设置了-Xms1m,运行可能会出现 rn Error occurred during initialization of VMrn Too small initial heap for new size specifiedrnrn-Xmx 堆大小上限,最大空间(-Xmx)是物理内存的1/4,如果程序中分配的内存超过了这个限制,那么会出现rnException in thread "main" java.lang.OutOfMemoryError: Java heap spacern 代码为:byte[] b = new byte[100000000];rnrn-Xss 线程栈大小,一般不用设置,JDK5.0以后每个线程堆栈大小为1M,以前每个线程堆栈大小为256K。更具应用的线程所需内存大小进行调整。有时候会发现一下异常,rn Exception in thread "main" java.lang.StackOverflowErrorrnrn 原因一般是:rnrn public static int callMyself()rn return callMyself();rn rnrn 方法的递归或者死循环,导致栈空间不够用了。rnrn 栈和堆到底存些什么,很多地方都有讲到,这里参考下《Think in java》的,栈里存放对象引用、基本类型的变量等,而堆里面存放对象和数组。方法的执行是在栈上进行的,这一点可以通过异常的时候,经常会默认打印e.printStackTrace();栈信息得知。rnrnrnRuntime类有几个函数,我们可以简单的通过这几个函数,看看JVM中的一些内存信息,下面是转自网络上的解释。rnrnmaxMemory()这个方法返回的是java虚拟机(这个进程)能构从操作系统那里挖到的最大的内存,以字节为单位,如果在运行java程序的时 候,没有添加-Xmx参数,那么就是64兆,也就是说maxMemory()返回的大约是64*1024*1024字节,这是java虚拟机默认情况下能 从操作系统那里挖到的最大的内存。如果添加了-Xmx参数,将以这个参数后面的值为准,例如java -cp ClassPath -Xmx512m ClassName,那么最大内存就是512*1024*0124字节。rnrntotalMemory()这个方法返回的是java虚拟机现在已经从操作系统那里挖过来的内存大小,也就是java虚拟机这个进程当时所占用的所有 内存。如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操作系统那里挖的,基本上是用多少挖多少,直 挖到maxMemory()为止,所以totalMemory()是慢慢增大的。如果用了-Xms参数,程序在启动的时候就会无条件的从操作系统中挖- Xms后面定义的内存数,然后在这些内存用的差不多的时候,再去挖。rnrnfreeMemory()是什么呢,刚才讲到如果在运行java的时候没有添加-Xms参数,那么,在java程序运行的过程的,内存总是慢慢的从操 作系统那里挖的,基本上是用多少挖多少,但是java虚拟机100%的情况下是会稍微多挖一点的,这些挖过来而又没有用上的内存,实际上就是 freeMemory(),所以freeMemory()的值一般情况下都是很小的,但是如果你在运行java程序的时候使用了-Xms,这个时候因为程 序在启动的时候就会无条件的从操作系统中挖-Xms后面定义的内存数,这个时候,挖过来的内存可能大部分没用上,所以这个时候freeMemory()可 能会有些大。rnrnrn下面我们来看看例子:rnrn Runtime rt = Runtime.getRuntime();rn rn info("Max memory: " + rt.maxMemory());rn long fisrt = rt.freeMemory();rn info("Total memory: " + rt.totalMemory());rn info("Free memory: " + fisrt);rn rn int size = 10000;rn rn byte[] b = new byte[size];rn long bL = rt.freeMemory();rn info("Free memory: " + bL);rn info("byte allocate Cost memory: " + (fisrt - bL) + ", Array size :" + size);rnrn 运行参数为 -Xms8m -Xmx32m (太大了可能看不出来),运行结果为:rn2011-02-22 10:28:01: Max memory: 33357824rn2011-02-22 10:28:01: Total memory: 8323072rn2011-02-22 10:28:01: Free memory: 7791752rn2011-02-22 10:28:01: Free memory: 7781736rn2011-02-22 10:28:01: byte allocate Cost memory: 10016, Array size :10000rnrn 33357824 <> 32*1025*1024(大约等于)rnrn 8323072 <> 8×1024×1024rnrn 最后看看10000长度的byte数组,分配了多少内存,大约为10016,这说明除了10000个大小为1字节的byte以外,还有16个字节其他的玩意。rnrn将byte换成int(4字节):rn2011-02-22 10:35:21: int allocate Cost memory: 40016, Array size :10000rn 与byte相同,也是4*10000+16rnrn将byte换成long(8字节):rn2011-02-22 10:32:47: long allocate Cost memory: 80016, Array size :10000rn与byte相同,也是8*10000+16rnrn再看看String数组:rn2011-02-22 10:34:40: String allocate Cost memory: 40016, Array size :10000rnString作为一个对象,分配的内存大小与int相同,说明了这台机器是32(4*8)位的rnrnrn最后看看Object对象,rn2011-02-22 10:37:02: Object allocate Cost memory: 40016, Array size :10000rn与String一样。rnrnrn2,第二类内存,我了解的主要是PermGen space,全称是Permanent Generation space,是指内存的永久保存区域,这块内存主要是被JVM存放Class和Meta信息的,Class在被Loader时就会被放到PermGen space中,它和存放类实例(Instance)的Heap区域不同,SUN的JDK在GC(Garbage Collection)不会在主程序运行期对PermGen space进行清理,所以如果你的应用中有很CLASS的话,就很可能出现PermGen space错误。rnrn 原来SUN 的JVM把内存分了不同的区,其中一个就是permenter区用来存放用得非常多的类和类描述。本来SUN设计的时候认为这个区域在JVM启动的时候就固定了,但他没有想到现在动态会用得这么广泛。而且这个区域有特殊的垃圾收回机制,现在的问题是动态加载类到这个区域后,gc根本没办法回收。rn rn Permgen space的参数为-XX:PermSize=128M -XX:MaxPermSize=512mrnrn 论坛

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