du6333137 2015-12-23 09:15
浏览 40
已采纳

Swift 2 - 使用PHP在数据库中插入设备令牌

EDIT: I'm developing an iOS application, which uses a webview, that has push notification and I'm trying to pass the device token to a php file (sampleIndex.php) for database registration.

My attempt on posting the device token isn't working. Here's the code:

EDIT (2): My current code is based from @mat 's answer (same concept, but cleaner)

extension NSData {
func hexString() -> String {
    // "Array" of all bytes:
    let bytes = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes), count:self.length)
    // Array of hex strings, one for each byte:
    let hexBytes = bytes.map { String(format: "%02hhx", $0) }
    // Concatenate all hex strings:
    return (hexBytes).joinWithSeparator("")
  }

}


func application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {

    let session = NSURLSession.sharedSession()
    let tk = deviceToken.hexString()
    let postBody = NSString(format: "token=%@", tk)
    let endBody = NSURL(string: "http://samplesite.com/subfolder/subfolder2/sampleIndex.php")
    let request = NSMutableURLRequest(URL: endBody!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 30.0)
    request.HTTPMethod = "POST";
    request.HTTPBody = postBody.dataUsingEncoding(NSUTF8StringEncoding)
    request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in

        if data != nil {

            print("data: \(response)")

        } else {

            print("failed: \(error!.localizedDescription)")

        }

    }//closure

    dataTask.resume()
}

Why can't I get the value of tk? (token device). Am I missing something? Sorry, I'm just new to this.

EDIT (3) Here's the php code (sampleIndex.php) where the token is being requested:

<?php 
  include_once("includes/myConnect.php");
  $token = $_REQUEST['token'];

if (empty($token)) {
  $sql = "UPDATE sampleDB . sampleTB SET token= '0' WHERE id='8982'";
  $result = mysqli_query($conn, $sql);
}else{
  $sql = "UPDATE sampleDB . sampleTB SET token= '1' WHERE id='8982'";
  $result = mysqli_query($conn, $sql);
}

?>

(token sets to value " 0 " which proves that the device token fails to be passed on sampleIndex.php)

  • 写回答

1条回答 默认 最新

  • dpdbu24262 2015-12-23 10:57
    关注

    First make sure that you don't get the following error "failed: The resource could not be loaded because the App Transport Security policy requires the use of a secure connection" if you do, add this to your plist: enter image description here

    The following code works for me. I have just changed the postBody and URL to answer your question but doing that I am able to save the token to my database.

    extension NSData {
    func hexString() -> String {
        // "Array" of all bytes:
        let bytes = UnsafeBufferPointer<UInt8>(start: UnsafePointer(self.bytes), count:self.length)
        // Array of hex strings, one for each byte:
        let hexBytes = bytes.map { String(format: "%02hhx", $0) }
        // Concatenate all hex strings:
        return (hexBytes).joinWithSeparator("")
      }
    
    }
    
    
    @UIApplicationMain
    
    
    class AppDelegate: UIResponder, UIApplicationDelegate {
    
    var window: UIWindow?
    
    
    func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
        // Override point for customization after application launch.
    
    
        //request notification
        let type: UIUserNotificationType = [UIUserNotificationType.Badge, UIUserNotificationType.Alert, UIUserNotificationType.Sound];
        let setting = UIUserNotificationSettings(forTypes: type, categories: nil);
        UIApplication.sharedApplication().registerUserNotificationSettings(setting);
        //register for remote notification - push notification
        UIApplication.sharedApplication().registerForRemoteNotifications();
    
        return true
    }
    
    fun application(application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: NSData) {
    
     let session = NSURLSession.sharedSession()
     let userId = "12345" // not sure you have a userId at this point but you can remove that line and also remove it from postBody
     let tk = deviceToken.hexString()
     let postBody = NSString(format: "user=%@&token=%@", userId, tk)
     let endBody = NSURL(string: "http://www.sampleurl.com/sampleIndex.php")
     let request = NSMutableURLRequest(URL: endBody!, cachePolicy: NSURLRequestCachePolicy.ReloadIgnoringLocalCacheData, timeoutInterval: 30.0)
     request.HTTPMethod = "POST";
     request.HTTPBody = postBody.dataUsingEncoding(NSUTF8StringEncoding)
                                                        request.setValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
         let dataTask = session.dataTaskWithRequest(request) { (data:NSData?, response:NSURLResponse?, error:NSError?) -> Void in
    
             if data != nil {
    
              print("data: \(response)")
    
               } else {
    
               print("failed: \(error!.localizedDescription)")
    
               }
    
           }//closure
    
           dataTask.resume()
    }
    

    To insert the token in the database I strongly suggest you to use prepare statement. I use OOP Php so I have a class Database that handle all the connections but I simplified the code:

    sampleIndex.php

    <?php 
    
    $userid = $_REQUEST['user'];
    $token = $_REQUEST['token'];
    
        if (empty($userid) || empty($token)) {
        return;
    }else{
    
        saveTokenToDatabase($userid, $token);
    }
    
    
    function saveTokenToDatabase($user, $token){
    
        $username = 'youDatabaseUsername';
        $password =  'yourPassword';
    
    $dbh = new PDO('mysql:host=localhost;dbname=database_name', $username, $password);
    
    // first verify if the token is already in the database 
    $sth = $dbh->prepare("SELECT token 
            FROM user_tokens 
            WHERE user_id = ? 
              AND token = ? LIMIT 1");
    
    $sth->bindParam(1, $user, PDO::PARAM_INT);
    $sth->bindParam(2, $token, PDO::PARAM_STR);
    $sth->execute();
    $tokenExists = ($sth->fetchColumn() > 0) ? true : false;
    
    //if token is not already there 
    if(!$tokenExists){
    
    $now = date("Y-m-d H:i:s");
    $query = $dbh->prepare("INSERT INTO user_tokens (user_id, token, datecreated)  VALUES(?,?,'".$now."')");
    $query->bindParam(1, $user, PDO::PARAM_INT);
    $query->bindParam(2, $token, PDO::PARAM_STR);       
    $query->execute();
    
    // determine if token already exists
    }
        //close the connection 
        $dbh = null;
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 echarts动画效果失效的问题。官网下载的例子。
  • ¥60 许可证msc licensing软件报错显示已有相同版本软件,但是下一步显示无法读取日志目录。
  • ¥15 Attention is all you need 的代码运行
  • ¥15 一个服务器已经有一个系统了如果用usb再装一个系统,原来的系统会被覆盖掉吗
  • ¥15 使用esm_msa1_t12_100M_UR50S蛋白质语言模型进行零样本预测时,终端显示出了sequence handled的进度条,但是并不出结果就自动终止回到命令提示行了是怎么回事:
  • ¥15 前置放大电路与功率放大电路相连放大倍数出现问题
  • ¥30 关于<main>标签页面跳转的问题
  • ¥80 部署运行web自动化项目
  • ¥15 腾讯云如何建立同一个项目中物模型之间的联系
  • ¥30 VMware 云桌面水印如何添加