怎么安装不了runkeeper 要不要联网app

怎么样创建一个像RunKeeper一样的app(二)swift版 - 简书
下载简书移动应用
写了34110字,被173人关注,获得了91个喜欢
怎么样创建一个像RunKeeper一样的app(二)swift版
怎么样创建一个像RunKeeper一样的APP(二)swift版
本博将不定期更新外网的iOS最新教程
简书: @西木
微博: @角落里的monster
本文翻译自raywenderlich,版权归原作者所有,转载请注明出处
原文地址为 /97945/make-app-like-runkeeper-swift-part-2
这是第二部分,也是这篇教程的最后一部分,我们将会完成badge的部分
在第一部分中,我们完成了
使用Core Location记录轨迹
持续更新你的轨迹并且显示平均速度等
跑步完成时显示跑步区域的地图,轨迹曲线为彩色显示,速度慢得部分为红色,速度快的部分为绿色
这个App可以很好地显示和记录你的跑步数据,但是要看到你的跑步中明显的各种变化,就不光是一个地图可以表现得,还需要做一些调整
这一部分中,你将完成MoonRunner的奖励体系的设置,它能够体现出你在运动过程中的愉悦和成就感。它能够帮助你有积极性来使用App记录你运动的历程
准备好解锁你第二部分额运动成就了吗?开始吧
Getting Started
如果你还没有看过第一部分的教程,可以查看我之前的博文
在项目文件的配置中已经包含了一个JSON文件,你可以先查看一下JSON文件,如果你好奇的话
徽章系统会从0开始记录,首先你需要完成一个马拉松,当然,很多人可能会完成更远的距离,你也可以想想是什么样的力量可以支持他们完成这些
首先,我们要把JSON数据转换成一个数组,新建一个swift文件,命名为Badge
然后,用下面的部分替换原文件的内容
import Foundation
let silverMultiplier = 1.05 // 5% speed increase
let goldMultiplier = 1.10 // 10% speed increase
class Badge {
let name: String?
let imageName: String?
let information: String?
let distance: Double?
init(json: [String: String]) {
name = json["name"]
information = json["information"]
imageName = json["imageName"]
distance = (json["distance"] as NSString?)?.doubleValue
如果字典中并没有包含所有的key的话,可以来这个问价查找
我们需要解析JSON数据完善你的徽章系统,仍然是这个文件,创建一个类命名为 BadgeController 并加入一下代码
class BadgeController {
static let sharedController = BadgeController()
lazy var badges : [Badge] = {
var _badges = [Badge]()
let filePath = NSBundle.mainBundle().pathForResource("badges", ofType: "json") as String!
let jsonData = NSData.dataWithContentsOfMappedFile(filePath) as! NSData
var error: NSError?
if let jsonBadges = NSJSONSerialization.JSONObjectWithData(jsonData, options: NSJSONReadingOptions.AllowFragments, error: &error) as? [Dictionary&String, String&] {
for jsonBadge in jsonBadges {
_badges.append(Badge(json: jsonBadge))
println(error)
return _badges
这里,你声明了 BadgeController 为一个单例,而且对 badges 数组做了懒加载,当第一次被调用的时候,会通过Badges.json 来初始化
Earning The Badge
你已经创建了Badge, 那么现在你需要一个对象来存储你获得的徽章奖励
这个对象需要把你的Badge 对象和Run 对象联系起来,如果有的话,还需要恩能够存储这个徽章的级别
打开 Badge.swift 在尾部添加以下代码
class BadgeEarnStatus {
let badge: Badge
var earnRun: Run?
var silverRun: Run?
var goldRun: Run?
var bestRun: Run?
init(badge: Badge) {
self.badge = badge
现在你已经可以把 Badge 和 Run 联系起来了,那么我们就需要建立它们之间的逻辑关系
添加以下代码到 Badge.swift 中
let silverMultiplier = 1.05 // 5% speed increase
let goldMultiplier = 1.10 // 10% speed increase
silverMultiplier 和 goldMultiplier是根据速度的快慢来划分的,越多的加成会获得更高级别的奖励
然后,添加以下方法在 BadgeController 类中
func badgeEarnStatusesForRuns(runs: [Run]) -& [BadgeEarnStatus] {
var badgeEarnStatuses = [BadgeEarnStatus]()
for badge in badges {
let badgeEarnStatus = BadgeEarnStatus(badge: badge)
for run in runs {
if run.distance.doubleValue & badge.distance {
// This is when the badge was first earned
if badgeEarnStatus.earnRun == nil {
badgeEarnStatus.earnRun = run
let earnRunSpeed = badgeEarnStatus.earnRun!.distance.doubleValue / badgeEarnStatus.earnRun!.duration.doubleValue
let runSpeed = run.distance.doubleValue / run.duration.doubleValue
// Does it deserve silver?
if badgeEarnStatus.silverRun == nil && runSpeed & earnRunSpeed * silverMultiplier {
badgeEarnStatus.silverRun = run
// Does it deserve gold?
if badgeEarnStatus.goldRun == nil && runSpeed & earnRunSpeed * goldMultiplier {
badgeEarnStatus.goldRun = run
// Is it the best for this distance?
if let bestRun = badgeEarnStatus.bestRun {
let bestRunSpeed = bestRun.distance.doubleValue / bestRun.duration.doubleValue
if runSpeed & bestRunSpeed {
badgeEarnStatus.bestRun = run
badgeEarnStatus.bestRun = run
badgeEarnStatuses.append(badgeEarnStatus)
return badgeEarnStatuses
这个方法会吧用户的跑步距离和对应的奖励的要求做个匹配,返回一个数组,数组里包含了所有的 BadgeEarnStatus
它的作用是,每当用户获得一个Badge的时候,它会产生一个像对应的速度,来判断这个奖励的级别是 silver version 还是 gold version
比如说,虽然你的小伙伴的速度比你快,但是如果你的进步足够大得话,依然有机会获得 gold version 的奖励
Displaying the Badges
现在是时候向用户展示你所有的奖励逻辑和UI界面了
你需要创建两个控制器和一个自定义的 table cell 来显示 Badg e数据
创建一个新的swift文件命名为 BadgeCell
打开这个文件,用下面的代码替换原来的内容
import UIKit
import HealthKit
class BadgeCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var descLabel: UILabel!
@IBOutlet weak var badgeImageView: UIImageView!
@IBOutlet weak var silverImageView: UIImageView!
@IBOutlet weak var goldImageView: UIImageView!
现在,你已经用 table view controller 为 badges 自定义了一个cell
接下来,在创建一个新的swift文件命名为 BadgesTableViewController, 打开文件替换里面的内容为
import UIKit
import HealthKit
class BadgesTableViewController: UITableViewController {
var badgeEarnStatusesArray: [BadgeEarnStatus]!
在之前的 BadgeController 里调用 badgeEarnStatusesForRuns(_:) 方法的时候会返回一个 badgeEarnStatuesArray 数组
添加如下属性给刚才的类
let redColor = UIColor(red: 1, green: 20/255, blue: 44/255, alpha: 1)
let greenColor = UIColor(red: 0, green: 146/255, blue: 78/255, alpha: 1)
let dateFormatter: NSDateFormatter = {
let _dateFormatter = NSDateFormatter()
_dateFormatter.dateStyle = .MediumStyle
return _dateFormatter
let transform = CGAffineTransformMakeRotation(CGFloat(M_PI/8.0))
每个cell会根据奖章的不同来显示不同的颜色
这些属性会保存在缓存里,不需要每次重新创建,每次创建新的会很耗性能,所以应该尽量考虑重复使用
然后,给 UITableViewDataSource 添加如下实现
// MARK: - UITableViewDataSource
extension BadgesTableViewController {
override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -& Int {
return badgeEarnStatusesArray.count
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -& UITableViewCell {
let cell = tableView.dequeueReusableCellWithIdentifier("BadgeCell") as! BadgeCell
let badgeEarnStatus = badgeEarnStatusesArray[indexPath.row]
cell.silverImageView.hidden = (badgeEarnStatus.silverRun != nil)
cell.goldImageView.hidden = (badgeEarnStatus.goldRun != nil)
if let earnRun = badgeEarnStatus.earnRun {
cell.nameLabel.textColor = greenColor
cell.nameLabel.text = badgeEarnStatus.badge.name!
cell.descLabel.textColor = greenColor
cell.descLabel.text = "Earned: " + dateFormatter.stringFromDate(earnRun.timestamp)
cell.badgeImageView.image = UIImage(named: badgeEarnStatus.badge.imageName!)
cell.silverImageView.transform = transform
cell.goldImageView.transform = transform
cell.userInteractionEnabled = true
cell.nameLabel.textColor = redColor
cell.nameLabel.text = "?????"
cell.descLabel.textColor = redColor
let distanceQuantity = HKQuantity(unit: HKUnit.meterUnit(), doubleValue: badgeEarnStatus.badge.distance!)
cell.descLabel.text = "Run \(distanceQuantity.description) to earn"
cell.badgeImageView.image = UIImage(named: badgeEarnStatus.badge.imageName!)
cell.userInteractionEnabled = false
return cell
这个方法告诉 tableView 要显示多少行,每个cell显示什么内容,你能够看到,每个cell对应的是不同的badge,而且,因为设置了 userInteractionEnabled,只有获得奖章的 cell才能被选中
现在你需要给 BadgesTableViewController 提供一些数据,打开 HomeViewController.swift 给 prepareForSegue(_:sender): 方法添加如下代码
else if segue.destinationViewController.isKindOfClass(BadgesTableViewController) {
let fetchRequest = NSFetchRequest(entityName: "Run")
let sortDescriptor = NSSortDescriptor(key: "timestamp", ascending: false)
fetchRequest.sortDescriptors = [sortDescriptor]
let runs = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as! [Run]
let badgesTableViewController = segue.destinationViewController as! BadgesTableViewController
badgesTableViewController.badgeEarnStatusesArray = BadgeController.sharedController.badgeEarnStatusesForRuns(runs)
这里,当 BadgesTableViewController 被压入导航栈里的时候,每一个奖励的状态都会被计算并且显示出来
链接storyboard,打开Main.storyboard做下面的事情
绑定 BadgeCell 和 BadgesTableViewController
脱线设置 name标签、Earned标签、头像icon和奖励标识如图所示
如果你已经用过它来跑步的话,肯定已经获得了 earth 级别的奖励,显然,奖励才刚开始
Badge Details
下一个控制器用来展示奖励的详细信息
创建一个新的swift文件命名为 BadgeDetailsViewController 并且替换内容为
import UIKit
import HealthKit
class BadgeDetailsViewController: UIViewController {
var badgeEarnStatus: BadgeEarnStatus!
@IBOutlet weak var badgeImageView: UIImageView!
@IBOutlet weak var silverImageView: UIImageView!
@IBOutlet weak var goldImageView: UIImageView!
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var distanceLabel: UILabel!
@IBOutlet weak var earnedLabel: UILabel!
@IBOutlet weak var silverLabel: UILabel!
@IBOutlet weak var goldLabel: UILabel!
@IBOutlet weak var bestLabel: UILabel!
这个类用来存储你的获奖的详细状态,可以用来添加标识
添加如下的代码设置View
override func viewDidLoad() {
super.viewDidLoad()
let formatter = NSDateFormatter()
formatter.dateStyle = .MediumStyle
let transform = CGAffineTransformMakeRotation(CGFloat(M_PI/8.0))
nameLabel.text = badgeEarnStatus.badge.name
let distanceQuantity = HKQuantity(unit: HKUnit.meterUnit(), doubleValue: badgeEarnStatus.badge.distance!)
distanceLabel.text = distanceQuantity.description
badgeImageView.image = UIImage(named: badgeEarnStatus.badge.imageName!)
if let run = badgeEarnStatus.earnRun {
earnedLabel.text = "Reached on " + formatter.stringFromDate(run.timestamp)
if let silverRun = badgeEarnStatus.silverRun {
silverImageView.transform = transform
silverImageView.hidden = false
silverLabel.text = "Earned on " + formatter.stringFromDate(silverRun.timestamp)
silverImageView.hidden = true
let paceUnit = HKUnit.secondUnit().unitDividedByUnit(HKUnit.meterUnit())
let paceQuantity = HKQuantity(unit: paceUnit, doubleValue: badgeEarnStatus.earnRun!.duration.doubleValue / badgeEarnStatus.earnRun!.distance.doubleValue)
silverLabel.text = "Pace & \(paceQuantity.description) for silver!"
if let goldRun = badgeEarnStatus.goldRun {
goldImageView.transform = transform
goldImageView.hidden = false
goldLabel.text = "Earned on " + formatter.stringFromDate(goldRun.timestamp)
goldImageView.hidden = true
let paceUnit = HKUnit.secondUnit().unitDividedByUnit(HKUnit.meterUnit())
let paceQuantity = HKQuantity(unit: paceUnit, doubleValue: badgeEarnStatus.earnRun!.duration.doubleValue / badgeEarnStatus.earnRun!.distance.doubleValue)
goldLabel.text = "Pace & \(paceQuantity.description) for gold!"
if let bestRun = badgeEarnStatus.bestRun {
let paceUnit = HKUnit.secondUnit().unitDividedByUnit(HKUnit.meterUnit())
let paceQuantity = HKQuantity(unit: paceUnit, doubleValue: bestRun.duration.doubleValue / bestRun.distance.doubleValue)
bestLabel.text = "Best: \(paceQuantity.description), \(formatter.stringFromDate(bestRun.timestamp))"
这段代码设置了 badge image和相关的label中的数据
最有趣的部分是鼓励用户怎么样获得更高级别的奖励,这些鼓励会增加你的积极性,因为它需要更快地跑步记录
最后,添加这个方法
@IBAction func infoButtonPressed(sender: AnyObject) {
UIAlertView(title: badgeEarnStatus.badge.name!,
message: rmation!,
delegate: nil,
cancelButtonTitle: "OK").show()
当用户点击info按钮的时候会来到这里,将会显示badge的信息
现在详情页设置完毕了,你还需要确保在segue之前badges table view能够发送badge信息
打开BadgesTableViewController.swift 给 BadgesTableViewController添加如下方法
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
if segue.destinationViewController.isKindOfClass(BadgeDetailsViewController) {
let badgeDetailsViewController = segue.destinationViewController as! BadgeDetailsViewController
let badgeEarnStatus = badgeEarnStatusesArray[tableView.indexPathForSelectedRow()!.row]
badgeDetailsViewController.badgeEarnStatus = badgeEarnStatus
当cell被点击的时候,BadgesDetailsViewController能展示相关的BadgeEarnStatus
现在,UI部分设置完毕了,打开Main.storyb做如下链接
绑定BadgeDetailsViewController
为BadgeDetailsVireController设置badgeImageView,bestLabel,distanceLabel,earnedLabel,goldImageView,goldLabel,nameLabel,silverImageLabel,silverLabel
为info按钮设置点击事件
Badge Motivation
作为徽章奖励系统新的一部分,你需要回到UI部分,把它纳入之前的徽章体系中
打开Main.storyboard,找到new Run场景,在stop按钮的上方添加一个UIImageView和一个UILabel
为UIImageView,使用自动布局设置约束
Align Center X to Superview
Width equals 70
Height equals 70
Align top with the Start button
为UILabel,使用自动布局设置约束
Align Center X to Superview
Top Space to:UIImageView equals 10
新的界面长长这样
新的view在start按钮的地方会有部分重叠,但是在开始跑步以后start按钮会隐藏起来只显示另外两个控件
在跑步时会使用“carrot-on-a-stick”方式激励用户,会显示一个山峰的样子来描述你离下一个级别的奖励还有都少差距
在显示UI之前,你需要添加两个方法给 BadgeController 来决定你最好在在这次可以拿到某个奖励然后再下一次就可以拿到另外一个奖励
打开 Badge.swift 给 BadgeController添加以下方法
func bestBadgeForDistance(distance: Double) -& Badge {
var bestBadge = badges.first as Badge!
for badge in badges {
if distance & badge.distance {
bestBadge = badge
return bestBadge
func nextBadgeForDistance(distance: Double) -& Badge {
var nextBadge = badges.first as Badge!
for badge in badges {
nextBadge = badge
if distance & badge.distance {
return nextBadge
这个很简单,只要你输入距离,就会返回
bestBadgeForDistance(_:): 你目前能获得的奖励
nextBadgeForDistance(_:): 你下一个能够获得的奖励
打开NewRunViewController.swift在顶部导入
import AudioToolbox
导入AudioToolbox之后你就能在用户每次获得新奖励的时候播放音效
接下来,为NewRunViewController 添加以下属性
var upcomingBadge : Badge?
@IBOutlet weak var nextBadgeLabel: UILabel!
@IBOutlet weak var nextBadgeImageView: UIImageView!
在viewWillAppear(_:)方法结尾处添加
nextBadgeLabel.hidden = true
nextBadgeImageView.hidden = true
badge label和badge image 一开始是需要隐藏的
给 startPressed(_:)方法结尾处添加
nextBadgeLabel.hidden = false
nextBadgeImageView.hidden = false
让 badge label 和 badge image 在跑步开始后显示
添加下面两个方法
func playSuccessSound() {
let soundURL = NSBundle.mainBundle().URLForResource("success", withExtension: "wav")
var soundID : SystemSoundID = 0
AudioServicesCreateSystemSoundID(soundURL, &soundID)
AudioServicesPlaySystemSound(soundID)
//also vibrate
AudioServicesPlaySystemSound(SystemSoundID(kSystemSoundID_Vibrate));
func checkNextBadge() {
let nextBadge = BadgeController.sharedController.nextBadgeForDistance(distance)
if let upcomingBadge = upcomingBadge {
if upcomingBadge.name! != nextBadge.name! {
playSuccessSound()
upcomingBadge = nextBadge
第一个方法播放音效的时候也会产生震动,以便在嘈杂的环境里通知用户或者防止播放音乐的过程中无法听到音效
当用户满足获得一个奖励的条件的时候会调用第二个方法检测这次获得的奖励是不是上一次获奖时记录的下一次即将获得的那个奖励,如果是,允许播放音效,并且把下一次即将要获得的奖励保存下来
为 eachSecond(_:)方法添加
checkNextBadge()
if let upcomingBadge = upcomingBadge {
let nextBadgeDistanceQuantity = HKQuantity(unit: HKUnit.meterUnit(), doubleValue: upcomingBadge.distance! - distance)
nextBadgeLabel.text = "\(nextBadgeDistanceQuantity.description) until \(upcomingBadge.name!)"
nextBadgeImageView.image = UIImage(named: upcomingBadge.imageName!)
这段代码可以让 nextBadgeLabel 和 nextBadgeImageView 在跑步的过程中持续更新
编译运行,start a new run
你可以看到label和image在不断更新
Where to go From Here
完成了一个可以在跑步过程中实时记录运行轨迹并且有成就激励系统的App
你可以在这里下载完整代码
/wp-content/uploads/2015/05/MoonRunner-Part2-Final.zip
根据这两篇教程,你做了一个app
用Core Location 测量你的轨迹
显示跑步过程中的实时数据
在地图上用不同颜色的曲线来标记你的轨迹和位置
速度和距离的个人奖励系统
这个app只是完成了这类app的基础功能,要让跟多的人使用你的app你还需要做更多地完善,成就奖励是一个“游戏化”app很好的方式
如果你想让你的app有进一步的提升,你还需要做
显示用户的跑步历史记录
将奖励和速度值标注在轨迹上
将奖励和注释标注在地图上
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
打开微信“扫一扫”,打开网页后点击屏幕右上角分享按钮
被以下专题收入,发现更多相似内容:
专题内容主要包括OC、swift等涉及到iOS开发进阶的内容。
swift可以关注下我的另一个专题:
swift开发...
· 5666人关注
Swift语言开发笔记
· 574人关注
· 490人关注
如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!
选择支付方式:查看: 355|回复: 0
RunKeeper数据同步到郁金香运动,数据分析和社交功能更强大
RunKeeper用户将运动数据同步到郁金香运动app中,可以享受郁金香运动更专业的数据分析和更便利的社交功能。
继成功同步Garmin运动手表的数据之后,郁金香运动app加入了很多Garmin用户,全站排行TOP20超过一半被Garmin用户占领,RunKeeper用户可以跟Garmin用户交流&PK了!
第一步、 下载郁金香运动app,并注册。
郁金香运动app目前只有iOS版本,安卓版正在内测中,将于12月16日正式上线,敬请期待。需要提前体验内测版本请联系小编微信:itangxia。
ios版本下载方法一:扫描以下二维码
ios版本下载方法二:app store中搜索“郁金香运动”。
下载并安装完成后,注册郁金香运动用户名。
(郁金香运动app注册、登陆页面)
第二步、联接RunKeeper。
联接RunKeeper的操作可以在郁金香运动网页版进行,也可以在手机app进行(目前只有ios版本可以在手机app直接操作,安卓版本后续也支持)。
网页版的联接操作步骤如下:
(1)打开郁金香运动网站
,使用刚注册的郁金香运动用户名和密码登陆。
(2)点击页面右上角的connect图标,进入联接页面。
(3)点击页面左侧的“其他APP联接”。
(4)点击“联接”,如下图所示:
(5)网页跳转到RunKeeper的网站上,输入RunKeeper的用户名和密码,点击“Log In”。
(6)成功“Log In”之后,点击“Allow”,即可联接RunKeeper。
提示:以上两步授权操作跳转到了RunKeeper的服务器,访问速度会比较慢,请耐心等待……
如果是ios版本,可以直接在手机app上进行联接操作,操作步骤如下:
(1)在app里点击“更多”,在“更多”界面点击“连接应用和设备”,如下图所示:
(2)点击“Runkeeper”,如下图所示:
(3)接下来,点击“联接Runkeeper”。
(4)输入RunKeeper的用户名和密码,点击“Log In”,进入之后点击“Allow”。
(5)联接成功。
联接成功后,RunKeeper上的所有活动数据皆可以同步到郁金香运动app中。
RunKeeper上的历史数据同步到郁金香运动app的时间需要看数据量的大小,一般一天之内都可以同步完成。RunKeeper上的新活动数据可实时同步。
以下是部分RunKeeper用户同步到郁金香运动app上的数据(只展示运动汇界面):
来吧!一起加入郁金香运动的橙色华人运动社区!(编辑: 小佛
您可以使用“← | →”键快速翻页,或者进入模式!
事件进展:
相关文章:
热门新闻排行本周本月&&(8915)&&(5053)&&(3971)&&(3003)&&(2816)&&(2682)&&(2562)&&(2452)&&(2115)&&(2094)&&(26342)&&(26276)&&(19907)&&(13241)&&(10031)&&(9483)&&(8915)&&(7889)&&(7515)&&(7108)
&&&&&&&&&&加载中,请稍候...
加载中,请稍候...
商品名称:
京东价:暂无报价
评价得分:
咨询内容:
我一直在用RunKeeper(iPhone5 ios8),不打算更换App。RunKeeper是可以连接心率监控器的,比如心率带之类的。这个耳机的心率监控能跟RunKeeper连接么?
京东回复:
您好!请联系售后客服电话,感谢您对京东的支持!祝您购物愉快!
发表咨询:
声明:您可在购买前对产品包装、颜色、运输、库存等方面进行咨询,我们有专人进行回复!因厂家随时会更改一些产品的包装、颜色、产地等参数,所以该回复仅在当时对提问者有效,其他网友仅供参考!咨询回复的工作时间为:周一至周五,9:00至18:00,请耐心等待工作人员回复。
咨询类型:
库存及配送
发票及保修
促销及赠品
京东承诺:商品均为原装正品行货,自带机打发票,严格执行国家三包政策,享受全国联保服务。
功能咨询:咨询商品功能建议您拨打各品牌的官方客服电话,以便获得更准确的信息。
发货时间:现货:下单后一日内即可发货;在途:一般1-2天发货; 预订:一般1-6天可发货;无货:已售完,相应物流中心覆盖地区内的用户不能购买
运&&&&费:如需查看快递运输收费标准及免运费规则,
货到付款:如需查看开通货到付款地区及运费,
上门自提:上门自提不收取运费,如需查看全部自提点位置、地图、注意事项,
物流中心:京东商城拥有北京、上海、广州三个物流中心,各物流中心覆盖不同的城市,
限&&&&额:如需查看各银行在线支付限额,
大额支付:快钱支付中的招行、工行、建行、农行、广发支持大额支付,最高单笔一次支付10000元
分期付款:单个商品价格在500元以上,可使用中国银行、招商银行发行的信用卡申请分期付款,
货到付款:如需查看开通货到付款地区及运费,
京东承诺:商品均为原装正品行货,自带机打发票,严格执行国家三包政策,享受全国联保服务。
发票类型:京东商城所售商品均自带机打发票,在提供相关企业资料证明后,可申请开取增值税发票。
退 换 货:京东商城为您提供完善的退换货服务,
咨询内容:

我要回帖

更多关于 runkeeper 的文章

 

随机推荐