title: cannot save snapshot at Google Play Games Services
body: <p>I implement savedgame at iOS.</p>
  
  <p><a href="https://developers.google.com/games/services/cpp/savedgames" rel="nofollow">https://developers.google.com/games/services/cpp/savedgames</a></p>
  
  <p>but cannot save snapshot on the premise that enable saved game at google play console and success to signin process.</p>
  
  <pre><code>2016-03-19 20:27:15.512 Ojichu[6912:2130626] Creating new snapshot
  2016-03-19 20:27:28.106 Ojichu[6912:2130626] new snapshot name is: ojimon_19700101090000
  2016-03-19 20:27:28.107 Ojichu[6912:2130626] Saving Snapshot ojimon_19700101090000
  2016-03-19 20:27:28.107 Ojichu[6912:2130626] desc
  2016-03-19 20:27:28.108 Ojichu[6912:2130626] ERROR: Invalid filename ojimon_19700101090000: not opening.
  2016-03-19 20:27:28.116 Ojichu[6912:2130626] Creating new snapshot
  2016-03-19 20:27:35.164 Ojichu[6912:2130626] new snapshot name is: ojimon_19700101090000
  2016-03-19 20:27:35.165 Ojichu[6912:2130626] Saving Snapshot ojimon_19700101090000
  2016-03-19 20:27:35.166 Ojichu[6912:2130626] desc
  2016-03-19 20:27:35.166 Ojichu[6912:2130626] ERROR: Invalid filename ojimon_19700101090000: not opening.
  2016-03-19 20:27:37.632 Ojichu[6912:2130626] ERROR_INTERNAL
  2016-03-19 20:27:41.663 Ojichu[6912:2130626] ERROR_INTERNAL
  2016-03-19 20:27:41.664 Ojichu[6912:2131093] VERBOSE: Snapshot cache fully expired: refreshing all.
  2016-03-19 20:27:43.590 Ojichu[6912:2131155] VERBOSE: Download file request: &lt;NSMutableURLRequest: 0x175612630&gt; { URL: https://doc-10-5c-docs.googleusercontent.com/docs/securesc/33he8l9b76c43lgcbshrpvv8v4q7ph0p/h1d7ha0sijr8a0afqi58e1vk50sb1c0d/1458381600000/14598062468829450291/14598062468829450291/1MBK837eoIA8e6iQ4iYtRW-cNgLJCXDGUb7ntuIxfqO__SOPtJjYI_ubJzQuyCbBjo7zYxsk?e=download&amp;gd=true }
  2016-03-19 20:27:43.591 Ojichu[6912:2131155] VERBOSE: Download file response: &lt;NSHTTPURLResponse: 0x17623dfc0&gt; { URL: https://doc-10-5c-docs.googleusercontent.com/docs/securesc/33he8l9b76c43lgcbshrpvv8v4q7ph0p/h1d7ha0sijr8a0afqi58e1vk50sb1c0d/1458381600000/14598062468829450291/14598062468829450291/1MBK837eoIA8e6iQ4iYtRW-cNgLJCXDGUb7ntuIxfqO__SOPtJjYI_ubJzQuyCbBjo7zYxsk?e=download&amp;gd=true } { status code: 200, headers {
  "Access-Control-Allow-Origin" = "*";
  "Cache-Control" = "private, max-age=0";
  "Content-Disposition" = "attachment;filename=\"save_19700101090000\";filename*=UTF-8''save_19700101090000";
  "Content-Length" = 0;
  "Content-Type" = "application/vnd.google-play-games.snapshot-initial";
  Date = "Sat, 19 Mar 2016 11:27:43 GMT";
  Expires = "Sat, 19 Mar 2016 11:27:43 GMT";
  Server = UploadServer;
  "access-control-allow-credentials" = false;
  "access-control-allow-headers" = "Accept, Accept-Language, Authorization, Cache-Control, Content-Disposition, Content-Encoding, Content-Language, Content-Length, Content-MD5, Content-Range, Content-Type, Date, GData-Version, Host, If-Match, If-Modified-Since, If-None-Match, If-Unmodified-Since, Origin, OriginToken, Pragma, Range, Slug, Transfer-Encoding, Want-Digest, X-ClientDetails, X-GData-Client, X-GData-Key, X-Goog-AuthUser, X-Goog-PageId, X-Goog-Encode-Response-If-Executable, X-Goog-Correlation-Id, X-Goog-Request-Info, X-Goog-Experiments, x-goog-iam-authority-selector, x-goog-iam-authorization-token, X-Goog-Spatula, X-Goog-Upload-Command, X-Goog-Upload-Content-Disposition, X-Goog-Upload-Content-Length, X-Goog-Upload-Content-Type, X-Goog-Upload-File-Name, X-Goog-Upload-Offset, X-Goog-Upload-Protocol, X-Goog-Visitor-Id, X-HTTP-Method-Override, X-JavaScript-User-Agent, X-Pan-Versionid, X-Origin, X-Referer, X-Upload-Content-Length, X-Upload-Content-Type, X-Use-HTTP-Status-Code-Override, X-YouTube-VVT, X-YouTube-Page-CL, X-YouTube-Page-Timestamp";
  "access-control-allow-methods" = "GET,OPTIONS";
  "alt-svc" = "quic=\":443\"; ma=2592000; v=\"31,30,29,28,27,26,25\"";
  "alternate-protocol" = "443:quic,p=1";
  "x-guploader-uploadid" = "AEnB2Urbfr6ZC5ugHKhy7J4rRs991A5BWbqobZzKEBPRBIhnY-fL5j4dGLouLw60b1URXquBsNm-1LTP0FRM-aGxqN9Vh-OVWg";
  } }
  2016-03-19 20:27:43.593 Ojichu[6912:2131155] VERBOSE: Download file file name: /var/mobile/Containers/Data/Application/3FC79FFD-1D7A-4827-9A62-08FDD8B15361/Library/Application Support/jp.usaya.Ojichu/snapshots/fe3b73dcc261e238df050ffc3a02fe24
  2016-03-19 20:27:43.599 Ojichu[6912:2131093] VERBOSE: Merging new snapshot: no entry for save_19700101090000.
  2016-03-19 20:27:51.235 Ojichu[6912:2130626] ERROR_INTERNAL
  </code></pre>
  
  <p>My code is below</p>
  
  <pre><code>/* Copyright (c) 2014 Google Inc.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
   *
   *     http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  #include "StateManager.h"
  
  #ifdef __APPLE__
  //
  //Logging for CoreFoundation
  //
  #include &lt;CoreFoundation/CoreFoundation.h&gt;
  extern "C" void NSLog(CFStringRef format, ...);
  const int32_t BUFFER_SIZE = 256;
  #define LOGI(...) {char c[BUFFER_SIZE];\
      snprintf(c,BUFFER_SIZE,__VA_ARGS__);\
      CFStringRef str = CFStringCreateWithCString(kCFAllocatorDefault, c, kCFStringEncodingMacRoman);\
      NSLog(str);\
      CFRelease(str);\
      }
  #else
  #include "android/log.h"
  #define DEBUG_TAG "TeapotNativeActivity"
  #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, DEBUG_TAG, __VA_ARGS__))
  
  #endif
  
  StateManager* StateManager::_instance = nullptr;
  
  void StateManager::onAuthActionFinished(gpg::AuthOperation op, gpg::AuthStatus status)
  {
      LOGI("OnAuthActionFinished");
      switch (status) {
          case gpg::AuthStatus::VALID:
              LOGI("Signed In");
              break;
          case gpg::AuthStatus::ERROR_INTERNAL:
          case gpg::AuthStatus::ERROR_NOT_AUTHORIZED:
          case gpg::AuthStatus::ERROR_VERSION_UPDATE_REQUIRED:
          case gpg::AuthStatus::ERROR_TIMEOUT:
          default:
              LOGI("Sign-in failure");
              break;
      }
  }
  
  void StateManager::onAuthActionStarted(gpg::AuthOperation op)
  {
      LOGI("OnAuthActionStarted");
      switch (op) {
          case gpg::AuthOperation::SIGN_IN:
              LOGI("Signing In");
              break;
          case gpg::AuthOperation::SIGN_OUT:
              LOGI("Signing Out");
              break;
      }
  }
  
  gpg::GameServices *StateManager::getGameServices()
  {
      return _gameServices.get();
  }
  
  void StateManager::beginUserInitiatedSignIn()
  {
      if (!_gameServices-&gt;IsAuthorized()) {
          LOGI("StartAuthorizationUI");
          _gameServices-&gt;StartAuthorizationUI();
      }
  }
  
  void StateManager::signOut()
  {
      if (_gameServices-&gt;IsAuthorized()) {
          LOGI("SignOut");
          _gameServices-&gt;SignOut();
      }
  }
  
  void StateManager::initServices(gpg::PlatformConfiguration &amp;pc)
  {
      LOGI("Initializing Services");
      LOGI(pc.Valid()? "configuration is valid":"configuration is invalid");
      if (!_gameServices) {
          LOGI("Uninitialized services, so creating");
          _gameServices = gpg::GameServices::Builder()
          .SetOnAuthActionStarted([this]( gpg::AuthOperation op ){
              LOGI("Sign in started");
              this-&gt;onAuthActionStarted(op);
          })
          .SetOnAuthActionFinished([this](gpg::AuthOperation op, gpg::AuthStatus status){
              LOGI("Sign in finished with a result of %d", status);
              _isSignedIn = status == gpg::AuthStatus::VALID;
              this-&gt;onAuthActionFinished(op, status);
          })
          .SetDefaultOnLog(gpg::LogLevel::VERBOSE)
          .EnableSnapshots()
          .Create(pc);
      }
      LOGI("Created");
  }
  
  void StateManager::committedSnapshot(gpg::SnapshotManager::CommitResponse const &amp; response)
  {
      switch (response.status) {
          case gpg::ResponseStatus::VALID:
              LOGI("Snapshot CommitResponse VALID");
              break;
          case gpg::ResponseStatus::VALID_BUT_STALE:
              LOGI("Snapshot CommitResponse VALID_BUT_STALE");
              break;
          case gpg::ResponseStatus::ERROR_LICENSE_CHECK_FAILED:
              LOGI("Snapshot CommitResponse ERROR_LICENSE_CHECK_FAILED");
              break;
          case gpg::ResponseStatus::ERROR_INTERNAL:
              LOGI("Snapshot CommitResponse ERROR_INTERNAL");
              break;
          case gpg::ResponseStatus::ERROR_NOT_AUTHORIZED:
              LOGI("Snapshot CommitResponse ERROR_NOT_AUTHORIZED");
              break;
          case gpg::ResponseStatus::ERROR_VERSION_UPDATE_REQUIRED:
              LOGI("Snapshot CommitResponse ERROR_VERSION_UPDATE_REQUIRED");
              break;
          case gpg::ResponseStatus::ERROR_TIMEOUT:
              LOGI("Snapshot CommitResponse ERROR_TIMEOUT");
              break;
          default:
              break;
      }
  }
  
  void StateManager::loadedSnapshot(gpg::SnapshotManager::ReadResponse const &amp; response)
  {
      switch (response.status) {
          case gpg::ResponseStatus::VALID:
              LOGI("Snapshot CommitResponse VALID");
              break;
          case gpg::ResponseStatus::VALID_BUT_STALE:
              LOGI("Snapshot CommitResponse VALID_BUT_STALE");
              break;
          case gpg::ResponseStatus::ERROR_LICENSE_CHECK_FAILED:
              LOGI("Snapshot CommitResponse ERROR_LICENSE_CHECK_FAILED");
              break;
          case gpg::ResponseStatus::ERROR_INTERNAL:
              LOGI("Snapshot CommitResponse ERROR_INTERNAL");
              break;
          case gpg::ResponseStatus::ERROR_NOT_AUTHORIZED:
              LOGI("Snapshot CommitResponse ERROR_NOT_AUTHORIZED");
              break;
          case gpg::ResponseStatus::ERROR_VERSION_UPDATE_REQUIRED:
              LOGI("Snapshot CommitResponse ERROR_VERSION_UPDATE_REQUIRED");
              break;
          case gpg::ResponseStatus::ERROR_TIMEOUT:
              LOGI("Snapshot CommitResponse ERROR_TIMEOUT");
              break;
          default:
              break;
      }
  }
  
  void StateManager::selectedSnapshot(gpg::SnapshotManager::SnapshotSelectUIResponse const &amp; response)
  {
      switch (response.status) {
          case gpg::UIStatus::VALID:
          {
              if ( response.data.Valid() )
              {
                  _currentSnapshot = response.data.FileName();
                  if (_gameServices)
                  {
                      LOGI("Loading Snapshot %s",_currentSnapshot.c_str());
                      _gameServices-&gt;Snapshots().Open(response.data.FileName(),
                                                      gpg::SnapshotConflictPolicy::LONGEST_PLAYTIME,
                                                      [this](gpg::SnapshotManager::OpenResponse const &amp; response) {
                                                          LOGI("Reading file");
                                                          _gameServices-&gt;Snapshots().Read(response.data,
                                                                                          std::bind(&amp;StateManager::loadedSnapshot, this,
                                                                                                    std::placeholders::_1));
                                                     });
                  }
              } else {
                  LOGI("Creating new snapshot");
                  _currentSnapshot.clear();
                  std::string str = "aaaaaaaaaaaa";
                  auto tp = std::chrono::system_clock::now();
                  auto d = tp.time_since_epoch();
                  auto m = std::chrono::duration_cast&lt;std::chrono::milliseconds&gt;(d);
                  std::vector&lt;uint8_t&gt; png;
                  std::vector&lt;uint8_t&gt; data(str.begin(),str.end());
                  saveSnapshot("desc", m, png, data);
              }
              break;
          }
          case gpg::UIStatus::ERROR_INTERNAL:
              LOGI("Snapshot SelectUIResponse ERROR_INTERNAL");
              break;
          case gpg::UIStatus::ERROR_NOT_AUTHORIZED:
              LOGI("Snapshot SelectUIResponse ERROR_NOT_AUTHORIZED");
              break;
          case gpg::UIStatus::ERROR_VERSION_UPDATE_REQUIRED:
              LOGI("Snapshot SelectUIResponse ERROR_VERSION_UPDATE_REQUIRED");
              break;
          case gpg::UIStatus::ERROR_TIMEOUT:
              LOGI("Snapshot SelectUIResponse ERROR_TIMEOUT");
              break;
          case gpg::UIStatus::ERROR_CANCELED:
              LOGI("Snapshot SelectUIResponse ERROR_CANCELED");
              break;
          case gpg::UIStatus::ERROR_UI_BUSY:
              LOGI("Snapshot SelectUIResponse ERROR_UI_BUSY");
              break;
          case gpg::UIStatus::ERROR_LEFT_ROOM:
              LOGI("Snapshot SelectUIResponse ERROR_LEFT_ROOM");
              break;
          default:
              break;
      }
  }
  
  void StateManager::saveSnapshot(std::string description,
                                  std::chrono::milliseconds playtime,
                                  std::vector&lt;uint8_t&gt; png_data,
                                  std::vector&lt;uint8_t&gt; snapData)
  {
      if (_gameServices)
      {
          //if we do not have current snapshot we generate the filename
          if (_currentSnapshot.empty())
          {
  
              std::chrono::system_clock::time_point today = std::chrono::system_clock::now();
              std::time_t tt = std::chrono::system_clock::to_time_t ( today );
  
              //using strftime
              time_t rawtime;
              struct tm * timeinfo;
              char buffer [32];
  
              time (&amp;tt);
              timeinfo = localtime (&amp;rawtime);
  
              strftime (buffer,32,"save_%Y%m%d%H%M%S",timeinfo);
  
              //put_time not available in GCC &lt; 5.0
              //std::ostringstream snapshot_name;
              //snapshot_name &lt;&lt; std::put_time(ctime(&amp;tt),"save_%Y%m%d%H%M%S");
              _currentSnapshot.assign(buffer,32);
              LOGI("new snapshot name is: %s",_currentSnapshot.c_str());
          }
  
          LOGI("Saving Snapshot %s",_currentSnapshot.c_str());
          LOGI("%s",description.c_str());
  
          _gameServices-&gt;Snapshots().Open(_currentSnapshot,
                                         gpg::SnapshotConflictPolicy::LONGEST_PLAYTIME,
                                         [this, description, playtime, png_data, snapData](gpg::SnapshotManager::OpenResponse const &amp;response)
                                         {
                                             gpg::SnapshotMetadata metadata;
                                             if (IsSuccess(response.status)) { // Always failure
                                                 metadata = response.data;
                                                 gpg::SnapshotMetadataChange::Builder builder;
                                                 if ( description != metadata.Description())
                                                 {
                                                     builder.SetDescription(description);
                                                 }
                                                 if ( playtime != metadata.PlayedTime())
                                                 {
                                                     builder.SetPlayedTime(static_cast&lt;gpg::Duration&gt;(playtime));
                                                 }
                                                 if ( ! png_data.empty() )
                                                 {
                                                     builder.SetCoverImageFromPngData(png_data);
                                                 }
                                                 gpg::SnapshotMetadataChange metadata_change = builder.Create();
                                                 _gameServices-&gt;Snapshots().Commit(
                                                     metadata,
                                                     metadata_change,
                                                     snapData,
                                                     std::bind(&amp;StateManager::committedSnapshot,this,std::placeholders::_1));
  
                                             }
                                         });
      }
  }
  
  void StateManager::selectSnapshot(std::string title, uint32_t max_snapshots, bool allow_create, bool allow_delete)
  {
      if (_gameServices)
      {
          LOGI("Listing Snapshot");
          LOGI("%s",title.c_str());
          _gameServices-&gt;Snapshots().ShowSelectUIOperation(allow_create,
                                                           allow_delete,
                                                           max_snapshots,
                                                           title,
                                                           std::bind(&amp;StateManager::selectedSnapshot, this,
                                                                     std::placeholders::_1));
      }
  }
  </code></pre>
  
  <p>Is there anyone solve this problem?</p>