• #if 和#ifdef的区别

    2015-12-04 10:55:26
    今天也碰到这个问题,使用#ifdef xxx 想选择编译一段代码,最后发现#ifdef 并不判断条件真假,只看是否前面有define,...参加华为的面试,竟然才发现#if 和#ifdef是有区别的,绝得无地自容。赶紧整理一下  先看个例

    今天也碰到这个问题,使用#ifdef xxx 想选择编译一段代码,最后发现#ifdef 并不判断条件真假,只看是否前面有define,下面转自 

    http://blog.csdn.net/zhangchiytu/article/details/7563329



    参加华为的面试,竟然才发现#if 和#ifdef是有区别的,绝得无地自容。赶紧整理一下

       先看个例子:

    #define TARGET_LITTLE_ENDINA 1
    #define TARGET_BIG_ENDINA   0

    #ifdef TARGET_LITTLE_ENDINA
    call little endina function
    #else
    call big endina function
    #endif
    不管把TARGET_LITTLE_ENDINATARGET_BIG_ENDINA定义成0或者1,甚至后面不写这个0或者1 ,调用的都是little endina函数,这段代码是有问题的,就是没有理解#if和#ifdef之间的区别。

    #if的使用说明

    #if的后面接的是表达式,如果表达式为1,则编译#if下面的代码

    #if (MAX==10)||(MAX==20)
     code...
    #endif
    

    它的作用是:如果(MAX==10)||(MAX==20)成立,那么编译器就会把其中的#if 与 #endif之间的代码编译进去(注意:是编译进去,不是执行!!)


    #ifdef的使用

    #if后面接的是一个

    #ifdef (x)
        ...code...
    #endif
    

    这个#ifdef 它不管里面的“x”的逻辑是“真”还是“假”,它只管这个程序前面的宏定义里面有没有定义“x”这个宏(即在这里#define  x 1和#define  x 0等效,都等同于#define x),如果定义了x这个宏,那么编译器会编译中间的…code…否则直接忽视中间的…code…代码。

    #if defined的使用

    #if defined() 的使用和#ifdef的用法一致
    #if !defined()又和 #ifndef 的用法一致。

    最后强调两点:
    第一:这几个宏定义只是决定代码块是否被编译!
    第二:别忘了#endif

    展开全文
  • #if#ifdef#define等宏定义使用

    吐槽:为了提前适配iOS 11,在xcode9 beta版使用过程中,有时候xcode9 beta看图层一点击就卡死啊,还得强退才行;playground全局搜索代码有时候失效啊;打包啊….��都得换回xcode8才行。。。
    最近碰到了个代码执行问题,iOS 11中一些新的API在xdode8中报错,每次切换xcode时,都得去注释掉这段代码,麻烦死了。怎么让一段代码在xcode8和9都能顺利编译不报错,可用宏做如下设置:

    #import "UIScrollView+SFScrollView.h”
    
    @implementation UIScrollView (SFScrollView)
    
    - (void)neverAdjustmentContentInset{
    #ifdef __IPHONE_11_0
        if (@available(iOS 11.0, *) ) {
            self.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
        }
    #endif
    }
    
    @end
    //> scrollview的分类中添加的方法,是iOS 11才有的。而宏__IPHONE_11_0,也是iOS 11才有的,故用#ifdef __IPHONE_11_0即可完美解决,
    整理一下,方便使用:

    预处理就是在进行编译的第一遍词法扫描和语法分析之前所作的工作。说白了,就是对源文件进行编译前,先对预处理部分进行处理,然后对处理后的代码进行编译。这样做的好处是,经过处理后的代码,将会变的很精短。

    #define  定义一个预处理宏
    #undef   取消宏的定义
    #if      编译预处理中的条件命令, 相当于C语法中的if语句
    #ifdef   判断某个宏是否被定义(#define过), 若已定义, 执行随后的语句
    #ifndef  与#ifdef相反, 判断某个宏是否未被定义
    #elif    若#if, #ifdef, #ifndef或前面的#elif条件不满足, 则执行#elif之后的语句, 相当于C语法中的else-ifelse    与#if, #ifdef, #ifndef对应, 若这些条件不满足, 则执行#else之后的语句, 相当于C语法中的else
    #endif   #if, #ifdef, #ifndef这些条件命令的结束标志.
    defined   与#if, #elif配合使用, 判断某个宏是否被定义
    #pragma  说明编译器信息
    #warning 显示编译警告信息
    #error   显示编译错误信息
    配置DEBUG宏:
    1.在 "Target > Build Settings > Preprocessor Macros > Debug" 设置"DEBUG=1”。
    
    2.之后在pch或工具类中就可以这么写了:
    #ifdef DEBUG  
    (debug 模式下的配置)
    #else  
    (release 模式下的配置)
    #endif 
    
    #ifdef DEBUG // 调试状态, 打开LOG功能
    
    #define SFString [NSString stringWithFormat:@"%s", __FILE__].lastPathComponent
    //打印出所在文件名,所在行,堆栈地址
    #define SFLog(...) printf("%s: %p (line = %d): %s\n\n", [SFString UTF8String] , &self, __LINE__, [[NSString stringWithFormat:__VA_ARGS__] UTF8String]);
    
    //#else
    //#define SFLog(s, ...) NSLog(@"<%@: %p (line = %d)> %@", self.class, self, __LINE__,[NSString stringWithFormat:(s),##__VA_ARGS__])
    //#endif
    
    #else // 发布状态, 关闭LOG功能
    #define SFLog(s, ...)
    #endif
    
    系统宏介绍:
    
     __LINE__:宏在预编译时会替换成当前的行号
    
     __FUNCTION__:宏在预编译时会替换成当前的函数名称
    
    __VA_ARGS__:简单的说,就是将左边…的内容替换进来

    #####详解#ifdef,#elif,#else,#endif,#if等:

    1:
      #ifdef _XXXX  (ifdef 即 if define )
      ...程序段1...
       #elif defined _YYYY
       ...程序段3...(相当于else if)
      #else
      ...程序段2...
      #endif
       
    >这表明如果_XXXX已被#define定义过,则对程序段1进行编译;再如果定义了_YYYY,执行程序段3,否则对程序段2进行编译。
    
      例: 
      #define NUM
      .............
    
      #ifdef NUM
       printf("之前NUM有过定义啦!:) \n");
      #else
       printf("之前NUM没有过定义!:( \n");
      #endif
    
    >如果程序开头有#define NUM这行,即NUM有定义,碰到下面#ifdef NUM的时候,当然执行第一个printf。否则第二个printf将被执行。
       我认为,用这种,可以很方便的开启/关闭整个程序的某项特定功能。
    2: 
      #ifndef _XXXX 
      ...程序段1... 
      #else 
      ...程序段2... 
      #endif
    
    >这里使用了#ifndef,表示的是if not def。和#ifdef相反的状况(如果没有定义了标识符_XXXX,那么执行程序段1,否则执行程序段2)
    3:
      #if 常量 
      ...程序段1...
      #else
      ...程序段2...
      #endif 
      
     >注意:#if后必须跟常量,不能是宏(因为宏是在运行阶段才有,#if是预编译阶段,找不到宏);
      如果常量为真(非0,随便什么数字,只要不是0),就执行程序段1,否则执行程序段2。
     我认为,这种方法可以将测试代码加进来。当需要开启测试的时候,只要将常量变1就好了。而不要测试的时候,只要将常量变0
    常用示例:

    1.判断当前app所支持的最大最小iOS版本

    #ifdef __IPHONE_OS_VERSION_MAX_ALLOWED // 当前软件支持的最大ios版本
    #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 90000  
          NSLog(@"当前app支持的最大版本,%d",__IPHONE_OS_VERSION_MAX_ALLOWED);
    #else
          NSLog(@"当前app支持的最大版本,%d",__IPHONE_OS_VERSION_MAX_ALLOWED);
    #endif
    #endif
    
    #ifdef __IPHONE_OS_VERSION_MIN_REQUIRED // 当前软件支持的最小ios版本
    #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80400
          NSLog(@"当前app支持的最小版本,%d",__IPHONE_OS_VERSION_MIN_REQUIRED);
    #else
         NSLog(@"当前app支持的最小版本,%d",__IPHONE_OS_VERSION_MIN_REQUIRED);
    #endif
    #endif

    2.判断真机/模拟器

    #if TARGET_OS_IOS
        NSLog(@"真机测试");
    #endif
    
    #if TARGET_IPHONE_SIMULATOR
        NSLog(@"模拟器");
    #endif

    3.获得当前设备的iOS版本

    #define kIOSVersion  [[UIDevice currentDevice].systemVersion doubleValue]

    4.字体(带参数的宏)

    #define SFSystemFont(FONTSIZE) [UIFont systemFontOfSize:FONTSIZE]

    5.weak strong (RAC写法)

    // weak self
    #ifndef weakify
    #if DEBUG
    #if __has_feature(objc_arc)
    #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object;
    #else
    #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object;
    #endif
    #else
    #if __has_feature(objc_arc)
    #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object;
    #else
    #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object;
    #endif
    #endif
    #endif
    
    // strong self
    #ifndef strongify
    #if DEBUG
    #if __has_feature(objc_arc)
    #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object;
    #else
    #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object;
    #endif
    #else
    #if __has_feature(objc_arc)
    #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object;
    #else
    #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object;
    #endif
    #endif
    #endif

    6.去警告

    #define SuppressPerformSelectorLeakWarning(Stuff) \
    do { \
    _Pragma("clang diagnostic push") \
    _Pragma("clang diagnostic ignored \"-Warc-performSelector-leaks\"") \
    Stuff; \
    _Pragma("clang diagnostic pop") \
    } while (0)

    7.GCD Block

    #define GCDBlock(block) dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), block)
    #define GCDMainBlock(block) dispatch_async(dispatch_get_main_queue(),block)
    #define CGDMainBack GCDMainBlock(^(){})

    8……很多很多………

    原写于简书

    展开全文
  • #ifdef IOS #if defined(_DEBUG) || defined(DEBUG) #define DLog(...) NSLog(__VA_ARGS__) #else #define DLog(...) #endif #endif //end IOS #ifdef win32 #if defined(_DEBU

    #ifdef IOS

    #if defined(_DEBUG) || defined(DEBUG)

    #define DLog(...)                       NSLog(__VA_ARGS__)

    #else

    #define DLog(...)

    #endif

    #endif   //end IOS


    #ifdef win32

    #if defined(_DEBUG) || defined(DEBUG)

    #define DLog(format, ...)               fprintf(stdout,format "\n", ##__VA_ARGS__)

    #else

    #define DLog(format, ...)

    #endif

    #endif  //end win32


    #ifdef Android

    #if defined(_DEBUG) || defined(DEBUG)

    #include <android/log.h>

    #define LOGI(...) __android_log_print(ANDROID_LOG_INFO,  LOG_TAG, __VA_ARGS__)

    #else

    #define LOGI(...)

    #endif

    #endif  //end Android


    IOS打印当前类名和函数名

     DLog(@" 类名:%@   函数名:%@",NSStringFromClass([self class]),NSStringFromSelector(_cmd));

    展开全文
  • 今天就由本菜鸟给大家做一个简单的IOSApp消息推送教程吧!一切从0开始,包括XCode6, IOS8, 以及苹果开发者中心最新如何注册应用,申请证书以及下载配置概要文件,相信很多刚开始接触ios的人会很想了解一下。(ps:...

    好久没有写过博客啦,今天就由本菜鸟给大家做一个简单的IOSApp消息推送教程吧!一切从0开始,包括XCode6, IOS8, 以及苹果开发者中心最新如何注册应用,申请证书以及下载配置概要文件,相信很多刚开始接触ios的人会很想了解一下。(ps:网上看了一下虽然有很多讲述推送的好教程,我也是看着一步步学会的,但是这些教程的时间都是去年或者更早时期的,对引导新手来说不是很合适

    第一部分

    首先第一步当然是介绍一下苹果的推送机制(APNS)咯(ps:其实每一篇教程都有),先来看一张苹果官方对其推送做出解释的概要图。

    Provider是给你手机应用发出推送消息的服务器,而APNS(Apple Push Notification Service)则是苹果消息推送服务器。你本地的服务器当需要给应用推送一条消息的时候,先要将消息发出到苹果推送服务器,然后再由苹果推送服务器将消息发到安装了该应用的手机。

    接下来再看一张解释图:


    根据上图的逻辑我来给大家解释一下:

    1.你的IOS应用需要去注册APNS消息推送功能。

    2.当苹果APNS推送服收到来自你应用的注册消息就会返回一串device token给你(很重要)

    3.将应用收到的device Token传给你本地的Push服务器。

    4.当你需要为应用推送消息的时候,你本地的推送服务器会将消息,以及Device Token打包发送到苹果的APNS服

    5.APNS再将消息推送给目的iphone


    第二部分

    1.从证书颁发机构颁发证书

    打开你mac的钥匙串访问: 然后点击钥匙串访问


    随后它会弹出一个窗口用户电子邮件信息就填写你苹果开发者账号的名称即可(应该是一个邮件名称),点击保存到磁盘的选

    项,点击继续,显示如下:



    点击存储,文件名为:CertificateSigningRequest.certSigningRequest 随后将他放在一个文件夹中我们取名push吧!


    第三部分

    访问苹果开发者网址:https://developer.apple.com/


    选中MemberCenter选项,进入登陆页面,用你的苹果开发者账号登陆,过一会网页就会自动跳转到下图。

    点击红色所选部分内容进行下一步的操作。


    选择Certificates选项,设置证书,如图所示先解释一下:

     


    Development选项的作用顾名思义就是用来作为开发使用的证书,Production选项则是用来发布产品使用的,名称很陌生是不是,之

    前的开发者网页是没有这一选项的,可能是苹果把他修改了,用这个名称更加能让人理解吧(字面上解释就是产品么)。两个选项生

    成证书的步骤是一样的,现在我们使用开发者的选项进行证书的制作,步骤如下:选择Development选项:



    点击上面的加号选项,



    选择APNS选项(开发么当然是在沙盒环境下了,模拟真实情况),然后Continue



    这个AppID我们在下一部分讲如何生成,现在我用的是已经生成好的一个应用ID,继续Continue



    这边就要选择在钥匙串访问环节下载下来的CertificateSigningRequest.certSigningRequest文件了,选择并生成:


    点击下载,得到aps_development .cer,保存到push文件中去。


    第四部分

    新建一个AppID,选择网页上的AppIDs,然后点击右上角的 “加号



    App的取名只要按照苹果要求的就可以了



    然后BundleID是比较重要的,在提交审核以及测试(苹果的TestFlight)和付费环节都需要用到,也只需按照苹果要求来写就好了。



    接下来就是对你的应用需要使用苹果的哪些服务进行选择就行了,例如广告,游戏中心,推送,付费等等情况。


    最后选择“Submit”选项,在下一个界面中选择“done”选项,这样我们设置AppID的步骤我们就完成了。


    第五部分:生成Provisioning Profiles

    这个配置概要文件分为两种,一种是为开发使用的,还有一种则是为发布到appStore上面。


    创建发布版的ProvisioningProfile与开发版的流程相同,点击Development然后点击右上角的加号


    会进入选择何种配置概要文件的界面:



    我们现在时测试,所以选择“IOS App Development”的选项,在下面的Distribution发布选项中有两个选择,“App Store”以及

    “Ad hoc”,你可以根据下面的描述选择你发布所需的选项。点击Continue进入下一步。


    选择你上一步创建的AppID,点击Continue 进行下一步


    选择你的开发者账号,Continue进行下一步


    在这一步上选择你的设备(你只有在这一步上勾选了你的设备,你才能在设备上用这个签名进行调试)。关于如何将你的设备号添加

    进去也是非常简单的,选择左侧的"Devices",然后点击右上角的加号,在随后出来的页面上添加你设备的UUID(在XCode中可以查

    看到)以及name( 可以随便取,自己看的懂就行)然后Register一下,照着流程走到最后一步就完成了。

    好咱们继续回到上面的Provisioning Profile配置环节,当你选好了你的设备后点击“Continue”进入下一页,



    输入一个文件名(最好是起的能看懂是干嘛的,当然也可以随便起),点击“Generate”进入下一个页面,在这个页面中就会有一个下

    载按钮让你下载这个文件,我们把它下载下来放在Push文件夹中。


    第六部分

    好了,前期的准备工作都已经做完了,现在让我们开始推送吧!(吼吼)

    首先双击我们生成的 “aps_development .cer” 文件,进入钥匙串访问,找到我们的专用秘钥(根据在第二部分中从证书机构颁发证书操作中填写的常用名



    我在第二部分填写的是“silicon”,由于换了一台mac之前安装的没有了,之前没有截图,所以随便找了个图给大家看一下,凭大家的聪明才智应该不难理解吧。

    然后右击导出,会弹出如下所示的图。



    将他存储到push文件夹中,命名为“push.p12”,在这一步中导出会让你输入密码并验证,你可以自定义一个密码,例如abc123

    现在push文件夹中应该有几个文件“aps_development .cer” ,"push.p12",“CertificateSigningRequest.certSigningRequest”以及

    刚才下下来的配置概要文件。


    接下来我们打开终端将他们生成.pem文件

    1.把aps_development .cer文件生成.pcm文件,cd到push文件夹下



    2.把push.p12文件生成为.pem文件


    上边输入的密码则是你导出证书所设的密码,即abc123.接着还会让你输入.pem文件的密码,还是使用abc123好了,防止混淆。

    这样我们在push文件夹中就又得到了两个文件,PushChatCert.pem和PushChatKey.pem。


    3.把PushChatCert.pem和PushChatKey.pem合并为一个pem文件,



    在push文件夹中又多了一个ck.pem文件,以上我们把需要使用的文件都准备好了


    接下来就要测试一下啦,是不是很激动~

    为了测试证书工作的状况,我们可以使用“telnet gateway.sandbox.push.apple.com 2195”来检测一下,如果显示下图则表示成功了。



    然后,我们使用我们生成的证书和私钥来设置一个安全的链接去链接苹果服务器

    在终端输入如下命令:openssl s_client -connect gateway.sandbox.push.apple.com:2195 -cert PushChatCert.pem -key PushChatKey.pem

    需要输入密码(abc123 我们刚才所设置的)。

    然后他会返回一系列的数据,这里我就粘贴一部分啦:


    CONNECTED(00000003)

    depth=1 /C=US/O=Entrust, Inc./OU=www.entrust.net/rpa is incorporated by reference/OU=(c) 2009 Entrust, Inc./CN=Entrust Certification Authority - L1C

    verify error:num=20:unable to get local issuer certificate

    verify return:0

    ---

    Certificate chain

    。。。。。(省略)

    。。。。。(省略)

    。。。。。(省略)

        Start Time: 1416389389

        Timeout   : 300 (sec)

        Verify return code: 0 (ok)

    ---

    测试就到这里啦。。。


    第七部分

    1.建立推送项目

    //
    //  AppDelegate.m
    //  TestPushNotifiy
    //
    //  Created by silicon on 14-10-30.
    //  Copyright (c) 2014年 silicon. All rights reserved.
    //
    
    #import "AppDelegate.h"
    
    @implementation AppDelegate
    @synthesize mainView = _mainView;
    
    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
        {
            //IOS8
            //创建UIUserNotificationSettings,并设置消息的显示类类型
            UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];
            
            [application registerUserNotificationSettings:notiSettings];
            
        } else{ // ios7
            [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge										 |UIRemoteNotificationTypeSound										 |UIRemoteNotificationTypeAlert)];
        }
        
        self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
        // Override point for customization after application launch.
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        
        self.mainView = [[MainViewController alloc] initWithNibName:@"MainViewController" bundle:nil];
        self.window.rootViewController = self.mainView;
        return YES;
    }
    
    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken{
        NSLog(@"---Token--%@", pToken);
    }
    
    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
        
        NSLog(@"userInfo == %@",userInfo);
        NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"];
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        
        [alert show];
    }
    
    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    
        NSLog(@"Regist fail%@",error);
    }
    
    - (void)applicationWillResignActive:(UIApplication *)application
    {
        // 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 throttle down OpenGL ES frame rates. Games should use this method to pause the game.
    }
    
    - (void)applicationDidEnterBackground:(UIApplication *)application
    {
        // 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.
    }
    
    - (void)applicationWillEnterForeground:(UIApplication *)application
    {
        // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
    }
    
    - (void)applicationDidBecomeActive:(UIApplication *)application
    {
        // 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.
    }
    
    - (void)applicationWillTerminate:(UIApplication *)application
    {
        // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
    }
    
    @end
    

    在appdelegate.m中加入以上代码,

    if ([application respondsToSelector:@selector(isRegisteredForRemoteNotifications)])
        {
            //IOS8
            //创建UIUserNotificationSettings,并设置消息的显示类类型
            UIUserNotificationSettings *notiSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIRemoteNotificationTypeSound) categories:nil];
            
            [application registerUserNotificationSettings:notiSettings];
            
        } else{ // ios7
            [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge										 |UIRemoteNotificationTypeSound										 |UIRemoteNotificationTypeAlert)];
        }

    由于ios8的推送跟ios7及以下的不一样,所以需要加判断来注册消息推送。

    函数:

    - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)pToken{
        NSLog(@"---Token--%@", pToken);
    }


    会接收来自苹果服务器给你返回的deviceToken,然后你需要将它添加到你本地的推送服务器上。(很重要,决定你的设备能不能接收到推送消息)。

    - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo{
        
        NSLog(@"userInfo == %@",userInfo);
        NSString *message = [[userInfo objectForKey:@"aps"]objectForKey:@"alert"];
        
        UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:message delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"确定", nil];
        
        [alert show];
    }

    这个函数则是当设备接收到来自苹果推送服务器的消息时触发的,用来显示推送消息。

    - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error{
    
        NSLog(@"Regist fail%@",error);
    }

    当注册失败时,触发此函数。



    2.PHP服务端

    将simplepush.php这个推送脚本也放在push文件夹中

    <?php
    
    // ??????????deviceToken???????????????
    $deviceToken = 'c95f661371b085e2517b4c12cc76293522775e5fd9bb1dea17dd80fe85583b41';
    
    // Put your private key's passphrase here:
    $passphrase = 'abc123';
    
    // Put your alert message here:
    $message = 'My first push test!';
    
    ////////////////////////////////////////////////////////////////////////////////
    
    $ctx = stream_context_create();
    stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
    stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
    
    // Open a connection to the APNS server
    //??????????
     //$fp = stream_socket_client(?ssl://gateway.push.apple.com:2195?, $err, $errstr, 60, //STREAM_CLIENT_CONNECT, $ctx);
    //?????????????appstore??????
    $fp = stream_socket_client(
    'ssl://gateway.sandbox.push.apple.com:2195', $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
    
    if (!$fp)
    exit("Failed to connect: $err $errstr" . PHP_EOL);
    
    echo 'Connected to APNS' . PHP_EOL;
    
    // Create the payload body
    $body['aps'] = array(
    'alert' => $message,
    'sound' => 'default'
    );
    
    // Encode the payload as JSON
    $payload = json_encode($body);
    
    // Build the binary notification
    $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
    
    // Send it to the server
    $result = fwrite($fp, $msg, strlen($msg));
    
    if (!$result)
    echo 'Message not delivered' . PHP_EOL;
    else
    echo 'Message successfully delivered' . PHP_EOL;
    
    // Close the connection to the server
    fclose($fp);
    ?>

    deviceToken填写你接收到的token,passPhrase则填写你的ck.pem设置的密码。

    此刻就是见证奇迹的时候了,使用终端进入到push文件夹,在终端输入 php simplepush.php



    若显示以上提示则表示推送成功了。附上一张成功图。



    推送就到这边吧!

    感谢这篇博客的指导:http://blog.csdn.net/showhilllee/article/details/8631734


    simplepush.php以及XCode工程我会上传到我的资源里去,大家可以去那边下载。有什么不明白的地方大家可以留言或者私信我,我会第一之间回复的~



    大家可以关注我的微信公众号与我互动,相关问题也可以直接用公众号联系我:












    展开全文
  • consider the snippet below: #ifdef AAA && (defined BBB) ... #endif gcc-4.5.2 complains on this line: ...extra tokens at the end of #ifdef directive. #ifdef will only work on one tok

    consider the snippet below:

    #ifdef AAA && (defined BBB)
    ...
    #endif

    gcc-4.5.2 complains on this line:

    extra tokens at the end of #ifdef directive.


    #ifdef will only work on one token. If you want to use more than one then write

    #if defined(AAA) && defined(BBB)

    如上所述,如果你想check多个东西是否定义,用下面这种写法,#ifdef只适用于check one thing。

    展开全文
  • 本文重点关注如何在iOS上扫描周围的iBeacon信号并读取信息,包括beacon设备的UUID,Major,Minor和当前距离。
  • UIImageView是iOS上最基本的图片显示控件,但默认情况下是不支持拖动,放大缩小等功能的。后来在stackoverflow上查找到一种很简单的方法,加上本人自己的理解,步骤整理如下:
  • 原文地址:ios 可变参数(va_list,va_start,va_end) 例如:UIAlertView的init方法中的otherButtonTitles:(NSString *)otherButtonTitles, ...等多个可变参数。 ios实现传递不定长的多个参数的方法是使用...
  • 由于iOS10之后CoreData Stack的更改无法在iOS9的系统中运行,所以我们需要对上一小节中封装的工具类进行系统版本的兼容 iOS9和iOS10中CoreData最本质的区别其实就是管理对象上下文iOS9中NSManagedObjectContext需要...
  • 现在想说的是,在你向pch添加全局的头文件之前,莫忘#ifdef __OBJC__ #end。  这个宏定义的作用是保证只有oc文件可以调用pch里面的头文件,一些非oc语言不能调用,比如.cpp,.mm。如果不加入,那么如果代码中带有....
  • 1、xcode提示的错误如下control may reach end of non-void function2、原因和解决办法函数在类的实现里面没有写返回值,所以提示这个,加上返回值就行了。
  • 在上一节中,本人按照官网上的教程练习了一遍星星游戏,今天,把它编译到IOS设备上。 首先,选择《项目》中的《构建发布》按钮 弹出如下窗口: 选择“发布平台”为IOS,其他选择默认设置就可以,然后点击...
  • iOS攻防 - (三)iOS应用的代码打包前混淆,不影响源代码 出于iOS应用的安全考虑,如:银行类型APP, 金融相关APP, 登录功能,支付功能等; 某些时候,我们需要对iOS应用的重要函数或名称进行混淆,因为即使是...
  • 用Lua编写iOS程序

    2012-10-08 11:39:04
    原文:http://luanova.org/ioswithlua/  本文讨论用Lua创建iOS应用的3种方法。包括用Lua创建完整的应用(Corona)一直到用Lua作为app中的脚本元素(通过Wax或diy)。在此之前,我们需要问自己两个问题:1、为什么要...
  • flutter调用ios 原生View

    2019-07-16 13:08:03
    本文详细描述 flutter 中嵌套使用ios原生组件
  • 一直觉得苹果生态圈很安全,iOS操作系统也很流畅,而且软件有严格的审核机制,软件来源唯一(当然是你不越狱),但是这也为苹果的霸权铺路;上家公司做了一个APP,可以充值虚拟金币,但是如果是虚拟道具,就必须使用...
  • iOS UIRefreshControl使用详解 简介:  UIRefreshControl是iOS6自带的UITableView下拉刷新控件。 iOS6中,UITableViewController已经内置了UIRefreshControl控件。UIRefreshControl目前只能用于...
  • 本地通知 本地通知是由本地应用触发的,它是基于时间行为的一种通知形式,例如闹钟定时、待办事项提醒,又或者一个应用在一段时候后不使用通常会提示用户使用此应用等都是本地通知。创建一个本地通知通常分为以下几...
  • 1.实现效果如图:原图、iOS8效果、Core Image效果、 VImage 效果 - 2. 代码 #import "ViewController.h" #import @interface ViewController () @end @implementation ViewController - (void)viewDidLoad { ...
  • 开发iOS应用,解决Crash问题始终是一个难题。Crash分为两种,一种是由EXC_BAD_ACCESS引起的,原因是访问了不属于本进程的内存地址,有可能是访问已被释放的内存;另一种是未被捕获的Objective-C异常(NSException)...
1 2 3 4 5 ... 20
收藏数 115,045
精华内容 46,018