doraemon0769 2011-07-02 04:17
浏览 40
已采纳

iPhone中的RESTful Web服务:未插入数据库的数据

I started out by doing a tutorial using the 'shapes' web services that comes with MAMP. Now I am trying to recreate a service for myself. I have now been looking for solutions or how to debug the problem for the past 5 hours. My forte is not PHP, so I am not sure how I can setup debug or some sort of way to print out the URL response. Anyone's help is greatly appreciated.

Objective-C Code:

NSString* serviceRootUrlString = @"http://localhost:8888/answers/Answers/";
NSURL* answerService = [NSURL URLWithString:serviceRootUrlString];
_database = [[Database alloc] initWithServiceUrl:answerService];

- (void)nextQuestionWithAnswer:(NSString *)answer andComment:(NSString *)comment
{
    NSString* deviceId = [[UIDevice currentDevice] uniqueIdentifier];
    NSData* deviceIdAsData = [deviceId dataUsingEncoding:NSUTF8StringEncoding];
    NSString* deviceHash = [Database MD5Hash:deviceIdAsData];

    NSMutableDictionary* answerDictionary = [NSMutableDictionary dictionary];
    [answerDictionary setObject:deviceHash forKey:@"SetId"];
    [answerDictionary setObject:[NSNumber numberWithInt:(_currentQuestionNumber + 1)] forKey:@"QuestionId"];
    [answerDictionary setObject:answer forKey:@"Answer"];
    [answerDictionary setObject:comment forKey:@"Comment"];

    [_database insertRecordWithDictionary:answerDictionary];

    [self nextQuestion];
}

- (BOOL)insertRecordWithDictionary:(NSDictionary *)recordDictionary
{
    NSData* recordPropertyListData = [NSPropertyListSerialization dataFromPropertyList:recordDictionary format:NSPropertyListXMLFormat_v1_0 errorDescription:nil];

    NSMutableURLRequest* urlRequest = [NSMutableURLRequest requestWithURL:_serviceUrl];
    [urlRequest setHTTPMethod:@"POST"];
    [urlRequest setHTTPBody:recordPropertyListData];

    NSURLResponse* response = nil;
    NSError* error = nil;

    NSData* responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];

    id propertyList = [NSPropertyListSerialization propertyListWithData:responseData options:NSPropertyListImmutable format:nil error:nil];

    NSDictionary* responseDictionary = (NSDictionary*)propertyList;

    NSLog(@"New Record result: %@", responseDictionary);

    if (error == nil)
    {
        return YES;
    }
    else
    {
        NSLog(@"Database Error: %@", [error description]);

        return NO;
    }
}

PHP Code:

<?php
require_once 'CFPropertyList/CFPropertyList.php';

// connect to database
$connection = mysql_connect("localhost:8889","root","root");
if (!$connection)
    die("Could not connect: " . mysql_error());

// Database layout
$databaseName = "answers";
$surveyAnswersTableName = "Answers";
$surveyAnswersArrayName = "Answers";
$answerId = "Id";
$answerTimeStamp = "TimeStamp";
$answerSetId = "SetId";
$answerQuestionId = "QuestionId";
$answerAnswer = "Answer";
$answerComment = "Comment";

// Determine the requested resource, stripping empty resource elements and the base name
$base = "answers";
$resourceKeys = array_merge(array_diff(explode("/", $_SERVER[REQUEST_URI]), array("", $base)));

// Detect usage of the old setup
if (count($resourceKeys) == 0)
    die("Specify a table that contains your shapes. Ex: http://the_host_name:8888/answers/your_user_name/");

// Use the first resource key as the table name, then strip it away
$surveyAnswersTableName = $resourceKeys[0];
$resourceKeys = array_merge(array_diff($resourceKeys, array($surveyAnswersTableName)));

// Check for the database. Create the database and populate it if it does not exist
$databaseExists = mysql_select_db($databaseName, $connection);
if (!$databaseExists)
{
    // Create and select the ozzie database
    mysql_query("CREATE DATABASE $databaseName",$connection);
    $databaseExists = mysql_select_db($databaseName, $connection);
    if (!$databaseExists)
        die("Could not create database $databaseName: " . mysql_error());
}

// Check for the requested answers table
$sql = "SHOW TABLES LIKE '$surveyAnswersTableName'"; 
mysql_query($sql, $connection);
$row = mysql_fetch_array($result);
print($row);

// Create it if it does not exist
if ($row == FALSE)
{
    // Create the table that holds the answers
    $sql = "CREATE TABLE $surveyAnswersTableName 
    (
        $answerId int NOT NULL AUTO_INCREMENT PRIMARY KEY,
        $answerTimeStamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
        $answerSetId text,
        $answerQuestionId int, 
        $answerAnswer text,
        $answerComment text
    )";

    mysql_query($sql, $connection);
}

if ($_SERVER[REQUEST_METHOD] == "POST")
{
    // Insert or append shape specified in POST to the database
    if (count($resourceKeys) == 0)
    {
        // Load the posted plist into a property list object
        // HACK: Save post data to file to load into plist. Should be able to load directly from php://input, but won't...
        $postdata = file_get_contents("php://input");
        $fileName = dirname(__FILE__) . "/tmp.php";
        $file = fopen($fileName, 'w') or die("Cannot open file");
        fwrite($file, $postdata);
        fclose($file);
        $postPlist = new CFPropertyList($fileName);
        unlink($fileName);

        // Unpack data for answer
        // TODO: Verify data
        $answerDictionary = $postPlist->getValue(true);
        $setId = $answerDictionary->get($answerSetId);
        $questionId = $answerDictionary->get($answerQuestionId);
        $answer = $answerDictionary->get($answerAnswer);
        $comment = $answerDictionary->get($answerComment);

        // Insert answer into database
        $sql = "INSERT INTO $surveyAnswersTableName
        (
            $answerSetId,
            $answerQuestionId, 
            $answerAnswer, 
            $answerComment
        ) 
        VALUES 
        (
            '$setId',
            '$questionId',
            '$answer',
            '$comment'
        )";

        mysql_query($sql,$connection);

        print($sql);

        // Package result into outer dictionary
        // TODO: Call method instead

        $resultDictionary = new CFDictionary();
        $resultDictionary->add($surveyAnswersArrayName, new CFString("Answer inserted."));

        // Package outer dictionary into a property list and transmit
        $resultPlist = new CFPropertyList();
        $resultPlist->add($resultDictionary);
        header("Content-type: text/xml");
        print($resultPlist->toXML(true));
    }
    else if (count($resourceKeys) >= 1)
    {
        // Load the posted plist into a property list object
        // HACK: Save post data to file to load into plist. Should be able to load directly from php://input, but won't...
        $postdata = file_get_contents("php://input");
        $fileName = dirname(__FILE__) . "/tmp.php";
        $file = fopen($fileName, 'w') or die("Cannot open file");
        fwrite($file, $postdata);
        fclose($file);
        $postPlist = new CFPropertyList($fileName);
        unlink($fileName);

        // Unpack data for shape
        // TODO: Verify data
        $answerDictionary = $postPlist->getValue(true);
        $setId = $answerDictionary->get($answerSetId);
        $questionId = $answerDictionary->get($answerQuestionId);
        $answer = $answerDictionary->get($answerAnswer);
        $comment = $answerDictionary->get($answerComment);

        // Determine requested shape
        $requestedAnswerSetId = $resourceKeys[0];

        // Query to re-number shapes
        $sql = "UPDATE $surveyAnswersTableName SET $answerId = $answerId + 1 WHERE $answerId >= $requestedAnswerId";
        print($sql);
        $result = mysql_query($sql);

        // Insert shape into database
        $sql = "INSERT INTO $surveyAnswersTableName
        (
            $answerSetId,
            $answerQuestionId, 
            $answerAnswer, 
            $answerComment
        ) 
        VALUES 
        (
            '$setId',
            '$questionId',
            '$answer',
            '$comment'
        )";

        mysql_query($sql,$connection);

        print($sql);

        // Package result into outer dictionary
        // TODO: Call method instead
        // TODO: Verify that add completed successfully
        $resultDictionary = new CFDictionary();
        $resultDictionary->add($surveyAnswersArrayName, new CFString("Answer inserted."));

        // Package outer dictionary into a property list and transmit
        $resultPlist = new CFPropertyList();
        $resultPlist->add($resultDictionary);
        header("Content-type: text/xml");
        print($resultPlist->toXML(true));
    }
    else 
        die("Invalid request");
}

?>

I know I am asking a lot for someone to analyze this code but it would be greatly appreciated.

  • 写回答

1条回答 默认 最新

  • douchun3680 2011-07-02 10:35
    关注

    For print response using iOS and XCode:

    NSData* responseData = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:&response error:&error];
    NSLog(@"Reponse: %@", [[[NSString alloc]initWithData:responseData encoding:NSUTF8StringEncoding] autorelease]);
    

    For check php response without iOS just create somewhere html file with HTML form which contains inputs. Those inputs must have the same keys and values like in your recordDictionary variable. Form action should be like in your serviceRootUrlString variable, method POST.

    See this tutorial for more information about HTML forms

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 wamp3.3.5安装完成后图标正常显示绿色,鼠标左右键点击图标均无反应。求解决方法。
  • ¥15 鼠标点击的这条记录了什么?
  • ¥15 在写pid调速的程序时,电机始终维持最大速度
  • ¥15 请问如何查看手机root记录?
  • ¥15 商城小程序订单号重复
  • ¥15 学校优化算法sbo和蚁群算法怎么结合
  • ¥21 matlab怎么求时域信号的二阶导数
  • ¥15 判断两个表是否完全相同
  • ¥15 java map类型数据格式,如何快速通过前缀匹配元素
  • ¥15 stc12c5a60s2、QMC5883L、LCD1602组合测量磁场所需程序