您能提供一些建议,如何为Flutter中的api请求设计类吗?我是ios开发人员,我在alamofire中使用了单例类。如果您提供一些代码,那就太好了!
class Client: ApiBase {
static let shared = Client()
private override init() {}
func login(phoneNumber: String, password: String, completion: @escaping(_ error: String?) -> Void) {
let params: [String : String] = [
"userId" : phoneNumber,
"password" : password,
]
baseRequest(route: ApiRouter.login(), params: params) { (response) in
if let json = response.json {
Session.current.sessionId = json["sessionId"].string
}
completion(response.error)
}
}
}
登录方法的调用方式:
@IBAction func singin(_ sender: TransitionButton) {
Client.shared.login(phoneNumber: "12312", password: "123") { (error) in
guard error == nil else {
// show error
return
}
// navigate to home page
}
}
答案 0 :(得分:0)
在扑朔迷离中,您不必处理IBAction的相对麻烦,将协议作为回调或保留周期,而您需要async
和await
来提供帮助。
有几种方法可以进行API调用-一种是将它们简单地放在与UI相同的代码中。这有缺点,但肯定可以理解。
class WhateverMyComponentIsState extends State<WateverMyComponentIs> {
Future<String> _doLogin({@required String phoneNumber, @required String password}) async {
final response = await http.post(LOGIN_URL, body: {'userId': phoneNumber, 'password': password})
if (response.statusCode == 200) {
final jsonResponse = jsonDecode(body);
return jsonResponse['sessionId'];
} else {
... error handling
}
}
String phoneNumber;
String password;
@override
Widget build(BuildContext context) {
return ...(
child: FlatButton(
onPressed: () async {
final sessionId = await _doLogin(phoneNumber: phoneNumber, password: password);
... do whatever - setState(() => loggedIn = true), or Navigator.push ...
}
),
)
}
}
如果需要,您可以将所有api调用提取到另一个类中-它们可以是静态方法,但这使它变得更加难以编写良好的测试(如果您决定这样做)。
我个人的建议是使用一种或多或少的“依赖注入”形式,方法是利用InheritedWidget提供一个类的实现,该类实际执行登录(并且可以保存sessionId)。不过,您可以使用我个人非常喜欢的ScopedModel
plugin,而不是自己实现所有这些,因为它可以大大减少所需的样板数量。
如果您正确地使用了ScopedModel(我将在练习中留给我-我很确定还有其他问题),则可以使用它或它提供的类来执行http请求,然后sessionId
存储在ScopedModel中。
这样做的好处是,如果您要开始编写测试(或不得不处理两个服务器等),则可以用实现相同接口但不使用相同接口的另一个ScopedModel替换ScopedModel。实际执行http请求或以不同的方式执行它们。
答案 1 :(得分:0)
在混乱中,您应该创建一个类似这样的类
class User {
String name;
String pass;
User({
this.name,
this.pass,
});
User.fromJson(Map<String, dynamic> json) {
name = json['name'];
pass= json['pass'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['name'] = this.name;
data['pass'] = this.pass;
return data;
}
}
现在创建类似这样的User
类类型的列表
final List<User> user;
现在调用用户身份验证的URL(API)
Future<void> validateUsr() async {
var client = new http.Client();
try {
var response = await client.get(
'https://xxxxxxxx/wp-json/jwt-auth/v1/token?username=xxxxx2&password=xxxxxx');
if (response.statusCode == 200) {
var data = json.decode(response.body);
var list = data as List;
setState(() {
user=list.map<User>((i) => User.fromJson(i)).toList();
});
} else {
print('Somthing went wrong');
}
} catch (e) {
print(e);
} finally {
client.close();
}
}
希望这对您有帮助