├── android ├── gradle.properties ├── .settings │ └── org.eclipse.buildship.core.prefs ├── app │ ├── .settings │ │ └── org.eclipse.buildship.core.prefs │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ ├── values │ │ │ │ └── styles.xml │ │ │ └── drawable │ │ │ │ └── launch_background.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── yourcompany │ │ │ │ └── gankflutter │ │ │ │ └── MainActivity.java │ │ │ └── AndroidManifest.xml │ ├── .classpath │ ├── .project │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── .gitignore ├── .project ├── settings.gradle ├── build.gradle ├── gradlew.bat └── gradlew ├── ios ├── Flutter │ ├── Debug.xcconfig │ ├── Release.xcconfig │ └── AppFrameworkInfo.plist ├── Runner │ ├── AppDelegate.h │ ├── Assets.xcassets │ │ ├── LaunchImage.imageset │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ ├── README.md │ │ │ └── Contents.json │ │ └── AppIcon.appiconset │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ └── Contents.json │ ├── main.m │ ├── AppDelegate.m │ ├── Base.lproj │ │ ├── Main.storyboard │ │ └── LaunchScreen.storyboard │ └── Info.plist ├── Runner.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ ├── xcshareddata │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ └── project.pbxproj ├── Runner.xcworkspace │ └── contents.xcworkspacedata ├── .gitignore ├── Podfile.lock └── Podfile ├── screenshots ├── screenshot_x01.png ├── screenshot_x02.png └── screenshot_x03.png ├── lib ├── main.dart └── app │ ├── data │ ├── pojo │ │ ├── photo.dart │ │ └── gank.dart │ └── repository │ │ ├── remote_repository.dart │ │ ├── cache_repository.dart │ │ ├── injector.dart │ │ └── remote_repository_impl.dart │ ├── util │ └── constants.dart │ ├── app.dart │ └── module │ └── home │ ├── home_contract.dart │ ├── home.dart │ ├── photo_widget.dart │ └── gank_list_widget.dart ├── .gitignore ├── .metadata ├── .vscode └── launch.json ├── test └── widget_test.dart ├── android.iml ├── gank_flutter.iml ├── README.md ├── gank_flutter_android.iml └── pubspec.yaml /android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | -------------------------------------------------------------------------------- /ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include "Generated.xcconfig" 2 | -------------------------------------------------------------------------------- /android/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | #Sat Jan 06 11:25:50 CST 2018 2 | connection.project.dir= 3 | -------------------------------------------------------------------------------- /android/app/.settings/org.eclipse.buildship.core.prefs: -------------------------------------------------------------------------------- 1 | #Sat Jan 06 11:25:50 CST 2018 2 | connection.project.dir=.. 3 | -------------------------------------------------------------------------------- /screenshots/screenshot_x01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/screenshots/screenshot_x01.png -------------------------------------------------------------------------------- /screenshots/screenshot_x02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/screenshots/screenshot_x02.png -------------------------------------------------------------------------------- /screenshots/screenshot_x03.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/screenshots/screenshot_x03.png -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/android/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:gank_flutter/app/app.dart'; 3 | 4 | void main() => runApp(new GankApp()); 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .atom/ 3 | .idea 4 | .packages 5 | .pub/ 6 | build/ 7 | ios/.generated/ 8 | packages 9 | pubspec.lock 10 | .flutter-plugins 11 | -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /lib/app/data/pojo/photo.dart: -------------------------------------------------------------------------------- 1 | class Photo { 2 | Photo({ 3 | this.url, 4 | this.title, 5 | }); 6 | 7 | final String title; 8 | final String url; 9 | } -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | GeneratedPluginRegistrant.java 10 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/saymagic/gank_flutter/HEAD/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /lib/app/data/repository/remote_repository.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:gank_flutter/app/data/pojo/gank.dart'; 4 | 5 | 6 | abstract class GankRepository{ 7 | 8 | Future> fetch(String category, int size); 9 | 10 | } -------------------------------------------------------------------------------- /ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: 8f65fec5f5f7d7afbb0965f4a44bdb330a28fb19 8 | channel: alpha 9 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // 使用 IntelliSense 了解相关属性。 3 | // 悬停以查看现有属性的描述。 4 | // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | { 9 | "name": "Flutter mobile app", 10 | "request": "launch", 11 | "type": "flutter" 12 | } 13 | ] 14 | } -------------------------------------------------------------------------------- /android/app/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /lib/app/util/constants.dart: -------------------------------------------------------------------------------- 1 | 2 | final String KEY_ANDROID = "Android"; 3 | final String KEY_IOS = "iOS"; 4 | final String KEY_WELFARE = "福利"; 5 | final String KEY_WEB= "前端"; 6 | final String KEY_VIDEO = "休息视频"; 7 | final String KEY_APP = "App"; 8 | final String KEY_EXPAND_RESOURCSES = "拓展资源"; 9 | final String KEY_RECOMMENDED = "瞎推荐"; 10 | final String KEY_ALL = "all"; 11 | 12 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | -------------------------------------------------------------------------------- /ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #include "AppDelegate.h" 2 | #include "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 7 | [GeneratedPluginRegistrant registerWithRegistry:self]; 8 | // Override point for customization after application launch. 9 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 10 | } 11 | 12 | @end 13 | -------------------------------------------------------------------------------- /android/app/src/main/java/com/yourcompany/gankflutter/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.yourcompany.gankflutter; 2 | 3 | import android.os.Bundle; 4 | 5 | import io.flutter.app.FlutterActivity; 6 | import io.flutter.plugins.GeneratedPluginRegistrant; 7 | 8 | public class MainActivity extends FlutterActivity { 9 | @Override 10 | protected void onCreate(Bundle savedInstanceState) { 11 | super.onCreate(savedInstanceState); 12 | GeneratedPluginRegistrant.registerWith(this); 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /android/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | android 4 | Project android created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.buildship.core.gradleprojectbuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.buildship.core.gradleprojectnature 16 | 17 | 18 | -------------------------------------------------------------------------------- /android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def flutterProjectRoot = rootProject.projectDir.parentFile.toPath() 4 | 5 | def plugins = new Properties() 6 | def pluginsFile = new File(flutterProjectRoot.toFile(), '.flutter-plugins') 7 | if (pluginsFile.exists()) { 8 | pluginsFile.withInputStream { stream -> plugins.load(stream) } 9 | } 10 | 11 | plugins.each { name, path -> 12 | def pluginDirectory = flutterProjectRoot.resolve(path).resolve('android').toFile() 13 | include ":$name" 14 | project(":$name").projectDir = pluginDirectory 15 | } 16 | -------------------------------------------------------------------------------- /test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // To perform an interaction with a widget in your test, use the WidgetTester utility that Flutter 3 | // provides. For example, you can send tap and scroll gestures. You can also use WidgetTester to 4 | // find child widgets in the widget tree, read text, and verify that the values of widget properties 5 | // are correct. 6 | 7 | import 'package:flutter/material.dart'; 8 | import 'package:flutter_test/flutter_test.dart'; 9 | 10 | import 'package:gank_flutter/main.dart'; 11 | 12 | void main() { 13 | 14 | } 15 | -------------------------------------------------------------------------------- /android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /lib/app/data/pojo/gank.dart: -------------------------------------------------------------------------------- 1 | 2 | class Gank { 3 | 4 | final String author; 5 | 6 | final String url; 7 | 8 | final String desc; 9 | 10 | final String type; 11 | 12 | final List pics; 13 | 14 | Gank(this.author, this.url, this.type, this.desc, this.pics); 15 | 16 | static Gank fromMap(Map map) { 17 | if(map["who"] == null){ 18 | map["who"] = ""; 19 | } 20 | if(map["desc"] == null){ 21 | map["desc"] = ""; 22 | } 23 | if(map["url"] == null){ 24 | map["url"] = ""; 25 | } 26 | return new Gank(map["who"], map["url"], map['type'], map["desc"], map["pics"]); 27 | } 28 | 29 | } -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | *.pbxuser 16 | *.mode1v3 17 | *.mode2v3 18 | *.perspectivev3 19 | 20 | !default.pbxuser 21 | !default.mode1v3 22 | !default.mode2v3 23 | !default.perspectivev3 24 | 25 | xcuserdata 26 | 27 | *.moved-aside 28 | 29 | *.pyc 30 | *sync/ 31 | Icon? 32 | .tags* 33 | 34 | /Flutter/app.flx 35 | /Flutter/app.zip 36 | /Flutter/App.framework 37 | /Flutter/Flutter.framework 38 | /Flutter/Generated.xcconfig 39 | /ServiceDefinitions.json 40 | 41 | Pods/ 42 | -------------------------------------------------------------------------------- /android/app/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | app 4 | Project app created by Buildship. 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.buildship.core.gradleprojectbuilder 15 | 16 | 17 | 18 | 19 | 20 | org.eclipse.jdt.core.javanature 21 | org.eclipse.buildship.core.gradleprojectnature 22 | 23 | 24 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | repositories { 3 | jcenter() 4 | maven { 5 | url "https://maven.google.com" 6 | } 7 | } 8 | 9 | dependencies { 10 | classpath 'com.android.tools.build:gradle:2.3.3' 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | jcenter() 17 | maven { 18 | url "https://maven.google.com" 19 | } 20 | } 21 | } 22 | 23 | rootProject.buildDir = '../build' 24 | subprojects { 25 | project.buildDir = "${rootProject.buildDir}/${project.name}" 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - url_launcher (0.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `/Users/saymagic/Library/flutter/bin/cache/artifacts/engine/ios`) 8 | - url_launcher (from `/Users/saymagic/.pub-cache/hosted/pub.dartlang.org/url_launcher-0.4.2+5/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: /Users/saymagic/Library/flutter/bin/cache/artifacts/engine/ios 13 | url_launcher: 14 | :path: /Users/saymagic/.pub-cache/hosted/pub.dartlang.org/url_launcher-0.4.2+5/ios 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: d674e78c937094a75ac71dd77e921e840bea3dbf 18 | url_launcher: 0067ddb8f10d36786672aa0722a21717dba3a298 19 | 20 | PODFILE CHECKSUM: 351e02e34b831289961ec3558a535cbd2c4965d2 21 | 22 | COCOAPODS: 1.3.1 23 | -------------------------------------------------------------------------------- /lib/app/data/repository/cache_repository.dart: -------------------------------------------------------------------------------- 1 | import 'package:gank_flutter/app/data/pojo/gank.dart'; 2 | 3 | 4 | abstract class CacheRepository { 5 | 6 | List get(String category); 7 | 8 | void save(String category, List ganks); 9 | 10 | } 11 | 12 | class CacheRepositoryImpl extends CacheRepository { 13 | 14 | Map> map = new Map(); 15 | 16 | @override 17 | List get(String category) { 18 | List ganks = map[category]; 19 | return ganks == null ? new List() : ganks; 20 | } 21 | 22 | @override 23 | void save(String category, List ganks) { 24 | List originGanks = map[category]; 25 | List newGanks = new List(); 26 | if (originGanks == null) { 27 | newGanks.addAll(ganks); 28 | } else { 29 | newGanks.addAll(ganks); 30 | newGanks.addAll(originGanks); 31 | } 32 | map[category] = newGanks; 33 | } 34 | } -------------------------------------------------------------------------------- /ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | UIRequiredDeviceCapabilities 24 | 25 | arm64 26 | 27 | MinimumOSVersion 28 | 8.0 29 | 30 | 31 | -------------------------------------------------------------------------------- /gank_flutter.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # gank_flutter 2 | 3 | [Gank](http://gank.io/) Client for Mobile made with Flutter 4 | 5 |
6 | 9 | 12 | 15 | 16 |
7 | 8 | 10 | 11 | 13 | 14 |
17 |
18 | 19 | ## Getting Started 20 | 21 | #### 1. [Setup Flutter](https://flutter.io/setup/) 22 | #### 2. Clone the repo 23 | ```sh 24 | $ git clone https://github.com/saymagic/gank_flutter.git 25 | $ cd gank_flutter/ 26 | ``` 27 | 28 | ## Run app 29 | 30 | You need latest version of Flutter installed in your system for build and run the project. 31 | 32 | ```sh 33 | $ flutter run 34 | ``` 35 | 36 | ## Licences 37 | 38 | Mit 39 | 40 | 41 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | if ENV['FLUTTER_FRAMEWORK_DIR'] == nil 5 | abort('Please set FLUTTER_FRAMEWORK_DIR to the directory containing Flutter.framework') 6 | end 7 | 8 | target 'Runner' do 9 | # Pods for Runner 10 | 11 | # Flutter Pods 12 | pod 'Flutter', :path => ENV['FLUTTER_FRAMEWORK_DIR'] 13 | 14 | if File.exists? '../.flutter-plugins' 15 | flutter_root = File.expand_path('..') 16 | File.foreach('../.flutter-plugins') { |line| 17 | plugin = line.split(pattern='=') 18 | if plugin.length == 2 19 | name = plugin[0].strip() 20 | path = plugin[1].strip() 21 | resolved_path = File.expand_path("#{path}/ios", flutter_root) 22 | pod name, :path => resolved_path 23 | else 24 | puts "Invalid plugin specification: #{line}" 25 | end 26 | } 27 | end 28 | end 29 | 30 | post_install do |installer| 31 | installer.pods_project.targets.each do |target| 32 | target.build_configurations.each do |config| 33 | config.build_settings['ENABLE_BITCODE'] = 'NO' 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/app/app.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:gank_flutter/app/data/repository/injector.dart'; 3 | import 'package:gank_flutter/app/module/home/home.dart'; 4 | 5 | class GankApp extends StatelessWidget { 6 | 7 | @override 8 | Widget build(BuildContext context) { 9 | Injector.configureFlavor(Flavor.PROD); 10 | return new MaterialApp( 11 | title: 'Gank', 12 | theme: new ThemeData( 13 | // This is the theme of your application. 14 | // 15 | // Try running your application with "flutter run". You'll see the 16 | // application has a blue toolbar. Then, without quitting the app, try 17 | // changing the primarySwatch below to Colors.green and then invoke 18 | // "hot reload" (press "r" in the console where you ran "flutter run", 19 | // or press Run > Flutter Hot Reload in IntelliJ). Notice that the 20 | // counter didn't reset back to zero; the application is not restarted. 21 | primarySwatch: Colors.indigo, 22 | ), 23 | home: new HomePage(), 24 | ); 25 | } 26 | 27 | 28 | } -------------------------------------------------------------------------------- /lib/app/data/repository/injector.dart: -------------------------------------------------------------------------------- 1 | import 'package:gank_flutter/app/data/repository/cache_repository.dart'; 2 | import 'package:gank_flutter/app/data/repository/remote_repository.dart'; 3 | import 'package:gank_flutter/app/data/repository/remote_repository_impl.dart'; 4 | 5 | enum Flavor { 6 | MOCK, 7 | PROD 8 | } 9 | 10 | class Injector { 11 | 12 | static final Injector _singleton = new Injector._internal(); 13 | 14 | static final CacheRepository _cache = new CacheRepositoryImpl(); 15 | 16 | static final GankRepository _remote = new GankRepositoryImpl(); 17 | static Flavor _flavor; 18 | 19 | static configureFlavor(Flavor flavor) { 20 | _flavor = flavor; 21 | } 22 | 23 | factory Injector() { 24 | return _singleton; 25 | } 26 | 27 | Injector._internal(); 28 | 29 | GankRepository get remoteRepository { 30 | switch (_flavor) { 31 | case Flavor.MOCK: 32 | return new GankRepositoryImpl(); 33 | break; 34 | default: 35 | return _remote; 36 | } 37 | } 38 | 39 | CacheRepository get cacheRepository { 40 | switch (_flavor) { 41 | case Flavor.MOCK: 42 | return new CacheRepositoryImpl(); 43 | break; 44 | default: 45 | return _cache; 46 | } 47 | } 48 | 49 | } -------------------------------------------------------------------------------- /lib/app/data/repository/remote_repository_impl.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'package:flutter/services.dart'; 4 | import 'package:gank_flutter/app/data/pojo/gank.dart'; 5 | import 'package:gank_flutter/app/data/repository/remote_repository.dart'; 6 | 7 | final String HOST_URL = "https://gank.io/api/random/data/"; 8 | 9 | 10 | class GankRepositoryImpl extends GankRepository { 11 | 12 | var httpClient = createHttpClient(); 13 | 14 | @override 15 | Future> fetch(String category, int size) async{ 16 | String url = HOST_URL + category + "/" + size.toString(); 17 | print("fetch " + url); 18 | var response = await httpClient.get(url); 19 | print('response status: ${response.statusCode}'); 20 | if (response.statusCode == 200) { 21 | Map data = JSON.decode(response.body); 22 | if (data != null && data["error"] == false) { 23 | List gankList = data["results"].map((obj) => 24 | Gank.fromMap(obj)).toList(); 25 | print("article size ${gankList.length}"); 26 | return gankList; 27 | } 28 | } 29 | throw new FetchDataException("fetch error"); 30 | } 31 | } 32 | 33 | class FetchDataException implements Exception { 34 | String _message; 35 | 36 | FetchDataException(this._message); 37 | 38 | String toString() { 39 | return "Exception: $_message"; 40 | } 41 | } -------------------------------------------------------------------------------- /gank_flutter_android.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/app/module/home/home_contract.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:gank_flutter/app/data/pojo/gank.dart'; 4 | import 'package:gank_flutter/app/data/repository/injector.dart'; 5 | 6 | 7 | abstract class GankHomeViewContract { 8 | 9 | void setPresenter(GankHomePresenterContract presenter); 10 | 11 | bool isMounted(); 12 | 13 | void showNewGanks(List ganks); 14 | 15 | void showLoadError(); 16 | 17 | void showLoading(); 18 | 19 | } 20 | 21 | abstract class GankHomePresenterContract { 22 | void loadGanks(String category, int size, Completer completer); 23 | } 24 | 25 | class GankHomePresenterContractImpl extends GankHomePresenterContract { 26 | 27 | GankHomeViewContract _view; 28 | 29 | Injector _injector = new Injector(); 30 | 31 | List ganks = new List(); 32 | 33 | GankHomePresenterContractImpl(this._view) { 34 | _view.setPresenter(this); 35 | } 36 | 37 | @override 38 | void loadGanks(String category, int size, Completer completer) { 39 | List cacheGanks = _injector.cacheRepository.get(category); 40 | if(completer == null && cacheGanks.isNotEmpty){ 41 | _view.showNewGanks(cacheGanks); 42 | return; 43 | } 44 | _view.showLoading(); 45 | new Injector().remoteRepository.fetch(category, size) 46 | .then((ganks) { 47 | if (_view.isMounted()) { 48 | _injector.cacheRepository.save(category, ganks); 49 | _view.showNewGanks(_injector.cacheRepository.get(category)); 50 | } 51 | }).catchError((error) { 52 | print(error); 53 | _view.showLoadError(); 54 | }).whenComplete(() { 55 | if(completer != null){ 56 | completer.complete(); 57 | } 58 | }); 59 | } 60 | 61 | 62 | } 63 | 64 | -------------------------------------------------------------------------------- /ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | gank_flutter 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UIRequiredDeviceCapabilities 30 | 31 | arm64 32 | 33 | UISupportedInterfaceOrientations 34 | 35 | UIInterfaceOrientationPortrait 36 | UIInterfaceOrientationLandscapeLeft 37 | UIInterfaceOrientationLandscapeRight 38 | 39 | UISupportedInterfaceOrientations~ipad 40 | 41 | UIInterfaceOrientationPortrait 42 | UIInterfaceOrientationPortraitUpsideDown 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationLandscapeRight 45 | 46 | UIViewControllerBasedStatusBarAppearance 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withInputStream { stream -> 5 | localProperties.load(stream) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | apply plugin: 'com.android.application' 15 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 16 | 17 | android { 18 | compileSdkVersion 25 19 | buildToolsVersion '25.0.3' 20 | 21 | lintOptions { 22 | disable 'InvalidPackage' 23 | } 24 | 25 | defaultConfig { 26 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 27 | applicationId "com.yourcompany.gankflutter" 28 | minSdkVersion 16 29 | targetSdkVersion 25 30 | versionCode 1 31 | versionName "1.0" 32 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 33 | } 34 | 35 | buildTypes { 36 | release { 37 | // TODO: Add your own signing config for the release build. 38 | // Signing with the debug keys for now, so `flutter run --release` works. 39 | signingConfig signingConfigs.debug 40 | } 41 | } 42 | } 43 | 44 | flutter { 45 | source '../..' 46 | } 47 | 48 | dependencies { 49 | androidTestCompile 'com.android.support:support-annotations:25.4.0' 50 | androidTestCompile 'com.android.support.test:runner:0.5' 51 | androidTestCompile 'com.android.support.test:rules:0.5' 52 | } 53 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: gank_flutter 2 | description: A new Flutter project. 3 | 4 | dependencies: 5 | flutter: 6 | sdk: flutter 7 | http: '>=0.11.3+12' 8 | url_launcher: ^0.4.1 9 | # The following adds the Cupertino Icons font to your application. 10 | # Use with the CupertinoIcons class for iOS style icons. 11 | cupertino_icons: ^0.1.0 12 | 13 | dev_dependencies: 14 | flutter_test: 15 | sdk: flutter 16 | 17 | 18 | # For information on the generic Dart part of this file, see the 19 | # following page: https://www.dartlang.org/tools/pub/pubspec 20 | 21 | # The following section is specific to Flutter. 22 | flutter: 23 | 24 | # The following line ensures that the Material Icons font is 25 | # included with your application, so that you can use the icons in 26 | # the material Icons class. 27 | uses-material-design: true 28 | 29 | # To add assets to your application, add an assets section, like this: 30 | # assets: 31 | # - images/a_dot_burr.jpeg 32 | # - images/a_dot_ham.jpeg 33 | 34 | # An image asset can refer to one or more resolution-specific "variants", see 35 | # https://flutter.io/assets-and-images/#resolution-aware. 36 | 37 | # For details regarding adding assets from package dependencies, see 38 | # https://flutter.io/assets-and-images/#from-packages 39 | 40 | # To add custom fonts to your application, add a fonts section here, 41 | # in this "flutter" section. Each entry in this list should have a 42 | # "family" key with the font family name, and a "fonts" key with a 43 | # list giving the asset and other descriptors for the font. For 44 | # example: 45 | # fonts: 46 | # - family: Schyler 47 | # fonts: 48 | # - asset: fonts/Schyler-Regular.ttf 49 | # - asset: fonts/Schyler-Italic.ttf 50 | # style: italic 51 | # - family: Trajan Pro 52 | # fonts: 53 | # - asset: fonts/TrajanPro.ttf 54 | # - asset: fonts/TrajanPro_Bold.ttf 55 | # weight: 700 56 | # 57 | # For details regarding fonts from package dependencies, 58 | # see https://flutter.io/custom-fonts/#from-packages 59 | -------------------------------------------------------------------------------- /android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 10 | 15 | 19 | 26 | 30 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/app/module/home/home.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:gank_flutter/app/module/home/gank_list_widget.dart'; 3 | import 'package:gank_flutter/app/util/constants.dart'; 4 | 5 | class HomePage extends StatefulWidget { 6 | 7 | @override 8 | HomePageState createState() => new HomePageState(); 9 | 10 | } 11 | 12 | class HomePageState extends State 13 | with SingleTickerProviderStateMixin { 14 | 15 | final GlobalKey _scaffoldKey = new GlobalKey(); 16 | 17 | TabController _tabController; 18 | _Page _selectedPage; 19 | bool _changed; 20 | 21 | @override 22 | void initState() { 23 | super.initState(); 24 | _tabController = new TabController(vsync: this, length: _pages.length); 25 | _tabController.addListener(_handleTabSelection); 26 | _selectedPage = _pages[0]; 27 | } 28 | 29 | void _handleTabSelection() { 30 | setState(() { 31 | _selectedPage = _pages[_tabController.index]; 32 | }); 33 | } 34 | 35 | @override 36 | void dispose() { 37 | _tabController.dispose(); 38 | super.dispose(); 39 | } 40 | 41 | Widget buildTabWidget(_Page page) { 42 | return new GankListPage(page.key, 20); 43 | } 44 | 45 | @override 46 | Widget build(BuildContext context) { 47 | return new Scaffold( 48 | key: _scaffoldKey, 49 | appBar: new AppBar( 50 | title: const Text("Gank"), 51 | bottom: new TabBar( 52 | isScrollable: true, 53 | controller: _tabController, 54 | tabs: _pages.map((_Page page) => new Tab(text: page.label,)) 55 | .toList(), 56 | ), 57 | ), 58 | body: new TabBarView( 59 | controller: _tabController, 60 | children: _pages.map(buildTabWidget).toList()), 61 | ); 62 | } 63 | 64 | } 65 | 66 | 67 | class _Page { 68 | 69 | _Page({this.key, this.label}); 70 | 71 | final String key; 72 | 73 | final String label; 74 | 75 | } 76 | 77 | final List<_Page> _pages = <_Page>[ 78 | new _Page(key: KEY_ANDROID, label: KEY_ANDROID), 79 | new _Page(key: KEY_IOS, label: KEY_IOS), 80 | new _Page(key: KEY_WELFARE, label: KEY_WELFARE), 81 | new _Page(key: KEY_WEB, label: KEY_WEB), 82 | new _Page(key: KEY_VIDEO, label: KEY_VIDEO), 83 | new _Page(key: KEY_APP, label: KEY_APP), 84 | new _Page(key: KEY_EXPAND_RESOURCSES, label: KEY_EXPAND_RESOURCSES), 85 | new _Page(key: KEY_RECOMMENDED, label: KEY_RECOMMENDED), 86 | new _Page(key: KEY_ALL, label: "随便看看"), 87 | ]; -------------------------------------------------------------------------------- /android/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | } 111 | ], 112 | "info" : { 113 | "version" : 1, 114 | "author" : "xcode" 115 | } 116 | } 117 | -------------------------------------------------------------------------------- /lib/app/module/home/photo_widget.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:gank_flutter/app/data/pojo/photo.dart'; 3 | 4 | const double _kMinFlingVelocity = 800.0; 5 | 6 | 7 | class GridPhotoViewer extends StatefulWidget { 8 | const GridPhotoViewer({ Key key, this.photo }) : super(key: key); 9 | 10 | final Photo photo; 11 | 12 | @override 13 | _GridPhotoViewerState createState() => new _GridPhotoViewerState(); 14 | } 15 | 16 | class _GridPhotoViewerState extends State with SingleTickerProviderStateMixin { 17 | AnimationController _controller; 18 | Animation _flingAnimation; 19 | Offset _offset = Offset.zero; 20 | double _scale = 1.0; 21 | Offset _normalizedOffset; 22 | double _previousScale; 23 | 24 | @override 25 | void initState() { 26 | super.initState(); 27 | _controller = new AnimationController(vsync: this) 28 | ..addListener(_handleFlingAnimation); 29 | } 30 | 31 | @override 32 | void dispose() { 33 | _controller.dispose(); 34 | super.dispose(); 35 | } 36 | 37 | // The maximum offset value is 0,0. If the size of this renderer's box is w,h 38 | // then the minimum offset value is w - _scale * w, h - _scale * h. 39 | Offset _clampOffset(Offset offset) { 40 | final Size size = context.size; 41 | final Offset minOffset = new Offset(size.width, size.height) * (1.0 - _scale); 42 | return new Offset(offset.dx.clamp(minOffset.dx, 0.0), offset.dy.clamp(minOffset.dy, 0.0)); 43 | } 44 | 45 | void _handleFlingAnimation() { 46 | setState(() { 47 | _offset = _flingAnimation.value; 48 | }); 49 | } 50 | 51 | void _handleOnScaleStart(ScaleStartDetails details) { 52 | setState(() { 53 | _previousScale = _scale; 54 | _normalizedOffset = (details.focalPoint - _offset) / _scale; 55 | // The fling animation stops if an input gesture starts. 56 | _controller.stop(); 57 | }); 58 | } 59 | 60 | void _handleOnScaleUpdate(ScaleUpdateDetails details) { 61 | setState(() { 62 | _scale = (_previousScale * details.scale).clamp(1.0, 4.0); 63 | // Ensure that image location under the focal point stays in the same place despite scaling. 64 | _offset = _clampOffset(details.focalPoint - _normalizedOffset * _scale); 65 | }); 66 | } 67 | 68 | void _handleOnScaleEnd(ScaleEndDetails details) { 69 | final double magnitude = details.velocity.pixelsPerSecond.distance; 70 | if (magnitude < _kMinFlingVelocity) 71 | return; 72 | final Offset direction = details.velocity.pixelsPerSecond / magnitude; 73 | final double distance = (Offset.zero & context.size).shortestSide; 74 | _flingAnimation = new Tween( 75 | begin: _offset, 76 | end: _clampOffset(_offset + direction * distance) 77 | ).animate(_controller); 78 | _controller 79 | ..value = 0.0 80 | ..fling(velocity: magnitude / 1000.0); 81 | } 82 | 83 | @override 84 | Widget build(BuildContext context) { 85 | return new GestureDetector( 86 | onScaleStart: _handleOnScaleStart, 87 | onScaleUpdate: _handleOnScaleUpdate, 88 | onScaleEnd: _handleOnScaleEnd, 89 | child: new ClipRect( 90 | child: new Transform( 91 | transform: new Matrix4.identity() 92 | ..translate(_offset.dx, _offset.dy) 93 | ..scale(_scale), 94 | child: new Image.network( 95 | widget.photo.url, 96 | fit: BoxFit.cover, 97 | ), 98 | ), 99 | ), 100 | ); 101 | } 102 | } -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 31 | 32 | 33 | 34 | 40 | 41 | 42 | 43 | 44 | 45 | 56 | 58 | 64 | 65 | 66 | 67 | 68 | 69 | 75 | 77 | 83 | 84 | 85 | 86 | 88 | 89 | 92 | 93 | 94 | -------------------------------------------------------------------------------- /lib/app/module/home/gank_list_widget.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:gank_flutter/app/data/pojo/gank.dart'; 5 | import 'package:gank_flutter/app/data/pojo/photo.dart'; 6 | import 'package:gank_flutter/app/module/home/home_contract.dart'; 7 | import 'package:gank_flutter/app/module/home/photo_widget.dart'; 8 | import 'package:gank_flutter/app/util/constants.dart'; 9 | import 'package:url_launcher/url_launcher.dart'; 10 | 11 | class GankListPage extends StatefulWidget { 12 | 13 | final String category; 14 | 15 | final int size; 16 | 17 | GankListPage(this.category, this.size); 18 | 19 | @override 20 | GankListState createState() { 21 | GankListState state = new GankListState(category, size); 22 | new GankHomePresenterContractImpl(state); 23 | return state; 24 | } 25 | 26 | } 27 | 28 | class GankListState extends State 29 | implements GankHomeViewContract { 30 | 31 | final GlobalKey _refreshIndicatorKey = new GlobalKey< 32 | RefreshIndicatorState>(); 33 | 34 | static const int STATE_LOADING = 0; 35 | static final int STATE_FAILED = 1; 36 | static final int STATE_SUCCESS = 2; 37 | 38 | int _state; 39 | 40 | List _ganks = new List(); 41 | 42 | final String _category; 43 | 44 | final int _size; 45 | 46 | GankHomePresenterContract _presenter; 47 | 48 | GankListState(this._category, this._size); 49 | 50 | @override 51 | void initState() { 52 | _presenter.loadGanks(_category, _size, null); 53 | } 54 | 55 | Widget _buildGankWidget(Gank gank) { 56 | if (gank.type == KEY_WELFARE) { 57 | var picWidth = MediaQuery 58 | .of(context) 59 | .size 60 | .width * 0.9; 61 | return new GestureDetector( 62 | onTap: () => _onTapPicGank(gank), 63 | child: new Card( 64 | child: new Column( 65 | crossAxisAlignment: CrossAxisAlignment.center, 66 | children: [ 67 | new Container( 68 | margin: const EdgeInsets.all(10.0), 69 | child: new Center( 70 | child: new Image.network( 71 | gank.url + "?imageView2/0/w/" + 72 | picWidth.toString(), 73 | fit: BoxFit.cover, width: picWidth), 74 | ) 75 | ), 76 | new Text(gank.author) 77 | ],), 78 | )); 79 | } else { 80 | return new Card( 81 | child: new ListTile( 82 | onTap: () => _onTapArticleGank(gank), 83 | title: new Text(gank.desc), 84 | subtitle: new Text(gank.author), 85 | ), 86 | ); 87 | } 88 | } 89 | 90 | Future _handleRefresh() { 91 | final Completer completer = new Completer(); 92 | _presenter.loadGanks(_category, _size, completer); 93 | return completer.future; 94 | } 95 | 96 | @override 97 | Widget build(BuildContext context) { 98 | Widget _body = null; 99 | if (_state == STATE_SUCCESS || _state == STATE_LOADING) { 100 | _body = new ListView.builder( 101 | itemCount: _ganks == null ? 0 : _ganks.length, 102 | itemBuilder: (context, index) => _buildGankWidget(_ganks[index]), 103 | ); 104 | } else { 105 | _body = new Center( 106 | child: new Text("加载失败,请稍后重试") 107 | ); 108 | } 109 | return new RefreshIndicator( 110 | key: _refreshIndicatorKey, 111 | onRefresh: _handleRefresh, 112 | child: _body); 113 | } 114 | 115 | 116 | @override 117 | bool isMounted() { 118 | return mounted; 119 | } 120 | 121 | @override 122 | void setPresenter(GankHomePresenterContract presenter) { 123 | this._presenter = presenter; 124 | } 125 | 126 | @override 127 | void showNewGanks(List ganks) { 128 | List newGanks = new List(); 129 | newGanks.addAll(ganks); 130 | newGanks.addAll(_ganks); 131 | setState(() { 132 | this._state = STATE_SUCCESS; 133 | this._ganks = newGanks; 134 | }); 135 | } 136 | 137 | @override 138 | void showLoadError() { 139 | setState(() { 140 | this._state = STATE_FAILED; 141 | }); 142 | } 143 | 144 | @override 145 | void showLoading() { 146 | setState(() { 147 | this._state = STATE_LOADING; 148 | }); 149 | } 150 | 151 | _onTapArticleGank(Gank gank){ 152 | String url = gank.url; 153 | launch(url); 154 | } 155 | 156 | _onTapPicGank(Gank gank) { 157 | Photo photo = new Photo( 158 | url: gank.url, title: "Recommended by " + gank.author); 159 | Navigator.push(context, new MaterialPageRoute( 160 | builder: (BuildContext context) { 161 | return new Scaffold( 162 | appBar: new AppBar( 163 | title: new Text(photo.title) 164 | ), 165 | body: new SizedBox.expand( 166 | child: new Hero( 167 | tag: gank.url, 168 | child: new GridPhotoViewer(photo: photo), 169 | ), 170 | ), 171 | ); 172 | } 173 | )); 174 | } 175 | } -------------------------------------------------------------------------------- /android/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; }; 13 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 3B80C3931E831B6300D905FE /* App.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 14 | 60935F4E9CD8F50EBB196FB3 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 1E41F1A05ADB7090D8B366B1 /* libPods-Runner.a */; }; 15 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; }; 16 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = 9740EEBA1CF902C7004384FC /* Flutter.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 17 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB21CF90195004384FC /* Debug.xcconfig */; }; 18 | 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB31CF90195004384FC /* Generated.xcconfig */; }; 19 | 9740EEBB1CF902C7004384FC /* app.flx in Resources */ = {isa = PBXBuildFile; fileRef = 9740EEB71CF902C7004384FC /* app.flx */; }; 20 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 21 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 22 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 23 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 24 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 25 | /* End PBXBuildFile section */ 26 | 27 | /* Begin PBXCopyFilesBuildPhase section */ 28 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 29 | isa = PBXCopyFilesBuildPhase; 30 | buildActionMask = 2147483647; 31 | dstPath = ""; 32 | dstSubfolderSpec = 10; 33 | files = ( 34 | 3B80C3951E831B6300D905FE /* App.framework in Embed Frameworks */, 35 | 9705A1C71CF904A300538489 /* Flutter.framework in Embed Frameworks */, 36 | ); 37 | name = "Embed Frameworks"; 38 | runOnlyForDeploymentPostprocessing = 0; 39 | }; 40 | /* End PBXCopyFilesBuildPhase section */ 41 | 42 | /* Begin PBXFileReference section */ 43 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 44 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 45 | 1E41F1A05ADB7090D8B366B1 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 47 | 3B80C3931E831B6300D905FE /* App.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = App.framework; path = Flutter/App.framework; sourceTree = ""; }; 48 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 49 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 50 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 51 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 52 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 53 | 9740EEB71CF902C7004384FC /* app.flx */ = {isa = PBXFileReference; lastKnownFileType = file; name = app.flx; path = Flutter/app.flx; sourceTree = ""; }; 54 | 9740EEBA1CF902C7004384FC /* Flutter.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Flutter.framework; path = Flutter/Flutter.framework; sourceTree = ""; }; 55 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 56 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 57 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 58 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 59 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 60 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 61 | /* End PBXFileReference section */ 62 | 63 | /* Begin PBXFrameworksBuildPhase section */ 64 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 65 | isa = PBXFrameworksBuildPhase; 66 | buildActionMask = 2147483647; 67 | files = ( 68 | 9705A1C61CF904A100538489 /* Flutter.framework in Frameworks */, 69 | 3B80C3941E831B6300D905FE /* App.framework in Frameworks */, 70 | 60935F4E9CD8F50EBB196FB3 /* libPods-Runner.a in Frameworks */, 71 | ); 72 | runOnlyForDeploymentPostprocessing = 0; 73 | }; 74 | /* End PBXFrameworksBuildPhase section */ 75 | 76 | /* Begin PBXGroup section */ 77 | 9740EEB11CF90186004384FC /* Flutter */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | 9740EEB71CF902C7004384FC /* app.flx */, 81 | 3B80C3931E831B6300D905FE /* App.framework */, 82 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 83 | 9740EEBA1CF902C7004384FC /* Flutter.framework */, 84 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 85 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 86 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 87 | ); 88 | name = Flutter; 89 | sourceTree = ""; 90 | }; 91 | 97C146E51CF9000F007C117D = { 92 | isa = PBXGroup; 93 | children = ( 94 | 9740EEB11CF90186004384FC /* Flutter */, 95 | 97C146F01CF9000F007C117D /* Runner */, 96 | 97C146EF1CF9000F007C117D /* Products */, 97 | C8BB37195344C3B5C91C49B8 /* Pods */, 98 | EABE26B3AE9E569B930A48E9 /* Frameworks */, 99 | ); 100 | sourceTree = ""; 101 | }; 102 | 97C146EF1CF9000F007C117D /* Products */ = { 103 | isa = PBXGroup; 104 | children = ( 105 | 97C146EE1CF9000F007C117D /* Runner.app */, 106 | ); 107 | name = Products; 108 | sourceTree = ""; 109 | }; 110 | 97C146F01CF9000F007C117D /* Runner */ = { 111 | isa = PBXGroup; 112 | children = ( 113 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 114 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 115 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 116 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 117 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 118 | 97C147021CF9000F007C117D /* Info.plist */, 119 | 97C146F11CF9000F007C117D /* Supporting Files */, 120 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 121 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 122 | ); 123 | path = Runner; 124 | sourceTree = ""; 125 | }; 126 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 127 | isa = PBXGroup; 128 | children = ( 129 | 97C146F21CF9000F007C117D /* main.m */, 130 | ); 131 | name = "Supporting Files"; 132 | sourceTree = ""; 133 | }; 134 | C8BB37195344C3B5C91C49B8 /* Pods */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | ); 138 | name = Pods; 139 | sourceTree = ""; 140 | }; 141 | EABE26B3AE9E569B930A48E9 /* Frameworks */ = { 142 | isa = PBXGroup; 143 | children = ( 144 | 1E41F1A05ADB7090D8B366B1 /* libPods-Runner.a */, 145 | ); 146 | name = Frameworks; 147 | sourceTree = ""; 148 | }; 149 | /* End PBXGroup section */ 150 | 151 | /* Begin PBXNativeTarget section */ 152 | 97C146ED1CF9000F007C117D /* Runner */ = { 153 | isa = PBXNativeTarget; 154 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 155 | buildPhases = ( 156 | 7B3AC66A899DAA54605DBC68 /* [CP] Check Pods Manifest.lock */, 157 | 9740EEB61CF901F6004384FC /* Run Script */, 158 | 97C146EA1CF9000F007C117D /* Sources */, 159 | 97C146EB1CF9000F007C117D /* Frameworks */, 160 | 97C146EC1CF9000F007C117D /* Resources */, 161 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 162 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 163 | 37825BC4E9B8434B5A3B250A /* [CP] Embed Pods Frameworks */, 164 | CAF578FDC58724A6D76532F4 /* [CP] Copy Pods Resources */, 165 | ); 166 | buildRules = ( 167 | ); 168 | dependencies = ( 169 | ); 170 | name = Runner; 171 | productName = Runner; 172 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 173 | productType = "com.apple.product-type.application"; 174 | }; 175 | /* End PBXNativeTarget section */ 176 | 177 | /* Begin PBXProject section */ 178 | 97C146E61CF9000F007C117D /* Project object */ = { 179 | isa = PBXProject; 180 | attributes = { 181 | LastUpgradeCheck = 0910; 182 | ORGANIZATIONNAME = "The Chromium Authors"; 183 | TargetAttributes = { 184 | 97C146ED1CF9000F007C117D = { 185 | CreatedOnToolsVersion = 7.3.1; 186 | }; 187 | }; 188 | }; 189 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 190 | compatibilityVersion = "Xcode 3.2"; 191 | developmentRegion = English; 192 | hasScannedForEncodings = 0; 193 | knownRegions = ( 194 | en, 195 | Base, 196 | ); 197 | mainGroup = 97C146E51CF9000F007C117D; 198 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 199 | projectDirPath = ""; 200 | projectRoot = ""; 201 | targets = ( 202 | 97C146ED1CF9000F007C117D /* Runner */, 203 | ); 204 | }; 205 | /* End PBXProject section */ 206 | 207 | /* Begin PBXResourcesBuildPhase section */ 208 | 97C146EC1CF9000F007C117D /* Resources */ = { 209 | isa = PBXResourcesBuildPhase; 210 | buildActionMask = 2147483647; 211 | files = ( 212 | 9740EEBB1CF902C7004384FC /* app.flx in Resources */, 213 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 214 | 9740EEB51CF90195004384FC /* Generated.xcconfig in Resources */, 215 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 216 | 9740EEB41CF90195004384FC /* Debug.xcconfig in Resources */, 217 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 218 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 219 | ); 220 | runOnlyForDeploymentPostprocessing = 0; 221 | }; 222 | /* End PBXResourcesBuildPhase section */ 223 | 224 | /* Begin PBXShellScriptBuildPhase section */ 225 | 37825BC4E9B8434B5A3B250A /* [CP] Embed Pods Frameworks */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputPaths = ( 231 | "${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", 232 | "${PODS_ROOT}/../../../../../Library/flutter/bin/cache/artifacts/engine/ios/Flutter.framework", 233 | ); 234 | name = "[CP] Embed Pods Frameworks"; 235 | outputPaths = ( 236 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/Flutter.framework", 237 | ); 238 | runOnlyForDeploymentPostprocessing = 0; 239 | shellPath = /bin/sh; 240 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 241 | showEnvVarsInLog = 0; 242 | }; 243 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 244 | isa = PBXShellScriptBuildPhase; 245 | buildActionMask = 2147483647; 246 | files = ( 247 | ); 248 | inputPaths = ( 249 | ); 250 | name = "Thin Binary"; 251 | outputPaths = ( 252 | ); 253 | runOnlyForDeploymentPostprocessing = 0; 254 | shellPath = /bin/sh; 255 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" thin"; 256 | }; 257 | 7B3AC66A899DAA54605DBC68 /* [CP] Check Pods Manifest.lock */ = { 258 | isa = PBXShellScriptBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | ); 262 | inputPaths = ( 263 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 264 | "${PODS_ROOT}/Manifest.lock", 265 | ); 266 | name = "[CP] Check Pods Manifest.lock"; 267 | outputPaths = ( 268 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 269 | ); 270 | runOnlyForDeploymentPostprocessing = 0; 271 | shellPath = /bin/sh; 272 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 273 | showEnvVarsInLog = 0; 274 | }; 275 | 9740EEB61CF901F6004384FC /* Run Script */ = { 276 | isa = PBXShellScriptBuildPhase; 277 | buildActionMask = 2147483647; 278 | files = ( 279 | ); 280 | inputPaths = ( 281 | ); 282 | name = "Run Script"; 283 | outputPaths = ( 284 | ); 285 | runOnlyForDeploymentPostprocessing = 0; 286 | shellPath = /bin/sh; 287 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 288 | }; 289 | CAF578FDC58724A6D76532F4 /* [CP] Copy Pods Resources */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | inputPaths = ( 295 | ); 296 | name = "[CP] Copy Pods Resources"; 297 | outputPaths = ( 298 | ); 299 | runOnlyForDeploymentPostprocessing = 0; 300 | shellPath = /bin/sh; 301 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n"; 302 | showEnvVarsInLog = 0; 303 | }; 304 | /* End PBXShellScriptBuildPhase section */ 305 | 306 | /* Begin PBXSourcesBuildPhase section */ 307 | 97C146EA1CF9000F007C117D /* Sources */ = { 308 | isa = PBXSourcesBuildPhase; 309 | buildActionMask = 2147483647; 310 | files = ( 311 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 312 | 97C146F31CF9000F007C117D /* main.m in Sources */, 313 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 314 | ); 315 | runOnlyForDeploymentPostprocessing = 0; 316 | }; 317 | /* End PBXSourcesBuildPhase section */ 318 | 319 | /* Begin PBXVariantGroup section */ 320 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 321 | isa = PBXVariantGroup; 322 | children = ( 323 | 97C146FB1CF9000F007C117D /* Base */, 324 | ); 325 | name = Main.storyboard; 326 | sourceTree = ""; 327 | }; 328 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 329 | isa = PBXVariantGroup; 330 | children = ( 331 | 97C147001CF9000F007C117D /* Base */, 332 | ); 333 | name = LaunchScreen.storyboard; 334 | sourceTree = ""; 335 | }; 336 | /* End PBXVariantGroup section */ 337 | 338 | /* Begin XCBuildConfiguration section */ 339 | 97C147031CF9000F007C117D /* Debug */ = { 340 | isa = XCBuildConfiguration; 341 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 342 | buildSettings = { 343 | ALWAYS_SEARCH_USER_PATHS = NO; 344 | CLANG_ANALYZER_NONNULL = YES; 345 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 346 | CLANG_CXX_LIBRARY = "libc++"; 347 | CLANG_ENABLE_MODULES = YES; 348 | CLANG_ENABLE_OBJC_ARC = YES; 349 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 350 | CLANG_WARN_BOOL_CONVERSION = YES; 351 | CLANG_WARN_COMMA = YES; 352 | CLANG_WARN_CONSTANT_CONVERSION = YES; 353 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 354 | CLANG_WARN_EMPTY_BODY = YES; 355 | CLANG_WARN_ENUM_CONVERSION = YES; 356 | CLANG_WARN_INFINITE_RECURSION = YES; 357 | CLANG_WARN_INT_CONVERSION = YES; 358 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 359 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 360 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 361 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 362 | CLANG_WARN_STRICT_PROTOTYPES = YES; 363 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 364 | CLANG_WARN_UNREACHABLE_CODE = YES; 365 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 366 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 367 | COPY_PHASE_STRIP = NO; 368 | DEBUG_INFORMATION_FORMAT = dwarf; 369 | ENABLE_STRICT_OBJC_MSGSEND = YES; 370 | ENABLE_TESTABILITY = YES; 371 | GCC_C_LANGUAGE_STANDARD = gnu99; 372 | GCC_DYNAMIC_NO_PIC = NO; 373 | GCC_NO_COMMON_BLOCKS = YES; 374 | GCC_OPTIMIZATION_LEVEL = 0; 375 | GCC_PREPROCESSOR_DEFINITIONS = ( 376 | "DEBUG=1", 377 | "$(inherited)", 378 | ); 379 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 380 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 381 | GCC_WARN_UNDECLARED_SELECTOR = YES; 382 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 383 | GCC_WARN_UNUSED_FUNCTION = YES; 384 | GCC_WARN_UNUSED_VARIABLE = YES; 385 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 386 | MTL_ENABLE_DEBUG_INFO = YES; 387 | ONLY_ACTIVE_ARCH = YES; 388 | SDKROOT = iphoneos; 389 | TARGETED_DEVICE_FAMILY = "1,2"; 390 | }; 391 | name = Debug; 392 | }; 393 | 97C147041CF9000F007C117D /* Release */ = { 394 | isa = XCBuildConfiguration; 395 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 396 | buildSettings = { 397 | ALWAYS_SEARCH_USER_PATHS = NO; 398 | CLANG_ANALYZER_NONNULL = YES; 399 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 400 | CLANG_CXX_LIBRARY = "libc++"; 401 | CLANG_ENABLE_MODULES = YES; 402 | CLANG_ENABLE_OBJC_ARC = YES; 403 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 404 | CLANG_WARN_BOOL_CONVERSION = YES; 405 | CLANG_WARN_COMMA = YES; 406 | CLANG_WARN_CONSTANT_CONVERSION = YES; 407 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 408 | CLANG_WARN_EMPTY_BODY = YES; 409 | CLANG_WARN_ENUM_CONVERSION = YES; 410 | CLANG_WARN_INFINITE_RECURSION = YES; 411 | CLANG_WARN_INT_CONVERSION = YES; 412 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 413 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 414 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 415 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 416 | CLANG_WARN_STRICT_PROTOTYPES = YES; 417 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 418 | CLANG_WARN_UNREACHABLE_CODE = YES; 419 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 420 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 421 | COPY_PHASE_STRIP = NO; 422 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 423 | ENABLE_NS_ASSERTIONS = NO; 424 | ENABLE_STRICT_OBJC_MSGSEND = YES; 425 | GCC_C_LANGUAGE_STANDARD = gnu99; 426 | GCC_NO_COMMON_BLOCKS = YES; 427 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 428 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 429 | GCC_WARN_UNDECLARED_SELECTOR = YES; 430 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 431 | GCC_WARN_UNUSED_FUNCTION = YES; 432 | GCC_WARN_UNUSED_VARIABLE = YES; 433 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 434 | MTL_ENABLE_DEBUG_INFO = NO; 435 | SDKROOT = iphoneos; 436 | TARGETED_DEVICE_FAMILY = "1,2"; 437 | VALIDATE_PRODUCT = YES; 438 | }; 439 | name = Release; 440 | }; 441 | 97C147061CF9000F007C117D /* Debug */ = { 442 | isa = XCBuildConfiguration; 443 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 444 | buildSettings = { 445 | ARCHS = arm64; 446 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 447 | ENABLE_BITCODE = NO; 448 | FRAMEWORK_SEARCH_PATHS = ( 449 | "$(inherited)", 450 | "$(PROJECT_DIR)/Flutter", 451 | ); 452 | INFOPLIST_FILE = Runner/Info.plist; 453 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 454 | LIBRARY_SEARCH_PATHS = ( 455 | "$(inherited)", 456 | "$(PROJECT_DIR)/Flutter", 457 | ); 458 | PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.gankFlutter; 459 | PRODUCT_NAME = "$(TARGET_NAME)"; 460 | }; 461 | name = Debug; 462 | }; 463 | 97C147071CF9000F007C117D /* Release */ = { 464 | isa = XCBuildConfiguration; 465 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 466 | buildSettings = { 467 | ARCHS = arm64; 468 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 469 | ENABLE_BITCODE = NO; 470 | FRAMEWORK_SEARCH_PATHS = ( 471 | "$(inherited)", 472 | "$(PROJECT_DIR)/Flutter", 473 | ); 474 | INFOPLIST_FILE = Runner/Info.plist; 475 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 476 | LIBRARY_SEARCH_PATHS = ( 477 | "$(inherited)", 478 | "$(PROJECT_DIR)/Flutter", 479 | ); 480 | PRODUCT_BUNDLE_IDENTIFIER = com.yourcompany.gankFlutter; 481 | PRODUCT_NAME = "$(TARGET_NAME)"; 482 | }; 483 | name = Release; 484 | }; 485 | /* End XCBuildConfiguration section */ 486 | 487 | /* Begin XCConfigurationList section */ 488 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 489 | isa = XCConfigurationList; 490 | buildConfigurations = ( 491 | 97C147031CF9000F007C117D /* Debug */, 492 | 97C147041CF9000F007C117D /* Release */, 493 | ); 494 | defaultConfigurationIsVisible = 0; 495 | defaultConfigurationName = Release; 496 | }; 497 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 498 | isa = XCConfigurationList; 499 | buildConfigurations = ( 500 | 97C147061CF9000F007C117D /* Debug */, 501 | 97C147071CF9000F007C117D /* Release */, 502 | ); 503 | defaultConfigurationIsVisible = 0; 504 | defaultConfigurationName = Release; 505 | }; 506 | /* End XCConfigurationList section */ 507 | }; 508 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 509 | } 510 | --------------------------------------------------------------------------------