当前位置: 首页 > 工具软件 > Apollo Client > 使用案例 >

ios 集成apollo client

乜清野
2023-12-01

ios 集成apollo client

开发环境准备 — 我本地的环境

  1. 安装node (v12.1.0)

    brew install node

  2. 安装node-apollo

    npm install -g apollo

  3. xcode v10.1 swift 4.2

下面开始集成 apollo,参考官方文档 (它的文档里面有些坑,不能全信)

https://www.apollographql.com/docs/ios/installation/

第一步 修改 Cartfile 文件,添加下面三个

# 要注明版本号,不然在 xcode v10.1, swift 4.2 版本下,它有问题
github "apollostack/apollo-ios" "0.9.5"

# 下面这两个是 apollo-ios 依赖的两个库,要指明版本,否则同样报错
github "daltoniam/Starscream" "3.0.6"
github "stephencelis/SQLite.swift" "0.11.5"

第二步

这是一个漫长的过程,它下载会很慢,要有耐心!!!

PS: 通过修改 hosts 文件访问 github 能加快下载速度,请自行百度

# 官方文档里面使用的这个,但这个会更新所有引用库,不推荐这个
carthage update
# 个人推荐这个命令
carthage bootstrap --platform iOS

第三步

添加Apollo.framework到项目中

点击"项目名称"-> “target” -> “Gerneral”,在最底部找到"Linked Frameworks and Libraries"。

打开Carthage文件夹,进入Build\iOS,拖拽Apollo.framework到Xcode的**Linked Frameworks and Libraries **中。

点击"项目名称"-> “target” -> “Build Phases”,点击 " + " ,选择 “New Run Script Phase”

一般取名叫 Run Script ,Shell为 bin/sh,脚本内容为:

/usr/local/bin/carthage copy-frameworks

Input Files 添加要使用的框架路径

$(SRCROOT)/Carthage/Build/iOS/Apollo.framework

第四步 添加编译graphql脚本

  1. 点击"项目名称"-> “target” -> “Build Phases”,点击 " + " ,选择 “New Run Script Phase”

  2. 输入名称 : “Generate Apollo GraphQL API”,并且要将它拖到 “Compile Sources” 前面

  3. 输入脚本内容

    APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"
    
    if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
      echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
      exit 1
    fi
    
    cd "${SRCROOT}/${TARGET_NAME}"
    $APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --schema=schema.json API.swift
    
    • 这段脚本会自动将 *.graphql文件,在编译时生成对应的 class 到 API.swift 文件中
    • schema.jsonAPI.swift 的路径可以调整

第五步 下载schea.json,并编写 graphql

  1. 下载 schema.json,这里要用到 node

    apollo schema:download --endpoint=http://localhost:8080/graphql schema.json
    
    # 或者
    apollo schema:download --endpoint=http://localhost:8080/graphql --header="Authorization: Bearer <token>"
    
  2. 新建 test.graphql 并输入相应的内容,编译,API.swift 会自动生成

  3. 将 API.swift 添加到项目中

    • API.swift 生成的代码有可能会报错,配置忽略它就行了

第六步 创建 Apollo Client

let apollo = ApolloClient(url: URL(string: "http://localhost:8080/graphql")!)

或者

let apollo: ApolloClient = {
  let configuration = URLSessionConfiguration.default
  configuration.httpAdditionalHeaders = ["Authorization": "Bearer <token>"]

  let url = URL(string: "http://localhost:8080/graphql")!

  return ApolloClient(networkTransport: HTTPNetworkTransport(url: url, configuration: configuration))
}()

query

// query grahpql
query HeroName($episode: Episode) {
  hero(episode: $episode) {
    name
  }
}
apollo.fetch(query: HeroAndFriendsNamesQuery(episode: .empire)) { (result, error) in
  guard let data = result?.data else { return }
  print(data.hero?.name)
  print(data.hero?.friends?.flatMap { $0?.name }.joined(separator: ", "))
}

mutation

// mutation grahpql
mutation UpvotePost($postId: Int!) {
  upvotePost(postId: $postId) {
    votes
  }
}
apollo.perform(mutation: UpvotePostMutation(postId: postId)) { (result, error) in
  self.configure(with: result?.data?.upvotePost?.fragments.postDetails)
}

第七步 填坑

如果服务器返回的类型如: JSON JSONString Long DateTime 等,apollo 将默认变成 String 类型

解决方法

将 “Generate Apollo GraphQL API” 脚本内容改为

APOLLO_FRAMEWORK_PATH="$(eval find $FRAMEWORK_SEARCH_PATHS -name "Apollo.framework" -maxdepth 1)"

if [ -z "$APOLLO_FRAMEWORK_PATH" ]; then
echo "error: Couldn't find Apollo.framework in FRAMEWORK_SEARCH_PATHS; make sure to add the framework to your project."
exit 1
fi

cd "${SRCROOT}/${TARGET_NAME}"
$APOLLO_FRAMEWORK_PATH/check-and-run-apollo-cli.sh codegen:generate --queries="$(find . -name '*.graphql')" --passthroughCustomScalars --schema=schema.json API.swift

还需要添加下面的代码

// JSON 类型
import SwiftyJSON
public typealias JSON = SwiftyJSON.JSON
extension JSON: JSONDecodable {
    public init(jsonValue value: JSONValue) {
        let dictionary = JSON.init(value)
        self = dictionary
    }
}

// JSONString 类型
public typealias JSONString = String

不要改 API.swift 的代码,改了也没用,每次编译都会重新生成

 类似资料: