【问题标题】:Passbook - Hardcoding locations in JSON works but not passing variablePassbook - JSON 中的硬编码位置有效,但不能传递变量
【发布时间】:2015-03-16 22:15:05
【问题描述】:

我正在使用 here 找到的预构建结构来创建 Apple Passbook 通行证。我使用的是星巴克示例,但参数不同。

背景: Apple 只允许将 10 个位置保存到通行证中。保存位置的目的是在您靠近时触发电话通知。

我系统的流程是:

  • 用户输入家庭住址
  • google 检索精确坐标 lat/lng
  • lat 和 lng 被设置为表单的隐藏输入,并被 POST 以传递创建 PHP。
  • 服务器查询最近的 10 个位置并将它们的位置添加到传递 JSON。
  • 通过创建和下载

问题

这可能是 PHP 或 Passbook 的问题。

在Mysql 中查询POSTed 变量就好了。在测试 JSON 时,JSON 匹配下面示例文档中给出的目标模式。最近的 10 家商店确实以正确的语法插入自己。但是,在 JSON 中硬编码其位置的通行证

    'locations' => array(

        array(
            'longitude' => 123456,
            'latitude' => 123456,
            'relevantText' => 'You are near store'
            )
        )

这些显示在地图位置。

位置以任何方式设置变量的通行证,例如

    'locations' => array(

        array(
            'longitude' => $lng,
            'latitude' => $lat,
            'relevantText' => 'You are near store'
            )
        )

不在地图上显示他们的位置。 我尝试混合使用这两种方法,果然,只有硬编码的位置会显示出来 - 变量提交的 lats 和 lngs 会被忽略。

就在最后的通道创建步骤之前,我得到了一个位置公式,例如:

"locations":[
{"longitude":-XX.XXXX,"latitude":XX.XXXX,"relevantText":"PLACE NAME"},
...(ten times.. comma'd until last one)...
]

可以和apple's documentation中的目标公式比较:

"locations" : [
    {"latitude" : 37.3229, "longitude" : -122.0323, "relevantText" : "Store nearby on 3rd and Main."}
]

我不明白为什么变量可以很好的传递,查询很好,输入JSON很好,但是要区分传递文件的作用。


编辑:应要求提供更多信息。 传递从谷歌地理编码给出的纬度/经度的索引上的 HTML 表单。

<form action="pass.php" method="post">   
        <fieldset>       
        <input type='text' id='lat' name='lat' value='' > //set thru jquery
        <input type='text' id='lng' name='lng' value='' > //set thru jquery      
        <input type="submit" class="btn primary" name='pass' id='passButton' value=" Create pass &gt; " disabled />
        </fieldset>
</form>

生成pass的pass.php:

<?php
require('PKPass/PKPass.php');

$lat = floatval($_POST['lat']);
$lng = floatval($_POST['lng']);

require_once ('../../functions.php'); //get mysql wrapper class


$query = "SELECT *, ( 3959 * acos( cos( radians($lat) ) * cos( radians( latitude ) ) * 
cos( radians( longitude ) - radians($lng) ) + sin( radians($lat) ) * 
sin( radians( latitude ) ) ) ) AS distance FROM dealers HAVING
distance < 25 ORDER BY distance LIMIT 0 , 10;";

$result = $db->doQuery($query); //wrapper class helps do queries
$pass = new PKPass\PKPass();


$pass->setCertificate('cert/pass.p12');
$pass->setCertificatePassword('PASSWORD');
$pass->setWWDRcertPath('cert/AppleWWDRCA.pem');

// Top-Level Keys 
$standardKeys         = array(
    'description'        => 'Demo pass',
    'formatVersion'      => 1,
    'organizationName'   => 'NAME',
    'passTypeIdentifier' => 'pass.place.coupon',
    'serialNumber'       => '123456',
    'teamIdentifier'     => 'IDENTIFIER'
);
$associatedAppKeys    = array();
$relevanceKeys        = array(
    'locations' => array(

    )  

);

while ($row = $result->fetch_object()) {

    $array = 
            array(
         'longitude' => sprintf("%.4f", floatval($row->longitude)),
         'latitude' => sprintf("%.4f",floatval($row->latitude)),
        'relevantText' => $row->name
   );

    $relevanceKeys['locations'][] = $array;

}


$styleKeys            = array(

    'coupon' => array(
    'primaryFields' => array(
      array(
        'key' => 'offer',
        'label' => 'ITEM',
        'value' => 'FREE'
      )
    ),

    'auxiliaryFields' => array(
      array(
        'key' => 'expires',
        'label' => 'EXPIRES',
        'value' => '2018-04-24T10:00-05:00',
        'isRelative' => true,
        'dateStyle' => 'PKDateStyleShort'
      )
    )
  )
);

$visualAppearanceKeys = array(
    'barcode'         => array(
        'format'          => 'PKBarcodeFormatPDF417',
//        'format'          => 'PKBarcodeFormatQR',
        'message'         => 'MESSAGE',
        'messageEncoding' => 'iso-8859-1'
    ),
//    'foregroundColor' => 'rgb(255, 255, 255)',
    'backgroundColor' => 'rgb(39,81,154)',
    'logoText'        => 'COMPANY'
);
$webServiceKeys       = array();

// Merge all pass data and set JSON for $pass object
$passData = array_merge(
    $standardKeys,
    $associatedAppKeys,
    $relevanceKeys,
    $styleKeys,
    $visualAppearanceKeys,
    $webServiceKeys
);

$pass->setJSON(json_encode($passData));

// Add files to the PKPass package
$pass->addFile('icon.png');
$pass->addFile('icon@2x.png');
$pass->addFile('logo.png');

if(!$pass->create(true)) { // Create and output the PKPass
    echo 'Error: '.$pass->getError();
}

大写的明显内容是省略。

生成的 JSON:

        {"description":"Demo pass","formatVersion":1,"organizationName":"NAME","passTypeIdentifier":"pass.place.coupon","serialNumber":"123456","teamIdentifier":"IDENTIFIER","locations":[{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_1"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_2"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_3"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_4"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_5"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_6"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_7"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_8"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_9"},{"longitude":"-xx.xxxx","latitude":"xx.xxxx","relevantText":"STORE_10"}],"coupon":{"primaryFields":[{"key":"offer","label":"ITEM","value":"FREE"}],"auxiliaryFields":[{"key":"expires","label":"EXPIRES","value":"2018-04-24T10:00-05:00","isRelative":true,"dateStyle":"PKDateStyleShort"}]},"barcode":{"format":"PKBarcodeFormatPDF417","message":"MESSAGE","messageEncoding":"iso-8859-1"},"backgroundColor":"rgb(39,81,154)","logoText":"COMPANY"}

显然,xx.xxxx 值是实数。它们是字符串或数字的事实似乎并不重要。当我对它们进行硬编码时,它们是字符串。 如果 lat/lng 是硬编码的,上面的 JSON 不会生成带有地图位置的传递文件。 在 PassWallet 上测试,有效。在 iO6 模拟器上,它显示“Safari 无法下载此文件”。当我得到它之前使用通行证。

【问题讨论】:

  • 您能否发布实际生成的 JSON 以及您的 PHP 代码。如果没有其中任何一个,就无法诊断您的问题。
  • @PassKit 好的,我已经添加了更多信息

标签: php html arrays json passbook


【解决方案1】:

有了附加信息,您的问题就很清楚了。

它们是字符串或数字的事实似乎没有 很重要。

实际上对于 Passbook 来说确实很重要。存折对类型非常挑剔。 sprintf("%.4f", floatval($row-&gt;longitude)) 将您的查询结果转换为字符串,其中包格式需要双精度。

来自Passbook Package Format Reference

无需格式化为任何特定数量的位置,只需输入原始浮点值就可以了。

【讨论】:

  • 谢谢,但我遇到这个问题已经有一段时间了,代码的 sprintf 部分是最近的一部分。很高兴知道它对双打很挑剔。删除 sprintf 时我仍然遇到同样的问题。
  • 您认为这与查询没有及时完成以创建传递的变量有关吗?
  • 如果它在 PassWallet 上工作,那么正确的 alues 会按预期进入,看来它们只是为 iOS 格式不正确。如果您删除了 sprintf 但它仍然无法正常工作,那么您的查询输出可能有问题。尝试检查 JSON 以检查它是否包含浮点值,并且这些值是您的测试位置的有效坐标。安装 pass 时还要检查 Xcode 中的设备日志。这可能会为您提供一些关于为什么忽略值的线索。
  • 随着 sprintf 的变化,我意识到我确实让 iO6 能够识别通行证。 (我不怎么用苹果,所以我不确定如何在存折中查看实时通行证的位置。但我可以在 PassWallet 的 UI 中。)我将继续调试,看看我能想出什么
  • 只需检查您的 JSON,如果它们是浮动且正确的,并且通行证正在摄取到 Passbook,那么您可能很高兴。你也可能想看看这个应用程序play.google.com/store/apps/details?id=com.passesalliance.wallet。与 PassWallet 一样好,但没有广告。
【解决方案2】:

原来是一个奇怪的范围错误。

所有计算和创建 JSON 似乎都很好,但在设置 JSON 和创建传递之间的某个地方,POST 变量将不再完整。它们会默认为 0/0,位于非洲附近的某个地方。

我能够通过使用会话变量而不是 GET/POST 来解决这个问题。在表单提交之前,我会 jquery ajax 设置会话变量,然后在传递创建页面中调用它们,用它进行任何计算,我需要派生 10 个额外的 lat/lngs。如果起始变量不再存在,则无法推导出其余变量!

只是在这里发布,以防有​​人遇到同样的问题。这个项目可能有点独特,但事情就是这样。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-13
    • 2016-08-04
    • 2016-04-05
    • 1970-01-01
    • 1970-01-01
    • 2016-08-15
    相关资源
    最近更新 更多