存折 - JSON 中的硬编码位置有效但不传递变量
Passbook - Hardcoding locations in JSON works but not passing variable
我正在使用 here 找到的预建结构来创建 Apple Passbook 通行证。我正在使用星巴克示例,但参数不同。
背景: Apple 只允许将 10 个位置保存到一个通行证中。保存位置的目的是在您靠近时触发 phone 通知。
我系统的流程是:
- 用户输入家庭住址
- google 检索精确坐标 lat/lng
- lat 和 lng 设置为表单的隐藏输入,并发布到传递创建 PHP。
- 服务器查询 10 个最近的位置并将它们的位置添加到通行证 JSON。
- 通过创建和下载
问题
可能是 PHP 或 Passbook 的问题。
POSTed变量查询在Mysql就好了。在测试 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."}
]
不明白为什么变量可以传fine,查询fine,输入JSONfine,但是要区分pass文件的作用
编辑:应要求提供更多信息。
索引上的 HTML 表单传递了 google 地理编码给出的 lat/lng。
<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 > " disabled />
</fieldset>
</form>
生成通行证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 值是实数。它们是字符串还是数字这一事实似乎并不重要。当我对它们进行硬编码时,它们是字符串。
上面的 JSON 不会生成带有地图位置的传递文件,如果 lat/lng 是硬编码的话。
在 PassWallet 上测试,有效。在 iO6 模拟器上,它说 "Safari cannot download this file." When I have get it to use passes before.
有了额外的信息,你的问题就清楚了。
The fact that they are strings or numbers does not seem to have
mattered.
实际上,对于存折来说,这很重要。存折对类型非常挑剔。 sprintf("%.4f", floatval($row->longitude))
将您的查询结果转换为字符串,其中包格式需要双精度。
来自Passbook Package Format Reference:
无需格式化为任何特定数量的位置,只需输入原始浮点值即可。
原来是一个奇怪的作用域错误。
所有计算和创建 JSON 似乎都没有问题,但在设置 JSON 和创建传递之间的某个地方,它不再具有完整的 POST 变量。他们将默认为 0/0,在非洲附近的某个地方。
我能够通过使用会话变量而不是 GET/POST 来解决这个问题。在提交表单之前,我 jquery ajax 设置会话变量,然后在通行证创建页面中调用它们,用它做任何我需要的计算来导出 10 个额外的 lat/lngs .如果起始变量不存在,则无法推导其余部分!
如果有人遇到同样的问题,请将其张贴在这里。这可能是这个项目的独特之处,但事情就是这样。
我正在使用 here 找到的预建结构来创建 Apple Passbook 通行证。我正在使用星巴克示例,但参数不同。
背景: Apple 只允许将 10 个位置保存到一个通行证中。保存位置的目的是在您靠近时触发 phone 通知。
我系统的流程是:
- 用户输入家庭住址
- google 检索精确坐标 lat/lng
- lat 和 lng 设置为表单的隐藏输入,并发布到传递创建 PHP。
- 服务器查询 10 个最近的位置并将它们的位置添加到通行证 JSON。
- 通过创建和下载
问题
可能是 PHP 或 Passbook 的问题。
POSTed变量查询在Mysql就好了。在测试 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."}
]
不明白为什么变量可以传fine,查询fine,输入JSONfine,但是要区分pass文件的作用
编辑:应要求提供更多信息。 索引上的 HTML 表单传递了 google 地理编码给出的 lat/lng。
<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 > " disabled />
</fieldset>
</form>
生成通行证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 值是实数。它们是字符串还是数字这一事实似乎并不重要。当我对它们进行硬编码时,它们是字符串。 上面的 JSON 不会生成带有地图位置的传递文件,如果 lat/lng 是硬编码的话。 在 PassWallet 上测试,有效。在 iO6 模拟器上,它说 "Safari cannot download this file." When I have get it to use passes before.
有了额外的信息,你的问题就清楚了。
The fact that they are strings or numbers does not seem to have mattered.
实际上,对于存折来说,这很重要。存折对类型非常挑剔。 sprintf("%.4f", floatval($row->longitude))
将您的查询结果转换为字符串,其中包格式需要双精度。
来自Passbook Package Format Reference:
无需格式化为任何特定数量的位置,只需输入原始浮点值即可。
原来是一个奇怪的作用域错误。
所有计算和创建 JSON 似乎都没有问题,但在设置 JSON 和创建传递之间的某个地方,它不再具有完整的 POST 变量。他们将默认为 0/0,在非洲附近的某个地方。
我能够通过使用会话变量而不是 GET/POST 来解决这个问题。在提交表单之前,我 jquery ajax 设置会话变量,然后在通行证创建页面中调用它们,用它做任何我需要的计算来导出 10 个额外的 lat/lngs .如果起始变量不存在,则无法推导其余部分!
如果有人遇到同样的问题,请将其张贴在这里。这可能是这个项目的独特之处,但事情就是这样。