Ios 在flatter中调用API不会';t在第一次加载应用程序时加载所需的JSON-颤振

Ios 在flatter中调用API不会';t在第一次加载应用程序时加载所需的JSON-颤振,ios,api,dart,cross-platform,flutter,Ios,Api,Dart,Cross Platform,Flutter,我最近在学习用flatter编写代码,并在iOS上使用它构建了一个应用程序。因此,我想用NASA APOD API制作一个 我创建了一个简单的UI,并设置了一个带有图像视图的卡,该卡将在从API的JSON传递url后加载图像 JSON: { "copyright": "Panther Observatory", "date": "2006-04-15", "explanation": "In this stunning cosmic vista, galaxy M81 is on the l

我最近在学习用flatter编写代码,并在iOS上使用它构建了一个应用程序。因此,我想用NASA APOD API制作一个

我创建了一个简单的UI,并设置了一个带有图像视图的卡,该卡将在从API的JSON传递url后加载图像

JSON:

{
"copyright": "Panther Observatory", 
"date": "2006-04-15", 
"explanation": "In this stunning cosmic vista, galaxy M81 is on the left surrounded by blue spiral arms.  On the right marked by massive gas and dust clouds, is M82.  These two mammoth galaxies have been locked in gravitational combat for the past billion years.   The gravity from each galaxy dramatically affects the other during each hundred million-year pass.  Last go-round, M82's gravity likely raised density waves rippling around M81, resulting in the richness of M81's spiral arms.  But M81 left M82 with violent star forming regions and colliding gas clouds so energetic the galaxy glows in X-rays.  In a few billion years only one galaxy will remain.", 
"hdurl": "https://apod.nasa.gov/apod/image/0604/M81_M82_schedler_c80.jpg", 
"media_type": "image", 
"service_version": "v1", 
"title": "Galaxy Wars: M81 versus M82", 
"url": "https://apod.nasa.gov/apod/image/0604/M81_M82_schedler_c25.jpg" },
现在我从这个JSON获取URL,并将其转换为字符串,然后将其传递给
Image.Network
函数

当我第一次运行应用程序时。图像未加载,并向我抛出一个错误

但是在我点击VisualStudio代码调试器控制台上的刷新按钮之后

代码将运行并提供所需的输出

所以问题是,第一次加载应用程序时,它总是抛出一个错误,表示url未定义,但在刷新应用程序后,图像和从API调用加载的所有数据都会出错
在这种情况下会有什么错误。我认为这与颤振状态有关。感谢您的帮助

这是密码

import 'package:flutter/material.dart';
import 'dart:async';
import 'dart:convert';
import 'package:http/http.dart' as http;

class Home extends StatefulWidget {
  @override
  StateApodCall createState() => new StateApodCall();
}

class StateApodCall extends State<Home> {
  final url = "https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY";
  List resBody;
  String imageUrl;
  String imageTitle;

  Future<String> getAPODData() async{
    var res = await http
    .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});

    var resBody = json.decode(res.body);
    print(resBody);
    print(resBody["copyright"]);
    imageUrl = resBody["hdurl"];
    imageTitle = resBody["title"];
    print(imageUrl);
    return "Success!!";
  }

  @override
  initState() {
    super.initState();
    this.getAPODData();
  }

  @override
  Widget build(BuildContext context) {
    return new Container(
      decoration: new BoxDecoration(
        gradient: new LinearGradient(
          colors: [
            const Color(0xFF1ca2e3),
            const Color(0xFF1450a3)
          ],
          begin: const FractionalOffset(1.0, 0.5),
          end: const FractionalOffset(0.3, 0.1),
          stops: [0.0, 0.5],
          tileMode: TileMode.clamp
        ),
      ),
      child: new Scaffold(
        backgroundColor: Colors.transparent,
        appBar: new AppBar(
          backgroundColor: const Color(0xFF124489),
          elevation: 20.0,
          leading: new IconButton(
            icon: new Icon(Icons.menu),
            onPressed: () {

            }
          ),
          title: new Text(
            "APOD",
            style: const TextStyle(
              color: Colors.white,
              fontFamily: 'Poppins',
              fontWeight: FontWeight.w600,
              fontSize: 34.0
              ),
            ),
        ),
        body: new ListView(
          children : [
            new Card(
              elevation: 3.0,
              child: new Column(
                children: [
                  new Image.network(
                    imageUrl,
                    width: double.infinity,
                    fit: BoxFit.fitWidth,
                  ),
                ],
              ),
            ),
            new Card(
              elevation: 2.0,
              child: new Text(imageTitle),
            ),
          ],
        ),
      )
    );
  }
}
导入“包装:颤振/材料.省道”;
导入“dart:async”;
导入“dart:convert”;
将“package:http/http.dart”导入为http;
类Home扩展了StatefulWidget{
@凌驾
StateApodCall createState()=>新StateApodCall();
}
类StateApodCall扩展状态{
最终url=”https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY";
名单正文;
字符串imageUrl;
字符串图像标题;
未来的getAPODData()异步{
var res=等待http
.get(Uri.encodeFull(url),头:{“接受”:“应用程序/json”});
var resBody=json.decode(res.body);
打印(正文);
印刷品(版权所有);
imageUrl=resBody[“hdurl”];
imageTitle=resBody[“title”];
打印(imageUrl);
返回“成功!!”;
}
@凌驾
initState(){
super.initState();
这个。getapodata();
}
@凌驾
小部件构建(构建上下文){
退回新货柜(
装饰:新盒子装饰(
渐变:新的线性渐变(
颜色:[
常量颜色(0xFF1ca2e3),
常量颜色(0xFF1450a3)
],
开始:常量分数偏移(1.0,0.5),
结束:常量分数偏移(0.3,0.1),
停止:[0.0,0.5],
tileMode:tileMode.clamp
),
),
儿童:新脚手架(
背景颜色:颜色。透明,
appBar:新的appBar(
背景颜色:常量颜色(0xFF124489),
标高:20.0,
领先:新图标按钮(
图标:新图标(图标菜单),
已按下:(){
}
),
标题:新文本(
“APOD”,
样式:consttextstyle(
颜色:颜色,白色,
fontFamily:“罂粟花”,
fontWeight:fontWeight.w600,
字体大小:34.0
),
),
),
正文:新列表视图(
儿童:[
新卡(
标高:3.0,
子:新列(
儿童:[
新图像网络(
imageUrl,
宽度:double.infinity,
适合:BoxFit.fitWidth,
),
],
),
),
新卡(
标高:2.0,
子项:新文本(imageTitle),
),
],
),
)
);
}
}

有多种方法可以解决此问题。您只需添加一个
ProgressIndicator
,当API调用完成时,它将被
ListView
替换

imageUrl!=null? new ListView(
//build
) : new Center(child:new CircularProgressIndicator()),
设置url时不要忘记添加
setState()
调用

setState((){
imageUrl = resBody["hdurl"];
});

为了解决这个问题,我在嵌套语句的主体中添加了这段代码

body: imageUrl != null ? new ListView(
      children: [
          new Card(
            elevation: 3.0,
            child: new Column(
              children: [
                new Image.network(
                  imageUrl,
                  width: double.infinity,
                  fit: BoxFit.fitWidth,
                ),
              ],
            ),
          ),
          new Card(
            elevation: 2.0,
            child: new Text(imageTitle),
          )
        ],
    ) : new Center(child:new CircularProgressIndicator(
      strokeWidth: 3.0,
    )),
还包括
setState
功能

this.setState((){
  resBody = json.decode(res.body);
  imageUrl = resBody["hdurl"];
  imageTitle = resBody["title"];
});

从Android API 28和iOS 9开始,这些平台默认禁用不安全的HTTP连接

随着这一变化,颤振也会禁用移动平台上的不安全连接。其他平台(桌面、web等)不受影响

您可以通过遵循特定于平台的准则来定义特定于域的网络策略来覆盖此行为。有关详细信息,请参阅下面的迁移指南

与平台非常相似,应用程序仍然可以打开不安全的套接字连接。颤振不在套接字级别强制执行任何策略;您将负责确保连接的安全


请阅读本指南

哇,非常感谢!成功了,谢谢你的快速回复!:)你知道如何使它成为一个确定的进度条吗!因为他们说把值设为非空,但我不能