请查看此 PR,了解我们可能很快会引入作为默认设置的替代方案! #71
这里有一个逐步指南,教你如何使用 Vapor (Swift) 托管自己的服务器: https://github.com/valentin-mille/RoadmapBackend
在你的应用中发布你的 roadmap,并允许用户为即将推出的功能投票,而无需创建后端!
Roadmap 通过远程 JSON 配置文件列出所有功能及其状态。我们建议将其托管在 GitHub Pages 或 simplejsoncms.com 上。
JSON 示例看起来如下所示
[
{
"id": "1",
"title": "Combine sentences",
"status": "planned",
"description" : "You can add a little bit of extra context here."
},
{
"id": "2",
"title": "Open with Finder support",
"status": "planned"
},
{
"id": "3",
"title": "Initial Launch",
"status": "finished",
"description" : "Release v1 to the public.",
"isFinished": true
}
]
键 id
和 title
是强制性的,并且都必须是字符串。你可以为 status
或 description
使用任何值。
如果你希望支持本地化,则需要在你的 JSON 中添加额外的可选参数,例如 localizedTitle
、localizedDescription
和 localizedStatus
,就像这样
[
{
"id": "0",
"title": "Adding a map",
"localizedTitle": [
{
"language": "ar",
"value": "اضافة خارطة"
},
{
"language": "en",
"value": "Adding a map"
}
],
"status": "planned",
"localizedStatus": [
{
"language": "ar",
"value": "مجدولة"
},
{
"language": "en",
"value": "Planned"
}
],
"description": "some description",
"localizedDescription": [
{
"language": "ar",
"value": "اضافة خارطة لمعرفة الاماكن القريبة"
},
{
"language": "en",
"value": "Adding a map to view nearby places"
}
]
}
]
如果你在 JSON 中将某个功能的 isFinished
设置为 true
,则投票视图将对用户隐藏,并且不会进行 API 调用来获取投票。这是一个可选值,其默认值为 false
。
在 Xcode 的 Package Manager 中添加 https://github.com/AvdLee/Roadmap.git
。
按照文档创建一个新的 Roadmap 配置
let configuration = RoadmapConfiguration(
roadmapJSONURL: URL(string: "https://simplejsoncms.com/api/k2f11wikc6")!
)
可选地,你也可以移交一个请求,用于更高级的端点,例如受 OAuth 保护的端点
var request = URLRequest(url: URL(string: "https://simplejsoncms.com/api/k2f11wikc6")!)
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.setValue("Bearer 1234567890", forHTTPHeaderField: "Authorization")
let configuration = RoadmapConfiguration(
roadmapRequest: request
)
并在 RoadmapView
中使用该配置
struct ContentView: View {
let configuration = RoadmapConfiguration(
roadmapJSONURL: URL(string: "https://simplejsoncms.com/api/k2f11wikc6")!,
namespace: "yourappname" // Defaults to your apps bundle id
allowVotes: true, // Present the roadmap in read-only mode by setting this to false
allowSearching: false // Allow users to filter the features list by adding a searchbar
)
var body: some View {
RoadmapView(configuration: configuration)
}
}
通过使用 RoadmapStyle
初始化 RoadmapConfiguration
,你可以创建自己的样式。
public struct RoadmapStyle {
/// The image used for the upvote button
let upvoteIcon : Image
/// The image used for the unvote button
let unvoteIcon : Image
/// The font used for the feature
let titleFont : Font
/// The font used for the count label
let numberFont : Font
/// The font used for the status views
let statusFont : Font
/// The tint color of the status view
let statusTintColor: (String) -> Color
/// The corner radius for the upvote button
let radius : CGFloat
/// The backgroundColor of each cell
let cellColor : Color
/// The color of the text and icon when voted
let selectedForegroundColor : Color
/// The main tintColor for the roadmap views.
let tintColor : Color
public init(upvoteIcon: Image,
unvoteIcon: Image,
titleFont: Font,
numberFont: Font,
statusFont: Font,
statusTintColor: @escaping (String) -> Color = { _ in Color.primary },
cornerRadius: CGFloat,
cellColor: Color = Color.defaultCellColor,
selectedColor: Color = .white,
tint: Color = .accentColor) {
self.upvoteIcon = icon
self.titleFont = titleFont
self.numberFont = numberFont
self.statusFont = statusFont
self.statusTintColor = statusTintColor
self.radius = cornerRadius
self.cellColor = cellColor
self.selectedForegroundColor = selectedColor
self.tintColor = tint
}
}
如果你不想配置自己的样式,你也可以使用模板之一。你可以选择 Standard
、Playful
、Classy
和 Technical
中的一个,选择最适合你应用的那个。
示例
struct ContentView: View {
let configuration = RoadmapConfiguration(
roadmapJSONURL: URL(string: "https://simplejsoncms.com/api/k2f11wikc6")!,
namespace: "roadmap",
style: RoadmapTemplate.playful.style, // You can also create your own RoadmapStyle
)
var body: some View {
RoadmapView(configuration: configuration)
}
}
默认情况下,Roadmap 将使用 Free Counting API 来存储投票,你可以查看他们的网站以获取更多信息。系统会为你提供一个命名空间,使用你应用程序的 bundle 标识符,但你可以在初始化 RoadmapConfiguration
时覆盖它。
let configuration = RoadmapConfiguration(
roadmapJSONURL: URL(string: "https://simplejsoncms.com/api/k2f11wikc6")!,
namespace: "my-custom-namespace"
)
如果你更愿意使用自己的 API,你可以创建一个新的结构体,使其符合 FeatureVoter
协议。这需要两个必需的函数,以便检索当前的投票数和投出新票。
struct CustomFeatureVoter: FeatureVoter {
var count = 0
func fetch(for feature: RoadmapFeature) async -> Int {
// query data from your API here
return count
}
func vote(for feature: RoadmapFeature) async -> Int? {
// push data to your API here
count += 1
return count
}
}
然后你可以将此结构体的实例传递给 RoadmapConfiguration
。
let configuration = RoadmapConfiguration(
roadmapJSONURL: URL(string: "https://simplejsoncms.com/api/k2f11wikc6")!,
voter: CustomFeatureVoter()
)
是的,如果用户已经对某个功能投过票,他们将无法在你的应用中再次投票。如果用户真的非常想要操纵你的投票,他们可以拦截你的网络流量并重放 API 调用。
Roadmap 带有四种不同的预配置样式,以匹配大多数应用。你可以更改 tintColor、赞成票图像等等。
为了保持 Roadmap 的开发轻松有趣,我们决定目前支持 iOS 15 及更高版本,以及 macOS Monterey 和 Ventura。
目前,功能列表以随机顺序加载。我们的想法是,这将防止对投票最多的功能产生偏见。我们将在未来研究使其成为可能的方法,但由于投票是在视图加载后检索的,因此我们需要对此进行研究。
Roadmap 不进行任何分析或跟踪。如果用户对某个功能投票,它只会增加 count API 上的一个数字。不存储任何标识符,甚至匿名标识符也不存储。
是的,我们希望保持 Roadmap 设置尽可能简单。如果你担心竞争对手(或真正想要某个特定功能的用户)搞乱你的优先级列表,也许可以使用其他方案。
非常欢迎!我们很乐意邀请你认领任何未解决的问题。我们将相应地审查你的 Pull Requests。
如果你已将 Roadmap 集成到你的应用中,并且想将其添加到此列表中,请提交 Pull Request。
这个库是由 Jordi Bruin、Hidde van der Ploeg 和 Antoine van der Lee 合作创建的。
Roadmap 在 MIT 许可下可用。有关更多信息,请参阅 LICENSE 文件。