app开发权限问题 ios
2018-09-16 21:41:00 weixin_33801856 阅读数 5

1、简介

  • iOS中经常会遇到访问相册、相机、麦克疯、蓝牙、以及推送等权限,所以每次我们要使用这些权限是都要记得查看用户是否允许了,如果用户禁止了你的访问权限,你仍然去调取相册或者相机等,那么就会先出现下面的这个提示。而且是英文的,这时候用户可能有些懵逼了,这个时候我们最好给一个提示,用户点击确定后,我们最好贴心的跳转到应用的权限出,让用户一键允许。
    1213778-20180916204349245-1795230608.png
  • 注意:iOS10 中需要在plist文件中添加获取权限声明,否则会崩溃,提示信息如下:
    [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.
    plist中的设置如下图
    1213778-20180916205419149-1767395931.jpg

2、相册权限

  • 2.1 检测照片权限

    typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
        PHAuthorizationStatusNotDetermined = 0,  // 用户尚未做出选择这个应用程序的问候
        PHAuthorizationStatusRestricted,         // 此应用程序没有被授权访问的照片数据。可能是家长控制权限
        PHAuthorizationStatusDenied,             // 用户已经明确否认了权限的访问
        PHAuthorizationStatusAuthorized          // 用户已经授权应用访问照片数据
    } PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);
    
    导入头文件#import<Photos/Photos.h>
    
    // 检查照片权限
    - (void) checkPhotoStauts {
        PHAuthorizationStatus photoAuthorStatus = [PHPhotoLibrary authorizationStatus];
    
        switch (photoAuthorStatus) {
            case PHAuthorizationStatusAuthorized:
                self.photoLibraryStatus = @"PHAuthorizationStatusAuthorized";
                break;
            case PHAuthorizationStatusDenied:
                self.photoLibraryStatus = @"PHAuthorizationStatusDenied";
                break;
            case PHAuthorizationStatusNotDetermined:
                self.photoLibraryStatus = @"PHAuthorizationStatusNotDetermined";
                break;
            case PHAuthorizationStatusRestricted:
                self.photoLibraryStatus = @"PHAuthorizationStatusRestricted";
                break;
            default:
                break;
        }
    }
  • 2.2 获取照片权限

    // 授权照片
    - (void)phontLibraryAction{
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    
        }];
    }

3、相机权限

  • 3.1 检测相机权限

    typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
        AVAuthorizationStatusNotDetermined = 0,    // 请问是否授权访问
        AVAuthorizationStatusRestricted,           // 权限都限制
        AVAuthorizationStatusDenied,               // 拒绝访问
        AVAuthorizationStatusAuthorized            // 授权访问
    } NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
    
    - (void) checkVideoStatus {
    
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
        switch (authStatus) {
            case AVAuthorizationStatusNotDetermined:
                // 没有询问是否开启相机
                self.videoStatus = @"AVAuthorizationStatusNotDetermined";
                break;
            case AVAuthorizationStatusRestricted:
                // 未授权,家长限制
                self.videoStatus = @"AVAuthorizationStatusRestricted";
                break;
            case AVAuthorizationStatusDenied:
                // 未授权
                self.videoStatus = @"AVAuthorizationStatusDenied";
                break;
            case AVAuthorizationStatusAuthorized:
                // 玩家授权
                self.videoStatus = @"AVAuthorizationStatusAuthorized";
                break;
            default:
                break;
        }
    }
  • 3.2 获取相机权限

    // 授权相机
    - (void)videoAuthAction {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            NSLog(@"%@",granted ? @"相机准许":@"相机不准许");
        }];
    }

4、蓝牙权限

  • 4.1 判断是否打开了蓝牙

    • 其实在我们使用蓝牙的时候即创建时就需要遵循CBCentralManagerDelegate这个代理,他有一个代理方法是不停的监控蓝牙状态的变化。
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
        switch (central.state) {
            case CBManagerStateUnknown:
                {
                // 初始的时候是未知的(刚刚创建的时候)
                }
                break;
            case CBManagerStateResetting:
                {
                // 正在重置状态
                }
                break;
            case CBManagerStateUnsupported:
                {
                // 设备不支持的状态
                }
                break;
            case CBManagerStateUnauthorized:
                {
                [stringForCentral appendString:@"Resetting\n"];
                // 设备未授权状态
                }
                break;
            case CBManagerStatePoweredOff:
                {
                //设备关闭状态
                }
                break;
            case CBManagerStatePoweredOn:
                {
                // 设备开启状态 -- 可用状态
                }
                break;
            default:
                {
    
                }
                break;
            }
        }
    }
  • 4.2 获取蓝牙权限

    • 我们可以在不同的状态下做一些事情。当然我们也可以通过CBCentralManager的state方法获取蓝牙的链接状态,还有就是我们创建CBCentralManager系统如果发现蓝牙没有开启会自动弹出一个窗口可以去设置里面打开蓝牙。
      1213778-20180916204429931-1139996638.png
    • 当然如果我们想自己给一个用户提示然后跳转到设置页面也是可以的,iOS10以后打开方式有些区别
    NSString *urlString = @"App-Prefs:root=Bluetooth";
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:urlString]]) {
    
        if (IOS_VERSION>10.0) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString] options:@{} completionHandler:nil];
        } 
        else {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
        }
    }

5、推送权限

  • 5.1 判断用户是否允许推送

    • 其中iOS8以上与iOS8以下有些区别,所以需要进行iOS版本判断。
    #define IOS8 ([[[UIDevice currentDevice] systemVersion] doubleValue] >=8.0 ? YES : NO)
    
    if (IOS8) { // iOS8以上包含iOS8
        if ([[UIApplication sharedApplication] currentUserNotificationSettings].types  ==UIUserNotificationTypeNone) {
            NSLog(@"没有开启");
        }
    } 
    else { // ios7 以下
        if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes]  == UIRemoteNotificationTypeNone) {
            NSLog(@"没有开启");
        }
    }
    typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
        UIUserNotificationTypeNone   = 0,      // 用户禁止了推送
        UIUserNotificationTypeBadge  = 1 << 0, // 用户开启了推送角标
        UIUserNotificationTypeSound  = 1 << 1, // 用户开启了推送提示音
        UIUserNotificationTypeAlert  = 1 << 2, // 用户开启了通知栏提醒
    } NS_ENUM_DEPRECATED_IOS(8_0, 10_0, "Use UserNotifications Framework's UNAuthorizationOptions") __TVOS_PROHIBITED;

6、位置服务权限

  • 6.1 判断位置服务是否被禁用

    if([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
        NSLog(@"没打开");
    }
    locationServicesEnabled这个返回的结果是否设置过位置服务,大概是这个意思,我们第一次访问位置是,系统会给用户一个提示,是否允许app使用位置信息。如果你选择了是或者否,这个值就是YES,kCLAuthorizationStatusDenied代表用户明确拒绝了访问位置信息。
    typedef NS_ENUM(int, CLAuthorizationStatus) {
    kCLAuthorizationStatusNotDetermined = 0, // 定位服务授权状态是用户没有决定是否使用定位服务。
    kCLAuthorizationStatusRestricted,        // 定位服务授权状态是受限制的。可能是由于活动限制定位服务,用户不能改变。这个状态可能不是用户拒绝的定位服务。
    kCLAuthorizationStatusDenied,            // 定位服务授权状态已经被用户明确禁止,或者在设置里的定位服务中关闭。
    kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),// 定位服务授权状态已经被用户允许在任何状态下获取位置信息。包括监测区域、访问区域、或者在有显著的位置变化的时候。
    kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),//定位服务授权状态仅被允许在使用应用程序的时候。
    kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") __TVOS_PROHIBITED __WATCHOS_PROHIBITED = kCLAuthorizationStatusAuthorizedAlways // 这个枚举值已经被废弃了。他相当于kCLAuthorizationStatusAuthorizedAlways这个值。
    };
  • 6.2 跳转到设置页面,让用户设置权限

    • 如果我们需要跳转到设置位置让用户允许权限的方法是
    NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        if (IOS_VERSION>10.0) {
            [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
        } 
        else {
    
            [[UIApplication sharedApplication] openURL:url];
        }
    }

7、麦克风权限

  • 7.1 检测麦克风权限

    // 检查麦克风权限
    - (void) checkAudioStatus {
    
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    
    switch (authStatus) {
        case AVAuthorizationStatusNotDetermined:
            // 没有询问是否开启麦克风
            self.audioStatus = @"AVAuthorizationStatusNotDetermined";
            break;
        case AVAuthorizationStatusRestricted:
            // 未授权,家长限制
            self.audioStatus = @"AVAuthorizationStatusRestricted";
            break;
        case AVAuthorizationStatusDenied:
            // 玩家未授权
            self.audioStatus = @"AVAuthorizationStatusDenied";
            break;
        case AVAuthorizationStatusAuthorized:
            // 玩家授权
            self.audioStatus = @"AVAuthorizationStatusAuthorized";
            break;
        default:
            break;
        }
    }
  • 7.2 获取麦克风权限

    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
        NSLog(@"%@",granted ? @"麦克风准许":@"麦克风不准许");
    }];

转载于:https://www.cnblogs.com/CH520/p/9657433.html

2017-12-21 13:59:00 weixin_34007906 阅读数 12
定位要写清楚用途,例如(为您导航, 到您想去的健身门店。)否则会遭拒绝的在水果商店
定位权限:Privacy - Location When In Use Usage Description         
定位权限: Privacy - Location Always Usage Description                
相机权限:Privacy - Camera Usage Description    是否允许此App使用你的相机?
相册权限: Privacy - Photo Library Usage Description   是否允许此App访问你的媒体资料库?
通讯录权限: Privacy - Contacts Usage Description                           
麦克风权限: Privacy - Microphone Usage Description                      
蓝牙权限: Privacy - Bluetooth Peripheral Usage Description           
日历权限:Privacy - Calendars Usage Description                         
语音转文字权限:Privacy - Speech Recognition Usage Description            
健康数据分享:  Privacy - Health Share Usage Description  
健康数据更新: Privacy - Health Update Usage Description 
运动传感器: Privacy - Motion Usage Description  
音乐:  Privacy - Music Usage Description  
播放音乐或者视频:  Privacy - Media Library Usage Description  
Siri:    Privacy - Siri Usage Description  
智能家具:  Privacy - HomeKit Usage Description  
电视提供商:   Privacy - TV Provider Usage Description  
视频订阅:  Privacy - Video Subscriber Account Usage Description 
备忘录: Privacy - Reminders Usage Description

网络请求的ATS如下:
App Transport Security Settings  (Type:Dictionary)
在添加子项如下:
Allow Arbitrary Loads            (Type:Boolean)设置为YES
2018-09-16 21:41:00 weixin_33862993 阅读数 1

1、简介

  • iOS中经常会遇到访问相册、相机、麦克疯、蓝牙、以及推送等权限,所以每次我们要使用这些权限是都要记得查看用户是否允许了,如果用户禁止了你的访问权限,你仍然去调取相册或者相机等,那么就会先出现下面的这个提示。而且是英文的,这时候用户可能有些懵逼了,这个时候我们最好给一个提示,用户点击确定后,我们最好贴心的跳转到应用的权限出,让用户一键允许。
    1213778-20180916204349245-1795230608.png
  • 注意:iOS10 中需要在plist文件中添加获取权限声明,否则会崩溃,提示信息如下:
    [access] This app has crashed because it attempted to access privacy-sensitive data without a usage description. The app's Info.plist must contain an NSMicrophoneUsageDescription key with a string value explaining to the user how the app uses this data.
    plist中的设置如下图
    1213778-20180916205419149-1767395931.jpg

2、相册权限

  • 2.1 检测照片权限

    typedef NS_ENUM(NSInteger, PHAuthorizationStatus) {
        PHAuthorizationStatusNotDetermined = 0,  // 用户尚未做出选择这个应用程序的问候
        PHAuthorizationStatusRestricted,         // 此应用程序没有被授权访问的照片数据。可能是家长控制权限
        PHAuthorizationStatusDenied,             // 用户已经明确否认了权限的访问
        PHAuthorizationStatusAuthorized          // 用户已经授权应用访问照片数据
    } PHOTOS_AVAILABLE_IOS_TVOS(8_0, 10_0);
    
    导入头文件#import<Photos/Photos.h>
    
    // 检查照片权限
    - (void) checkPhotoStauts {
        PHAuthorizationStatus photoAuthorStatus = [PHPhotoLibrary authorizationStatus];
    
        switch (photoAuthorStatus) {
            case PHAuthorizationStatusAuthorized:
                self.photoLibraryStatus = @"PHAuthorizationStatusAuthorized";
                break;
            case PHAuthorizationStatusDenied:
                self.photoLibraryStatus = @"PHAuthorizationStatusDenied";
                break;
            case PHAuthorizationStatusNotDetermined:
                self.photoLibraryStatus = @"PHAuthorizationStatusNotDetermined";
                break;
            case PHAuthorizationStatusRestricted:
                self.photoLibraryStatus = @"PHAuthorizationStatusRestricted";
                break;
            default:
                break;
        }
    }
  • 2.2 获取照片权限

    // 授权照片
    - (void)phontLibraryAction{
        [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
    
        }];
    }

3、相机权限

  • 3.1 检测相机权限

    typedef NS_ENUM(NSInteger, AVAuthorizationStatus) {
        AVAuthorizationStatusNotDetermined = 0,    // 请问是否授权访问
        AVAuthorizationStatusRestricted,           // 权限都限制
        AVAuthorizationStatusDenied,               // 拒绝访问
        AVAuthorizationStatusAuthorized            // 授权访问
    } NS_AVAILABLE_IOS(7_0) __TVOS_PROHIBITED;
    
    - (void) checkVideoStatus {
    
        AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeVideo];
    
        switch (authStatus) {
            case AVAuthorizationStatusNotDetermined:
                // 没有询问是否开启相机
                self.videoStatus = @"AVAuthorizationStatusNotDetermined";
                break;
            case AVAuthorizationStatusRestricted:
                // 未授权,家长限制
                self.videoStatus = @"AVAuthorizationStatusRestricted";
                break;
            case AVAuthorizationStatusDenied:
                // 未授权
                self.videoStatus = @"AVAuthorizationStatusDenied";
                break;
            case AVAuthorizationStatusAuthorized:
                // 玩家授权
                self.videoStatus = @"AVAuthorizationStatusAuthorized";
                break;
            default:
                break;
        }
    }
  • 3.2 获取相机权限

    // 授权相机
    - (void)videoAuthAction {
        [AVCaptureDevice requestAccessForMediaType:AVMediaTypeVideo completionHandler:^(BOOL granted) {
            NSLog(@"%@",granted ? @"相机准许":@"相机不准许");
        }];
    }

4、蓝牙权限

  • 4.1 判断是否打开了蓝牙

    • 其实在我们使用蓝牙的时候即创建时就需要遵循CBCentralManagerDelegate这个代理,他有一个代理方法是不停的监控蓝牙状态的变化。
    - (void)centralManagerDidUpdateState:(CBCentralManager *)central {
        switch (central.state) {
            case CBManagerStateUnknown:
                {
                // 初始的时候是未知的(刚刚创建的时候)
                }
                break;
            case CBManagerStateResetting:
                {
                // 正在重置状态
                }
                break;
            case CBManagerStateUnsupported:
                {
                // 设备不支持的状态
                }
                break;
            case CBManagerStateUnauthorized:
                {
                [stringForCentral appendString:@"Resetting\n"];
                // 设备未授权状态
                }
                break;
            case CBManagerStatePoweredOff:
                {
                //设备关闭状态
                }
                break;
            case CBManagerStatePoweredOn:
                {
                // 设备开启状态 -- 可用状态
                }
                break;
            default:
                {
    
                }
                break;
            }
        }
    }
  • 4.2 获取蓝牙权限

    • 我们可以在不同的状态下做一些事情。当然我们也可以通过CBCentralManager的state方法获取蓝牙的链接状态,还有就是我们创建CBCentralManager系统如果发现蓝牙没有开启会自动弹出一个窗口可以去设置里面打开蓝牙。
      1213778-20180916204429931-1139996638.png
    • 当然如果我们想自己给一个用户提示然后跳转到设置页面也是可以的,iOS10以后打开方式有些区别
    NSString *urlString = @"App-Prefs:root=Bluetooth";
    if ([[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:urlString]]) {
    
        if (IOS_VERSION>10.0) {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString] options:@{} completionHandler:nil];
        } 
        else {
            [[UIApplication sharedApplication] openURL:[NSURL URLWithString:urlString]];
        }
    }

5、推送权限

  • 5.1 判断用户是否允许推送

    • 其中iOS8以上与iOS8以下有些区别,所以需要进行iOS版本判断。
    #define IOS8 ([[[UIDevice currentDevice] systemVersion] doubleValue] >=8.0 ? YES : NO)
    
    if (IOS8) { // iOS8以上包含iOS8
        if ([[UIApplication sharedApplication] currentUserNotificationSettings].types  ==UIUserNotificationTypeNone) {
            NSLog(@"没有开启");
        }
    } 
    else { // ios7 以下
        if ([[UIApplication sharedApplication] enabledRemoteNotificationTypes]  == UIRemoteNotificationTypeNone) {
            NSLog(@"没有开启");
        }
    }
    typedef NS_OPTIONS(NSUInteger, UIUserNotificationType) {
        UIUserNotificationTypeNone   = 0,      // 用户禁止了推送
        UIUserNotificationTypeBadge  = 1 << 0, // 用户开启了推送角标
        UIUserNotificationTypeSound  = 1 << 1, // 用户开启了推送提示音
        UIUserNotificationTypeAlert  = 1 << 2, // 用户开启了通知栏提醒
    } NS_ENUM_DEPRECATED_IOS(8_0, 10_0, "Use UserNotifications Framework's UNAuthorizationOptions") __TVOS_PROHIBITED;

6、位置服务权限

  • 6.1 判断位置服务是否被禁用

    if([CLLocationManager locationServicesEnabled] && [CLLocationManager authorizationStatus] == kCLAuthorizationStatusDenied) {
        NSLog(@"没打开");
    }
    locationServicesEnabled这个返回的结果是否设置过位置服务,大概是这个意思,我们第一次访问位置是,系统会给用户一个提示,是否允许app使用位置信息。如果你选择了是或者否,这个值就是YES,kCLAuthorizationStatusDenied代表用户明确拒绝了访问位置信息。
    typedef NS_ENUM(int, CLAuthorizationStatus) {
    kCLAuthorizationStatusNotDetermined = 0, // 定位服务授权状态是用户没有决定是否使用定位服务。
    kCLAuthorizationStatusRestricted,        // 定位服务授权状态是受限制的。可能是由于活动限制定位服务,用户不能改变。这个状态可能不是用户拒绝的定位服务。
    kCLAuthorizationStatusDenied,            // 定位服务授权状态已经被用户明确禁止,或者在设置里的定位服务中关闭。
    kCLAuthorizationStatusAuthorizedAlways NS_ENUM_AVAILABLE(10_12, 8_0),// 定位服务授权状态已经被用户允许在任何状态下获取位置信息。包括监测区域、访问区域、或者在有显著的位置变化的时候。
    kCLAuthorizationStatusAuthorizedWhenInUse NS_ENUM_AVAILABLE(NA, 8_0),//定位服务授权状态仅被允许在使用应用程序的时候。
    kCLAuthorizationStatusAuthorized NS_ENUM_DEPRECATED(10_6, NA, 2_0, 8_0, "Use kCLAuthorizationStatusAuthorizedAlways") __TVOS_PROHIBITED __WATCHOS_PROHIBITED = kCLAuthorizationStatusAuthorizedAlways // 这个枚举值已经被废弃了。他相当于kCLAuthorizationStatusAuthorizedAlways这个值。
    };
  • 6.2 跳转到设置页面,让用户设置权限

    • 如果我们需要跳转到设置位置让用户允许权限的方法是
    NSURL * url = [NSURL URLWithString:UIApplicationOpenSettingsURLString];
    if ([[UIApplication sharedApplication] canOpenURL:url]) {
        if (IOS_VERSION>10.0) {
            [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:nil];
        } 
        else {
    
            [[UIApplication sharedApplication] openURL:url];
        }
    }

7、麦克风权限

  • 7.1 检测麦克风权限

    // 检查麦克风权限
    - (void) checkAudioStatus {
    
    AVAuthorizationStatus authStatus = [AVCaptureDevice authorizationStatusForMediaType:AVMediaTypeAudio];
    
    switch (authStatus) {
        case AVAuthorizationStatusNotDetermined:
            // 没有询问是否开启麦克风
            self.audioStatus = @"AVAuthorizationStatusNotDetermined";
            break;
        case AVAuthorizationStatusRestricted:
            // 未授权,家长限制
            self.audioStatus = @"AVAuthorizationStatusRestricted";
            break;
        case AVAuthorizationStatusDenied:
            // 玩家未授权
            self.audioStatus = @"AVAuthorizationStatusDenied";
            break;
        case AVAuthorizationStatusAuthorized:
            // 玩家授权
            self.audioStatus = @"AVAuthorizationStatusAuthorized";
            break;
        default:
            break;
        }
    }
  • 7.2 获取麦克风权限

    [AVCaptureDevice requestAccessForMediaType:AVMediaTypeAudio completionHandler:^(BOOL granted) {
        NSLog(@"%@",granted ? @"麦克风准许":@"麦克风不准许");
    }];

转载于:https://www.cnblogs.com/CH520/p/9657433.html

2018-09-07 15:56:07 DAXIAOJIEWW 阅读数 269

苹果APP开发技术支持

  • iOS program design & system consultation
  • if you have any question, please contact me with no hesitate
  • Email: 917991064@qq.com
  • 联系人:薇薇
  • iOS应用系统设计、支撑与咨询服务
  • Add: 2B05 of Fudan Software Park, Baoshan District, Shanghai, China
2019-03-02 15:24:59 u010401391 阅读数 278

20180505添加:
1、购买
先在商城里购买,点击付款(不用付款成功),然后打开数据库GameUserDB--UserRechargeOrder,根据账号ID查找OrderID,然后在数据库点击可编程性-存储过程-dbo.GSP_GP_UserMallBuyResult--执行
sql语句为:
SELECT TOP 1000 [ID]
      ,[UserID]
      ,[productID]
      ,[OrderID]
      ,[ProductName]
      ,[ProductPrice]
      ,[RechargeDate]
      ,[States]
      ,[RechargeWay]
      ,[TotalScore]
      ,[ProductNameAdd]
      ,[HotFlag]
      ,[HookDate]
  FROM [QPGameUserDB].[dbo].[UserRechargeOrder] where userid=3295766
  exec [QPGameUserDB].[dbo].GSP_GP_UserMallBuyResult '9120180505000001'

http://www.cnblogs.com/pengyingh/articles/2536828.html
我把整个过程叫做三方协定,也叫四次握手.
1、由客户端APP发出购买请求,这里要求要向服务器,苹果APP STORE同时发送购买请求.
1.1手机请求付费,服务器返回许可编号;
服务端接收到请求之后,在数据库log_Purcharse中新增一条记录,并将新增记录的ID返回给客户端.(log_Purcharse表的设计见后文)
1.2手机请求付费,苹果返回验证字符串,开始扣费;
苹果APP STORE接收到请求之后,进行扣费,返回一个付费成功详细信息,或者失败信息.
以上我们称之为一次和第二次握手
如果苹果APP STORE返回付费失败,则客户端终止购买流程.
如果苹果APP STORE返回付费成功,则将第一次服务端返回的ID和苹果返回的付费详情字符串一同发送给服务端.
这里是第三次握手开始.
3、发送许可编号+验证字符串给服务器
服务端接收到ID和付费详情字符串,首先到数据库中检索ID是否合法(检验方法详见后文),ID不合法则返回给客户端失败,客户端终止购买流程,ID合法则将付费详情字符串发送给苹果APP STORE进行验证.
4、服务器将验证字符串发送给苹果,验证付费是否成功
苹果APP STORE验证付费字符串之后会返回给服务端一个付费验证成功码(0表示成功),或者失败码(很多情况,各有其含义).
这里称作第四次握手.
服务端检测苹果APP STORE返回的成败信息,更新表log_Purcharse对应ID下面的数值.
返回给客户端成功/失败信息,成功客户端增加购买物品,失败客户端终止购买流程.
此处算是第三次握手的结束.
附一:log_Purcharse表结构设计与简单解析:
Id 自增主键,自增主键是一次握手时客户端请求时添加的主键,也就是将此键值返回给客户端.三次握手的时候也将根据此值来定位购买信息
UserId 付费用户ID,用于三次握手时的验证条件之一
GoodsId 购买物品ID
IAPState 苹果返回状态,三次握手的时候将更新此值,以便记录苹果的具体返回情况,方便核对,为后期客服服务提供依据.
ServerState DEFAULT ’0′ 是否付费成功,0未验证,1成功,2不成功
Money 充值钱数
PayTime 付费请求时间,一次握手更新此值
DateTime 付费成功时间,四次握手成功更新此值
附二:检索ID是否合法的方法:
根据ID,检索数据库中对应的字段,此时需要验证UserId是否与发出请求的UserId一致,检测ServerState是否仍处于未验证状态,IAPState是否为未返回状态,如果这几项都符合验证,表明付费成功,给客户端返回成功,增加购买物品.

//充值 - iPhone
#define SUB_GP_APPLY_PAY_IP    600// apple应用内购买完成,向服务器申请充值
#define SUB_GP_PAY_REVE_IP    601// 申请充值后,服务器返回的数据
// apple应用内购买完成,向服务器申请充值
typedef struct
{
DWORD    dwUserID;// 用户ID
LONGLONG    lPayMoney;// 充值金额 (为人民币,不是游戏豆豆)
BYTE    cbPhoneMode;// 系统  1:Android  2:iPhone
TCHART    szPayDesc[128];// 验证字符串
} CMD_GP_ApplyPayIP;

// 申请充值后,服务器返回的数据
typedef struct
{
DWORD    dwUserID;// 用户ID
TCHART    szDesc[128];// 返回客户端描述
} CMD_GP_PayDescIP;

 //////////////////////////////////////////////////////////////////////////////////////////////
//case SUB_GP_PAY_REVE_IP:             // apple应用内购买完成,向服务器申请充值,服务器返回的结果  601
//{
////return [self OnSocketGetIapResult:buffer bufferSize:size];
//}

//////////////////////////////////////////////////////////////////////////////////////////////
//OC中去除了私有方法的语法,但是大家约定在.m文件中实现而不在.h文件中声明的方法称之为私有方法,调用私有方法使用perform调用。
// apple应用内购买完成,向服务器申请充值,服务器返回的结果。

-(bool)OnSocketGetIapResult:(void*)buffer bufferSize:(WORD)size

{

    CMD_GP_PayDescIP descip;
    memcpy(&descip, buffer, size);

    NSString* descipText = [NSString CreateStringWithTHCAR:descip.szDesc size:sizeof(descip.szDesc)];
    NSLog(@"OnSocketGetIapResult dwUserID =%ld, descipText = %@", descip.dwUserID, descipText);

    // 购买成功提示
    // 删除动画
    [[CFramePlaza shareFramePlaza] deleteFrameSpinnerView];

//    所有的充值提示修改为:
//    你花费¥XXX购买了会员服务。
//    赠送XXX游戏豆
    UIAlertView* alert=[[[UIAlertView alloc] initWithTitle:@"提示" message:descipText delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil] autorelease];
    [alert show];

    // 些处增加银行查询功能,这样可以刷新充值后的哈皮豆数据
    [self sendPacketWithStrongboxInfo];

    return true;
}


20180508添加:
//原生iOS App之oc代码:
以-开头的是实例方法,以+开头的是类方法
FrameDate.h
FrameDate.m

 

case SUB_MB_LOGON_FAILURE:// 101
{
return [self OnSocketSubLogonFailure:buffer size:size];
}

 

//大厅登录失败
-(bool)OnSocketSubLogonFailure:(void*)buffer size:(WORD)size;

 

//大厅登录失败
-(bool) OnSocketSubLogonFailure:(void*)buffer size:(WORD)size
{
CMD_MB_LogonFailure* failuer=(CMD_MB_LogonFailure*)buffer;
NSString* str =[NSString CreateStringWithTHCAR:failuer->szDescribeString size:sizeof(failuer->szDescribeString)];
UIAlertView *alert = [[[UIAlertView alloc] initWithTitle:@"提示" message:str delegate:m_pPlaza cancelButtonTitle:@"确定" otherButtonTitles:nil] autorelease];
alert.tag=ALERT_LOAD_TIPS;
[alert show];
return true;
}

 

 

 

//HPKJ框架之C++代码
//大厅登录失败
//bool MsgDispatch::OnSocketSubLogonFailure(void *buffer, WORD size)
//{
//CCLOG("OnSocketSubLogonFailure");
//EntityMgr::instance()->getDispatch()->closeLoginSocket();
//

 

////变量定义
//CMD_MB_LogonFailure* pLogonError = (CMD_MB_LogonFailure *)buffer;
//
//NotificationCenter::getInstance()->postNotification(MSG_UI_ANS_LOGINFAIL);
//return true;
//}

 

 

 

cbMustUpdate=1,cbAdviceUpdate=0,dwCurrentVersion=102563856

 


        case 200://SUB_GR_LOGON_NOTIFY:            // 登陆提示TIPS    104
        {
            return [self OnSocketSubUpdateNotify:buffer bufferSize:size];//这里bufferSize要与方法中的一致,否则会出现运行时错误unrecognized selector sent to instance,例如都改成bufSize
            //return [self OnSocketSubGRLogonNotify:buffer bufferSize:size];
        }

 

//更新提示
-(bool)OnSocketSubUpdateNotify:(void*)buffer bufferSize:(WORD)size;
//更新提示
-(bool)OnSocketSubUpdateNotify:(void*)buffer bufferSize:(WORD)size
{

 

DebugFrameDate(@"更新提示");
    CMD_MB_UpdateNotify* pRsp=(CMD_MB_UpdateNotify*)buffer;
    NSLog(@"cbMustUpdate=%d,cbAdviceUpdate=%d,dwCurrentVersion=%d", pRsp->cbMustUpdate, pRsp->cbAdviceUpdate,pRsp->dwCurrentVersion);
    return true;
}

2018-05-08 11:22:50.089215+0800 BeefView[314:28285] 发送帐号登录
2018-05-08 11:22:50.651683+0800 BeefView[314:28285] OnTCPNetworkWithMBDataLoad wMainCmdID=1,wSubCmdID=100,size=449
2018-05-08 11:22:50.664554+0800 BeefView[314:28285] -[NSError init] called; this results in an invalid NSError instance. It will raise an exception in a future release. Please call errorWithDomain:code:userInfo: or initWithDomain:code:userInfo:. This message shown only once.
2018-05-08 11:22:50.680412+0800 BeefView[314:28395] App Transport Security has blocked a cleartext HTTP (http://) resource load since it is insecure. Temporary exceptions can be configured via your app's Info.plist file.
2018-05-08 11:22:50.698019+0800 BeefView[314:28285] OnTCPNetworkWithMBDataLoad wMainCmdID=2,wSubCmdID=100,size=408
2018-05-08 11:22:50.698229+0800 BeefView[314:28285] OnTCPNetworkWithMBDataLoad wMainCmdID=2,wSubCmdID=101,size=4620
2018-05-08 11:22:50.698304+0800 BeefView[314:28285] OnTCPNetworkWithMBDataLoad wMainCmdID=2,wSubCmdID=102,size=222
2018-05-08 11:22:50.698393+0800 BeefView[314:28285] size=222
2018-05-08 11:22:50.698538+0800 BeefView[314:28285] 游戏房间数 count=1, 可使用服务器房间总数=1
2018-05-08 11:22:50.698822+0800 BeefView[314:28285] lBeginScore=0, lMinScore=0 server.wSortID=282, roomName=
2018-05-08 11:22:50.710762+0800 BeefView[314:28285] OnTCPNetworkWithMBDataLoad wMainCmdID=2,wSubCmdID=103,size=0
2018-05-08 11:23:11.990890+0800 BeefView[314:28285] 登录完成
Message from debugger: Terminated due to signal 9

 

IosApp开发简单实例

阅读数 343

ios app开发步骤

阅读数 280

iOS app开发入门

阅读数 9

ios app开发实例

阅读数 547

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