[{"data":1,"prerenderedAt":2101},["ShallowReactive",2],{"\u002Fblog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026\u002F":3,"\u002Fblog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026\u002F-related":545,"\u002Fblog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026\u002F-resources":2091},{"id":4,"title":5,"author":6,"body":10,"category":476,"createdAt":477,"description":478,"disclosure":479,"extension":480,"faq":481,"howTo":479,"lastVerified":479,"location":497,"meta":498,"navigation":283,"ogImage":479,"path":504,"primaryKeyword":505,"readingTime":506,"related":507,"seo":511,"sources":512,"stem":535,"tags":536,"takeaways":537,"updatedAt":477,"url":543,"__hash__":544},"blog\u002Fblog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026.md","ITMS-90683: Fix Missing Purpose String in Info.plist",{"name":7,"social":8},"Simon Dziak",{"twitter":9},"@SzymonDziak",{"type":11,"value":12,"toc":467},"minimark",[13,21,24,30,35,52,55,124,128,137,140,156,165,169,172,186,194,229,232,235,239,242,257,363,370,377,380,393,397,423,440,444,447,451,463],[14,15,16,20],"p",{},[17,18,19],"strong",{},"If App Store Connect emailed you ITMS-90683, your app's code references an API that accesses sensitive user data, and Info.plist has no purpose string for it."," The email names the missing key, for example NSCameraUsageDescription or NSPhotoLibraryUsageDescription. In a Flutter app the trigger is often a plugin, not your own code. The fix is to add an accurate purpose string for features you really ship, or to remove the access so the key is no longer needed.",[14,22,23],{},"The facts below come from Apple's developer documentation, the App Review Guidelines, the plugin READMEs and the GitHub issues listed in the sources. I checked each one on October 18, 2026.",[14,25,26,29],{},[17,27,28],{},"Disclosure:"," App369 is my studio. I build and fix Android and iOS apps, mostly in Flutter, and the last section mentions what I sell. Apple doesn't pay me for anything on this page.",[31,32,34],"h2",{"id":33},"what-the-email-says","What the email says",[14,36,37,38,45,46,51],{},"The email heading is \"ITMS-90683: Missing Purpose String in Info.plist\". A Flutter issue (",[39,40,44],"a",{"href":41,"rel":42},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F113603",[43],"nofollow","113603",") quotes one such email, posted by an image_picker user. It includes this sentence: \"While your app might not use these APIs, a purpose string is still required.\" Your wording may differ. Another issue (",[39,47,50],{"href":48,"rel":49},"https:\u002F\u002Fgithub.com\u002FBaseflow\u002Fflutter-permission-handler\u002Fissues\u002F1543",[43],"permission_handler 1543",") quotes a version that also mentions entitlements, so read your own email for the key name.",[14,53,54],{},"That key name is the part you need. These are the keys I have seen in the sources for this page:",[56,57,58,74],"table",{},[59,60,61],"thead",{},[62,63,64,68,71],"tr",{},[65,66,67],"th",{},"Key in the email",[65,69,70],{},"What it is for",[65,72,73],{},"Where I saw it",[75,76,77,93,107],"tbody",{},[62,78,79,83,86],{},[80,81,82],"td",{},"NSCameraUsageDescription",[80,84,85],{},"Required if your app uses APIs that access the device's camera",[80,87,88],{},[39,89,92],{"href":90,"rel":91},"https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Finformation-property-list\u002Fnscamerausagedescription",[43],"Apple",[62,94,95,98,101],{},[80,96,97],{},"NSPhotoLibraryUsageDescription",[80,99,100],{},"Required if your app uses APIs with read or write access to the photo library. If your app only adds assets and doesn't read them, Apple points to a different key",[80,102,103],{},[39,104,92],{"href":105,"rel":106},"https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Finformation-property-list\u002Fnsphotolibraryusagedescription",[43],[62,108,109,112,115],{},[80,110,111],{},"NSMicrophoneUsageDescription, NSContactsUsageDescription, NSLocationWhenInUseUsageDescription, NSBluetoothAlwaysUsageDescription",[80,113,114],{},"Microphone, contacts, location while in use, Bluetooth",[80,116,117,118,123],{},"Listed in the permission_handler ",[39,119,122],{"href":120,"rel":121},"https:\u002F\u002Fgithub.com\u002FBaseflow\u002Fflutter-permission-handler\u002Fblob\u002Fmain\u002Fpermission_handler\u002FREADME.md",[43],"README"," table of permissions and Info.plist keys",[31,125,127],{"id":126},"why-a-flutter-app-gets-it-for-features-it-doesnt-use","Why a Flutter app gets it for features it doesn't use",[14,129,130,131,136],{},"Apple's documentation says it plainly. App Review checks for the use of protected resources and rejects apps that contain code accessing them without a purpose string. It also says that external libraries or SDKs may reference APIs that require a purpose string, that a purpose string is still necessary even if your app doesn't use those APIs, and that you are responsible for all access of protected resources, including external SDK and library access. Source: ",[39,132,135],{"href":133,"rel":134},"https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fuikit\u002Frequesting-access-to-protected-resources",[43],"Apple, Requesting access to protected resources",".",[14,138,139],{},"Two common Flutter cases:",[141,142,143,150],"ul",{},[144,145,146,149],"li",{},[17,147,148],{},"image_picker."," Its README says to add NSPhotoLibraryUsageDescription, NSCameraUsageDescription and, if you intend to record videos, NSMicrophoneUsageDescription. It adds that the photo library permission won't be requested if you always pass false for requestFullMetadata, but that \"App Store policy requires including the plist entry.\" That matches the email quoted in issue 113603.",[144,151,152,155],{},[17,153,154],{},"permission_handler."," The README says the plugin uses macros to control whether a permission is enabled. If a permission's code is compiled in, the app references that API, and Apple's page says App Review rejects code that accesses a protected resource without a purpose string.",[14,157,158,159,164],{},"Flutter's older issue ",[39,160,163],{"href":161,"rel":162},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F21941",[43],"21941"," shows this isn't new. In 2018 a developer got the same kind of email for contacts, calendars, Apple Music, motion and speech recognition keys that their app didn't use.",[31,166,168],{"id":167},"fix-1-add-accurate-purpose-strings","Fix 1: add accurate purpose strings",[14,170,171],{},"Do this for features your app really ships. Apple's rules for a purpose string:",[141,173,174,177,180,183],{},[144,175,176],{},"It isn't blank and isn't only whitespace.",[144,178,179],{},"It is shorter than 4,000 bytes. Typical strings are one complete sentence.",[144,181,182],{},"It is accurate, meaningful and specific about why the app needs the resource.",[144,184,185],{},"The same rules apply to localized strings.",[14,187,188,189,193],{},"Add the key to ",[190,191,192],"code",{},"ios\u002FRunner\u002FInfo.plist",". Here is the shape. These strings are examples only. Rewrite each one to say what your own app does with the data:",[195,196,201],"pre",{"className":197,"code":198,"language":199,"meta":200,"style":200},"language-xml shiki shiki-themes github-light github-dark","\u003Ckey>NSCameraUsageDescription\u003C\u002Fkey>\n\u003Cstring>EXAMPLE: Rewrite this. The camera lets you take a photo to attach to a job report.\u003C\u002Fstring>\n\u003Ckey>NSPhotoLibraryUsageDescription\u003C\u002Fkey>\n\u003Cstring>EXAMPLE: Rewrite this. Your photo library lets you choose an existing photo to attach to a job report.\u003C\u002Fstring>\n","xml","",[190,202,203,211,217,223],{"__ignoreMap":200},[204,205,208],"span",{"class":206,"line":207},"line",1,[204,209,210],{},"\u003Ckey>NSCameraUsageDescription\u003C\u002Fkey>\n",[204,212,214],{"class":206,"line":213},2,[204,215,216],{},"\u003Cstring>EXAMPLE: Rewrite this. The camera lets you take a photo to attach to a job report.\u003C\u002Fstring>\n",[204,218,220],{"class":206,"line":219},3,[204,221,222],{},"\u003Ckey>NSPhotoLibraryUsageDescription\u003C\u002Fkey>\n",[204,224,226],{"class":206,"line":225},4,[204,227,228],{},"\u003Cstring>EXAMPLE: Rewrite this. Your photo library lets you choose an existing photo to attach to a job report.\u003C\u002Fstring>\n",[14,230,231],{},"Apple's page says purpose strings help people make an informed decision, and that explaining accurately and concisely, typically in one complete sentence, improves the chances they grant access.",[14,233,234],{},"My advice: don't paste a generic sentence into every key just to clear the email. App Review guideline 5.1.1(ii) says \"Ensure your purpose strings clearly and completely describe your use of the data.\" A string that describes a feature your app doesn't have is a new problem.",[31,236,238],{"id":237},"fix-2-remove-the-access-you-dont-use","Fix 2: remove the access you don't use",[14,240,241],{},"Guideline 5.1.1(iii) says apps should only request access to data relevant to the core functionality of the app. Apple's page, in its example of an App Review message, says to either provide a purpose string or remove the code that's accessing the resource.",[14,243,244,245,248,249,252,253,256],{},"With permission_handler on CocoaPods, the README gives this procedure. In your Podfile's ",[190,246,247],{},"post_install"," block, set the macro of each permission you don't need to 0, and delete that same permission's usage description from Info.plist. The README says to use ",[190,250,251],{},"PERMISSION_CAMERA=0"," instead of ",[190,254,255],{},"PERMISSION_CAMERA=1",", for example. Trimmed shape:",[195,258,262],{"className":259,"code":260,"language":261,"meta":200,"style":200},"language-ruby shiki shiki-themes github-light github-dark","post_install do |installer|\n  installer.pods_project.targets.each do |target|\n    flutter_additional_ios_build_settings(target)\n\n    target.build_configurations.each do |config|\n      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [\n        '$(inherited)',\n        # permissions you use: keep the macro, set to 1, for example:\n        'PERMISSION_PHOTOS=1',\n        # permissions you don't use: set to 0, or leave the macro out\n        'PERMISSION_CAMERA=0',\n        'PERMISSION_CONTACTS=0',\n        'PERMISSION_MICROPHONE=0',\n      ]\n    end\n  end\nend\n","ruby",[190,263,264,269,274,279,285,291,297,303,309,315,321,327,333,339,345,351,357],{"__ignoreMap":200},[204,265,266],{"class":206,"line":207},[204,267,268],{},"post_install do |installer|\n",[204,270,271],{"class":206,"line":213},[204,272,273],{},"  installer.pods_project.targets.each do |target|\n",[204,275,276],{"class":206,"line":219},[204,277,278],{},"    flutter_additional_ios_build_settings(target)\n",[204,280,281],{"class":206,"line":225},[204,282,284],{"emptyLinePlaceholder":283},true,"\n",[204,286,288],{"class":206,"line":287},5,[204,289,290],{},"    target.build_configurations.each do |config|\n",[204,292,294],{"class":206,"line":293},6,[204,295,296],{},"      config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [\n",[204,298,300],{"class":206,"line":299},7,[204,301,302],{},"        '$(inherited)',\n",[204,304,306],{"class":206,"line":305},8,[204,307,308],{},"        # permissions you use: keep the macro, set to 1, for example:\n",[204,310,312],{"class":206,"line":311},9,[204,313,314],{},"        'PERMISSION_PHOTOS=1',\n",[204,316,318],{"class":206,"line":317},10,[204,319,320],{},"        # permissions you don't use: set to 0, or leave the macro out\n",[204,322,324],{"class":206,"line":323},11,[204,325,326],{},"        'PERMISSION_CAMERA=0',\n",[204,328,330],{"class":206,"line":329},12,[204,331,332],{},"        'PERMISSION_CONTACTS=0',\n",[204,334,336],{"class":206,"line":335},13,[204,337,338],{},"        'PERMISSION_MICROPHONE=0',\n",[204,340,342],{"class":206,"line":341},14,[204,343,344],{},"      ]\n",[204,346,348],{"class":206,"line":347},15,[204,349,350],{},"    end\n",[204,352,354],{"class":206,"line":353},16,[204,355,356],{},"  end\n",[204,358,360],{"class":206,"line":359},17,[204,361,362],{},"end\n",[14,364,365,366,369],{},"A macro set to 1 compiles that permission in. A macro set to 0, or left out, leaves it out. Keep 1 only for permissions your app really uses. The ",[190,367,368],{},"||="," line is copied from the README.",[14,371,372,373,376],{},"Use the full list from the ",[39,374,122],{"href":120,"rel":375},[43],". Its table maps each Permission to its Info.plist key and macro. Location has two macros: PERMISSION_LOCATION covers when-in-use and always, and the README says an app that only needs when-in-use should specify only PERMISSION_LOCATION_WHENINUSE.",[14,378,379],{},"The README also says that permission_handler by default excludes all permissions since version 8.0.0, and developers only enable those the app needs. If your Podfile came from an old template with every macro set to 1, that is a place to look.",[14,381,382,383,386,387,392],{},"If you build with Swift Package Manager, the README describes a different mechanism. It finds your Info.plist through the INFOPLIST_FILE setting and compiles in the permissions whose keys it finds there, so a single-flavor app needs no extra configuration. It also says that for apps with flavors, a permission declared in one plist can be compiled into every build, which it calls grounds for App Store rejection (ITMS-90683). It documents a ",[190,384,385],{},"permission_handler.yaml"," file to give each flavor its own plist. Issue ",[39,388,391],{"href":389,"rel":390},"https:\u002F\u002Fgithub.com\u002FBaseflow\u002Fflutter-permission-handler\u002Fissues\u002F1558",[43],"1558"," shows a related report about location. Check the current README for your plugin version.",[31,394,396],{"id":395},"rebuild-and-re-upload","Rebuild and re-upload",[398,399,400,406,417,420],"ol",{},[144,401,402,403,405],{},"Edit ",[190,404,192],{}," and, for CocoaPods, the Podfile.",[144,407,408,409,412,413,416],{},"From the ",[190,410,411],{},"ios"," folder, run ",[190,414,415],{},"pod install",". The README's last step for the Podfile route is \"Clean & Rebuild\".",[144,418,419],{},"Build a new archive. The upload needs a new build number.",[144,421,422],{},"Upload again and wait for the processing email.",[14,424,425,426,430,431,435,436,136],{},"My advice: if your upload also fails with a different code, read it separately. For SDK version errors see ",[39,427,429],{"href":428},"\u002Fblog\u002Fitms-90725-sdk-version-issue-xcode-26-flutter-2026\u002F","the ITMS-90725 guide",". For privacy manifest errors see ",[39,432,434],{"href":433},"\u002Fblog\u002Fapple-privacy-manifest-itms-91053-itms-91061-flutter-fix-2026\u002F","the ITMS-91053 and ITMS-91061 guide",". If a Flutter upgrade broke the iOS build itself, see ",[39,437,439],{"href":438},"\u002Fblog\u002Fflutter-ios-build-failed-after-upgrade-2026\u002F","the iOS build-failed-after-upgrade guide",[31,441,443],{"id":442},"what-happens-if-the-string-is-missing-at-runtime","What happens if the string is missing at runtime",[14,445,446],{},"Apple's page says to always provide a valid purpose string in the Signing and Capabilities editor if your app uses a protected resource. It continues: \"If you don't, attempts to access the resource fail, and might cause your app to crash.\" So a missing string can hurt users as well as your upload. Add the string for any feature you ship.",[31,448,450],{"id":449},"need-a-hand","Need a hand?",[14,452,453,454,458,459,136],{},"If App Store Connect keeps flagging missing purpose strings, or App Review rejects the wording, the ",[39,455,457],{"href":456},"\u002Ffixed-price\u002Fflutter-firebase-bug-fix\u002F","App Fix Ticket"," covers it in two fixed-price steps. A $450 Diagnosis gives you the root cause with evidence and a fixed repair quote within 3 business days, credited toward the fix. If you go ahead, the $1,200 Fix takes 5 business days and comes as a pull request. Or ",[39,460,462],{"href":461},"\u002Fcontact\u002F","send me a short description",[464,465,466],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":200,"searchDepth":213,"depth":213,"links":468},[469,470,471,472,473,474,475],{"id":33,"depth":213,"text":34},{"id":126,"depth":213,"text":127},{"id":167,"depth":213,"text":168},{"id":237,"depth":213,"text":238},{"id":395,"depth":213,"text":396},{"id":442,"depth":213,"text":443},{"id":449,"depth":213,"text":450},"AI & Technology","2026-10-18T21:30:00.000Z","App Store Connect emails ITMS-90683 when your app, or a plugin inside it, references an API that needs a purpose string and Info.plist has none. Why Flutter apps get it for features they never use, and how to fix it with accurate strings or permission_handler Podfile macros, from Apple's and the plugins' sources checked October 18, 2026.",null,"md",[482,485,488,491,494],{"question":483,"answer":484},"What does ITMS-90683 Missing purpose string mean?","It means the app's code references an API that accesses sensitive user data, and the Info.plist has no purpose string for it. Apple's documentation says App Review rejects apps that contain code accessing protected resources without a purpose string. The email names the key it expects.",{"question":486,"answer":487},"Why do I get it for a camera or contacts feature I do not use?","Apple says external libraries and SDKs may reference APIs that require a purpose string, and that a purpose string is still necessary even if your app does not use those APIs. In Flutter, a plugin such as permission_handler or image_picker can link those APIs.",{"question":489,"answer":490},"Can I just write any text in the purpose string?","No. Apple says a purpose string must not be blank and must be accurate, meaningful and specific about why the app needs the resource. Write what your app really does with the data, and only add keys for features you ship.",{"question":492,"answer":493},"How do I turn off unused permissions in permission_handler?","For CocoaPods, the plugin README says to set the macro to 0 in the GCC_PREPROCESSOR_DEFINITIONS list in your Podfile, for example PERMISSION_CAMERA=0, and delete that permission's usage description from Info.plist. Then clean and rebuild.",{"question":495,"answer":496},"What happens if the purpose string is missing at runtime?","Apple says that if you do not provide a valid purpose string for a protected resource your app uses, attempts to access the resource fail and might cause your app to crash.","Boynton Beach, FL",{"readingTimeStats":499},{"text":500,"minutes":501,"time":502,"words":503},"7 min read",6.365,381900,1273,"\u002Fblog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026","itms-90683","7 min",[508,509,510],"apple-privacy-manifest-itms-91053-itms-91061-flutter-fix-2026","itms-90725-sdk-version-issue-xcode-26-flutter-2026","flutter-ios-build-failed-after-upgrade-2026",{"title":5,"description":478},[513,515,517,519,522,524,527,529,531,533],{"title":514,"url":133},"Apple Developer, Requesting access to protected resources",{"title":516,"url":90},"Apple Developer, NSCameraUsageDescription",{"title":518,"url":105},"Apple Developer, NSPhotoLibraryUsageDescription",{"title":520,"url":521},"Apple Developer, App Review Guidelines (5.1.1 Data Collection and Storage)","https:\u002F\u002Fdeveloper.apple.com\u002Fapp-store\u002Freview\u002Fguidelines\u002F",{"title":523,"url":120},"Baseflow on GitHub, permission_handler README (iOS setup, Podfile macros, Swift Package Manager)",{"title":525,"url":526},"flutter\u002Fpackages on GitHub, image_picker README (iOS setup)","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fpackages\u002Fblob\u002Fmain\u002Fpackages\u002Fimage_picker\u002Fimage_picker\u002FREADME.md",{"title":528,"url":41},"Flutter on GitHub, issue 113603 (ITMS-90683 email text for NSPhotoLibraryUsageDescription with image_picker)",{"title":530,"url":161},"Flutter on GitHub, issue 21941 (earlier Apple email text, keys for features the app did not use)",{"title":532,"url":48},"permission_handler on GitHub, issue 1543 (ITMS-90683 email for a location key)",{"title":534,"url":389},"permission_handler on GitHub, issue 1558 (location permission and ITMS-90683 with Swift Package Manager)","blog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026","itms-90683, itms-90683 missing purpose string, missing purpose string info.plist flutter, nscamerausagedescription flutter, nsphotolibraryusagedescription flutter, permission_handler podfile, permission_camera=0, image_picker info.plist, app store connect email flutter",[538,539,540,541,542],"ITMS-90683 means your app, or a library inside it, references an API that accesses sensitive user data and Info.plist has no matching purpose string. The email names the key it wants, such as NSCameraUsageDescription.","Apple says you are responsible for all access of protected resources, including access by external SDKs and libraries. A plugin can trigger the email even if your app never uses that feature.","You have two fixes. Add an accurate purpose string for the key, or remove the access: with permission_handler, set the unused PERMISSION_ macros to 0 in the Podfile and delete that permission's key from Info.plist.","Apple says each purpose string must be accurate, meaningful and specific, and App Review guideline 5.1.1 asks that purpose strings clearly and completely describe your use of the data. A vague placeholder is a risk.","After you change the Podfile or Info.plist, run pod install, rebuild, and upload a new build.","https:\u002F\u002Fapp369.com\u002Fblog\u002Fitms-90683-missing-purpose-string-info-plist-flutter-2026\u002F","DlDVqFGdCLi9s936ZbhhDiik0K1_LXLBot7SsfVNAZo",[546,1197,1581],{"id":547,"title":548,"author":549,"body":551,"category":476,"createdAt":1124,"description":1125,"disclosure":479,"extension":480,"faq":1126,"howTo":479,"lastVerified":479,"location":497,"meta":1142,"navigation":283,"ogImage":479,"path":1148,"primaryKeyword":1149,"readingTime":506,"related":1150,"seo":1153,"sources":1154,"stem":1187,"tags":1188,"takeaways":1189,"updatedAt":1124,"url":1195,"__hash__":1196},"blog\u002Fblog\u002Fapple-privacy-manifest-itms-91053-itms-91061-flutter-fix-2026.md","ITMS-91053 and ITMS-91061: Fix Privacy Manifest Emails",{"name":7,"social":550},{"twitter":9},{"type":11,"value":552,"toc":1114},[553,559,562,566,570,608,623,627,699,702,711,715,718,790,793,797,858,861,865,868,885,888,891,1016,1019,1022,1026,1075,1079,1090,1093,1096,1103,1105,1112],[14,554,555,558],{},[17,556,557],{},"If App Store Connect emailed you ITMS-91053 or ITMS-91061, a PrivacyInfo.xcprivacy file is missing or incomplete, either in your own code or in a third-party SDK."," ITMS-91053 is about required reason APIs used without a declared reason. ITMS-91061 is about a commonly used SDK, such as Flutter itself, that ships without a privacy manifest. In a Flutter app the fix is usually to upgrade Flutter and your plugins first, and to add your own manifest only for native code you wrote.",[14,560,561],{},"The facts below come from Apple's developer documentation, Apple's SDK requirements page, the Flutter team's comments on GitHub and the plugin manifests listed in the sources. I checked each one on October 18, 2026.",[14,563,564,29],{},[17,565,28],{},[31,567,569],{"id":568},"what-the-two-errors-mean","What the two errors mean",[56,571,572,584],{},[59,573,574],{},[62,575,576,579,581],{},[65,577,578],{},"Code",[65,580,34],{},[65,582,583],{},"What it means",[75,585,586,597],{},[62,587,588,591,594],{},[80,589,590],{},"ITMS-91053",[80,592,593],{},"\"Missing API declaration\": your app's code references APIs that require reasons, and names categories such as NSPrivacyAccessedAPICategoryFileTimestamp or NSPrivacyAccessedAPICategoryUserDefaults",[80,595,596],{},"Code in your app or an SDK uses a required reason API, and no privacy manifest gives an approved reason for it",[62,598,599,602,605],{},[80,600,601],{},"ITMS-91061",[80,603,604],{},"\"Missing privacy manifest\": your app includes an SDK that was identified as a commonly used third-party SDK, for example Frameworks\u002FFlutter.framework\u002FFlutter",[80,606,607],{},"That SDK has no privacy manifest file",[14,609,610,611,616,617,622],{},"The wording comes from emails quoted in Flutter issues ",[39,612,615],{"href":613,"rel":614},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F145269",[43],"145269"," and ",[39,618,621],{"href":619,"rel":620},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F163455",[43],"163455",". Your email may differ a little, so read the file name it gives. That name is your first clue.",[31,624,626],{"id":625},"the-dates","The dates",[56,628,629,642],{},[59,630,631],{},[62,632,633,636,639],{},[65,634,635],{},"Date",[65,637,638],{},"What Apple or the email said",[65,640,641],{},"Source",[75,643,644,667,682],{},[62,645,646,651,654],{},[80,647,648],{},[17,649,650],{},"May 1, 2024",[80,652,653],{},"Apps that don't describe their use of required reason APIs in their privacy manifest aren't accepted by App Store Connect. Apple's upcoming requirements page says you need approved reasons, including for third-party SDK code, to upload a new or updated app",[80,655,656,661,662],{},[39,657,660],{"href":658,"rel":659},"https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Fdescribing-use-of-required-reason-api",[43],"Apple, required reason API",", ",[39,663,666],{"href":664,"rel":665},"https:\u002F\u002Fdeveloper.apple.com\u002Fnews\u002Fupcoming-requirements\u002F",[43],"Apple, upcoming requirements",[62,668,669,672,675],{},[80,670,671],{},"November 12, 2024",[80,673,674],{},"An ITMS-91061 email posted in a Flutter issue says that from this date a new privacy-impacting SDK must include a manifest",[80,676,677],{},[39,678,681],{"href":679,"rel":680},"https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F156141",[43],"Flutter issue 156141",[62,683,684,689,692],{},[80,685,686],{},[17,687,688],{},"February 12, 2025",[80,690,691],{},"Apple says apps submitted for review in App Store Connect must contain a valid privacy manifest for a certain number of commonly used third-party SDKs",[80,693,694],{},[39,695,698],{"href":696,"rel":697},"https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Fadding-a-privacy-manifest-to-your-app-or-third-party-sdk",[43],"Apple, adding a privacy manifest",[14,700,701],{},"Apple's SDK page says you must include the manifest for any listed SDK when you submit a new app that includes it, or an update that adds it. It also says signatures are required where the listed SDKs are used as binary dependencies, and that any version of a listed SDK is covered. That page didn't state a date when I read it, so I rely on the other Apple page for February 12, 2025.",[14,703,704,705,710],{},"The list includes Flutter, FirebaseCore, FirebaseAuth, FirebaseMessaging, path_provider, shared_preferences_ios, url_launcher, image_picker_ios, sqflite and many more. Check ",[39,706,709],{"href":707,"rel":708},"https:\u002F\u002Fdeveloper.apple.com\u002Fsupport\u002Fthird-party-SDK-requirements\u002F",[43],"Apple's list"," for the plugins in your app.",[31,712,714],{"id":713},"the-five-required-reason-api-categories","The five required reason API categories",[14,716,717],{},"Apple describes these APIs as ones that could be misused to fingerprint a device or user. Each category goes in the NSPrivacyAccessedAPITypes array with one or more reason codes. These are the categories and the codes I read in Apple's documentation:",[56,719,720,733],{},[59,721,722],{},[62,723,724,727,730],{},[65,725,726],{},"Category key",[65,728,729],{},"What it covers",[65,731,732],{},"Reason codes from Apple",[75,734,735,746,757,768,779],{},[62,736,737,740,743],{},[80,738,739],{},"NSPrivacyAccessedAPICategoryFileTimestamp",[80,741,742],{},"File timestamps and metadata (fstat, lstat, getattrlist and similar)",[80,744,745],{},"DDA9.1 display to the user, C617.1 files inside the app container, 3B52.1 files the user granted access to, 0A2A.1 third-party SDK wrapper",[62,747,748,751,754],{},[80,749,750],{},"NSPrivacyAccessedAPICategorySystemBootTime",[80,752,753],{},"System boot time, such as mach_absolute_time",[80,755,756],{},"35F9.1 measure elapsed time within the app, 8FFB.1 absolute timestamps for events in the app, 3D61.1 optional bug report",[62,758,759,762,765],{},[80,760,761],{},"NSPrivacyAccessedAPICategoryDiskSpace",[80,763,764],{},"Available disk space (statfs, volume capacity keys and similar)",[80,766,767],{},"85F4.1 display to the user, E174.1 check space before writing files, 7D9E.1 optional bug report, B728.1 health research apps",[62,769,770,773,776],{},[80,771,772],{},"NSPrivacyAccessedAPICategoryActiveKeyboards",[80,774,775],{},"List of active keyboards",[80,777,778],{},"3EC4.1 custom keyboard apps, 54BD.1 customize the UI based on the active keyboard",[62,780,781,784,787],{},[80,782,783],{},"NSPrivacyAccessedAPICategoryUserDefaults",[80,785,786],{},"UserDefaults",[80,788,789],{},"CA92.1 data only the app itself can access, 1C8F.1 data shared in the same App Group, C56D.1 third-party SDK wrapper, AC6B.1 managed app configuration set by MDM",[14,791,792],{},"Each reason comes with limits. For example, Apple says information accessed for several of these reasons may not be sent off-device. Read the full text for your code before you pick one.",[31,794,796],{"id":795},"find-which-sdk-or-plugin-triggers-it","Find which SDK or plugin triggers it",[398,798,799,805,820,834,848],{},[144,800,801,804],{},[17,802,803],{},"Read the email."," It names the file. \"Runner\" means your app target, or a plugin built statically into it. A path like Frameworks\u002FFlutter.framework\u002FFlutter means that framework.",[144,806,807,810,811,815,816,819],{},[17,808,809],{},"Upgrade first."," The Flutter team's guidance in ",[39,812,814],{"href":613,"rel":813},[43],"issue 145269"," (comment dated April 22, 2024) starts with ",[190,817,818],{},"flutter pub upgrade",", because many plugins added their manifests after the rules came out.",[144,821,822,825,826,829,830,833],{},[17,823,824],{},"Look at what your build contains."," The same guidance says to run ",[190,827,828],{},"find build\u002Fios\u002Fiphoneos -name \"*.xcprivacy\""," and look at each ",[190,831,832],{},"PrivacyInfo.xcprivacy"," inside the plugin bundles. Compare their declarations with the categories in your email. If all of them together don't cover the email, at least one dependency has no manifest.",[144,835,836,839,840,843,844,847],{},[17,837,838],{},"Try packaging plugins as frameworks."," The same guidance says adding the ",[190,841,842],{},"use_frameworks!"," line from Flutter's Podfile template can change a warning from \"Runner\" to a named framework. Then you know which plugin to contact. Plugins that set ",[190,845,846],{},"static_framework = true"," override it.",[144,849,850,853,854,857],{},[17,851,852],{},"Search your own code."," In ",[190,855,856],{},"ios\u002FRunner.xcworkspace",", use Find in Workspace for the APIs listed in the flagged category, and check whether the matches are in code you wrote or in a plugin.",[14,859,860],{},"The Flutter team also noted a bug in App Store Connect, at least as of April 2024, that could produce a warning for static frameworks that do declare their reasons. If your plugins all have manifests and the warning still names Runner, that comment is worth reading.",[31,862,864],{"id":863},"add-or-edit-privacyinfoxcprivacy-in-xcode","Add or edit PrivacyInfo.xcprivacy in Xcode",[14,866,867],{},"Do this only for code in your own app, or if an SDK can't be updated. Apple's steps:",[398,869,870,876,879,882],{},[144,871,872,873,875],{},"Open ",[190,874,856],{}," in Xcode.",[144,877,878],{},"Choose File > New File.",[144,880,881],{},"Scroll to the Resource section and select the App Privacy File type, then click Next.",[144,883,884],{},"Check the Runner target in the Targets list and click Create.",[14,886,887],{},"The file is named PrivacyInfo.xcprivacy by default, and that is the required name. Apple says the file must be in the target's resources for Xcode to use it, and that for an iOS app Xcode places it at the root of the app bundle.",[14,889,890],{},"A minimal manifest for an app whose own code reads and writes UserDefaults for itself looks like this. It matches the structure in Flutter's own plugin manifests:",[195,892,894],{"className":197,"code":893,"language":199,"meta":200,"style":200},"\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n\u003C!DOCTYPE plist PUBLIC \"-\u002F\u002FApple\u002F\u002FDTD PLIST 1.0\u002F\u002FEN\" \"http:\u002F\u002Fwww.apple.com\u002FDTDs\u002FPropertyList-1.0.dtd\">\n\u003Cplist version=\"1.0\">\n\u003Cdict>\n    \u003Ckey>NSPrivacyTracking\u003C\u002Fkey>\n    \u003Cfalse\u002F>\n    \u003Ckey>NSPrivacyTrackingDomains\u003C\u002Fkey>\n    \u003Carray\u002F>\n    \u003Ckey>NSPrivacyCollectedDataTypes\u003C\u002Fkey>\n    \u003Carray\u002F>\n    \u003Ckey>NSPrivacyAccessedAPITypes\u003C\u002Fkey>\n    \u003Carray>\n        \u003Cdict>\n            \u003Ckey>NSPrivacyAccessedAPIType\u003C\u002Fkey>\n            \u003Cstring>NSPrivacyAccessedAPICategoryUserDefaults\u003C\u002Fstring>\n            \u003Ckey>NSPrivacyAccessedAPITypeReasons\u003C\u002Fkey>\n            \u003Carray>\n                \u003Cstring>CA92.1\u003C\u002Fstring>\n            \u003C\u002Farray>\n        \u003C\u002Fdict>\n    \u003C\u002Farray>\n\u003C\u002Fdict>\n\u003C\u002Fplist>\n",[190,895,896,901,906,911,916,921,926,931,936,941,945,950,955,960,965,970,975,980,986,992,998,1004,1010],{"__ignoreMap":200},[204,897,898],{"class":206,"line":207},[204,899,900],{},"\u003C?xml version=\"1.0\" encoding=\"UTF-8\"?>\n",[204,902,903],{"class":206,"line":213},[204,904,905],{},"\u003C!DOCTYPE plist PUBLIC \"-\u002F\u002FApple\u002F\u002FDTD PLIST 1.0\u002F\u002FEN\" \"http:\u002F\u002Fwww.apple.com\u002FDTDs\u002FPropertyList-1.0.dtd\">\n",[204,907,908],{"class":206,"line":219},[204,909,910],{},"\u003Cplist version=\"1.0\">\n",[204,912,913],{"class":206,"line":225},[204,914,915],{},"\u003Cdict>\n",[204,917,918],{"class":206,"line":287},[204,919,920],{},"    \u003Ckey>NSPrivacyTracking\u003C\u002Fkey>\n",[204,922,923],{"class":206,"line":293},[204,924,925],{},"    \u003Cfalse\u002F>\n",[204,927,928],{"class":206,"line":299},[204,929,930],{},"    \u003Ckey>NSPrivacyTrackingDomains\u003C\u002Fkey>\n",[204,932,933],{"class":206,"line":305},[204,934,935],{},"    \u003Carray\u002F>\n",[204,937,938],{"class":206,"line":311},[204,939,940],{},"    \u003Ckey>NSPrivacyCollectedDataTypes\u003C\u002Fkey>\n",[204,942,943],{"class":206,"line":317},[204,944,935],{},[204,946,947],{"class":206,"line":323},[204,948,949],{},"    \u003Ckey>NSPrivacyAccessedAPITypes\u003C\u002Fkey>\n",[204,951,952],{"class":206,"line":329},[204,953,954],{},"    \u003Carray>\n",[204,956,957],{"class":206,"line":335},[204,958,959],{},"        \u003Cdict>\n",[204,961,962],{"class":206,"line":341},[204,963,964],{},"            \u003Ckey>NSPrivacyAccessedAPIType\u003C\u002Fkey>\n",[204,966,967],{"class":206,"line":347},[204,968,969],{},"            \u003Cstring>NSPrivacyAccessedAPICategoryUserDefaults\u003C\u002Fstring>\n",[204,971,972],{"class":206,"line":353},[204,973,974],{},"            \u003Ckey>NSPrivacyAccessedAPITypeReasons\u003C\u002Fkey>\n",[204,976,977],{"class":206,"line":359},[204,978,979],{},"            \u003Carray>\n",[204,981,983],{"class":206,"line":982},18,[204,984,985],{},"                \u003Cstring>CA92.1\u003C\u002Fstring>\n",[204,987,989],{"class":206,"line":988},19,[204,990,991],{},"            \u003C\u002Farray>\n",[204,993,995],{"class":206,"line":994},20,[204,996,997],{},"        \u003C\u002Fdict>\n",[204,999,1001],{"class":206,"line":1000},21,[204,1002,1003],{},"    \u003C\u002Farray>\n",[204,1005,1007],{"class":206,"line":1006},22,[204,1008,1009],{},"\u003C\u002Fdict>\n",[204,1011,1013],{"class":206,"line":1012},23,[204,1014,1015],{},"\u003C\u002Fplist>\n",[14,1017,1018],{},"Use this as a shape, not as an answer. The Flutter team warns that a manifest is an attestation to Apple that you use data and APIs only in the ways it describes, and that copying arbitrary text could misrepresent your app. Set NSPrivacyTracking to true and list domains only if your app tracks as Apple defines it. Fill NSPrivacyCollectedDataTypes to match what you collect.",[14,1020,1021],{},"Apple also says App Store Connect rejects submissions with invalid manifests, so use only the keys and values Apple documents.",[31,1023,1025],{"id":1024},"update-flutter-plugins-and-pods","Update Flutter, plugins and pods",[141,1027,1028,1040,1049,1069],{},[144,1029,1030,1033,1034,616,1036,136],{},[17,1031,1032],{},"Flutter itself."," Flutter's engine source has a PrivacyInfo.xcprivacy for the iOS framework. A maintainer replied to someone on Flutter 2.5.3 that the version is more than three years old and predates framework privacy manifests, so it can't be published as a new app under Apple's rules. If your ITMS-91061 names Flutter, upgrade Flutter. My advice: if the upgrade breaks the iOS build, see ",[39,1035,439],{"href":438},[39,1037,1039],{"href":1038},"\u002Fblog\u002Fflutter-uiscene-migration-xcode-27-app-wont-launch-2026\u002F","the UIScene migration guide",[144,1041,1042,1045,1046,1048],{},[17,1043,1044],{},"Plugins."," Run ",[190,1047,818],{},", then check the plugins on Apple's list against their changelogs. The shared_preferences iOS plugin, for example, declares UserDefaults with reason 1C8F.1 in its own manifest.",[144,1050,1051,1054,1055,1057,1058,1061,1062,616,1065,1068],{},[17,1052,1053],{},"Pods."," After a plugin update, run ",[190,1056,415],{}," from ",[190,1059,1060],{},"ios\u002F"," and rebuild. My advice: delete ",[190,1063,1064],{},"Pods",[190,1066,1067],{},"Podfile.lock"," first if CocoaPods keeps the old versions.",[144,1070,1071,1074],{},[17,1072,1073],{},"A plugin with no update."," Ask its maintainer to add a manifest, replace the plugin, or as a last resort, declare its usage in your own manifest. Apple's documentation says an SDK can't rely on an app's manifest to report its own use, so this is a stopgap.",[31,1076,1078],{"id":1077},"check-the-archive-and-re-upload","Check the archive and re-upload",[398,1080,1081,1084,1087],{},[144,1082,1083],{},"In Xcode, choose Product > Archive.",[144,1085,1086],{},"In the Organizer, Control-click the archive and choose Generate Privacy Report.",[144,1088,1089],{},"Choose where to save it and open the report in Preview.",[14,1091,1092],{},"Apple says the report aggregates the privacy manifests from your app and the third-party SDKs it links to, and that Xcode won't generate it correctly if you define your own collected data types or purposes instead of Apple's listed values. Then upload again and wait for the processing email.",[14,1094,1095],{},"If Apple's email points at an invalid manifest inside an SDK, Apple's documentation says to choose Window > Organizer, click Archives, Control-click your archive and choose Show in Finder, then Control-click it in the Finder and choose Show Package Contents. My advice: contact the SDK's developer first rather than editing a signed framework.",[14,1097,1098,1099,136],{},"For every other dated Apple, Google Play and Firebase requirement in 2026 and 2027, see ",[39,1100,1102],{"href":1101},"\u002Fblog\u002Fapp-store-google-play-deadlines-2026-2027\u002F","App Store and Google Play deadlines for 2026 and 2027",[31,1104,450],{"id":449},[14,1106,1107,1108,458,1110,136],{},"If App Store Connect keeps rejecting your upload with ITMS-91053 or ITMS-91061, the ",[39,1109,457],{"href":456},[39,1111,462],{"href":461},[464,1113,466],{},{"title":200,"searchDepth":213,"depth":213,"links":1115},[1116,1117,1118,1119,1120,1121,1122,1123],{"id":568,"depth":213,"text":569},{"id":625,"depth":213,"text":626},{"id":713,"depth":213,"text":714},{"id":795,"depth":213,"text":796},{"id":863,"depth":213,"text":864},{"id":1024,"depth":213,"text":1025},{"id":1077,"depth":213,"text":1078},{"id":449,"depth":213,"text":450},"2026-10-18T19:30:00.000Z","App Store Connect emails ITMS-91053 (missing API declaration) and ITMS-91061 (missing privacy manifest) mean your app or an SDK in it lacks a PrivacyInfo.xcprivacy. The dates, the five required reason API categories, how to find the culprit and how to fix a Flutter or native iOS app, from Apple's and Flutter's sources checked October 18, 2026.",[1127,1130,1133,1136,1139],{"question":1128,"answer":1129},"What does ITMS-91053 Missing API declaration mean?","It means your app's code, or code in an SDK, references an API that Apple calls a required reason API, such as file timestamps or user defaults, and the privacy manifest doesn't give an approved reason for it. Apple says that starting May 1, 2024, apps that don't describe that use aren't accepted by App Store Connect.",{"question":1131,"answer":1132},"What does ITMS-91061 Missing privacy manifest mean?","It means your app includes a third-party SDK from Apple's list of commonly used SDKs, and that SDK has no privacy manifest. For Flutter apps, the email I found in Flutter's issue tracker names Frameworks\u002FFlutter.framework\u002FFlutter. Upgrading to a Flutter version that ships a manifest is the usual fix.",{"question":1134,"answer":1135},"Do I need my own PrivacyInfo.xcprivacy in a Flutter app?","Only if your own native code in ios\u002FRunner uses required reason APIs, or an SDK without its own manifest forces you to. The Flutter team's guidance is that if every SDK in your dependency tree has its own manifest, your app's manifest should only need to describe usage directly in your app's code.",{"question":1137,"answer":1138},"Which reason code do I use for UserDefaults?","Apple lists CA92.1 for reading and writing information that is only accessible to the app itself, and 1C8F.1 for apps, extensions and App Clips in the same App Group. Pick the one that matches what your code does. Don't copy a code just because another project used it.",{"question":1140,"answer":1141},"How do I check what my archive declares?","In Xcode, choose Product > Archive, then Control-click the archive in the Organizer and choose Generate Privacy Report. Apple says it aggregates the privacy manifests from your app and the third-party SDKs it links to. For the file-level check, Flutter's guidance is to search the built app for .xcprivacy files.",{"readingTimeStats":1143},{"text":1144,"minutes":1145,"time":1146,"words":1147},"8 min read",7.48,448800,1496,"\u002Fblog\u002Fapple-privacy-manifest-itms-91053-itms-91061-flutter-fix-2026","itms-91053",[1151,510,1152],"flutter-uiscene-migration-xcode-27-app-wont-launch-2026","google-play-16kb-page-size-flutter-android-2026",{"title":548,"description":1125},[1155,1157,1160,1163,1165,1168,1170,1172,1174,1177,1179,1181,1184],{"title":1156,"url":658},"Apple Developer, Describing use of required reason API",{"title":1158,"url":1159},"Apple Developer, NSPrivacyAccessedAPIType (categories and reason codes)","https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Fapp-privacy-configuration\u002Fnsprivacyaccessedapitypes\u002Fnsprivacyaccessedapitype",{"title":1161,"url":1162},"Apple Developer, Privacy manifest files","https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Fprivacy-manifest-files",{"title":1164,"url":696},"Apple Developer, Adding a privacy manifest to your app or third-party SDK",{"title":1166,"url":1167},"Apple Developer, Describing data use in privacy manifests (privacy report)","https:\u002F\u002Fdeveloper.apple.com\u002Fdocumentation\u002Fbundleresources\u002Fdescribing-data-use-in-privacy-manifests",{"title":1169,"url":707},"Apple Developer, Third-party SDK requirements",{"title":1171,"url":664},"Apple Developer, Upcoming requirements (Approved reasons for APIs, since May 1, 2024)",{"title":1173,"url":613},"Flutter on GitHub, issue 145269 (ITMS-91053 email text and the Flutter team's guidance)",{"title":1175,"url":1176},"Flutter on GitHub, issue 131940 (privacy manifests in packages, and the warning about copying manifests)","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fissues\u002F131940",{"title":1178,"url":679},"Flutter on GitHub, issue 156141 (ITMS-91061 email text, November 12, 2024)",{"title":1180,"url":619},"Flutter on GitHub, issue 163455 (ITMS-91061 email text, February 12, 2025)",{"title":1182,"url":1183},"Flutter on GitHub, engine PrivacyInfo.xcprivacy for the iOS framework","https:\u002F\u002Fraw.githubusercontent.com\u002Fflutter\u002Fflutter\u002Fmaster\u002Fengine\u002Fsrc\u002Fflutter\u002Fshell\u002Fplatform\u002Fdarwin\u002Fios\u002Fframework\u002FPrivacyInfo.xcprivacy",{"title":1185,"url":1186},"flutter\u002Fpackages on GitHub, shared_preferences_foundation PrivacyInfo.xcprivacy","https:\u002F\u002Fraw.githubusercontent.com\u002Fflutter\u002Fpackages\u002Fmain\u002Fpackages\u002Fshared_preferences\u002Fshared_preferences_foundation\u002Fdarwin\u002Fshared_preferences_foundation\u002FSources\u002Fshared_preferences_foundation\u002FResources\u002FPrivacyInfo.xcprivacy","blog\u002Fapple-privacy-manifest-itms-91053-itms-91061-flutter-fix-2026","itms-91053, itms-91061, itms-91053 missing api declaration, itms-91061 missing privacy manifest, privacyinfo.xcprivacy flutter, privacy manifest flutter, required reason api, nsprivacyaccessedapitypes, ca92.1 user defaults, app store connect privacy manifest email",[1190,1191,1192,1193,1194],"ITMS-91053 means code in your app or an SDK uses a required reason API without a reason in its privacy manifest. Apple says that since May 1, 2024, apps that don't describe that use aren't accepted by App Store Connect.","ITMS-91061 means a commonly used third-party SDK in your app, such as Flutter, shipped without a privacy manifest. Apple says that starting February 12, 2025, apps submitted for review must contain a valid manifest for a certain number of those SDKs.","Apple's required reason APIs fall into five categories: file timestamp, system boot time, disk space, active keyboards and user defaults. Each needs one or more approved reason codes.","Most Flutter fixes start with upgrading Flutter and running flutter pub upgrade, because many plugins added their manifests after the rules were announced. You only add your own PrivacyInfo.xcprivacy for code you wrote.","Never paste a privacy manifest from the internet. The Flutter team says a manifest is an attestation to Apple that you use data and APIs only in the ways it describes.","https:\u002F\u002Fapp369.com\u002Fblog\u002Fapple-privacy-manifest-itms-91053-itms-91061-flutter-fix-2026\u002F","h7adom0QeA0We-wvgR4Nxy3zAKynORl2rBt9zt1r4rQ",{"id":1198,"title":1199,"author":1200,"body":1202,"category":476,"createdAt":1507,"description":1508,"disclosure":479,"extension":480,"faq":1509,"howTo":479,"lastVerified":479,"location":497,"meta":1525,"navigation":283,"ogImage":479,"path":1531,"primaryKeyword":1532,"readingTime":1533,"related":1534,"seo":1535,"sources":1536,"stem":1571,"tags":1572,"takeaways":1573,"updatedAt":1507,"url":1579,"__hash__":1580},"blog\u002Fblog\u002Fitms-90725-sdk-version-issue-xcode-26-flutter-2026.md","ITMS-90725 SDK Version Issue: Fix in Flutter (Xcode 26)",{"name":7,"social":1201},{"twitter":9},{"type":11,"value":1203,"toc":1495},[1204,1210,1213,1217,1221,1224,1230,1233,1237,1295,1302,1305,1309,1317,1321,1324,1348,1367,1371,1388,1393,1397,1403,1438,1445,1449,1456,1459,1462,1466,1469,1473,1479,1483,1485,1492],[14,1205,1206,1209],{},[17,1207,1208],{},"If App Store Connect shows ITMS-90725 \"SDK version issue,\" the build you uploaded was made with an older SDK than Apple now accepts, and the fix is to rebuild it with Xcode 26 or later."," Apple's upcoming requirements page says that since April 28, 2026, apps uploaded to App Store Connect must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26 or watchOS 26. In a Flutter app, that often means the Mac or CI machine that builds the IPA is still running Xcode 16.",[14,1211,1212],{},"The facts below come from Apple's requirements and release pages, Flutter's docs and source, and GitHub's runner image lists, as shown in the sources. I checked each one on October 18, 2026.",[14,1214,1215,29],{},[17,1216,28],{},[31,1218,1220],{"id":1219},"what-the-error-says","What the error says",[14,1222,1223],{},"The wording below is a developer's copy of the email, posted in an Apple Developer Forums thread in January 2026. It is not Apple's own documentation:",[1225,1226,1227],"blockquote",{},[14,1228,1229],{},"This app was built with the iOS 18.2 SDK. Starting April 2026, all iOS and iPadOS apps must be built with the iOS 26 SDK or later, included in Xcode 26 or later, in order to be uploaded to App Store Connect or submitted for distribution.",[14,1231,1232],{},"The same thread shows the message arrived months before the date it names. A GitHub issue in a project named pot-g-flutter, dated February 2026, describes the same warning on a build made with the iOS 18.5 SDK. Your email will name the SDK your build used. That number tells you how far behind your build machine is.",[31,1234,1236],{"id":1235},"what-apple-requires-today","What Apple requires today",[56,1238,1239,1250],{},[59,1240,1241],{},[62,1242,1243,1245,1248],{},[65,1244,635],{},[65,1246,1247],{},"What Apple says",[65,1249,641],{},[75,1251,1252,1267,1280],{},[62,1253,1254,1259,1262],{},[80,1255,1256],{},[17,1257,1258],{},"Since April 28, 2026",[80,1260,1261],{},"\"Apps uploaded to App Store Connect must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26, or watchOS 26.\"",[80,1263,1264],{},[39,1265,666],{"href":664,"rel":1266},[43],[62,1268,1269,1272,1275],{},[80,1270,1271],{},"Since September 9, 2026",[80,1273,1274],{},"iOS and iPadOS apps uploaded to App Store Connect must target iOS 13 or later. This is a minimum deployment target, not an SDK rule",[80,1276,1277],{},[39,1278,666],{"href":664,"rel":1279},[43],[62,1281,1282,1285,1288],{},[80,1283,1284],{},"September 14, 2026",[80,1286,1287],{},"Xcode 27 released. Apple's releases page lists Xcode 27.1 as the newest release, dated October 15, 2026",[80,1289,1290],{},[39,1291,1294],{"href":1292,"rel":1293},"https:\u002F\u002Fdeveloper.apple.com\u002Fnews\u002Freleases\u002F",[43],"Apple, releases",[14,1296,1297,1298,1301],{},"On October 18, 2026, the upcoming requirements page had no entry for Xcode 27 or the iOS 27 SDK. So Apple hasn't published an Xcode 27 upload requirement that I can find. Xcode 26 or later is the stated minimum. My advice: build with Xcode 26.6, or Xcode 27 once the app has migrated to UIScene. Read the ",[39,1299,1300],{"href":1038},"UIScene guide"," before you move a Flutter app to Xcode 27.",[14,1303,1304],{},"Apple doesn't say whether this is a warning or a rejection. Its page says apps \"must be built\" this way, so plan on fixing it, not waiting to see.",[31,1306,1308],{"id":1307},"step-1-install-the-required-xcode","Step 1: Install the required Xcode",[398,1310,1311,1314],{},[144,1312,1313],{},"Install Xcode 26 or later from the Mac App Store or Apple's developer downloads. Apple's releases page lists Xcode 26.6 (June 25, 2026) as the newest Xcode 26 release.",[144,1315,1316],{},"Open it once and let it install its components.",[31,1318,1320],{"id":1319},"step-2-make-the-command-line-use-it","Step 2: Make the command line use it",[14,1322,1323],{},"A Flutter build runs through the command-line tools, so the selected Xcode matters, not the one you last opened. Flutter's iOS setup page gives this command for pointing the tools at an Xcode install:",[195,1325,1329],{"className":1326,"code":1327,"language":1328,"meta":200,"style":200},"language-bash shiki shiki-themes github-light github-dark","sudo sh -c 'xcode-select -s \u002FApplications\u002FXcode.app\u002FContents\u002FDeveloper && xcodebuild -runFirstLaunch'\n","bash",[190,1330,1331],{"__ignoreMap":200},[204,1332,1333,1337,1341,1345],{"class":206,"line":207},[204,1334,1336],{"class":1335},"sScJk","sudo",[204,1338,1340],{"class":1339},"sZZnC"," sh",[204,1342,1344],{"class":1343},"sj4cs"," -c",[204,1346,1347],{"class":1339}," 'xcode-select -s \u002FApplications\u002FXcode.app\u002FContents\u002FDeveloper && xcodebuild -runFirstLaunch'\n",[14,1349,1350,1351,1354,1355,1358,1359,1362,1363,1366],{},"Replace ",[190,1352,1353],{},"\u002FApplications\u002FXcode.app"," if you installed it somewhere else. Apple's TN2339 documents ",[190,1356,1357],{},"xcode-select --print-path"," to see the current selection, and ",[190,1360,1361],{},"xcode-select -switch"," to change it. Then run ",[190,1364,1365],{},"xcodebuild -version"," to see the version in use. My advice: do this on every Mac that builds the app, including old laptops and CI machines you forgot about.",[31,1368,1370],{"id":1369},"step-3-dont-trust-flutter-doctor-for-this","Step 3: Don't trust flutter doctor for this",[14,1372,1373,1376,1377,1380,1381,1384,1385,1387],{},[190,1374,1375],{},"flutter doctor"," checks Xcode, but not against Apple's upload rule. In the Flutter source on the master branch, ",[190,1378,1379],{},"xcodeRequiredVersion"," is 15 and ",[190,1382,1383],{},"xcodeRecommendedVersion"," is 16. The doctor warns below the recommended version. Xcode 16 passes that check but would still trigger ITMS-90725. So a clean doctor result doesn't mean Apple will accept the build. Check ",[190,1386,1365],{}," yourself.",[14,1389,1390,1391,136],{},"If your Flutter is old and the build breaks under Xcode 26, upgrade Flutter and see ",[39,1392,439],{"href":438},[31,1394,1396],{"id":1395},"step-4-rebuild-pods-and-the-archive","Step 4: Rebuild pods and the archive",[14,1398,1399,1400,1402],{},"After switching Xcode, old build output can linger. Work from least to most destructive, from the ",[190,1401,411],{}," folder:",[398,1404,1405,1410,1428],{},[144,1406,1407,136],{},[190,1408,1409],{},"pod install --repo-update",[144,1411,1412,1413,616,1415,1417,1418,661,1421,1424,1425,1427],{},"If pods still build against the old toolchain, delete ",[190,1414,1064],{},[190,1416,1067],{},", run ",[190,1419,1420],{},"flutter clean",[190,1422,1423],{},"flutter pub get",", then ",[190,1426,1409],{}," again.",[144,1429,1430,1431,1434,1435,1437],{},"Build the archive with ",[190,1432,1433],{},"flutter build ipa",", or archive in Xcode from ",[190,1436,856],{},", and upload again.",[14,1439,1440,1441,1444],{},"The ",[39,1442,1443],{"href":438},"build-failed guide"," covers the deployment target, CocoaPods and plugin mismatches in more detail. Keep the two targets apart: the SDK is what you build with, and the deployment target is the oldest iOS you support. Apple's September 9, 2026 entry only requires iOS 13 or later. Your plugins may ask for more.",[31,1446,1448],{"id":1447},"fix-it-on-ci","Fix it on CI",[14,1450,1451,1452,1455],{},"If the upload comes from a build server, the server's Xcode decides the SDK. For GitHub Actions, the macOS 26 arm64 image readme I read lists Xcode 26.6 as the default, along with 26.5, 26.4.1, 26.3, 26.2, 26.1.1 and 26.0.1. It also lists CocoaPods 1.17.0. GitHub announced a separate ",[190,1453,1454],{},"xcode-27"," image label in July 2026, marked preview, and its readme lists Xcode 27.0 as that image's default.",[14,1457,1458],{},"If your workflow pins an older image or selects an old Xcode, change it. Older images list different Xcode versions, so check the readme for the image your workflow uses.",[14,1460,1461],{},"On other CI services, such as Codemagic, check the provider's own page for the Xcode versions it offers.",[31,1463,1465],{"id":1464},"other-services-that-build-for-you","Other services that build for you",[14,1467,1468],{},"The warning can also reach people who don't run the build themselves. If a hosted or no-code builder makes your iOS build, the Xcode it uses is the vendor's choice. Check its documentation for the Xcode version, and if it is older than 26, export the project and build it locally with Xcode 26 or later, or wait for the vendor to upgrade.",[31,1470,1472],{"id":1471},"related-errors","Related errors",[14,1474,1475,1476,136],{},"If the next email is about privacy manifests, see ",[39,1477,1478],{"href":433},"ITMS-91053 and ITMS-91061",[14,1480,1098,1481,136],{},[39,1482,1102],{"href":1101},[31,1484,450],{"id":449},[14,1486,1487,1488,458,1490,136],{},"If App Store Connect keeps rejecting your build with ITMS-90725, or the app breaks after the Xcode upgrade, the ",[39,1489,457],{"href":456},[39,1491,462],{"href":461},[464,1493,1494],{},"html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":200,"searchDepth":213,"depth":213,"links":1496},[1497,1498,1499,1500,1501,1502,1503,1504,1505,1506],{"id":1219,"depth":213,"text":1220},{"id":1235,"depth":213,"text":1236},{"id":1307,"depth":213,"text":1308},{"id":1319,"depth":213,"text":1320},{"id":1369,"depth":213,"text":1370},{"id":1395,"depth":213,"text":1396},{"id":1447,"depth":213,"text":1448},{"id":1464,"depth":213,"text":1465},{"id":1471,"depth":213,"text":1472},{"id":449,"depth":213,"text":450},"2026-10-18T20:00:00.000Z","ITMS-90725 SDK version issue means App Store Connect saw an app built with an older SDK than it now accepts. What Apple's upcoming requirements page says about Xcode 26 today, and how to fix it in a Flutter app, from Apple's, Flutter's and GitHub's sources checked October 18, 2026.",[1510,1513,1516,1519,1522],{"question":1511,"answer":1512},"What does ITMS-90725 SDK version issue mean?","It means App Store Connect found that the app was built with an older SDK than Apple now requires. A forum post from January 2026 quotes the message as: \"This app was built with the iOS 18.2 SDK. Starting April 2026, all iOS and iPadOS apps must be built with the iOS 26 SDK or later, included in Xcode 26 or later.\" The fix is to rebuild with Xcode 26 or later.",{"question":1514,"answer":1515},"What Xcode version does Apple require right now?","Apple's upcoming requirements page says that since April 28, 2026, apps uploaded to App Store Connect must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26 or watchOS 26. On October 18, 2026, that page had no entry for Xcode 27.",{"question":1517,"answer":1518},"Do I need Xcode 27 to upload?","Not according to Apple's upcoming requirements page as of October 18, 2026. It names Xcode 26 or later and gives no Xcode 27 date. Xcode 27 does change Flutter apps in one way: see the UIScene guide before you switch.",{"question":1520,"answer":1521},"Does this raise my minimum iOS version?","No. The SDK you build with is separate from the iOS version you support. Apple's page has a separate entry saying that since September 9, 2026, iOS and iPadOS apps uploaded to App Store Connect must target iOS 13 or later. Your plugins may require a higher target than that.",{"question":1523,"answer":1524},"Does the version already in the App Store stop working?","I found no Apple statement on that. A reply in a 2024 Apple forum thread, from a user who isn't identified as Apple staff, said the version already in the store is unaffected. Treat that as a forum opinion. The rule applies to new uploads.",{"readingTimeStats":1526},{"text":1527,"minutes":1528,"time":1529,"words":1530},"6 min read",5.38,322800,1076,"\u002Fblog\u002Fitms-90725-sdk-version-issue-xcode-26-flutter-2026","itms-90725","6 min",[508,1151,510],{"title":1199,"description":1508},[1537,1539,1541,1544,1547,1550,1553,1556,1559,1562,1565,1568],{"title":1538,"url":664},"Apple Developer, Upcoming requirements (SDK minimum requirements since April 28, 2026)",{"title":1540,"url":1292},"Apple Developer, Releases (Xcode 27 on September 14, 2026; Xcode 26.6)",{"title":1542,"url":1543},"Apple Developer Forums, 90725: SDK version issue - iOS SDK 26 support (January 2026)","https:\u002F\u002Fdeveloper.apple.com\u002Fforums\u002Fthread\u002F813123",{"title":1545,"url":1546},"Apple Developer Forums, ITMS-90725: SDK version issue (April 2024)","https:\u002F\u002Fdeveloper.apple.com\u002Fforums\u002Fthread\u002F750346",{"title":1548,"url":1549},"Apple Developer, Technical Note TN2339 (xcode-select)","https:\u002F\u002Fdeveloper.apple.com\u002Flibrary\u002Farchive\u002Ftechnotes\u002Ftn2339\u002F_index.html",{"title":1551,"url":1552},"Flutter docs, Set up iOS development (page last updated 2026-09-14)","https:\u002F\u002Fdocs.flutter.dev\u002Fplatform-integration\u002Fios\u002Fsetup",{"title":1554,"url":1555},"Flutter on GitHub, xcode_validator.dart (Xcode messages for flutter doctor)","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_tools\u002Flib\u002Fsrc\u002Fmacos\u002Fxcode_validator.dart",{"title":1557,"url":1558},"Flutter on GitHub, xcode.dart (required and recommended Xcode versions)","https:\u002F\u002Fgithub.com\u002Fflutter\u002Fflutter\u002Fblob\u002Fmaster\u002Fpackages\u002Fflutter_tools\u002Flib\u002Fsrc\u002Fmacos\u002Fxcode.dart",{"title":1560,"url":1561},"gsainfoteam\u002Fpot-g-flutter on GitHub, issue 437 (a Flutter team hitting ITMS-90725, February 2026)","https:\u002F\u002Fgithub.com\u002Fgsainfoteam\u002Fpot-g-flutter\u002Fissues\u002F437",{"title":1563,"url":1564},"GitHub Actions runner images, macOS 26 (arm64) readme","https:\u002F\u002Fgithub.com\u002Factions\u002Frunner-images\u002Fblob\u002Fmain\u002Fimages\u002Fmacos\u002Fmacos-26-arm64-Readme.md",{"title":1566,"url":1567},"GitHub Actions runner images, macOS 27 \u002F Xcode 27 (arm64) readme","https:\u002F\u002Fgithub.com\u002Factions\u002Frunner-images\u002Fblob\u002Fmain\u002Fimages\u002Fmacos\u002Fxcode-27-arm64-Readme.md",{"title":1569,"url":1570},"GitHub Actions runner images, issue 14404 (Xcode 27 preview and the xcode-27 label)","https:\u002F\u002Fgithub.com\u002Factions\u002Frunner-images\u002Fissues\u002F14404","blog\u002Fitms-90725-sdk-version-issue-xcode-26-flutter-2026","itms-90725, sdk version issue, itms-90725 sdk version issue, app store connect xcode 26 required, built with ios 18 sdk, ios 26 sdk required, flutter xcode 26, xcode-select flutter, flutter doctor xcode, github actions xcode 26",[1574,1575,1576,1577,1578],"ITMS-90725 means the build you uploaded was made with an older SDK than App Store Connect accepts. Apple's upcoming requirements page says that since April 28, 2026, uploads must be built with Xcode 26 or later using an SDK for iOS 26, iPadOS 26, tvOS 26, visionOS 26 or watchOS 26.","As of October 18, 2026, that page names no Xcode 27 or iOS 27 SDK requirement. Xcode 27 was released on September 14, 2026, but Xcode 26 or later is still the stated minimum.","In a Flutter app the fix is to build the upload with Xcode 26 or later. Check which Xcode the command line uses with xcode-select -p, because Flutter builds with the selected one.","flutter doctor will not warn you. In the Flutter source I read, the required Xcode version is 15 and the recommended one is 16, far below Apple's minimum.","On CI, the build machine decides the SDK. GitHub's macOS 26 runner image lists Xcode 26.0.1 to 26.6, with 26.6 as the default, and a separate xcode-27 image exists.","https:\u002F\u002Fapp369.com\u002Fblog\u002Fitms-90725-sdk-version-issue-xcode-26-flutter-2026\u002F","blb6tX8dMgApxA0OL3iPgFmPbCHy8TWRSblSQYxx-Gs",{"id":1582,"title":1583,"author":1584,"body":1586,"category":476,"createdAt":2078,"description":2079,"disclosure":479,"extension":480,"faq":479,"howTo":479,"lastVerified":479,"location":497,"meta":2080,"navigation":283,"ogImage":479,"path":2085,"primaryKeyword":479,"readingTime":506,"related":479,"seo":2086,"sources":479,"stem":2087,"tags":2088,"takeaways":479,"updatedAt":2078,"url":2089,"__hash__":2090},"blog\u002Fblog\u002Fflutter-ios-build-failed-after-upgrade-2026.md","Flutter iOS Build Failed After an Upgrade? Fix CocoaPods and Xcode Errors (2026)",{"name":7,"social":1585},{"twitter":9},{"type":11,"value":1587,"toc":2061},[1588,1594,1605,1609,1612,1645,1648,1704,1708,1736,1740,1749,1773,1777,1783,1825,1897,1913,1917,1929,1962,1966,1975,1978,1982,1985,1989,1995,1999,2004,2018,2022,2034,2038,2041,2045,2051,2055,2058],[14,1589,1590,1593],{},[17,1591,1592],{},"When a Flutter iOS build breaks right after an upgrade, the cause is almost always one of four things: a stale CocoaPods lock, a deployment target that is too low, FlutterFire plugins on mismatched versions, or an Xcode that no longer matches the SDKs you depend on."," The error Xcode shows first is rarely the real one. This guide is the order to work in, from reading the actual failure to the fixes that cover most upgrade breakages.",[14,1595,1596,1597,1600,1601,136],{},"It is the same approach Simon uses on Workspace369, his production Flutter and Firebase SaaS, and it is the iOS build part of App369's ",[39,1598,1599],{"href":456},"fixed-price Flutter & Firebase Fix Ticket",". For the wider method, see ",[39,1602,1604],{"href":1603},"\u002Fblog\u002Fhow-to-debug-a-flutter-firebase-bug-2026\u002F","how to debug a Flutter and Firebase bug",[31,1606,1608],{"id":1607},"step-1-read-the-real-error","Step 1: Read the real error",[14,1610,1611],{},"Don't start by deleting folders. First get the full output.",[398,1613,1614,1621,1635],{},[144,1615,1616,1617,1620],{},"Run ",[190,1618,1619],{},"flutter doctor -v"," and fix anything it flags under Xcode or CocoaPods.",[144,1622,1616,1623,1626,1627,1630,1631,1634],{},[190,1624,1625],{},"flutter build ios -v"," (or ",[190,1628,1629],{},"flutter run -v",") and read from the first line that says ",[190,1632,1633],{},"error:",", not the last line. The final \"Xcode build failed\" message is a summary.",[144,1636,1637,1638,1640,1641,1644],{},"If the failure happens in Xcode itself, open ",[190,1639,856],{}," (never ",[190,1642,1643],{},"Runner.xcodeproj",") and use the Report navigator to open the build log. Filter for errors and read the first one.",[14,1646,1647],{},"Where the error appears tells you which step failed:",[56,1649,1650,1660],{},[59,1651,1652],{},[62,1653,1654,1657],{},[65,1655,1656],{},"Where it fails",[65,1658,1659],{},"Likely area",[75,1661,1662,1672,1680,1688,1696],{},[62,1663,1664,1669],{},[80,1665,1666,1668],{},[190,1667,415],{}," output, before compiling",[80,1670,1671],{},"CocoaPods resolution, Podfile, specs",[62,1673,1674,1677],{},[80,1675,1676],{},"\"Compiling for iOS X, but module requires iOS Y\"",[80,1678,1679],{},"Deployment target too low",[62,1681,1682,1685],{},[80,1683,1684],{},"Swift or Objective-C compile errors inside a plugin",[80,1686,1687],{},"Plugin and Xcode or SDK version mismatch",[62,1689,1690,1693],{},[80,1691,1692],{},"Linking or \"framework not found\"",[80,1694,1695],{},"Stale Pods or build cache",[62,1697,1698,1701],{},[80,1699,1700],{},"Code signing messages",[80,1702,1703],{},"Signing and provisioning, covered at the end",[31,1705,1707],{"id":1706},"step-2-check-your-xcode-and-cocoapods-versions","Step 2: Check your Xcode and CocoaPods versions",[14,1709,1710,1711,1716,1717,616,1720,1722,1723,1727,1728,1731,1732,1735],{},"Upgrades often fail because the Firebase SDK moved its minimum requirements. The ",[39,1712,1715],{"href":1713,"rel":1714},"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Fios\u002Finstallation-methods",[43],"Firebase Apple platforms installation docs"," list the current Xcode requirement and say the CocoaPods distribution needs CocoaPods 1.12.0 or higher. Check yours with ",[190,1718,1719],{},"pod --version",[190,1721,1365],{},", and update if either is below what your plugins need. Flutter's own ",[39,1724,1726],{"href":1552,"rel":1725},[43],"iOS setup page"," covers pointing the command-line tools at the right Xcode (",[190,1729,1730],{},"xcode-select",") and accepting licenses (",[190,1733,1734],{},"sudo xcodebuild -license","); a second Xcode installed on the machine is a common reason a build uses the wrong toolchain.",[31,1737,1739],{"id":1738},"step-3-fix-the-ios-deployment-target","Step 3: Fix the iOS deployment target",[14,1741,1742,1743,1748],{},"A plugin upgrade can raise the minimum iOS version. The ",[39,1744,1747],{"href":1745,"rel":1746},"https:\u002F\u002Ffirebase.google.com\u002Fdocs\u002Fflutter\u002Fsetup",[43],"Firebase Flutter setup page"," lists iOS 15 or later as the Apple requirement for the FlutterFire plugins. Check three places and make them agree:",[141,1750,1751,1761,1764],{},[144,1752,1753,1756,1757,1760],{},[190,1754,1755],{},"ios\u002FPodfile",": the line ",[190,1758,1759],{},"platform :ios, '15.0'"," (use the minimum your plugins ask for; if the line is commented out, uncomment it).",[144,1762,1763],{},"Xcode: Runner target, General tab, \"Minimum Deployments\".",[144,1765,1440,1766,1768,1769,1772],{},[190,1767,247],{}," block in the Podfile, if you have one that sets ",[190,1770,1771],{},"IPHONEOS_DEPLOYMENT_TARGET"," on every pod. A value there that is lower than a pod's own minimum produces the \"module requires iOS Y\" error.",[31,1774,1776],{"id":1775},"step-4-refresh-cocoapods-then-clean-it-out","Step 4: Refresh CocoaPods, then clean it out",[14,1778,1779,1780,1782],{},"Work from least to most destructive. Run these inside the ",[190,1781,411],{}," folder.",[398,1784,1785,1792,1819],{},[144,1786,1787,1791],{},[17,1788,1789],{},[190,1790,1409],{}," refreshes the local spec repository and then installs. It is the right first move after upgrading a plugin, because a stale local spec list can't find the new version.",[144,1793,1794,1799,1800,1802,1803,1808,1809,1811,1812,1814,1815,1818],{},[17,1795,1796],{},[190,1797,1798],{},"pod update PODNAME"," if one pod needs to move to a newer version than ",[190,1801,1067],{}," allows. As the ",[39,1804,1807],{"href":1805,"rel":1806},"https:\u002F\u002Fguides.cocoapods.org\u002Fusing\u002Fpod-install-vs-update.html",[43],"CocoaPods guide"," explains, ",[190,1810,415],{}," respects the versions in ",[190,1813,1067],{},", while ",[190,1816,1817],{},"pod update"," ignores the lock and fetches the newest version your constraints allow.",[144,1820,1821,1824],{},[17,1822,1823],{},"A clean reinstall."," If it is still broken, remove the generated pieces and rebuild them:",[195,1826,1828],{"className":1326,"code":1827,"language":1328,"meta":200,"style":200},"cd ios\nrm -rf Pods Podfile.lock\ncd ..\nflutter clean\nflutter pub get\ncd ios && pod install --repo-update\n",[190,1829,1830,1838,1852,1859,1867,1877],{"__ignoreMap":200},[204,1831,1832,1835],{"class":206,"line":207},[204,1833,1834],{"class":1343},"cd",[204,1836,1837],{"class":1339}," ios\n",[204,1839,1840,1843,1846,1849],{"class":206,"line":213},[204,1841,1842],{"class":1335},"rm",[204,1844,1845],{"class":1343}," -rf",[204,1847,1848],{"class":1339}," Pods",[204,1850,1851],{"class":1339}," Podfile.lock\n",[204,1853,1854,1856],{"class":206,"line":219},[204,1855,1834],{"class":1343},[204,1857,1858],{"class":1339}," ..\n",[204,1860,1861,1864],{"class":206,"line":225},[204,1862,1863],{"class":1335},"flutter",[204,1865,1866],{"class":1339}," clean\n",[204,1868,1869,1871,1874],{"class":206,"line":287},[204,1870,1863],{"class":1335},[204,1872,1873],{"class":1339}," pub",[204,1875,1876],{"class":1339}," get\n",[204,1878,1879,1881,1884,1888,1891,1894],{"class":206,"line":293},[204,1880,1834],{"class":1343},[204,1882,1883],{"class":1339}," ios",[204,1885,1887],{"class":1886},"sVt8B"," && ",[204,1889,1890],{"class":1335},"pod",[204,1892,1893],{"class":1339}," install",[204,1895,1896],{"class":1343}," --repo-update\n",[14,1898,1899,1900,1902,1903,1905,1906,1908,1909,1912],{},"Deleting ",[190,1901,1064],{}," is safe because it is generated. Deleting ",[190,1904,1067],{}," is also safe for a one-off repair, but it lets every pod re-resolve, so you may get newer versions than before. The CocoaPods guide recommends committing ",[190,1907,1067],{},", so review the diff after the reinstall and commit the new one once the build passes. If you only suspect Xcode's cache, you can also delete ",[190,1910,1911],{},"~\u002FLibrary\u002FDeveloper\u002FXcode\u002FDerivedData","; it only holds build products, and Xcode recreates it.",[31,1914,1916],{"id":1915},"step-5-upgrade-the-flutterfire-plugins-together","Step 5: Upgrade the FlutterFire plugins together",[14,1918,1919,661,1922,661,1925,1928],{},[190,1920,1921],{},"firebase_core",[190,1923,1924],{},"cloud_firestore",[190,1926,1927],{},"firebase_auth"," and the other FlutterFire plugins are versioned together and each one depends on a specific Firebase SDK release. Upgrading one and leaving the others behind is a common source of build errors, including duplicate or conflicting native pods.",[141,1930,1931,1941,1956],{},[144,1932,1616,1933,1936,1937,1940],{},[190,1934,1935],{},"flutter pub outdated"," to see the gap, then upgrade the whole FlutterFire family in one ",[190,1938,1939],{},"pubspec.yaml"," change.",[144,1942,1943,1944,1947,1948,1952,1953,136],{},"Re-run ",[190,1945,1946],{},"flutterfire configure"," if you added a Firebase service or platform; the ",[39,1949,1951],{"href":1745,"rel":1950},[43],"Firebase docs"," say re-running it keeps your configuration current. Install the tool with ",[190,1954,1955],{},"dart pub global activate flutterfire_cli",[144,1957,1958,1959,1961],{},"If you pin a Firebase SDK version in the Podfile, remove the pin and let the plugins choose it. A manual pin that disagrees with ",[190,1960,1921],{}," is a classic conflict.",[31,1963,1965],{"id":1964},"step-6-know-that-cocoapods-is-being-phased-out","Step 6: Know that CocoaPods is being phased out",[14,1967,1968,1969,1974],{},"This matters for upgrades in late 2026. Firebase's docs warn that it will stop publishing new versions to CocoaPods in October 2026 and recommend Swift Package Manager. Flutter's ",[39,1970,1973],{"href":1971,"rel":1972},"https:\u002F\u002Fdocs.flutter.dev\u002Fpackages-and-plugins\u002Fswift-package-manager\u002Ffor-app-developers",[43],"Swift Package Manager page"," says SwiftPM support is on by default as of Flutter 3.44, that Flutter falls back to CocoaPods for plugins that don't support it yet, and that the CocoaPods registry becomes read-only on December 2, 2026.",[14,1976,1977],{},"In practice: after a Flutter upgrade, the first build may modify your Xcode project to add SwiftPM integration. Commit that change rather than reverting it, and if a build error mentions a Swift package, read it the same way as a pod error: find the first real failure.",[31,1979,1981],{"id":1980},"step-7-signing-errors-briefly","Step 7: Signing errors, briefly",[14,1983,1984],{},"If it compiles but fails to archive, it is usually signing. In Xcode, open the Runner target, Signing & Capabilities, and check that a team is selected, the bundle identifier matches your App Store Connect app, and \"Automatically manage signing\" is on unless you manage profiles yourself. Flutter's iOS setup page notes a signed developer certificate is needed even for device testing.",[31,1986,1988],{"id":1987},"when-to-get-help","When to get help",[14,1990,1991,1992,1994],{},"If an iOS build has eaten more than a day and the steps above haven't moved it, App369's ",[39,1993,1599],{"href":456}," covers build failures after a Flutter or FlutterFire upgrade. The $450 Diagnosis delivers the root cause with evidence and a fixed repair quote within 3 business days, and the $450 is credited toward the fix. The $1,200 Fix delivers the scoped defect as a pull request with a regression test within 5 business days. App Store approval isn't something anyone can guarantee; the ticket covers the code defect itself.",[31,1996,1998],{"id":1997},"frequently-asked-questions","Frequently Asked Questions",[2000,2001,2003],"h3",{"id":2002},"why-did-my-flutter-ios-build-fail-after-upgrading-flutter","Why did my Flutter iOS build fail after upgrading Flutter?",[14,2005,2006,2007,2009,2010,2012,2013,2015,2016,136],{},"Most often the Podfile or Xcode project still has an old iOS deployment target, ",[190,2008,1067],{}," pins old pod versions, or plugin versions no longer match each other. Run ",[190,2011,1625],{},", find the first ",[190,2014,1633],{}," line, then work through the deployment target and ",[190,2017,1409],{},[2000,2019,2021],{"id":2020},"is-it-safe-to-delete-podfilelock-and-the-pods-folder","Is it safe to delete Podfile.lock and the Pods folder?",[14,2023,2024,2025,2027,2028,2030,2031,2033],{},"Yes, for a repair. ",[190,2026,1064],{}," is generated and ",[190,2029,1067],{}," is rebuilt by ",[190,2032,415],{},". The catch is that pods may resolve to newer versions, so check the new lock file and commit it once the build works.",[2000,2035,2037],{"id":2036},"what-does-pod-install-repo-update-do","What does \"pod install --repo-update\" do?",[14,2039,2040],{},"It refreshes CocoaPods' local list of available pod versions before installing. Use it when a newly upgraded plugin needs a pod version your machine's spec list doesn't know about yet.",[2000,2042,2044],{"id":2043},"should-i-upgrade-only-one-flutterfire-plugin","Should I upgrade only one FlutterFire plugin?",[14,2046,2047,2048,2050],{},"Avoid it. FlutterFire plugins depend on matching Firebase SDK releases, so upgrade ",[190,2049,1921],{}," and the other FlutterFire packages together and rebuild.",[2000,2052,2054],{"id":2053},"do-i-need-to-switch-from-cocoapods-to-swift-package-manager","Do I need to switch from CocoaPods to Swift Package Manager?",[14,2056,2057],{},"Flutter handles it for you in recent versions and falls back to CocoaPods for plugins that don't support SwiftPM yet. Given Firebase's announced CocoaPods change, keep your plugins current rather than pinning old versions.",[464,2059,2060],{},"html pre.shiki code .sj4cs, html code.shiki .sj4cs{--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sZZnC, html code.shiki .sZZnC{--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sScJk, html code.shiki .sScJk{--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sVt8B, html code.shiki .sVt8B{--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":200,"searchDepth":213,"depth":213,"links":2062},[2063,2064,2065,2066,2067,2068,2069,2070,2071],{"id":1607,"depth":213,"text":1608},{"id":1706,"depth":213,"text":1707},{"id":1738,"depth":213,"text":1739},{"id":1775,"depth":213,"text":1776},{"id":1915,"depth":213,"text":1916},{"id":1964,"depth":213,"text":1965},{"id":1980,"depth":213,"text":1981},{"id":1987,"depth":213,"text":1988},{"id":1997,"depth":213,"text":1998,"children":2072},[2073,2074,2075,2076,2077],{"id":2002,"depth":219,"text":2003},{"id":2020,"depth":219,"text":2021},{"id":2036,"depth":219,"text":2037},{"id":2043,"depth":219,"text":2044},{"id":2053,"depth":219,"text":2054},"2026-10-12T18:00:00.000Z","Flutter iOS build failing after upgrading Flutter, FlutterFire or Xcode? How to read the real error, then fix CocoaPods, deployment target and plugin version mismatches.",{"readingTimeStats":2081},{"text":1527,"minutes":2082,"time":2083,"words":2084},5.995,359700,1199,"\u002Fblog\u002Fflutter-ios-build-failed-after-upgrade-2026",{"title":1583,"description":2079},"blog\u002Fflutter-ios-build-failed-after-upgrade-2026","flutter ios build failed, cocoapods error, pod install failed, flutterfire upgrade, xcode build error, flutter build ios, firebase ios","https:\u002F\u002Fapp369.com\u002Fblog\u002Fflutter-ios-build-failed-after-upgrade-2026\u002F","j_nFje3qmyZUdc4vyGtG-sRzwIjhUzh5-9fXsxoyaZA",[2092,2094,2097,2100],{"keyword":5,"url":543,"title":5,"relevance":2093},70,{"keyword":2095,"url":2096,"title":2095,"relevance":305},"Flutter \"Applying Gradle Plugin Imperatively\" Error: The Fix","https:\u002F\u002Fapp369.com\u002Fblog\u002Fflutter-gradle-plugin-applied-imperatively-fix-2026\u002F",{"keyword":2098,"url":2099,"title":2098,"relevance":305},"Flutter 3.29: New Features for Business","https:\u002F\u002Fapp369.com\u002Fblog\u002Fflutter-3-29-app369-business-wins\u002F",{"keyword":1199,"url":1579,"title":1199,"relevance":293},1792364506142]