首页 > 其他分享 >IOS内购数据拉取

IOS内购数据拉取

时间:2023-04-27 11:15:44浏览次数:44  
标签:内购 body return String IOS 拉取 put new response

目标:拉取app store connect 内购数据拉取,自己做数据报表。

1:api秘钥

  接口需要token,token生成需要秘钥。参考官方文档:https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api 。

 

 vendorNumber在这个界面查找:

 

2:生成token

根据上面保存的东西生成token。官方文档: https://developer.apple.com/documentation/appstoreconnectapi/generating_tokens_for_api_requests

这里用 java+vertx框架实现的:

  private JWTAuth iniJwt() {
        JsonObject header = new JsonObject()
                .put("alg", "ES256")
                .put("kid", keyID) //key_id
                .put("typ", "JWT");
        JWTOptions options = new JWTOptions()
                .setAlgorithm("ES256")
                .setHeader(header);
        Vertx vertx = ConfigHelp.vertx;
        //加载下载的 p8文件
        Buffer iosPayKeyBuffer = vertx.fileSystem().readFileBlocking("resource/AuthKey_A2BRZ78255.p8");
        Buffer keyBuffer = iosPayKeyBuffer;
        JWTAuthOptions config = new JWTAuthOptions()
                .addPubSecKey(new PubSecKeyOptions()
                        .setAlgorithm("ES256")
                        .setBuffer(keyBuffer))
                .setJWTOptions(options);
        return JWTAuth.create(vertx, config);
    }
private String getToken(String parameter) {
long sT = (int) (System.currentTimeMillis() / 1000);
long eT = sT + 60 * 15; //过期时间

String params = "GET " + parameter;
List<String> scope = new ArrayList<>(1);
scope.add(params);

JsonObject body = new JsonObject()
.put("iss", issuer) //issuer
.put("iat", sT)
.put("exp", eT)
.put("aud", "appstoreconnect-v1")
.put("scope", scope);

JWTAuth provider = iniJwt();
return provider.generateToken(body);
}

 

3:下载销售报告

财务报告是每月生成,销售报告是每天生成。参考文档:https://developer.apple.com/documentation/appstoreconnectapi/download_sales_and_trends_reports

 这里请求数据post使用的是 okhttp3,所以需要添加 pom.xml:

        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <version>4.10.0</version>
        </dependency>

 请求代码

//参数
String curDate = "2023-04-20"; //需要下载报表的日期
String vendorNumber = "21432532456";//通过上面消息得到的 vendor_number
String params = "/v1/salesReports?filter[frequency]=DAILY&filter[reportSubType]=SUMMARY" +
"&filter[reportType]=SALES" +
"&filter[vendorNumber]=" + vendorNumber + "&filter[reportDate]=" + curDate;
//请求数据
String token = getToken(params);
String url = "https://api.appstoreconnect.apple.com" + params;
Request request = new Request.Builder()
                .url(url)
                .method("GET", null)
                .addHeader("Authorization", "Bearer " + token)
                .addHeader("Accept", "application/a-gzip")
                .build();

 try {
      OkHttpClient client = new OkHttpClient().newBuilder()
                    .addInterceptor(new UnzippingInterceptor())
                    .build();
      Response response = client.newCall(request).execute();

      String body = Objects.requireNonNull(response.body()).string();
      System.out.println(body);
 } catch (IOException e) {
            System.out.println(e);
 }

 

 注意:请求数据返回的是zip文件,所以这里需要解压。addInterceptor(new UnzippingInterceptor())就是用来解压zip的。

package com.gcms.postdata.pay;

import okhttp3.Headers;
import okhttp3.Interceptor;
import okhttp3.Response;
import okhttp3.internal.http.RealResponseBody;
import okio.GzipSource;
import okio.Okio;
import org.jetbrains.annotations.NotNull;

import java.io.IOException;

public class UnzippingInterceptor implements Interceptor {
    @NotNull
    @Override
    public Response intercept(@NotNull Chain chain) throws IOException {
        Response response = chain.proceed(chain.request());
        return unzip(response);
    }

    // copied from okhttp3.internal.http.HttpEngine (because is private)
    private Response unzip(final Response response) throws IOException
    {
        if (response.body() == null)
        {
            return response;
        }

        //check if we have gzip response
        String contentEncoding = response.headers().get("Content-Encoding");

        if(contentEncoding == null)
            return response;

        //this is used to decompress gzipped responses
        if (contentEncoding.equals("gzip") || contentEncoding.equals("agzip"))
        {
            Long contentLength = response.body().contentLength();
            GzipSource responseBody = new GzipSource(response.body().source());
            Headers strippedHeaders = response.headers().newBuilder().build();
            return response.newBuilder().headers(strippedHeaders)
                    .body(new RealResponseBody(response.body().contentType().toString(), contentLength, Okio.buffer(responseBody)))
                    .build();
        }
        else
        {
            return response;
        }
    }
}
View Code

 最后得到的body就是解析后的数据。

 

 4:解析数据

 得到的数据是按照excel形式在txt文件中展示的,需要解析出自己需要的数据

       String[] separated = body.split("\n"); //使用 \n 拆分行,
        int len = separated.length;
        for (int i = 1; i < len; i++) { //遍历每一行数据
            String[] row = separated[i].split("\t"); //使用 \t 拆分列,得到每一列数据

            String packId = row[17];//包名
            float proceeds = Float.parseFloat(row[8]); //收益
            if (proceeds == 0)
                continue;

            float price = Float.parseFloat(row[15]);  //定价
            //其他字段
        }

 

 具体的报告字段参考:https://developer.apple.com/help/app-store-connect/reference/summary-sales-report

 

5:完成。具体的数据自己储存到数据库,自己使用。

 

注意:得到的数据各种货币都有,需要自己转为一种类型的货币。自己查找汇率。

举个例子:在计算或者展示时,统一转为美金计算。units * proceeds * 汇率 = 内购

        //转为美金的汇率
        switch (city) {
            case "GBP":
                return 1.20469f;
            case "AUD":
                return 0.66903f;
            case "USD":
                return 1;
            case "CHF":
                return 1.07279f;
            case "CAD":
                return 0.73338f;
        }

 

标签:内购,body,return,String,IOS,拉取,put,new,response
From: https://www.cnblogs.com/cj8988/p/17358356.html

相关文章

  • 使用axios下载文件
    使用axios下载文件/***下载文件*@param{string}url下载地址*@param{string}fileName文件名,例:1.png*/exportfunctiondownload(url,fileName){axios({url:url,method:'GET',responseType:'blob',}).then((r......
  • How to use axios.js instead of request.js to get data as a buffer All In One
    Howtouseaxios.jsinsteadofrequest.jstogetdataasabufferAllInOne如何使用axios.js代替request.js获取数据作为缓冲区questionconstfs=require("fs");varpath=require("path");const{exit}=require("process");//requ......
  • iOS描述文件(.mobileprovision)一键申请
    转载:IOS描述文件制作教程iOS描述文件(.mobileprovision)一键申请在主界面上点击描述文件按钮。​编辑切换为居中添加图片注释,不超过140字(可选)  新建ios描述文件然后点击新建,然后输入描述文件名称,描述文件名称字符和数字,自己好辨识就可以。......
  • iOS MachineLearning 系列(5)—— 视频中的物体运动追踪
    iOSMachineLearning系列(5)——视频中的物体运动追踪本系列的前面几篇文章中,我们将静态图片分析相关的API做了详尽的介绍。在Vision框架中,还提供了视频中物体追踪的能力。仔细想来,其实视频的分析和静态图片的分析本质上并无太大的区别,我们可以将视频拆解成图片帧,之后再对图片进......
  • EasyNTS穿透内网后,海康硬盘录像机拉取不到RTSP流是什么原因?
    EasyNTS上云网关具备内网穿透、组网运维、多协议视频流拉转推、设备/业务上云等功能,它可以解决异地视频共享/组网/上云的需求。其中,EasyNTS上云网关硬件(EasyNTD)可以放置在项目现场,它也同样具备EasyNTS软件平台的功能。有用户反馈,在项目现场利用EasyNTD配合EasyNTS穿透内网,基于海......
  • iOS MachineLearning 系列(4)—— 静态图像分析之物体识别与分类
    iOSMachineLearning系列(4)——静态图像分析之物体识别与分类本系列的前几篇文件,详细了介绍了Vision框架中关于静态图片区域识别的内容。本篇文章,我们将着重介绍静态图片中物体的识别与分类。物体识别和分类也是MachineLearning领域重要的应用。通过大量的图片数据进行训练后,模......
  • 如何建设一个用于编译 iOS App 的 macOS 云服务器集群?
    作者:京东零售叶萌现代软件开发一般会借助CI/CD来提升代码质量、加快发版速度、自动化重复的事情,iOSApp只能在mac机器上编译,CI/CD工具因此需要有一个macOS云服务器集群来执行iOSApp的编译。今天就来谈谈如何建设macOS云服务器集群购买macmini/MacStudio机......
  • vite + vue3 + vue-router4 + ts + element plus + pinia + axios构建项目
    最后是完整的vite.config.ts、main.ts配置1、先用vite创建一个项目npmcreatevite@latest2、安装elementplusyarnaddelement-plus@element-plus/icons-vuevite.config.ts配置组件按需导入,图标自动导入npminstall-Dunplugin-vue-componentsunplugin-auto-impor......
  • iOS面试!
    只是为了防止原作者删除以保存备份一下,方便以后需要时查看https://www.cnblogs.com/berry1124/articles/17352477.html原出处转载自:https://www.jianshu.com/p/9713f816a995 ......
  • ios apns推送 离线锁屏语音播报
    一、背景公司正在研发的一款App,需要在进行消息推送时支持语音播报。具体要求:离线:App在用户未打开时,可收到消息推送锁屏:用户在设备锁屏状态下,仍可收到消息推送语音播报:收到消息推送时可同时进行语音播放苹果的APNs消息推送,支持在应用未打开及设备锁屏状态下收到推送。而......