pkpass file open in Safari Mac but not on iPhone

1.2k views Asked by At

I created a pass successfully and it opens properly on my MacBook safari browser however, when I try to open it on my physical iPhone or the Simulator it looks like safari doesn't recognize the pass file.

On Mac Safari it shows this: Snapshot of how the pass looks when I download it on Mac Safari

On iPhone or Simulator Safari it shows this: Sanpshot of how it look on iPhone or Simulator Safari

I've checked that all image assets are included in the bundle as well as using the right mime type(application/vnd.apple.pkpass) which I even added to my server mime.types conf file.

Any other thing to check in order to fix this strange issue.

Request and response headers:

URL: http://hayak.localhost/api/request/pass?locale=en-us&uuid=eb5b16db-2a33-4bc8-b3e6-b5dcc5240dfd
Request GET /api/request/pass HTTP/1.1 
Accept: */* 
Accept-Encoding: gzip, deflate
Accept-Language: en-us 
Host: hayak.localhost 
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_6) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.2 Safari/605.1.15 Connection: keep-alive Referer: http://hayak.localhost/request/vw
Response HTTP/1.1 200 OK 
Content-Type: application/vnd.apple.pkpass
Keep-Alive: timeout=5, max=100 
Pragma: no-cache 
Content-Disposition: attachment; filename=CP_3_731585792.pkpass
Last-Modified: Tue, 02 Feb 2021 16:00:53 GMT
Cache-Control: public 
Date: Wed, 03 Feb 2021 15:18:46 GMT 
Content-Length: 302319 
Connection: Keep-Alive 
Accept-Ranges: bytes
Vary: Authorization 
X-Powered-By: PHP/7.4.12 Server: Apache/2.4.46 (Unix) OpenSSL/1.0.2u PHP/7.4.12 mod_wsgi/3.5 Python/2.7.13 mod_fastcgi/mod_fastcgi-SNAP-0910052141 mod_perl/2.0.11 Perl/v5.30.1 Content-Transfer-Encoding: binary X-RateLimit-Limit: 60 X-RateLimit-Remaining: 52 Content-Description: File Transfer

JS (Vue) Code:

methods: 
    {
        forceFileDownload(response){
          const url = window.URL.createObjectURL(new Blob([response.data]))
          const link = document.createElement('a')
          link.href = url
          link.setAttribute('download', 'pass.pkpass') //or any other extension
          document.body.appendChild(link)
          link.click()
        },
        downloadWithAxios(){
        axios({
          method: 'get',
          url: '/request/pass',
          params: {locale: this.$i18n.locale, uuid: this.$store.state.app.request.uuid},
          responseType: 'arraybuffer'
        })
        .then(response => {
          
          this.forceFileDownload(response)
          
        })
        .catch(() => console.log('error occured'))
      }  
    }

PHP code:

$path = storage_path().'/passgenerator/'.$pass_identifier.'.pkpass';
        
        return response()->download($path, $pass_identifier.'.pkpass', 
        [
          'Content-Transfer-Encoding' => 'binary',
          'Content-Description' => 'File Transfer',
          'Content-Disposition' => 'attachment; filename=pass.pkpass',
          'Content-length' => strlen($pkpass),
          'Content-Type' => PassGenerator::getPassMimeType(),
          'Pragma' => 'no-cache',
        ]);
1

There are 1 answers

1
thaintp On

Since you do not get the file directly from server URL, but through axios then construct the file again, therefore setting these things in PHP will not help:

'Content-Transfer-Encoding' => 'binary',
'Content-Description' => 'File Transfer',
'Content-Disposition' => 'attachment; filename=pass.pkpass',
'Content-length' => strlen($pkpass),
'Content-Type' => PassGenerator::getPassMimeType(),

You could remove them if you want, because we only need the buffer data.

The problem is when you construct the file again in frontend, you must provide MINE type application/vnd.apple.pkpass for it, it will help Safari recognize the pkpass file and open it automatically.

So, replace this line:

const url = window.URL.createObjectURL(new Blob([response.data]))

with this may help:

const url = window.URL.createObjectURL(
  new Blob([response.data], {
    type: "application/vnd.apple.pkpass",
  })
);