From 4471af11d57906f405f395442a4ea51c39322fbc Mon Sep 17 00:00:00 2001 From: stfsession <185467273+stfsession@users.noreply.github.com> Date: Mon, 13 Jan 2025 00:08:40 +0000 Subject: [PATCH 1/2] [Automated] Update translations from Crowdin --- Session/Meta/Translations/Localizable.xcstrings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Session/Meta/Translations/Localizable.xcstrings b/Session/Meta/Translations/Localizable.xcstrings index c11e3b868b..331eccbf42 100644 --- a/Session/Meta/Translations/Localizable.xcstrings +++ b/Session/Meta/Translations/Localizable.xcstrings @@ -304068,7 +304068,7 @@ "km" : { "stringUnit" : { "state" : "translated", - "value" : "ការបង្កើតគណនីគឺមានភ្លាមៗ, \noofសាន្ត និងមិនបង្ហាញអត្តសញ្ញាណ {emoji}" + "value" : "ការបង្កើតគណនីគឺភ្លាមៗ ឥតគិតថ្លៃ និងអនាមិក {emoji}" } }, "kn" : { From 37ea2a89bc8b0162e3ce90c05660c852c18a1332 Mon Sep 17 00:00:00 2001 From: Morgan Pretty Date: Tue, 14 Jan 2025 12:24:19 +1100 Subject: [PATCH 2/2] Fixed a number of crashes currently affecting production MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit • Fixed a crash due to our ThreadSafe code using a struct instead of a class (rendering it non thread safe) • Fixed a crash which could occur on the home screen if the data loaded before the UI finished loading • (Hopefully) Fixed a crash which could occur when the OS optimised async execution to run immediately within an existing database transaction (potentially resulting in re-entrant database access) • Fixed an issue where the database read/write publishers weren't checking for a valid database state before actual query execution (only during the creation of the stream) --- Session.xcodeproj/project.pbxproj | 8 +-- Session/Conversations/ConversationVC.swift | 2 +- .../Conversations/ConversationViewModel.swift | 2 +- Session/Home/HomeVC.swift | 4 +- Session/Meta/AppDelegate.swift | 11 ++-- Session/Meta/SessionApp.swift | 5 +- Session/Meta/Translations/InfoPlist.xcstrings | 2 +- .../Jobs/Types/GarbageCollectionJob.swift | 7 ++- .../Jobs/Types/UpdateProfilePictureJob.swift | 8 +-- .../Sending & Receiving/MessageSender.swift | 7 +-- .../LibSession/LibSession+Networking.swift | 7 ++- SessionUtilitiesKit/Database/Storage.swift | 51 ++++++++++++------- .../Types/PagedDatabaseObserver.swift | 25 +++++---- SessionUtilitiesKit/JobRunner/JobRunner.swift | 14 +++-- .../Utilities/ThreadSafe.swift | 8 +-- 15 files changed, 101 insertions(+), 60 deletions(-) diff --git a/Session.xcodeproj/project.pbxproj b/Session.xcodeproj/project.pbxproj index 62dc187f77..ca7b114b1b 100644 --- a/Session.xcodeproj/project.pbxproj +++ b/Session.xcodeproj/project.pbxproj @@ -7683,7 +7683,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Developer"; - CURRENT_PROJECT_VERSION = 519; + CURRENT_PROJECT_VERSION = 526; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; ENABLE_TESTABILITY = YES; @@ -7720,7 +7720,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ""; IPHONEOS_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 2.8.5; + MARKETING_VERSION = 2.8.6; ONLY_ACTIVE_ARCH = YES; OTHER_CFLAGS = ( "-fobjc-arc-exceptions", @@ -7762,7 +7762,7 @@ CLANG_WARN__ARC_BRIDGE_CAST_NONARC = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CODE_SIGN_IDENTITY = "iPhone Distribution"; - CURRENT_PROJECT_VERSION = 519; + CURRENT_PROJECT_VERSION = 526; ENABLE_BITCODE = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_NO_COMMON_BLOCKS = YES; @@ -7794,7 +7794,7 @@ GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = ""; IPHONEOS_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 2.8.5; + MARKETING_VERSION = 2.8.6; ONLY_ACTIVE_ARCH = NO; OTHER_CFLAGS = ( "-DNS_BLOCK_ASSERTIONS=1", diff --git a/Session/Conversations/ConversationVC.swift b/Session/Conversations/ConversationVC.swift index 2304a1e928..eaa2c9e6c9 100644 --- a/Session/Conversations/ConversationVC.swift +++ b/Session/Conversations/ConversationVC.swift @@ -656,7 +656,7 @@ final class ConversationVC: BaseVC, LibSessionRespondingViewController, Conversa // PagedDatabaseObserver won't have them so we need to force a re-fetch of the current // data to ensure everything is up to date if didReturnFromBackground { - DispatchQueue.global(qos: .background).async { + DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 0.01) { self?.viewModel.pagedDataObserver?.reload() } } diff --git a/Session/Conversations/ConversationViewModel.swift b/Session/Conversations/ConversationViewModel.swift index 5a18e72cdb..be83298a52 100644 --- a/Session/Conversations/ConversationViewModel.swift +++ b/Session/Conversations/ConversationViewModel.swift @@ -198,7 +198,7 @@ public class ConversationViewModel: OWSAudioPlayerDelegate, NavigatableStateHold ) // Run the initial query on a background thread so we don't block the push transition - DispatchQueue.global(qos: .userInitiated).async { [weak self] in + DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 0.01) { [weak self] in // If we don't have a `initialFocusedInfo` then default to `.pageBefore` (it'll query // from a `0` offset) switch (focusedInteractionInfo ?? initialData?.initialUnreadInteractionInfo) { diff --git a/Session/Home/HomeVC.swift b/Session/Home/HomeVC.swift index bfc5c92a33..497abcb556 100644 --- a/Session/Home/HomeVC.swift +++ b/Session/Home/HomeVC.swift @@ -46,7 +46,7 @@ final class HomeVC: BaseVC, LibSessionRespondingViewController, UITableViewDataS // MARK: - UI - private var tableViewTopConstraint: NSLayoutConstraint! + private var tableViewTopConstraint: NSLayoutConstraint? private lazy var seedReminderView: SeedReminderView = { let result = SeedReminderView() @@ -451,7 +451,7 @@ final class HomeVC: BaseVC, LibSessionRespondingViewController, UITableViewDataS // Update the 'view seed' UI if updatedState.showViewedSeedBanner != self.viewModel.state.showViewedSeedBanner { - tableViewTopConstraint.isActive = false + tableViewTopConstraint?.isActive = false seedReminderView.isHidden = !updatedState.showViewedSeedBanner if updatedState.showViewedSeedBanner { diff --git a/Session/Meta/AppDelegate.swift b/Session/Meta/AppDelegate.swift index c20ebfe697..e6ccfb40d4 100644 --- a/Session/Meta/AppDelegate.swift +++ b/Session/Meta/AppDelegate.swift @@ -564,7 +564,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// There is a warning which can happen on launch because the Database read can be blocked by another database operation /// which could result in this blocking the main thread, as a result we want to check the identity exists on a background thread /// and then return to the main thread only when required - DispatchQueue.global(qos: .default).async { [weak self] in + DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 0.01) { [weak self] in guard Identity.userExists() else { return } self?.enableBackgroundRefreshIfNecessary() @@ -679,7 +679,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// We want to start observing the changes for the 'HomeVC' and want to wait until we actually get data back before we /// continue as we don't want to show a blank home screen - DispatchQueue.global(qos: .userInitiated).async { + DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 0.01) { viewController.startObservingChanges() { populateHomeScreenTimer.invalidate() @@ -719,7 +719,7 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// On application startup the `Storage.read` can be slightly slow while GRDB spins up it's database /// read pools (up to a few seconds), since this read is blocking we want to dispatch it to run async to ensure /// we don't block user interaction while it's running - DispatchQueue.global(qos: .default).async { + DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 0.01) { let unreadCount: Int = Storage.shared .read { db in try Interaction.fetchUnreadCount(db) } .defaulting(to: 0) @@ -814,7 +814,10 @@ class AppDelegate: UIResponder, UIApplicationDelegate, UNUserNotificationCenterD /// Start the pollers on a background thread so that any database queries they need to run don't /// block the main thread - DispatchQueue.global(qos: .background).async { [weak self] in + /// + /// **Note:** We add a delay of `0.01` to prevent potential database re-entrancy if this is triggered + /// within the completion block of a database transaction, this gives it the time to complete the transaction + DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 0.01) { [weak self] in self?.poller.start() guard shouldStartGroupPollers else { return } diff --git a/Session/Meta/SessionApp.swift b/Session/Meta/SessionApp.swift index f568dd0b33..70c7f52aa1 100644 --- a/Session/Meta/SessionApp.swift +++ b/Session/Meta/SessionApp.swift @@ -80,8 +80,9 @@ public struct SessionApp { ) } - /// The thread should generally exist at the time of calling this method, but on the off chance it doesn't then we need to `fetchOrCreate` it and - /// should do it on a background thread just in case something is keeping the DBWrite thread busy as in the past this could cause the app to hang + /// The thread should generally exist at the time of calling this method, but on the off chance it doesn't then we need to + /// `fetchOrCreate` it and should do it on a background thread just in case something is keeping the DBWrite thread + /// busy as in the past this could cause the app to hang guard threadInfo?.threadExists == true else { DispatchQueue.global(qos: .userInitiated).async { Storage.shared.write { db in diff --git a/Session/Meta/Translations/InfoPlist.xcstrings b/Session/Meta/Translations/InfoPlist.xcstrings index 7e1d224367..7ab3cd5b59 100644 --- a/Session/Meta/Translations/InfoPlist.xcstrings +++ b/Session/Meta/Translations/InfoPlist.xcstrings @@ -1 +1 @@ -{"sourceLanguage":"en","strings":{"CFBundleDisplayName":{"comment":"Bundle display name","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":"Session"}}}},"CFBundleGetInfoString":{"comment":"Get Info string","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":""}}}},"CFBundleName":{"comment":"Bundle name","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":"Session"}}}},"New Message":{},"NSAppleMusicUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session moet Apple Music gebruik om media-aanhegsels te speel."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج استخدام Apple Music لتشغيل مرفقات الوسائط."}},"az":{"stringUnit":{"state":"translated","value":"Session media qoşmalarını oxutmaq üçün Apple Music-i istifadə etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session xیس پاتبسینہ ایپل موزیک لو پہ اجرأ ہٰن اختیارات استعمالے"}},"be":{"stringUnit":{"state":"translated","value":"Session патрэбен доступ да Apple Music, каб прайграваць медыя ўкладанні."}},"bg":{"stringUnit":{"state":"translated","value":"Session трябва да използва Apple Music, за да възпроизвежда медийни прикачени файлове."}},"bn":{"stringUnit":{"state":"translated","value":"মিডিয়া সংযুক্তি প্লে করার জন্য Session কে Apple Music ব্যবহার করতে হবে।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita utilitzar Apple Music per reproduir fitxers adjunts de suports."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje použít Apple Music pro přehrávání mediálních příloh."}},"cy":{"stringUnit":{"state":"translated","value":"Mae angen i Session ddefnyddio Apple Music i chwarae atodiadau cyfryngau."}},"da":{"stringUnit":{"state":"translated","value":"Session skal bruge Apple Music for at afspille medievedhæftninger."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt Zugriff auf Apple Music, um Medienanhänge abzuspielen."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στο Apple Music για αναπαραγωγή συνημμένων πολυμέσων."}},"en":{"stringUnit":{"state":"translated","value":"Session needs to use Apple Music to play media attachments."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas uzi Apple Music por ludi aŭdvidaĵojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita usar Apple Music para reproducir archivos adjuntos multimedia."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita usar Apple Music para reproducir archivos adjuntos de medios."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab Apple Musici kasutamist, et esitada meediamanuseid."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k Apple Music erabiltzea behar du hedabide eranskinak erreproduzitzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session باید از Apple Music برای پخش پیوست‌های رسانه‌ای استفاده کند."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee käyttää Apple Musiikkia mediasisältöjen toistamiseen."}},"fil":{"stringUnit":{"state":"translated","value":"Kinakailangang magamit ng Session ang Apple Music upang magpatugtog ng mga media attachment."}},"fr":{"stringUnit":{"state":"translated","value":"Session doit accéder à Apple Music pour lire les pièces jointes multimédias."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita usar Apple Music para reproducir anexos multimedia."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar amfani da Apple Music don kunna abin haɗe-haɗen kafofin watsa labarai."}},"he":{"stringUnit":{"state":"translated","value":"Session זקוק ל-Apple Music כדי להפעיל צרופות מדיה."}},"hi":{"stringUnit":{"state":"translated","value":"मीडिया संलग्नक बजाने के लिए Session को Apple Music के उपयोग की आवश्यकता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba koristiti Apple Music za reprodukciju medijskih privitaka."}},"hu":{"stringUnit":{"state":"translated","value":"Session-nak szüksége van az Apple Music használatára a média mellékletek lejátszásához."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պետք է օգտագործի Apple Music՝ մեդիա կցորդները նվագարկելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan Apple Music untuk memutar lampiran media."}},"it":{"stringUnit":{"state":"translated","value":"Session deve utilizzare Apple Music per riprodurre gli allegati multimediali."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionはメディア添付ファイルを再生するためにApple Musicを使用する必要があります"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება Apple Music-ის გამოყენება მედიამიკრძურბების სათამაშოდ."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការប្រើប្រាស់ Apple Music ដើម្បីចាក់មេឌៀភ្ជាប់"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಮಾಧ್ಯಮ ಅಟ್ಯಾಚ್ಮೆಂಟ್‌ಗಳನ್ನು ಪ್ಲೇ ಮಾಡಲು ಆಪಲ್ ಮ್ಯೂಸಿಕ್ ಬಳಸಬೇಕು."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 미디어 첨부 파일을 재생하기 위해 Apple Music을 사용해야 합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بە پارێزمەنیی ژمارەی تەلەفۆنەکان بۆ بەکردنەوەی هەموو پەیوەستەکان."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya bikar anînina Apple Music hewce dike da ku tesawirên medyayê bixebitîne."}},"lg":{"stringUnit":{"state":"translated","value":"Session keetaaga kuzannyisa Apple Music okuzannyisa ekwatibwako okuva mu mikutu."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງໃຊ້ Apple Music ເພື່ອປ່ອຍແນບສື່ມວນຊົນ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia naudoti Apple Music, kad galėtų leisti medijos priedus."}},"lv":{"stringUnit":{"state":"translated","value":"Session nepieciešams izmantot Apple Music, lai atskaņotu multivides pielikumus."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од Apple Music за да ги репродуцира медиумските прилози."}},"mn":{"stringUnit":{"state":"translated","value":"Session медиа хавсралтуудыг тоглуулахын тулд Apple Music-ийг ашиглах хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session perlu menggunakan Apple Music untuk memainkan lampiran media."}},"my":{"stringUnit":{"state":"translated","value":"Session သည် Apple Music ကို အသုံးပြု၍ မီဒီယာလုံခြုံမှုကို ဖွင့်ရန် လိုအပ်သည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger å bruke Apple Music for å spille av mediavedlegg."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session må bruke Apple Music for å spille medievedlegg."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई मिडिया अट्याचमेन्टहरू प्ले गर्न एप्पल म्यूजिक प्रयोग गर्नु पर्छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session moet Apple Music gebruiken om mediabijlagen af te spelen."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger Apple Music for å spille av media-vedlegg."}},"ny":{"stringUnit":{"state":"translated","value":"Session iyenera kugwiritsa ntchito Apple Music kuti izisintha ma attachment a media."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਮੀਡੀਆ ਅਟੈਚਮੈਂਟਸ ਖੇਡਣ ਲਈ ਐਪਲ ਮਿਊਜ਼ਿਕ ਵਰਤਣ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Do odtwarzania załączników multimedialnych aplikacja Session potrzebuje używać aplikacji Apple Music."}},"ps":{"stringUnit":{"state":"translated","value":"Session میوزیک مولا زموږ توانیدونکی د Apple Music نه په لوبولوکې کارول کیږي."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa usar a Apple Music para reproduzir anexos de mídia."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa usar o Apple Music para reproduzir anexos de multimédia."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la Apple Music pentru a reda atașamente media."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к Apple Music для воспроизведения медиафайлов."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba koristiti Apple Music za reprodukciju medijskih privitaka."}},"si-LK":{"stringUnit":{"state":"translated","value":"මාධ්‍ය ඇමුණුම් වාදනය කිරීමට Session ට Apple Music භාවිත කිරීම අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje používať Apple Music na prehrávanie mediálnych príloh."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje uporabo Apple Music za predvajanje medijskih prilog."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë të përdorë Apple Music për të luajtur attachment-e mediaje."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба да користи Apple Music да би репродуковао медијске прилоге."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba da koristi Apple Music za reprodukciju medijskih priloga."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till Apple Music för att spela upp bifogade mediafiler."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji kutumia Apple Music kucheza viambatanisho vya vyombo vya habari."}},"ta":{"stringUnit":{"state":"translated","value":"Session மெடியா இணைப்புகளை விளையாட Apple Music ஐ பயன்படுத்த வேண்டும்."}},"te":{"stringUnit":{"state":"translated","value":"మీడియా అటాచ్మెంట్‌లను ప్లే చేయడానికి Session Apple Musicను ఉపయోగించాలి."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องใช้ Apple Music เพื่อเล่นไฟล์สื่อที่แนบมา"}},"tr":{"stringUnit":{"state":"translated","value":"Session, medya eklerini çalmak için Apple Music'i kullanmak zorunda."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує використовувати Apple Music для відтворення медіавкладень."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو میڈیا اٹیچمنٹ چلانے کے لیے ایپل میوزک کا استعمال کرنا ہوگا۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session media tarkiblarini ijro etish uchun Apple Music'dan foydalanishi kerak."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần sử dụng Apple Music để phát các tập tin đính kèm phương tiện."}},"xh":{"stringUnit":{"state":"translated","value":"Session kufuneka isebenzise uMculo weApple ukudlala iziphumo zemidiya."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要使用Apple Music来播放媒体附件。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要使用 Apple Music 來播放媒體附件。"}}}},"NSCameraUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het kamera toegang nodig om foto's en video's te neem, of om QR-kodes te skandeer."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى الكاميرا لالتقاط الصور ومقاطع الفيديو، أو لمسح رموز الاستجابة السريعة."}},"az":{"stringUnit":{"state":"translated","value":"Session foto və video çəkmək və ya QR kodlarını skan etmək üçün kameraya müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session کماٹ پاتبسینہ مجبورے تصاویرا و ویڈیوشاں بیہ QR سکینشہ."}},"be":{"stringUnit":{"state":"translated","value":"Session патрэбен дазвол на камеру, каб рабіць фота ці відэа альбо сканаваць QR-коды."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до камерата, за да прави снимки и видеота, или да сканира QR кодове."}},"bn":{"stringUnit":{"state":"translated","value":"ছবি ও ভিডিও করার জন্য Session এর ক্যামেরা অ্যাকসেস প্রয়োজন বা QR কোড স্ক্যান করা।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés a la càmera per fer fotografies i vídeos, o escanejar codis QR."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k fotoaparátu pro pořizování fotografií a videí nebo skenování QR kódů."}},"cy":{"stringUnit":{"state":"translated","value":"Mae angen mynediad i'r camera ar Session i dynnu lluniau a fideos, neu i sganio côd QR."}},"da":{"stringUnit":{"state":"translated","value":"Session kræver tilladelse til at tilgå dit kamera, for at kunne tage billeder eller scanne QR-koder."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt die Berechtigung »Kamera«, um Fotos oder Videos aufzunehmen oder QR-Codes zu scannen."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στην κάμερα για λήψη φωτογραφιών και βίντεο ή για σάρωση κωδικών QR."}},"en":{"stringUnit":{"state":"translated","value":"Session needs camera access to take photos and videos, or scan QR codes."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas fotilan aliron por preni fotojn kaj videojn, aŭ skani QR-kodojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso a la cámara para tomar fotos y videos, o escanear códigos QR."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso a la cámara para tomar fotos y videos, o escanear códigos QR."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab fotode ja videote salvestamiseks või QR-koodide skannimiseks kaamera juurdepääsu."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k kameraren sarbidea behar du argazkiak eta bideoak ateratzeko, edo QR kodeak eskaneatzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای گرفتن عکس‌ و ویدئو، یا اسکن کد‌های QR نیاز به دسترسی دوربین دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee kameran käyttöoikeuden kuvien ja videoiden ottamiseksi tai QR-koodien skannaamiseksi."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa camera upang kumuha ng litrato at video, o mag-scan ng mga QR code."}},"fr":{"stringUnit":{"state":"translated","value":"Session a besoin de l’autorisation Caméra pour prendre des photos ou des vidéos, ou scanner des codes QR."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita acceder á cámara para tirar fotografías e facer vídeos ou escanear códigos QR."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar kyamara don ɗaukar hotuna da bidiyo, ko duba lambobin QR."}},"he":{"stringUnit":{"state":"translated","value":"Session צריך הרשאות מצלמה כדי לצלם תצלומים או להקליט וידיאו או לסרוק קודי QR."}},"hi":{"stringUnit":{"state":"translated","value":"फ़ोटो और वीडियो लेने या क्यूआर कोड स्कैन करने के लिए Session को कैमरा एक्सेस की आवश्यकता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup kameri za snimanje fotografija i videozapisa, ili skeniranje QR kôdova."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak kamera-hozzáférésre van szüksége fotók és videók készítéséhez, illetve QR-kódok beolvasásához."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պետք է հասանելիություն տեսախցիկին՝ լուսանկարներ և տեսանյութեր անելու կամ QR կոդերը սկանավորելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses kamera untuk mengambil foto dan video, atau memindai kode QR."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso alla fotocamera per scattare foto e video, o scansionare i codici QR."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionで写真や動画を撮るには、またはQRコードをスキャンするにはカメラへのアクセスが必要です。"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება კამერის წვდომა ფოტოებისა და ვიდეოების გადასაღებად, ან QR კოდების დასანახად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការការចូលប្រើកាមេរ៉ាដើម្បីថតរូប និងវីដេអូ ឬស្កេនកូដ QR ។"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಚಿತ್ರಗಳು, ವೀಡಿಯೊಗಳು, ಅಥವಾ QR ಕೋಡ್ಗಳು ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಕ್ಯಾಮೆರಾ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 사진과 동영상을 찍거나 QR 코드를 스캔하기 위해 카메라 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بەکارهێنانی کامێرای پێویستە بۆ وەرگرتنی وێنه‌ و ڤیدیۆکان، یان ڕووپیاکانی QR codeکان."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya kamera hewce dike da ku wêneyên û vedîdarên twist bike, an QR kodên scanner bike."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa ya kkamera okutwala ebifaananyi n’ebifaananyi ebya vidiyo, oba okukebera QR codes."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງກ້ອງເພື່ອຖ່າຍຮູບແລະວິດີໂອ, ຫຼືສະແກນ QR codes."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie kameros, kad galėtumėte fotografuoti, filmuoti ar skenuoti QR kodus."}},"lv":{"stringUnit":{"state":"translated","value":"Session ir nepieciešama piekļuve kamerai, lai uzņemtu attēlus un video, vai skenētu QR kodus."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до камерата за да слика фотографии и видеа, или да скенира QR-кодови."}},"mn":{"stringUnit":{"state":"translated","value":"Session нь гэрэл зураг болон видеог авах эсвэл QR кодыг скан хийхийн тулд камерт хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses kamera untuk mengambil gambar dan video, atau mengimbas kod QR."}},"my":{"stringUnit":{"state":"translated","value":"Session က ဓါတ်ပုံတွေနဲ့ ဗီဒီယိုတွေရိုက်ဖို့၊ ဒါမှမဟုတ် QR ကုဒ်တွေ ရှာဖွေရန် အတွက် ကင်မရာသုံးစွဲခွင့် လိုအပ်ပါတယ်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger kameratilgang for å ta bilder og videoer eller skanne QR-koder."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger kameratilgang for å ta bilder og video, eller skanne QR-koder."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई फोटो र भिडियो लिन वा QR कोड स्क्यान गर्न क्यामेराको पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft toegang tot de camera nodig om foto's en video's te maken of QR-codes te scannen."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session treng tilgang til kameraet for å ta bilete eller videoar, eller skanna QR-kodar."}},"ny":{"stringUnit":{"state":"translated","value":"Session iyenera kupititsa mwayi kwa kamera kuti kutenga zithunzi ndi makanema, kapena kuwunika ma QR codes."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓਜ਼ ਲੈਣ ਜਾਂ QR ਕੋਡ ਸਕੈਨ ਕਰਨ ਲਈ ਕੈਮਰਾ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby robić zdjęcia, nagrywać filmy i skanować kody QR, aplikacja Session potrzebuje dostępu do aparatu"}},"ps":{"stringUnit":{"state":"translated","value":"Session ته اړتیا ده چې عکسونه او ویډیوګانې واخلي، یا QR کوډونه سکین کړي."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso à câmera para tirar fotos e vídeos, ou escanear códigos QR."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso à câmera para tirar fotos e vídeos, ou escanear códigos QR."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la cameră pentru a realiza poze și clipuri video sau pentru a scana coduri QR."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к камере для съемки фото, видео, а также сканирования QR-кодов."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup kameri kako bi snimio slike ili video, ili skenirao QR kodove."}},"si-LK":{"stringUnit":{"state":"translated","value":"Sessionට ඡායාරූප සහ වීඩියෝ ගැනීමට හෝ QR කේත පරිලෝකනය කිරීමට කැමරා ප්‍රවේශය අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup ku kamere na vytvárať fotografie a videá, alebo skenovanie QR kódov."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do kamere za fotografiranje in snemanje, ali skeniranje QR kod."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje përdorimi të kamerës për të bërë foto dhe video, ose për të skanuar kodet QR."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба дозволу за камеру да прави слике и видео клипове, или скенира QR кодове."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup kameri da slika fotografije i snima videe, ili skenira QR kodove."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till kameran för att kunna fotografera och filma eller skanna QR-koder."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya kamera kuchukua picha na video, au kuchanganua misimbo ya QR."}},"ta":{"stringUnit":{"state":"translated","value":"Session புகைப்படங்கள், வீடியோக்களை எடுக்க, QR குறியீடுகளை ஸ்கேன் செய்ய கேமரா அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"ఫోటోలను మరియు వీడియోలను తీసుకోవడం లేదా QR కోడ్లను స్కాన్ చేయడానికి Session కు కెమెరా యాక్సెస్ కావాలి."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงกล้องเพื่อถ่ายรูปและวิดีโอ หรือสแกนรหัส QR"}},"tr":{"stringUnit":{"state":"translated","value":"Session, fotoğraf ve video çekmek veya QR kodları taramak için kamera erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступ до камери, щоб фотографувати, знімати відео або сканувати QR-коди."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو تصاویر اور ویڈیوز لینے یا QR کوڈز اسکین کرنے کے لیے کیمرے کی اجازت درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session fotosuratlar va videolarni olish yoki QR kodlarni skanerlash uchun kameraga kirishga ruxsat talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần truy cập máy ảnh để chụp ảnh, quay video hoặc quét mã QR."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwikhamera ukuthatha iifoto nevidiyo, okanye ukukhangela iikhowudi ze-QR."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要相机权限来拍摄照片和视频,或扫描二维码。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要使用相機來拍攝照片和影片,或掃描 QR 圖碼。"}}}},"NSFaceIDUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Die skermsluitfunksie op Session gebruik Face ID."}},"ar":{"stringUnit":{"state":"translated","value":"ميزة قفل الشاشة على Session تستخدم Face ID."}},"az":{"stringUnit":{"state":"translated","value":"Session tətbiqinin ekran kilidi özəlliyi Face ID istifadə edir."}},"bal":{"stringUnit":{"state":"translated","value":"Session رو پیلناکردگ لاگو کردانت پاس ID."}},"be":{"stringUnit":{"state":"translated","value":"Функцыя блакіроўкі экрана ў Session выкарыстоўвае Face ID."}},"bg":{"stringUnit":{"state":"translated","value":"Функцията за заключване на екрана в Session използва Face ID."}},"bn":{"stringUnit":{"state":"translated","value":"Session এর স্ক্রিন লক ফিচারটি ফেস আইডি ব্যবহৃত হয়।"}},"ca":{"stringUnit":{"state":"translated","value":"La funció de bloqueig de pantalla en Session utilitza Face ID."}},"cs":{"stringUnit":{"state":"translated","value":"Funkce zamčení obrazovky Session používá Face ID."}},"cy":{"stringUnit":{"state":"translated","value":"Mae'r nodwedd cloi sgrin ar Session yn defnyddio ID Wyneb."}},"da":{"stringUnit":{"state":"translated","value":"Skærmlåsfunktionen på Session bruger Face ID."}},"de":{"stringUnit":{"state":"translated","value":"Die Bildschirmsperrfunktion von Session verwendet Face ID."}},"el":{"stringUnit":{"state":"translated","value":"Η λειτουργία κλειδώματος οθόνης στο Session χρησιμοποιεί το Face ID."}},"en":{"stringUnit":{"state":"translated","value":"The screen lock feature on Session uses Face ID."}},"eo":{"stringUnit":{"state":"translated","value":"La ŝlosila ekrano en Session uzas Vizaĝo-ID."}},"es-419":{"stringUnit":{"state":"translated","value":"La función de pantalla bloqueada en Session usa Face ID."}},"es-ES":{"stringUnit":{"state":"translated","value":"La función de bloqueo de pantalla en Session usa Face ID."}},"et":{"stringUnit":{"state":"translated","value":"Session ekraaniluku funktsioon kasutab Face ID-d."}},"eu":{"stringUnit":{"state":"translated","value":"Session-ko pantaila blokeatzearen funtzioak Face ID erabiltzen du."}},"fa":{"stringUnit":{"state":"translated","value":"ویژگی قفل صفحه در Session از Face ID استفاده می‌کند."}},"fi":{"stringUnit":{"state":"translated","value":"Näytön lukitusominaisuus Session käyttää Face ID:tä."}},"fil":{"stringUnit":{"state":"translated","value":"Ang screen lock feature ng Session ay gumagamit ng Face ID."}},"fr":{"stringUnit":{"state":"translated","value":"La fonctionnalité de verrouillage d'écran sur Session utilise Face ID."}},"gl":{"stringUnit":{"state":"translated","value":"A funcionalidade de bloqueo de pantalla en Session usa Face ID."}},"ha":{"stringUnit":{"state":"translated","value":"Tsarin kulle allo akan Session yana amfani da Face ID."}},"he":{"stringUnit":{"state":"translated","value":"תכונת נעילת המסך ב-Session משתמשת בזיהוי פנים."}},"hi":{"stringUnit":{"state":"translated","value":"Session पर स्क्रीन लॉक फीचर Face ID का उपयोग करता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Funkcija zaključavanja zaslona na Session koristi Face ID."}},"hu":{"stringUnit":{"state":"translated","value":"A Session képernyőzár funkciója Face ID-t használ."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ի էկրանային կողպման հատկությունը օգտագործում է Face ID:"}},"id":{"stringUnit":{"state":"translated","value":"Fitur kunci layar pada Session menggunakan Face ID."}},"it":{"stringUnit":{"state":"translated","value":"La funzione di blocco schermo su Session usa il Face ID."}},"ja":{"stringUnit":{"state":"translated","value":"Session の画面ロック機能はFace IDを使用します。"}},"ka":{"stringUnit":{"state":"translated","value":"ეკრანის დაბლოკვის ფუნქცია Session-ზე იყენებს Face ID-ს"}},"km":{"stringUnit":{"state":"translated","value":"The screen lock feature on Session uses Face ID."}},"kn":{"stringUnit":{"state":"translated","value":"Session ನ ತರ್ಣ್ ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯವು ಫೇಸ್ ಐಡಿ ಅನ್ನು ಬಳಸುತ್ತದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session의 화면 잠금 기능은 Face ID를 사용합니다."}},"ku":{"stringUnit":{"state":"translated","value":"فەرمۆن جێگیرکردنی تابلەکردنی سکرین ناستەوەی Session پێی ئەنجامدەدرێت."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Taybetmendiya serrnderkî ya Session bi Face ID bicîh dike."}},"lg":{"stringUnit":{"state":"translated","value":"Enkozesa y'ekiwandiiko k'amaaso ekiriko Session ekosa Face ID."}},"lt":{"stringUnit":{"state":"translated","value":"Ekrano užraktas Session naudoja Face ID."}},"lv":{"stringUnit":{"state":"translated","value":"Ekrāna bloķēšanas funkcija lietotnē Session izmanto Face ID."}},"mk":{"stringUnit":{"state":"translated","value":"Функцијата за заклучување екранот во Session користи Face ID."}},"mn":{"stringUnit":{"state":"translated","value":"Session дэлгэц түгжихэд Face ID ашиглана."}},"ms":{"stringUnit":{"state":"translated","value":"Ciri kunci skrin pada Session menggunakan Face ID."}},"my":{"stringUnit":{"state":"translated","value":"Session တွင် အမ်ကာ မျက်နှာ မြင်စနစ် लॉग इन ၏ လုံခြုံစေသည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Skjermlåsfunksjonen på Session bruker Face ID."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Skjermlåsfunksjonen på Session bruker Face ID."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Sessionको स्क्रिन लक विशेषताले Face ID प्रयोग गर्छ।"}},"nl":{"stringUnit":{"state":"translated","value":"De vergrendelfunctie op Session gebruikt Face ID."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Skjermlåsfunksjonen på Session bruker Face ID."}},"ny":{"stringUnit":{"state":"translated","value":"Ntchito yotseka chinsalu pa Session imagwiritsa ntchito Face ID."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਉੱਤੇ ਸਕرين ਲਾਕ ਫੀਚਰ Face ID ਵਰਤਦਾ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Funkcja blokady ekranu w aplikacji Session używa Face ID."}},"ps":{"stringUnit":{"state":"translated","value":"د Session سکرین لاک فیچر د مخ پيژندنه (Face ID) کاروي."}},"pt-BR":{"stringUnit":{"state":"translated","value":"A funcionalidade de bloqueio de tela no Session usa reconhecimento facial."}},"pt-PT":{"stringUnit":{"state":"translated","value":"A funcionalidade de bloqueio de ecrã Session usa Face ID."}},"ro":{"stringUnit":{"state":"translated","value":"Funcția de blocare a ecranului din Session folosește Face ID."}},"ru":{"stringUnit":{"state":"translated","value":"Функция блокировки экрана в Session использует Face ID."}},"sh":{"stringUnit":{"state":"translated","value":"Značajka zaključavanja ekrana na Session koristi Face ID."}},"si-LK":{"stringUnit":{"state":"translated","value":"Session මත තිර අගුළු විශේෂාංගය Face ID භාවිතා කරයි."}},"sk":{"stringUnit":{"state":"translated","value":"Funkcia zámku obrazovky na Session používa Face ID."}},"sl":{"stringUnit":{"state":"translated","value":"Funkcija zaklepanja zaslona na Session uporablja Face ID."}},"sq":{"stringUnit":{"state":"translated","value":"Veçoria e mbylljes së ekranit në Session përdor Face ID."}},"sr":{"stringUnit":{"state":"translated","value":"Функција закључавања екрана на Session користи Face ID."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Funkcija zaključavanja ekrana na Session koristi Face ID."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Skärmlåsfunktionen på Session använder Face ID."}},"sw":{"stringUnit":{"state":"translated","value":"Kipengele cha kufuli skrini kwenye Session kinatumia Face ID."}},"ta":{"stringUnit":{"state":"translated","value":"Session இல் திரை பூட்டு அம்சம் முக அடையாளத்தை பயன்படுத்துகிறது."}},"te":{"stringUnit":{"state":"translated","value":"Sessionలో స్క్రీన్ లాక్ ఫీచర్ ఫేస్ ఐడి నీ ఉపయోగిస్తుంది."}},"th":{"stringUnit":{"state":"translated","value":"ฟีเจอร์ล็อกหน้าจอใน Session ใช้ Face ID"}},"tr":{"stringUnit":{"state":"translated","value":"Session ekran kilidi özelliği Face ID kullanır."}},"uk":{"stringUnit":{"state":"translated","value":"Функція блокування екрана в Session використовує Face ID."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session پر سکرین لاک خصوصیت Face ID کا استعمال کرتی ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session dagi ekran blokirovkasi funksiyasi Face ID dan foydalanadi."}},"vi":{"stringUnit":{"state":"translated","value":"Tính năng khóa màn hình trên Session sử dụng Face ID."}},"xh":{"stringUnit":{"state":"translated","value":"Umsebenzi wokutshixa isikrini kwi-Session usebenzisa i-Face ID."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session的屏幕锁功能使用 Face ID。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 上的螢幕鎖功能使用 Face ID。"}}}},"NSHumanReadableCopyright":{"comment":"Copyright (human-readable)","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":"com.loki-project.loki-messenger"}}}},"NSMicrophoneUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het mikrofoon toegang nodig om oproepe te maak en oudioboodskappe op te neem."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى الميكروفون لإجراء المكالمات وتسجيل الرسائل الصوتية."}},"az":{"stringUnit":{"state":"translated","value":"Session zəng etmək və səsli mesajlar yazmaq üçün mikrofona müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session مایکروفون پاتبسینہ حاصل نودہ کلمات پیغامشین زانت"}},"be":{"stringUnit":{"state":"translated","value":"Session патрэбен доступ да мікрафона, каб здзяйсняць званкі і запісваць аўдыя паведамленні."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до микрофона, за да осъществява обаждания и записва аудио съобщения."}},"bn":{"stringUnit":{"state":"translated","value":"কল করার জন্য এবং অডিও মেসেজ রেকর্ড করার জন্য Session এর মাইক্রোফোন অ্যাকসেস প্রয়োজন।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés al micròfon per fer trucades i gravar missatges d'àudio."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k mikrofonu pro volání a nahrávání zvukových zpráv."}},"cy":{"stringUnit":{"state":"translated","value":"Mae Session angen mynediad i'r meicroffon i wneud galwadau a recordio negeseuon sain."}},"da":{"stringUnit":{"state":"translated","value":"Session kræver mikrofonadgang for at foretage opkald og optage lydmeddelelser."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt Mikrofonzugriff, um Anrufe zu tätigen und Audionachrichten aufzuzeichnen."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στο μικρόφωνο για την αποστολή ηχητικών μηνυμάτων."}},"en":{"stringUnit":{"state":"translated","value":"Session needs microphone access to make calls and record audio messages."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas mikrofonan aliron por fari vokojn kaj registri aŭdajn mesaĝojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso al micrófono para hacer llamadas y grabar mensajes de audio."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso al micrófono para hacer llamadas y grabar mensajes de audio."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab mikrofoni juurdepääsu, et teha kõnesid ja salvestada helisõnumeid."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k mikrofonoaren sarbidea behar du deiak egiteko eta audio mezuak grabatzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای برقراری تماس و ضبط پیام‌های صوتی نیاز به دسترسی میکروفن دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee mikrofonin käyttöoikeuden puheluiden soittamiseen ja ääniviestien nauhoittamiseen."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa mikropono upang tumawag at mag-record ng mga mensaheng audio."}},"fr":{"stringUnit":{"state":"translated","value":"Session a besoin de l’accès au microphone pour passer des appels et enregistrer des messages audio."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita acceder ao micrófono para facer chamadas e gravar mensaxes de audio."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar makirufo don yin kira da rikodin saƙonnin murya."}},"he":{"stringUnit":{"state":"translated","value":"Session צריך הרשאת מיקרופון לשיחות ולהודעות שמע."}},"hi":{"stringUnit":{"state":"translated","value":"कॉल करने और ऑडियो संदेश रिकॉर्ड करने के लिए Session को माइक्रोफोन एक्सेस की आवश्यकता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup mikrofonu za obavljanje poziva i snimanje audio poruka."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak mikrofon-hozzáférésre van szüksége hívások bonyolítására és hangüzeneteket rögzítésére."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պահանջում է խոսափողին հասանելիություն զանգեր կատարելու և ձայնային հաղորդագրություններ արձանագրելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses mikrofon untuk melakukan panggilan dan merekam pesan audio."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso al microfono per effettuare chiamate e registrare messaggi audio."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionで通話をかけたり、音声メッセージを録音するにはマイクへのアクセスが必要です。"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება მიკროფონის წვდომა ზარების შესასრულებლად და აუდიო შეტყობინებების ჩასაწერად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការវិស្សមន្តងសម្រាប់ដាក់ស្នើរ និងថតសារ​សំឡេង។"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಕಾಲ್‌ಗಳು ಮಾಡಲು ಮತ್ತು ಆಡಿಯೊ ಸಂದೇಶಗಳನ್ನು ದಾಖಲು ಮಾಡಲು ಮೈಕ್ರೊಫೋನ್ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 통화를 하고 음성 메시지를 녹음하기 위해 마이크 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session دەتوانێت بەکارهێنانی داده‌یەکیی وەکو پەیوەستەکان بکات بۆ پەیوەندیش"}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya mîkrofon hewce dike da ku lêgerîn bike û peyman dengî record bike."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa ya mmikirofono okukola eyitibwamu n’okuwandiika obubaka obuweereze."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງໄມໂຄໂຟນເພື່ອໂທແລະບັນທຶກເສັຽງຂໍ້ຄວາມສຽງ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie mikrofono, kad galėtumėte skambinti ir įrašinėti garso žinutes."}},"lv":{"stringUnit":{"state":"translated","value":"Session ir nepieciešama piekļuve mikrofonam, lai veiktu zvanus un ierakstītu audio ziņas."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до микрофонот за да врши повици и снима аудио пораки."}},"mn":{"stringUnit":{"state":"translated","value":"Session дуудлага хийх болон аудио мессеж бичихийн тулд микрофоны хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses mikrofon untuk membuat panggilan dan merakam mesej audio."}},"my":{"stringUnit":{"state":"translated","value":"Session မှ ဖုန်းခေါ်ဆိုမှုများနှင့် အသံမက်ဆေ့များကို မှတ်တမ်းတင်ရန် မိုက်ခရိုဖုန်းအသုံးပြုခွင့် လိုအပ်ပါတယ်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger mikrofontilgang for å ringe og spille inn lydmeldinger."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger mikrofontilgang for å foreta samtaler og ta opp lydmeldinger."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई कल गर्न र अडियो सन्देशहरू रेकर्ड गर्न माइक्रोफोनको पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft toegang tot de microfoon nodig om audioberichten op te nemen."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger mikrofontilgang for å ringe og ta opp lydmeldinger."}},"ny":{"stringUnit":{"state":"translated","value":"Session iyenera kuitanira microphone kuti ipangane mafoni ndi kujambula mauthenga am'mawu."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਕਾਲਾ ਕਰਣ ਅਤੇ ਆਡੀਓ ਸੁਨੇਹੇ ਰਿਕਾਰਡ ਕਰਨ ਲਈ ਮਾਈਕਰੋਫੋਨ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby wykonywać połączenia i nagrywać wiadomości audio, aplikacja Session potrzebuje dostępu do mikrofonu."}},"ps":{"stringUnit":{"state":"translated","value":"Session د غږیزو پیغامونو لیږلو کولو لپاره مایکروفون ته اړتیا لري."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao microfone para fazer chamadas e gravar mensagens de áudio."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao microfone para fazer chamadas e gravar mensagens de áudio."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la microfon pentru a efectua apeluri și a înregistra mesaje audio."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к микрофону для совершения звонков и записи голосовых сообщений."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup mikrofonu za obavljanje poziva i snimanje audio poruka."}},"si-LK":{"stringUnit":{"state":"translated","value":"ඇමතුම් ලබා දීම සහ ශ්‍රව්‍ය පණිවිඩ පටිගත කිරීම සඳහා Sessionට මයික්‍රෆෝන ප්‍රවේශය අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup k mikrofónu na uskutočnenie hovorov a nahranie zvukových správ."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do mikrofona za klice in snemanje zvočnih sporočil."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje përdorimi të mikrofonit për të bërë thirrje dhe për të regjistruar mesazhe audio."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба дозволу за микрофон да би обављао позиве и снимао аудио поруке."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup mikrofonu da bi obavljao pozive i snimao audio poruke."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver mikrofonåtkomst för att ringa och spela in ljudmeddelanden."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya kipaza sauti kupiga simu na kurekodi ujumbe wa sauti."}},"ta":{"stringUnit":{"state":"translated","value":"Session அழைப்புகளை செய்ய மற்றும் ஆடியோ தகவல்களை பதிவு செய்ய மைக்ரோஃபோன் அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"కాల్ చేయడానికి మరియు ఆడియో సందేశాలను రికార్డ్ చేయడానికి Session మైక్రోఫోన్ యాక్సెస్ అవసరం."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงไมโครโฟนเพื่อโทรและบันทึกข้อความเสียง"}},"tr":{"stringUnit":{"state":"translated","value":"Session, arama yapmak ve sesli mesaj kaydetmek için mikrofon erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступу до мікрофона для здійснення дзвінків та запису голосових повідомлень."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو کال کرنے اور آڈیو پیغامات ریکارڈ کرنے کے لیے مائیکروفون تک رسائی درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session qo'ng'iroqlar va audio xabarlarni yozish uchun mikrofonga kirishga ruxsat talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần quyền truy cập microphone để gọi điện và ghi âm tin nhắn thoại."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwisixhobo somculo wokwenza iminxeba kunye nokurekhoda imiyalezo yesandi."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要麦克风访问权限来进行语音通话及录制语音消息。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要麥克風存取權來語音通話和錄製語音訊息。"}}}},"NSPhotoLibraryAddUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het berging toegang nodig om aanhegsels en media te stoor."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى التخزين لحفظ المرفقات والوسائط."}},"az":{"stringUnit":{"state":"translated","value":"Session qoşmaları və medianı saxlamaq üçün anbara müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session ذخیرہ پاتبسینہ محفوظ عریض او ذرہے"}},"be":{"stringUnit":{"state":"translated","value":"Session патрабуе дазволу да сховішча каб захоўваць ўкладанні і медыя."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до хранилището, за да запазва прикачени файлове и медия."}},"bn":{"stringUnit":{"state":"translated","value":"সংযুক্তি এবং মিডিয়া সংরক্ষণ করতে Session এর স্টোরেজ অ্যাকসেস প্রয়োজন।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés a l'emmagatzematge per desar els fitxers adjunts i els suports."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k úložišti pro ukládání příloh a médií."}},"cy":{"stringUnit":{"state":"translated","value":"Mae Session angen mynediad i storio i gadw atodiadau a chyfryngau."}},"da":{"stringUnit":{"state":"translated","value":"Session skal have lageradgang for at gemme vedhæftninger og mediefiler."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt Speicherzugriff, um Anhänge und Medien zu speichern."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για να αποθηκεύσει συνημμένα και πολυμέσα."}},"en":{"stringUnit":{"state":"translated","value":"Session needs storage access to save attachments and media."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas aliron al memoro por konservi aldonaĵojn kaj aŭdvidaĵojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso al almacenamiento para guardar adjuntos y multimedia."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso de almacenamiento para guardar archivos adjuntos y medios."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab salvestusruumi ligipääsu, et salvestada manuseid ja meediat."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k biltegirako sarbidea behar du eranskinak eta hedabideak gordetzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای ذخیره پیوست‌ها و رسانه‌ها نیاز به دسترسی به حافظه دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee tallennustilan käyttöoikeuden liitteiden ja median tallentamiseksi."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa storage upang mag-save ng mga attachment at media."}},"fr":{"stringUnit":{"state":"translated","value":"Session doit accéder au stockage pour enregistrer les pièces jointes et les médias."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita permiso para acceder ao almacenamento para gardar anexos e medios."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar ajiya don adana abubuwan haɗe-haɗe da kafofin watsa labarai."}},"he":{"stringUnit":{"state":"translated","value":"Session זקוק לגישה לאחסון כדי לשמור צרופות ומדיה."}},"hi":{"stringUnit":{"state":"translated","value":"Session को अनुलग्नक और मीडिया को सहेजने के लिए संग्रहण पहुंच चाहिए।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup memoriji za spremanje privitaka i medija."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak tárhely-hozzáférésre van szüksége a mellékletek és médiák mentéséhez."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պահանջում է պահեստային հասանելիություն կցորդներն ու մեդիան պահպանելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses penyimpanan untuk menyimpan lampiran dan media."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso allo storage per salvare allegati e media."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionは添付ファイルやメディアを保存するためにストレージへのアクセスが必要です。"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება მეხსიერების წვდომა მიმაგრებული ფაილებისა და მედიების შესანახად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការចូលប្រើវើសកម្មដើម្បីរក្សាទុកឯកសារ និងមេឌៀ។"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಅಟ್ಯಾಚ್ಮೆಂಟ್‌ಗಳು ಮತ್ತು ಮಾಧ್ಯಮವನ್ನು ಉಳಿಸಲು ಸಂಗ್ರಹಣೆಯ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 첨부 파일과 미디어를 저장하기 위해 저장 공간 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بەکارهێنانی خزینەی فایل بۆ هەڵگرتنی پەیوەستەکان و میدیا ناردن"}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya hilkişina xelasî û medyayê hewce dike."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa y’obusobozi okusigala ekwatibwako aammaamu n’emikutu."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງຟາຍເພື່ອບັນທຶກຢາງແລະວິດີໂອ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie saugyklos, kad galėtų įrašyti priedus ir mediją."}},"lv":{"stringUnit":{"state":"translated","value":"Session ir nepieciešama pieeja glabātuve failu un multimediju saglabāšanai."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до складиштето за да зачува прилози и медиуми."}},"mn":{"stringUnit":{"state":"translated","value":"Session нь хавсралт болон медиа хадгалахын тулд сангийн хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses storan untuk menyimpan lampiran dan media."}},"my":{"stringUnit":{"state":"translated","value":"Session သည် ပူးတွဲချက်များနှင့် မီဒီယာကို သိမ်းဆည်းရန် သိုလှောင်မှုခွင့်ပြုချက်လိုအပ်ပါသည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å lagre vedlegg og media."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å lagre vedlegg og media."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई अट्याचमेन्ट र मिडिया सेभ गर्न स्टोरज पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft opslagtoegang nodig om bijlagen en media op te slaan."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å lagre vedlegg og media."}},"ny":{"stringUnit":{"state":"translated","value":"Session imafuna mwayi wosungira kuti asunge attachments ndi media."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਅਟੈਚਮੈਂਟਸ ਅਤੇ ਮੀਡੀਆ ਸੰਭਾਲਣ ਲਈ ਸਟੋਰੇਜ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby zapisywać załączniki i multimedia, aplikacja Session potrzebuje dostępu do pamięci."}},"ps":{"stringUnit":{"state":"translated","value":"Session پیوستونونو او میډیا خوندي کولو لپاره ذخیره کولو ته اړتیا لري."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao armazenamento para salvar anexos e mídias."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao armazenamento para salvar anexos e mídia."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la spațiul de stocare pentru a salva atașamente și media."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к хранилищу для сохранения вложений и медиафайлов."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup pohrani za spremanje privitaka i medija."}},"si-LK":{"stringUnit":{"state":"translated","value":"ඇමුණුම් සහ මාධ්‍ය සුරැකීම සඳහා Sessionට ගබඩා ප්‍රවේශය අවශ්‍යවේ."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup k úložisku na uloženie príloh a médií."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do shrambe za shranjevanje prilog in medijev."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje të hapësirës ruajtëse për të ruajtur attachment-et dhe median."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба приступ складишту да сачува прилоге и медије."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup skladištu da sačuva priloge i medije."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till lagringsutrymmet för att kunna spara bifogade filer och media."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya hifadhi ili kuhifadhi viambatanisho na vyombo vya habari."}},"ta":{"stringUnit":{"state":"translated","value":"Session இணைப்புகள் மற்றும் மெடியாவை சேமிக்க சேமிப்பக அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"అటాచ్మెంట్‌లు మరియు మీడియాను సేవ్ చేయడానికి Session కు నిల్వ యాక్సెస్ అవసరం."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงที่เก็บข้อมูลเพื่อบันทึกไฟล์แนบและสื่อ"}},"tr":{"stringUnit":{"state":"translated","value":"Session, ekleri ve medyayı kaydetmek için depolama erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступу до сховища для збереження вкладень та медіа."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو منسلکات اور میڈیا محفوظ کرنے کے لیے اسٹوریج کی اجازت درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session fayl va media tarkiblarini saqlash uchun saqlashga kirishni talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần quyền truy cập lưu trữ để lưu các tập tin đính kèm và phương tiện."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwindawo yokugcina ukuthumela iziphumo kunye nemidiya."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要存储权限来保存附件和媒体。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要存儲權限以保存附件和媒體。"}}}},"NSPhotoLibraryUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het berging toegang nodig om foto's en video's te stuur."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى التخزين لإرسال الصور ومقاطع الفيديو."}},"az":{"stringUnit":{"state":"translated","value":"Session foto və videoları göndərmək üçün anbara müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session ذخیرہ پاتبسینہ بھیجنے تصویریں دکنیں"}},"be":{"stringUnit":{"state":"translated","value":"Session патрабуе дазволу да сховішча каб дасылаць фота і відэа."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до хранилището, за да изпраща снимки и видеота."}},"bn":{"stringUnit":{"state":"translated","value":"ছবি এবং ভিডিও প্রেরণ করতে Session এর স্টোরেজ অ্যাকসেস প্রয়োজন।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés a l'emmagatzematge per enviar fotografies i vídeos."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k úložišti pro odesílání fotografií a videí."}},"cy":{"stringUnit":{"state":"translated","value":"Mae Session angen mynediad i storio i anfon lluniau a fideos."}},"da":{"stringUnit":{"state":"translated","value":"Session har brug for lageradgang for at sende billeder og videoer."}},"de":{"stringUnit":{"state":"translated","value":"Session Benötigt Speicherzugriff, um Fotos und Videos zu senden."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για την αποστολή φωτογραφιών και βίντεο."}},"en":{"stringUnit":{"state":"translated","value":"Session needs storage access to send photos and videos."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas aliron al memoro por sendi bildojn kaj videojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso al almacenamiento para enviar fotos y videos."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso de almacenamiento para enviar fotos y videos."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab fotode ja videote saatmiseks juurdepääsu salvestusruumile."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k biltegirako sarbidea behar du argazkiak eta bideoak bidaltzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای ارسال عکس‌ها و ویدئو‌ها نیاز به دسترسی حافظه دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee tallennustilan käyttöoikeuden kuvien ja videoiden lähettämiseksi."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa storage upang magpadala ng mga litrato at video."}},"fr":{"stringUnit":{"state":"translated","value":"Session a besoin d'un accès au stockage pour envoyer des photos et des vidéos."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita permiso para acceder ao almacenamento para enviar fotos e vídeos."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar ajiya don aikawa da hotuna da bidiyo."}},"he":{"stringUnit":{"state":"translated","value":"Session צריך הרשאות גישה לאחסון על מנת לשלוח תמונות ווידיאו."}},"hi":{"stringUnit":{"state":"translated","value":"Session को फ़ोटो और वीडियो भेजने के लिए संग्रहण पहुंच चाहिए।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup memoriji za slanje fotografija i videozapisa."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak tárhely-hozzáférésre van szüksége a fotók és videók elküldéséhez."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պահանջում է պահեստային հասանելիություն՝ լուսանկարներ և տեսանյութեր ուղարկելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses penyimpanan untuk mengirim foto dan video."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso all'archiviazione per inviare foto e video."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionは写真や動画を送信するためにストレージへのアクセスが必要です"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება მეხსიერების წვდომა ფოტოებისა და ვიდეოების გასაგზავნად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការភ្ជាប់អង្គរក្សាទុកដើម្បីផ្ញើរូបទិញនិងវីដេអូ."}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಕಳುಹಿಸಲು ಸಂಗ್ರಹಣೆಯ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 사진과 동영상을 전송하기 위해 저장공간 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بەکارهێنانی خزینە بۆ ناردنی وێنە و ڤیدیۆکان."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya hilkişina wêneyên û vedîdarên bişîne."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa y’obusobozi okutuma ebifaananyi n’ebifaananyi ebya vidiyo."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງຟາຍເພື່ອສົ່ງຮູບແລະວິດີໂອ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie saugyklos norint siųsti nuotraukas ir vaizdo įrašus."}},"lv":{"stringUnit":{"state":"translated","value":"Session vajag pieeju failiem, lai sūtītu atēlus un video."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до складиштето за да испраќа фотографии и видеа."}},"mn":{"stringUnit":{"state":"translated","value":"Session зураг болон видеонуудыг илгээхийн тулд сангийн хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses storan untuk menghantar foto dan video."}},"my":{"stringUnit":{"state":"translated","value":"Session သည် ဓာတ်ပုံများနှင့် ဗွီဒီယိုများ ပို့ရန် သိမ်းဆည်းမှုပုံစံခွင့်လိုအပ်သည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å sende bilder og videoer."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å sende bilder og videoer."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई फोटो र भिडियोहरू पठाउन स्टोरज पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft toegang nodig tot de opslag om foto's en video's te kunnen verzenden."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å sende bilete og videoar."}},"ny":{"stringUnit":{"state":"translated","value":"Session imafuna mwayi wosungira kuti atumize zithunzi ndi makanema."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓਜ਼ ਭੇਜਣ ਲਈ ਸਟੋਰੇਜ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby wysyłać zdjęcia i filmy, aplikacja Session potrzebuje dostępu do pamięci."}},"ps":{"stringUnit":{"state":"translated","value":"Session عکسونه او ویډیوګانې لیږلو لپاره ذخیره کولو ته اړتیا لري."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao seu armazenamento para enviar fotos e vídeos."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao armazenamento para enviar fotos e vídeos."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la spațiul de stocare pentru a trimite poze și clipuri video."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к хранилищу для отправки фотографий и видео."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup pohrani za slanje slika i videa."}},"si-LK":{"stringUnit":{"state":"translated","value":"ඡායාරූප සහ වීඩියෝ යැවීමට Sessionට ගබඩා ප්‍රවේශය අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup na disk na posielanie fotiek a videí."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do shrambe za pošiljanje fotografij in videoposnetkov."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje të hapësirës ruajtëse për të dërguar foto dhe video."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба дозволу за складиште да шаље слике и видео клипове."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup skladištu da šalje fotografije i videe."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till lagringsutrymmet för att kunna skicka foton och filmer."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya kuhifadhi ili kutuma picha na video."}},"ta":{"stringUnit":{"state":"translated","value":"Session புகைப்படங்கள் மற்றும் வீடியோக்களை அனுப்ப சேமிப்பக அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"ఫోటోలు మరియు వీడియోలను పంపడానికి Session కు నిల్వ యాక్సెస్ అవసరం."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงที่เก็บข้อมูลเพื่อส่งรูปภาพและวิดีโอ"}},"tr":{"stringUnit":{"state":"translated","value":"Session, fotoğraf ve video göndermek için depolama erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступу до сховища для відправлення фотографій та відео."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو تصاویر اور ویڈیوز بھیجنے کے لیے اسٹوریج کی اجازت درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session fotosuratlar va videolarni yuborish uchun saqlashga kirishni talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần quyền truy cập lưu trữ để gửi ảnh và video."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwindawo yokugcina ukuthumela iifoto nevidiyo."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要存储权限以取用及发送照片或视频。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要存儲權限來發送照片和影片。"}}}}},"version":"1.0"} \ No newline at end of file +{"sourceLanguage":"en","strings":{"CFBundleDisplayName":{"comment":"Bundle display name","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":"Session"}}}},"CFBundleGetInfoString":{"comment":"Get Info string","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":""}}}},"CFBundleName":{"comment":"Bundle name","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":"Session"}}}},"New Message":{},"NSAppleMusicUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session moet Apple Music gebruik om media-aanhegsels te speel."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج استخدام Apple Music لتشغيل مرفقات الوسائط."}},"az":{"stringUnit":{"state":"translated","value":"Session media qoşmalarını oxutmaq üçün Apple Music-i istifadə etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session xیس پاتبسینہ ایپل موزیک لو پہ اجرأ ہٰن اختیارات استعمالے"}},"be":{"stringUnit":{"state":"translated","value":"Session патрэбен доступ да Apple Music, каб прайграваць медыя ўкладанні."}},"bg":{"stringUnit":{"state":"translated","value":"Session трябва да използва Apple Music, за да възпроизвежда медийни прикачени файлове."}},"bn":{"stringUnit":{"state":"translated","value":"মিডিয়া সংযুক্তি প্লে করার জন্য Session কে Apple Music ব্যবহার করতে হবে।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita utilitzar Apple Music per reproduir fitxers adjunts de suports."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje použít Apple Music pro přehrávání mediálních příloh."}},"cy":{"stringUnit":{"state":"translated","value":"Mae angen i Session ddefnyddio Apple Music i chwarae atodiadau cyfryngau."}},"da":{"stringUnit":{"state":"translated","value":"Session skal bruge Apple Music for at afspille medievedhæftninger."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt Zugriff auf Apple Music, um Medienanhänge abzuspielen."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στο Apple Music για αναπαραγωγή συνημμένων πολυμέσων."}},"en":{"stringUnit":{"state":"translated","value":"Session needs to use Apple Music to play media attachments."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas uzi Apple Music por ludi aŭdvidaĵojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita usar Apple Music para reproducir archivos adjuntos multimedia."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita usar Apple Music para reproducir archivos adjuntos de medios."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab Apple Musici kasutamist, et esitada meediamanuseid."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k Apple Music erabiltzea behar du hedabide eranskinak erreproduzitzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session باید از Apple Music برای پخش پیوست‌های رسانه‌ای استفاده کند."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee käyttää Apple Musiikkia mediasisältöjen toistamiseen."}},"fil":{"stringUnit":{"state":"translated","value":"Kinakailangang magamit ng Session ang Apple Music upang magpatugtog ng mga media attachment."}},"fr":{"stringUnit":{"state":"translated","value":"Session doit accéder à Apple Music pour lire les pièces jointes multimédias."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita usar Apple Music para reproducir anexos multimedia."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar amfani da Apple Music don kunna abin haɗe-haɗen kafofin watsa labarai."}},"he":{"stringUnit":{"state":"translated","value":"Session זקוק ל-Apple Music כדי להפעיל צרופות מדיה."}},"hi":{"stringUnit":{"state":"translated","value":"मीडिया संलग्नक बजाने के लिए Session को Apple Music के उपयोग की आवश्यकता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba koristiti Apple Music za reprodukciju medijskih privitaka."}},"hu":{"stringUnit":{"state":"translated","value":"Session-nak szüksége van az Apple Music használatára a média mellékletek lejátszásához."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պետք է օգտագործի Apple Music՝ մեդիա կցորդները նվագարկելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan Apple Music untuk memutar lampiran media."}},"it":{"stringUnit":{"state":"translated","value":"Session deve utilizzare Apple Music per riprodurre gli allegati multimediali."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionはメディア添付ファイルを再生するためにApple Musicを使用する必要があります"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება Apple Music-ის გამოყენება მედიამიკრძურბების სათამაშოდ."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការប្រើប្រាស់ Apple Music ដើម្បីចាក់មេឌៀភ្ជាប់"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಮಾಧ್ಯಮ ಅಟ್ಯಾಚ್ಮೆಂಟ್‌ಗಳನ್ನು ಪ್ಲೇ ಮಾಡಲು ಆಪಲ್ ಮ್ಯೂಸಿಕ್ ಬಳಸಬೇಕು."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 미디어 첨부 파일을 재생하기 위해 Apple Music을 사용해야 합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بە پارێزمەنیی ژمارەی تەلەفۆنەکان بۆ بەکردنەوەی هەموو پەیوەستەکان."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya bikar anînina Apple Music hewce dike da ku tesawirên medyayê bixebitîne."}},"lg":{"stringUnit":{"state":"translated","value":"Session keetaaga kuzannyisa Apple Music okuzannyisa ekwatibwako okuva mu mikutu."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງໃຊ້ Apple Music ເພື່ອປ່ອຍແນບສື່ມວນຊົນ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia naudoti Apple Music, kad galėtų leisti medijos priedus."}},"lv":{"stringUnit":{"state":"translated","value":"Session nepieciešams izmantot Apple Music, lai atskaņotu multivides pielikumus."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од Apple Music за да ги репродуцира медиумските прилози."}},"mn":{"stringUnit":{"state":"translated","value":"Session медиа хавсралтуудыг тоглуулахын тулд Apple Music-ийг ашиглах хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session perlu menggunakan Apple Music untuk memainkan lampiran media."}},"my":{"stringUnit":{"state":"translated","value":"Session သည် Apple Music ကို အသုံးပြု၍ မီဒီယာလုံခြုံမှုကို ဖွင့်ရန် လိုအပ်သည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger å bruke Apple Music for å spille av mediavedlegg."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session må bruke Apple Music for å spille medievedlegg."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई मिडिया अट्याचमेन्टहरू प्ले गर्न एप्पल म्यूजिक प्रयोग गर्नु पर्छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session moet Apple Music gebruiken om mediabijlagen af te spelen."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger Apple Music for å spille av media-vedlegg."}},"ny":{"stringUnit":{"state":"translated","value":"Session iyenera kugwiritsa ntchito Apple Music kuti izisintha ma attachment a media."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਮੀਡੀਆ ਅਟੈਚਮੈਂਟਸ ਖੇਡਣ ਲਈ ਐਪਲ ਮਿਊਜ਼ਿਕ ਵਰਤਣ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Do odtwarzania załączników multimedialnych aplikacja Session potrzebuje używać aplikacji Apple Music."}},"ps":{"stringUnit":{"state":"translated","value":"Session میوزیک مولا زموږ توانیدونکی د Apple Music نه په لوبولوکې کارول کیږي."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa usar a Apple Music para reproduzir anexos de mídia."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa usar o Apple Music para reproduzir anexos de multimédia."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la Apple Music pentru a reda atașamente media."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к Apple Music для воспроизведения медиафайлов."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba koristiti Apple Music za reprodukciju medijskih privitaka."}},"si-LK":{"stringUnit":{"state":"translated","value":"මාධ්‍ය ඇමුණුම් වාදනය කිරීමට Session ට Apple Music භාවිත කිරීම අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje používať Apple Music na prehrávanie mediálnych príloh."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje uporabo Apple Music za predvajanje medijskih prilog."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë të përdorë Apple Music për të luajtur attachment-e mediaje."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба да користи Apple Music да би репродуковао медијске прилоге."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba da koristi Apple Music za reprodukciju medijskih priloga."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till Apple Music för att spela upp bifogade mediafiler."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji kutumia Apple Music kucheza viambatanisho vya vyombo vya habari."}},"ta":{"stringUnit":{"state":"translated","value":"Session மெடியா இணைப்புகளை விளையாட Apple Music ஐ பயன்படுத்த வேண்டும்."}},"te":{"stringUnit":{"state":"translated","value":"మీడియా అటాచ్మెంట్‌లను ప్లే చేయడానికి Session Apple Musicను ఉపయోగించాలి."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องใช้ Apple Music เพื่อเล่นไฟล์สื่อที่แนบมา"}},"tr":{"stringUnit":{"state":"translated","value":"Session, medya eklerini çalmak için Apple Music'i kullanmak zorunda."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує використовувати Apple Music для відтворення медіавкладень."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو میڈیا اٹیچمنٹ چلانے کے لیے ایپل میوزک کا استعمال کرنا ہوگا۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session media tarkiblarini ijro etish uchun Apple Music'dan foydalanishi kerak."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần sử dụng Apple Music để phát các tập tin đính kèm phương tiện."}},"xh":{"stringUnit":{"state":"translated","value":"Session kufuneka isebenzise uMculo weApple ukudlala iziphumo zemidiya."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要使用Apple Music来播放媒体附件。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要使用 Apple Music 來播放媒體附件。"}}}},"NSCameraUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het kamera toegang nodig om foto's en video's te neem, of om QR-kodes te skandeer."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى الكاميرا لالتقاط الصور ومقاطع الفيديو، أو لمسح رموز الاستجابة السريعة."}},"az":{"stringUnit":{"state":"translated","value":"Session foto və video çəkmək və ya QR kodlarını skan etmək üçün kameraya müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session کماٹ پاتبسینہ مجبورے تصاویرا و ویڈیوشاں بیہ QR سکینشہ."}},"be":{"stringUnit":{"state":"translated","value":"Session патрэбен дазвол на камеру, каб рабіць фота ці відэа альбо сканаваць QR-коды."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до камерата, за да прави снимки и видеота, или да сканира QR кодове."}},"bn":{"stringUnit":{"state":"translated","value":"ছবি ও ভিডিও করার জন্য Session এর ক্যামেরা অ্যাকসেস প্রয়োজন বা QR কোড স্ক্যান করা।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés a la càmera per fer fotografies i vídeos, o escanejar codis QR."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k fotoaparátu pro pořizování fotografií a videí nebo skenování QR kódů."}},"cy":{"stringUnit":{"state":"translated","value":"Mae angen mynediad i'r camera ar Session i dynnu lluniau a fideos, neu i sganio côd QR."}},"da":{"stringUnit":{"state":"translated","value":"Session kræver tilladelse til at tilgå dit kamera, for at kunne tage billeder eller scanne QR-koder."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt die Berechtigung »Kamera«, um Fotos oder Videos aufzunehmen oder QR-Codes zu scannen."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στην κάμερα για λήψη φωτογραφιών και βίντεο ή για σάρωση κωδικών QR."}},"en":{"stringUnit":{"state":"translated","value":"Session needs camera access to take photos and videos, or scan QR codes."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas fotilan aliron por preni fotojn kaj videojn, aŭ skani QR-kodojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso a la cámara para tomar fotos y videos, o escanear códigos QR."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso a la cámara para tomar fotos y videos, o escanear códigos QR."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab fotode ja videote salvestamiseks või QR-koodide skannimiseks kaamera juurdepääsu."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k kameraren sarbidea behar du argazkiak eta bideoak ateratzeko, edo QR kodeak eskaneatzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای گرفتن عکس‌ و ویدئو، یا اسکن کد‌های QR نیاز به دسترسی دوربین دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee kameran käyttöoikeuden kuvien ja videoiden ottamiseksi tai QR-koodien skannaamiseksi."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa camera upang kumuha ng litrato at video, o mag-scan ng mga QR code."}},"fr":{"stringUnit":{"state":"translated","value":"Session a besoin de l’autorisation Caméra pour prendre des photos ou des vidéos, ou scanner des codes QR."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita acceder á cámara para tirar fotografías e facer vídeos ou escanear códigos QR."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar kyamara don ɗaukar hotuna da bidiyo, ko duba lambobin QR."}},"he":{"stringUnit":{"state":"translated","value":"Session צריך הרשאות מצלמה כדי לצלם תצלומים או להקליט וידיאו או לסרוק קודי QR."}},"hi":{"stringUnit":{"state":"translated","value":"फ़ोटो और वीडियो लेने या क्यूआर कोड स्कैन करने के लिए Session को कैमरा एक्सेस की आवश्यकता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup kameri za snimanje fotografija i videozapisa, ili skeniranje QR kôdova."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak kamera-hozzáférésre van szüksége fotók és videók készítéséhez, illetve QR-kódok beolvasásához."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պետք է հասանելիություն տեսախցիկին՝ լուսանկարներ և տեսանյութեր անելու կամ QR կոդերը սկանավորելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses kamera untuk mengambil foto dan video, atau memindai kode QR."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso alla fotocamera per scattare foto e video, o scansionare i codici QR."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionで写真や動画を撮るには、またはQRコードをスキャンするにはカメラへのアクセスが必要です。"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება კამერის წვდომა ფოტოებისა და ვიდეოების გადასაღებად, ან QR კოდების დასანახად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការការចូលប្រើកាមេរ៉ាដើម្បីថតរូប និងវីដេអូ ឬស្កេនកូដ QR ។"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಚಿತ್ರಗಳು, ವೀಡಿಯೊಗಳು, ಅಥವಾ QR ಕೋಡ್ಗಳು ಸ್ಕ್ಯಾನ್ ಮಾಡಲು ಕ್ಯಾಮೆರಾ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 사진과 동영상을 찍거나 QR 코드를 스캔하기 위해 카메라 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بەکارهێنانی کامێرای پێویستە بۆ وەرگرتنی وێنه‌ و ڤیدیۆکان، یان ڕووپیاکانی QR codeکان."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya kamera hewce dike da ku wêneyên û vedîdarên twist bike, an QR kodên scanner bike."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa ya kkamera okutwala ebifaananyi n’ebifaananyi ebya vidiyo, oba okukebera QR codes."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງກ້ອງເພື່ອຖ່າຍຮູບແລະວິດີໂອ, ຫຼືສະແກນ QR codes."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie kameros, kad galėtumėte fotografuoti, filmuoti ar skenuoti QR kodus."}},"lv":{"stringUnit":{"state":"translated","value":"Session ir nepieciešama piekļuve kamerai, lai uzņemtu attēlus un video, vai skenētu QR kodus."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до камерата за да слика фотографии и видеа, или да скенира QR-кодови."}},"mn":{"stringUnit":{"state":"translated","value":"Session нь гэрэл зураг болон видеог авах эсвэл QR кодыг скан хийхийн тулд камерт хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses kamera untuk mengambil gambar dan video, atau mengimbas kod QR."}},"my":{"stringUnit":{"state":"translated","value":"Session က ဓါတ်ပုံတွေနဲ့ ဗီဒီယိုတွေရိုက်ဖို့၊ ဒါမှမဟုတ် QR ကုဒ်တွေ ရှာဖွေရန် အတွက် ကင်မရာသုံးစွဲခွင့် လိုအပ်ပါတယ်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger kameratilgang for å ta bilder og videoer eller skanne QR-koder."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger kameratilgang for å ta bilder og video, eller skanne QR-koder."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई फोटो र भिडियो लिन वा QR कोड स्क्यान गर्न क्यामेराको पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft toegang tot de camera nodig om foto's en video's te maken of QR-codes te scannen."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session treng tilgang til kameraet for å ta bilete eller videoar, eller skanna QR-kodar."}},"ny":{"stringUnit":{"state":"translated","value":"Session iyenera kupititsa mwayi kwa kamera kuti kutenga zithunzi ndi makanema, kapena kuwunika ma QR codes."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓਜ਼ ਲੈਣ ਜਾਂ QR ਕੋਡ ਸਕੈਨ ਕਰਨ ਲਈ ਕੈਮਰਾ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby robić zdjęcia, nagrywać filmy i skanować kody QR, aplikacja Session potrzebuje dostępu do aparatu"}},"ps":{"stringUnit":{"state":"translated","value":"Session ته اړتیا ده چې عکسونه او ویډیوګانې واخلي، یا QR کوډونه سکین کړي."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso à câmera para tirar fotos e vídeos, ou escanear códigos QR."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso à câmera para tirar fotos e vídeos, ou escanear códigos QR."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la cameră pentru a realiza poze și clipuri video sau pentru a scana coduri QR."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к камере для съемки фото, видео, а также сканирования QR-кодов."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup kameri kako bi snimio slike ili video, ili skenirao QR kodove."}},"si-LK":{"stringUnit":{"state":"translated","value":"Sessionට ඡායාරූප සහ වීඩියෝ ගැනීමට හෝ QR කේත පරිලෝකනය කිරීමට කැමරා ප්‍රවේශය අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup ku kamere na vytvárať fotografie a videá, alebo skenovanie QR kódov."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do kamere za fotografiranje in snemanje, ali skeniranje QR kod."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje përdorimi të kamerës për të bërë foto dhe video, ose për të skanuar kodet QR."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба дозволу за камеру да прави слике и видео клипове, или скенира QR кодове."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup kameri da slika fotografije i snima videe, ili skenira QR kodove."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till kameran för att kunna fotografera och filma eller skanna QR-koder."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya kamera kuchukua picha na video, au kuchanganua misimbo ya QR."}},"ta":{"stringUnit":{"state":"translated","value":"Session புகைப்படங்கள், வீடியோக்களை எடுக்க, QR குறியீடுகளை ஸ்கேன் செய்ய கேமரா அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"ఫోటోలను మరియు వీడియోలను తీసుకోవడం లేదా QR కోడ్లను స్కాన్ చేయడానికి Session కు కెమెరా యాక్సెస్ కావాలి."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงกล้องเพื่อถ่ายรูปและวิดีโอ หรือสแกนรหัส QR"}},"tr":{"stringUnit":{"state":"translated","value":"Session, fotoğraf ve video çekmek veya QR kodları taramak için kamera erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступ до камери, щоб фотографувати, знімати відео або сканувати QR-коди."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو تصاویر اور ویڈیوز لینے یا QR کوڈز اسکین کرنے کے لیے کیمرے کی اجازت درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session fotosuratlar va videolarni olish yoki QR kodlarni skanerlash uchun kameraga kirishga ruxsat talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần truy cập máy ảnh để chụp ảnh, quay video hoặc quét mã QR."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwikhamera ukuthatha iifoto nevidiyo, okanye ukukhangela iikhowudi ze-QR."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要相机权限来拍摄照片和视频,或扫描二维码。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要使用相機來拍攝照片和影片,或掃描 QR 圖碼。"}}}},"NSFaceIDUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Die skermsluitfunksie op Session gebruik Face ID."}},"ar":{"stringUnit":{"state":"translated","value":"ميزة قفل الشاشة على Session تستخدم Face ID."}},"az":{"stringUnit":{"state":"translated","value":"Session tətbiqinin ekran kilidi özəlliyi Face ID istifadə edir."}},"bal":{"stringUnit":{"state":"translated","value":"Session رو پیلناکردگ لاگو کردانت پاس ID."}},"be":{"stringUnit":{"state":"translated","value":"Функцыя блакіроўкі экрана ў Session выкарыстоўвае Face ID."}},"bg":{"stringUnit":{"state":"translated","value":"Функцията за заключване на екрана в Session използва Face ID."}},"bn":{"stringUnit":{"state":"translated","value":"Session এর স্ক্রিন লক ফিচারটি ফেস আইডি ব্যবহৃত হয়।"}},"ca":{"stringUnit":{"state":"translated","value":"La funció de bloqueig de pantalla en Session utilitza Face ID."}},"cs":{"stringUnit":{"state":"translated","value":"Funkce zamčení obrazovky Session používá Face ID."}},"cy":{"stringUnit":{"state":"translated","value":"Mae'r nodwedd cloi sgrin ar Session yn defnyddio ID Wyneb."}},"da":{"stringUnit":{"state":"translated","value":"Skærmlåsfunktionen på Session bruger Face ID."}},"de":{"stringUnit":{"state":"translated","value":"Die Bildschirmsperrfunktion von Session verwendet Face ID."}},"el":{"stringUnit":{"state":"translated","value":"Η λειτουργία κλειδώματος οθόνης στο Session χρησιμοποιεί το Face ID."}},"en":{"stringUnit":{"state":"translated","value":"The screen lock feature on Session uses Face ID."}},"eo":{"stringUnit":{"state":"translated","value":"La ŝlosila ekrano en Session uzas Vizaĝo-ID."}},"es-419":{"stringUnit":{"state":"translated","value":"La función de pantalla bloqueada en Session usa Face ID."}},"es-ES":{"stringUnit":{"state":"translated","value":"La función de bloqueo de pantalla en Session usa Face ID."}},"et":{"stringUnit":{"state":"translated","value":"Session ekraaniluku funktsioon kasutab Face ID-d."}},"eu":{"stringUnit":{"state":"translated","value":"Session-ko pantaila blokeatzearen funtzioak Face ID erabiltzen du."}},"fa":{"stringUnit":{"state":"translated","value":"ویژگی قفل صفحه در Session از Face ID استفاده می‌کند."}},"fi":{"stringUnit":{"state":"translated","value":"Näytön lukitusominaisuus Session käyttää Face ID:tä."}},"fil":{"stringUnit":{"state":"translated","value":"Ang screen lock feature ng Session ay gumagamit ng Face ID."}},"fr":{"stringUnit":{"state":"translated","value":"La fonctionnalité de verrouillage d'écran sur Session utilise Face ID."}},"gl":{"stringUnit":{"state":"translated","value":"A funcionalidade de bloqueo de pantalla en Session usa Face ID."}},"ha":{"stringUnit":{"state":"translated","value":"Tsarin kulle allo akan Session yana amfani da Face ID."}},"he":{"stringUnit":{"state":"translated","value":"תכונת נעילת המסך ב-Session משתמשת בזיהוי פנים."}},"hi":{"stringUnit":{"state":"translated","value":"Session पर स्क्रीन लॉक फीचर Face ID का उपयोग करता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Funkcija zaključavanja zaslona na Session koristi Face ID."}},"hu":{"stringUnit":{"state":"translated","value":"A Session képernyőzár funkciója Face ID-t használ."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ի էկրանային կողպման հատկությունը օգտագործում է Face ID:"}},"id":{"stringUnit":{"state":"translated","value":"Fitur kunci layar pada Session menggunakan Face ID."}},"it":{"stringUnit":{"state":"translated","value":"La funzione di blocco schermo su Session usa il Face ID."}},"ja":{"stringUnit":{"state":"translated","value":"Session の画面ロック機能はFace IDを使用します。"}},"ka":{"stringUnit":{"state":"translated","value":"ეკრანის დაბლოკვის ფუნქცია Session-ზე იყენებს Face ID-ს"}},"km":{"stringUnit":{"state":"translated","value":"The screen lock feature on Session uses Face ID."}},"kn":{"stringUnit":{"state":"translated","value":"Session ನ ತರ್ಣ್ ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯವು ಫೇಸ್ ಐಡಿ ಅನ್ನು ಬಳಸುತ್ತದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session의 화면 잠금 기능은 Face ID를 사용합니다."}},"ku":{"stringUnit":{"state":"translated","value":"فەرمۆن جێگیرکردنی تابلەکردنی سکرین ناستەوەی Session پێی ئەنجامدەدرێت."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Taybetmendiya serrnderkî ya Session bi Face ID bicîh dike."}},"lg":{"stringUnit":{"state":"translated","value":"Enkozesa y'ekiwandiiko k'amaaso ekiriko Session ekosa Face ID."}},"lt":{"stringUnit":{"state":"translated","value":"Ekrano užraktas Session naudoja Face ID."}},"lv":{"stringUnit":{"state":"translated","value":"Ekrāna bloķēšanas funkcija lietotnē Session izmanto Face ID."}},"mk":{"stringUnit":{"state":"translated","value":"Функцијата за заклучување екранот во Session користи Face ID."}},"mn":{"stringUnit":{"state":"translated","value":"Session дэлгэц түгжихэд Face ID ашиглана."}},"ms":{"stringUnit":{"state":"translated","value":"Ciri kunci skrin pada Session menggunakan Face ID."}},"my":{"stringUnit":{"state":"translated","value":"Session တွင် အမ်ကာ မျက်နှာ မြင်စနစ် लॉग इन ၏ လုံခြုံစေသည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Skjermlåsfunksjonen på Session bruker Face ID."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Skjermlåsfunksjonen på Session bruker Face ID."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Sessionको स्क्रिन लक विशेषताले Face ID प्रयोग गर्छ।"}},"nl":{"stringUnit":{"state":"translated","value":"De vergrendelfunctie op Session gebruikt Face ID."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Skjermlåsfunksjonen på Session bruker Face ID."}},"ny":{"stringUnit":{"state":"translated","value":"Ntchito yotseka chinsalu pa Session imagwiritsa ntchito Face ID."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਉੱਤੇ ਸਕرين ਲਾਕ ਫੀਚਰ Face ID ਵਰਤਦਾ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Funkcja blokady ekranu w aplikacji Session używa Face ID."}},"ps":{"stringUnit":{"state":"translated","value":"د Session سکرین لاک فیچر د مخ پيژندنه (Face ID) کاروي."}},"pt-BR":{"stringUnit":{"state":"translated","value":"A funcionalidade de bloqueio de tela no Session usa reconhecimento facial."}},"pt-PT":{"stringUnit":{"state":"translated","value":"A funcionalidade de bloqueio de ecrã Session usa Face ID."}},"ro":{"stringUnit":{"state":"translated","value":"Funcția de blocare a ecranului din Session folosește Face ID."}},"ru":{"stringUnit":{"state":"translated","value":"Функция блокировки экрана в Session использует Face ID."}},"sh":{"stringUnit":{"state":"translated","value":"Značajka zaključavanja ekrana na Session koristi Face ID."}},"si-LK":{"stringUnit":{"state":"translated","value":"Session මත තිර අගුළු විශේෂාංගය Face ID භාවිතා කරයි."}},"sk":{"stringUnit":{"state":"translated","value":"Funkcia zámku obrazovky na Session používa Face ID."}},"sl":{"stringUnit":{"state":"translated","value":"Funkcija zaklepanja zaslona na Session uporablja Face ID."}},"sq":{"stringUnit":{"state":"translated","value":"Veçoria e mbylljes së ekranit në Session përdor Face ID."}},"sr":{"stringUnit":{"state":"translated","value":"Функција закључавања екрана на Session користи Face ID."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Funkcija zaključavanja ekrana na Session koristi Face ID."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Skärmlåsfunktionen på Session använder Face ID."}},"sw":{"stringUnit":{"state":"translated","value":"Kipengele cha kufuli skrini kwenye Session kinatumia Face ID."}},"ta":{"stringUnit":{"state":"translated","value":"Session இல் திரை பூட்டு அம்சம் முக அடையாளத்தை பயன்படுத்துகிறது."}},"te":{"stringUnit":{"state":"translated","value":"Sessionలో స్క్రీన్ లాక్ ఫీచర్ ఫేస్ ఐడి నీ ఉపయోగిస్తుంది."}},"th":{"stringUnit":{"state":"translated","value":"ฟีเจอร์ล็อกหน้าจอใน Session ใช้ Face ID"}},"tr":{"stringUnit":{"state":"translated","value":"Session ekran kilidi özelliği Face ID kullanır."}},"uk":{"stringUnit":{"state":"translated","value":"Функція блокування екрана в Session використовує Face ID."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session پر سکرین لاک خصوصیت Face ID کا استعمال کرتی ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session dagi ekran blokirovkasi funksiyasi Face ID dan foydalanadi."}},"vi":{"stringUnit":{"state":"translated","value":"Tính năng khóa màn hình trên Session sử dụng Face ID."}},"xh":{"stringUnit":{"state":"translated","value":"Umsebenzi wokutshixa isikrini kwi-Session usebenzisa i-Face ID."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session的屏幕锁功能使用 Face ID。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 上的螢幕鎖功能使用 Face ID。"}}}},"NSHumanReadableCopyright":{"comment":"Copyright (human-readable)","extractionState":"extracted_with_value","localizations":{"en":{"stringUnit":{"state":"new","value":"com.loki-project.loki-messenger"}}}},"NSMicrophoneUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het mikrofoon toegang nodig om oproepe te maak en oudioboodskappe op te neem."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى الميكروفون لإجراء المكالمات وتسجيل الرسائل الصوتية."}},"az":{"stringUnit":{"state":"translated","value":"Session zəng etmək və səsli mesajlar yazmaq üçün mikrofona müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session مایکروفون پاتبسینہ حاصل نودہ کلمات پیغامشین زانت"}},"be":{"stringUnit":{"state":"translated","value":"Session патрэбен доступ да мікрафона, каб здзяйсняць званкі і запісваць аўдыя паведамленні."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до микрофона, за да осъществява обаждания и записва аудио съобщения."}},"bn":{"stringUnit":{"state":"translated","value":"কল করার জন্য এবং অডিও মেসেজ রেকর্ড করার জন্য Session এর মাইক্রোফোন অ্যাকসেস প্রয়োজন।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés al micròfon per fer trucades i gravar missatges d'àudio."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k mikrofonu pro volání a nahrávání zvukových zpráv."}},"cy":{"stringUnit":{"state":"translated","value":"Mae Session angen mynediad i'r meicroffon i wneud galwadau a recordio negeseuon sain."}},"da":{"stringUnit":{"state":"translated","value":"Session kræver mikrofonadgang for at foretage opkald og optage lydmeddelelser."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt Mikrofonzugriff, um Anrufe zu tätigen und Audionachrichten aufzuzeichnen."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στο μικρόφωνο για την αποστολή ηχητικών μηνυμάτων."}},"en":{"stringUnit":{"state":"translated","value":"Session needs microphone access to make calls and record audio messages."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas mikrofonan aliron por fari vokojn kaj registri aŭdajn mesaĝojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso al micrófono para hacer llamadas y grabar mensajes de audio."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso al micrófono para hacer llamadas y grabar mensajes de audio."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab mikrofoni juurdepääsu, et teha kõnesid ja salvestada helisõnumeid."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k mikrofonoaren sarbidea behar du deiak egiteko eta audio mezuak grabatzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای برقراری تماس و ضبط پیام‌های صوتی نیاز به دسترسی میکروفن دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee mikrofonin käyttöoikeuden puheluiden soittamiseen ja ääniviestien nauhoittamiseen."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa mikropono upang tumawag at mag-record ng mga mensaheng audio."}},"fr":{"stringUnit":{"state":"translated","value":"Session a besoin de l’accès au microphone pour passer des appels et enregistrer des messages audio."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita acceder ao micrófono para facer chamadas e gravar mensaxes de audio."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar makirufo don yin kira da rikodin saƙonnin murya."}},"he":{"stringUnit":{"state":"translated","value":"Session צריך הרשאת מיקרופון לשיחות ולהודעות שמע."}},"hi":{"stringUnit":{"state":"translated","value":"कॉल करने और ऑडियो संदेश रिकॉर्ड करने के लिए Session को माइक्रोफोन एक्सेस की आवश्यकता है।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup mikrofonu za obavljanje poziva i snimanje audio poruka."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak mikrofon-hozzáférésre van szüksége hívások bonyolítására és hangüzeneteket rögzítésére."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պահանջում է խոսափողին հասանելիություն զանգեր կատարելու և ձայնային հաղորդագրություններ արձանագրելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses mikrofon untuk melakukan panggilan dan merekam pesan audio."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso al microfono per effettuare chiamate e registrare messaggi audio."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionで通話をかけたり、音声メッセージを録音するにはマイクへのアクセスが必要です。"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება მიკროფონის წვდომა ზარების შესასრულებლად და აუდიო შეტყობინებების ჩასაწერად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការវិស្សមន្តងសម្រាប់ដាក់ស្នើរ និងថតសារ​សំឡេង។"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಕಾಲ್‌ಗಳು ಮಾಡಲು ಮತ್ತು ಆಡಿಯೊ ಸಂದೇಶಗಳನ್ನು ದಾಖಲು ಮಾಡಲು ಮೈಕ್ರೊಫೋನ್ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 통화를 하고 음성 메시지를 녹음하기 위해 마이크 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session دەتوانێت بەکارهێنانی داده‌یەکیی وەکو پەیوەستەکان بکات بۆ پەیوەندیش"}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya mîkrofon hewce dike da ku lêgerîn bike û peyman dengî record bike."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa ya mmikirofono okukola eyitibwamu n’okuwandiika obubaka obuweereze."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງໄມໂຄໂຟນເພື່ອໂທແລະບັນທຶກເສັຽງຂໍ້ຄວາມສຽງ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie mikrofono, kad galėtumėte skambinti ir įrašinėti garso žinutes."}},"lv":{"stringUnit":{"state":"translated","value":"Session ir nepieciešama piekļuve mikrofonam, lai veiktu zvanus un ierakstītu audio ziņas."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до микрофонот за да врши повици и снима аудио пораки."}},"mn":{"stringUnit":{"state":"translated","value":"Session дуудлага хийх болон аудио мессеж бичихийн тулд микрофоны хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses mikrofon untuk membuat panggilan dan merakam mesej audio."}},"my":{"stringUnit":{"state":"translated","value":"Session မှ ဖုန်းခေါ်ဆိုမှုများနှင့် အသံမက်ဆေ့များကို မှတ်တမ်းတင်ရန် မိုက်ခရိုဖုန်းအသုံးပြုခွင့် လိုအပ်ပါတယ်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger mikrofontilgang for å ringe og spille inn lydmeldinger."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger mikrofontilgang for å foreta samtaler og ta opp lydmeldinger."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई कल गर्न र अडियो सन्देशहरू रेकर्ड गर्न माइक्रोफोनको पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft toegang tot de microfoon nodig om audioberichten op te nemen."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger mikrofontilgang for å ringe og ta opp lydmeldinger."}},"ny":{"stringUnit":{"state":"translated","value":"Session iyenera kuitanira microphone kuti ipangane mafoni ndi kujambula mauthenga am'mawu."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਕਾਲਾ ਕਰਣ ਅਤੇ ਆਡੀਓ ਸੁਨੇਹੇ ਰਿਕਾਰਡ ਕਰਨ ਲਈ ਮਾਈਕਰੋਫੋਨ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby wykonywać połączenia i nagrywać wiadomości audio, aplikacja Session potrzebuje dostępu do mikrofonu."}},"ps":{"stringUnit":{"state":"translated","value":"Session د غږیزو پیغامونو لیږلو کولو لپاره مایکروفون ته اړتیا لري."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao microfone para fazer chamadas e gravar mensagens de áudio."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao microfone para fazer chamadas e gravar mensagens de áudio."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la microfon pentru a efectua apeluri și a înregistra mesaje audio."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к микрофону для совершения звонков и записи голосовых сообщений."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup mikrofonu za obavljanje poziva i snimanje audio poruka."}},"si-LK":{"stringUnit":{"state":"translated","value":"ඇමතුම් ලබා දීම සහ ශ්‍රව්‍ය පණිවිඩ පටිගත කිරීම සඳහා Sessionට මයික්‍රෆෝන ප්‍රවේශය අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup k mikrofónu na uskutočnenie hovorov a nahranie zvukových správ."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do mikrofona za klice in snemanje zvočnih sporočil."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje përdorimi të mikrofonit për të bërë thirrje dhe për të regjistruar mesazhe audio."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба дозволу за микрофон да би обављао позиве и снимао аудио поруке."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup mikrofonu da bi obavljao pozive i snimao audio poruke."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver mikrofonåtkomst för att ringa och spela in ljudmeddelanden."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya kipaza sauti kupiga simu na kurekodi ujumbe wa sauti."}},"ta":{"stringUnit":{"state":"translated","value":"Session அழைப்புகளை செய்ய மற்றும் ஆடியோ தகவல்களை பதிவு செய்ய மைக்ரோஃபோன் அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"కాల్ చేయడానికి మరియు ఆడియో సందేశాలను రికార్డ్ చేయడానికి Session మైక్రోఫోన్ యాక్సెస్ అవసరం."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงไมโครโฟนเพื่อโทรและบันทึกข้อความเสียง"}},"tr":{"stringUnit":{"state":"translated","value":"Session, arama yapmak ve sesli ileti kaydetmek için mikrofon erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступу до мікрофона для здійснення дзвінків та запису голосових повідомлень."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو کال کرنے اور آڈیو پیغامات ریکارڈ کرنے کے لیے مائیکروفون تک رسائی درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session qo'ng'iroqlar va audio xabarlarni yozish uchun mikrofonga kirishga ruxsat talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần quyền truy cập microphone để gọi điện và ghi âm tin nhắn thoại."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwisixhobo somculo wokwenza iminxeba kunye nokurekhoda imiyalezo yesandi."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要麦克风访问权限来进行语音通话及录制语音消息。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要麥克風存取權來語音通話和錄製語音訊息。"}}}},"NSPhotoLibraryAddUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het berging toegang nodig om aanhegsels en media te stoor."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى التخزين لحفظ المرفقات والوسائط."}},"az":{"stringUnit":{"state":"translated","value":"Session qoşmaları və medianı saxlamaq üçün anbara müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session ذخیرہ پاتبسینہ محفوظ عریض او ذرہے"}},"be":{"stringUnit":{"state":"translated","value":"Session патрабуе дазволу да сховішча каб захоўваць ўкладанні і медыя."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до хранилището, за да запазва прикачени файлове и медия."}},"bn":{"stringUnit":{"state":"translated","value":"সংযুক্তি এবং মিডিয়া সংরক্ষণ করতে Session এর স্টোরেজ অ্যাকসেস প্রয়োজন।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés a l'emmagatzematge per desar els fitxers adjunts i els suports."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k úložišti pro ukládání příloh a médií."}},"cy":{"stringUnit":{"state":"translated","value":"Mae Session angen mynediad i storio i gadw atodiadau a chyfryngau."}},"da":{"stringUnit":{"state":"translated","value":"Session skal have lageradgang for at gemme vedhæftninger og mediefiler."}},"de":{"stringUnit":{"state":"translated","value":"Session benötigt Speicherzugriff, um Anhänge und Medien zu speichern."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για να αποθηκεύσει συνημμένα και πολυμέσα."}},"en":{"stringUnit":{"state":"translated","value":"Session needs storage access to save attachments and media."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas aliron al memoro por konservi aldonaĵojn kaj aŭdvidaĵojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso al almacenamiento para guardar adjuntos y multimedia."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso de almacenamiento para guardar archivos adjuntos y medios."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab salvestusruumi ligipääsu, et salvestada manuseid ja meediat."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k biltegirako sarbidea behar du eranskinak eta hedabideak gordetzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای ذخیره پیوست‌ها و رسانه‌ها نیاز به دسترسی به حافظه دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee tallennustilan käyttöoikeuden liitteiden ja median tallentamiseksi."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa storage upang mag-save ng mga attachment at media."}},"fr":{"stringUnit":{"state":"translated","value":"Session doit accéder au stockage pour enregistrer les pièces jointes et les médias."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita permiso para acceder ao almacenamento para gardar anexos e medios."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar ajiya don adana abubuwan haɗe-haɗe da kafofin watsa labarai."}},"he":{"stringUnit":{"state":"translated","value":"Session זקוק לגישה לאחסון כדי לשמור צרופות ומדיה."}},"hi":{"stringUnit":{"state":"translated","value":"Session को अनुलग्नक और मीडिया को सहेजने के लिए संग्रहण पहुंच चाहिए।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup memoriji za spremanje privitaka i medija."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak tárhely-hozzáférésre van szüksége a mellékletek és médiák mentéséhez."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պահանջում է պահեստային հասանելիություն կցորդներն ու մեդիան պահպանելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses penyimpanan untuk menyimpan lampiran dan media."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso allo storage per salvare allegati e media."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionは添付ファイルやメディアを保存するためにストレージへのアクセスが必要です。"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება მეხსიერების წვდომა მიმაგრებული ფაილებისა და მედიების შესანახად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការចូលប្រើវើសកម្មដើម្បីរក្សាទុកឯកសារ និងមេឌៀ។"}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಅಟ್ಯಾಚ್ಮೆಂಟ್‌ಗಳು ಮತ್ತು ಮಾಧ್ಯಮವನ್ನು ಉಳಿಸಲು ಸಂಗ್ರಹಣೆಯ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 첨부 파일과 미디어를 저장하기 위해 저장 공간 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بەکارهێنانی خزینەی فایل بۆ هەڵگرتنی پەیوەستەکان و میدیا ناردن"}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya hilkişina xelasî û medyayê hewce dike."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa y’obusobozi okusigala ekwatibwako aammaamu n’emikutu."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງຟາຍເພື່ອບັນທຶກຢາງແລະວິດີໂອ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie saugyklos, kad galėtų įrašyti priedus ir mediją."}},"lv":{"stringUnit":{"state":"translated","value":"Session ir nepieciešama pieeja glabātuve failu un multimediju saglabāšanai."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до складиштето за да зачува прилози и медиуми."}},"mn":{"stringUnit":{"state":"translated","value":"Session нь хавсралт болон медиа хадгалахын тулд сангийн хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses storan untuk menyimpan lampiran dan media."}},"my":{"stringUnit":{"state":"translated","value":"Session သည် ပူးတွဲချက်များနှင့် မီဒီယာကို သိမ်းဆည်းရန် သိုလှောင်မှုခွင့်ပြုချက်လိုအပ်ပါသည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å lagre vedlegg og media."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å lagre vedlegg og media."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई अट्याचमेन्ट र मिडिया सेभ गर्न स्टोरज पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft opslagtoegang nodig om bijlagen en media op te slaan."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å lagre vedlegg og media."}},"ny":{"stringUnit":{"state":"translated","value":"Session imafuna mwayi wosungira kuti asunge attachments ndi media."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਅਟੈਚਮੈਂਟਸ ਅਤੇ ਮੀਡੀਆ ਸੰਭਾਲਣ ਲਈ ਸਟੋਰੇਜ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby zapisywać załączniki i multimedia, aplikacja Session potrzebuje dostępu do pamięci."}},"ps":{"stringUnit":{"state":"translated","value":"Session پیوستونونو او میډیا خوندي کولو لپاره ذخیره کولو ته اړتیا لري."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao armazenamento para salvar anexos e mídias."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao armazenamento para salvar anexos e mídia."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la spațiul de stocare pentru a salva atașamente și media."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к хранилищу для сохранения вложений и медиафайлов."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup pohrani za spremanje privitaka i medija."}},"si-LK":{"stringUnit":{"state":"translated","value":"ඇමුණුම් සහ මාධ්‍ය සුරැකීම සඳහා Sessionට ගබඩා ප්‍රවේශය අවශ්‍යවේ."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup k úložisku na uloženie príloh a médií."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do shrambe za shranjevanje prilog in medijev."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje të hapësirës ruajtëse për të ruajtur attachment-et dhe median."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба приступ складишту да сачува прилоге и медије."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup skladištu da sačuva priloge i medije."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till lagringsutrymmet för att kunna spara bifogade filer och media."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya hifadhi ili kuhifadhi viambatanisho na vyombo vya habari."}},"ta":{"stringUnit":{"state":"translated","value":"Session இணைப்புகள் மற்றும் மெடியாவை சேமிக்க சேமிப்பக அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"అటాచ్మెంట్‌లు మరియు మీడియాను సేవ్ చేయడానికి Session కు నిల్వ యాక్సెస్ అవసరం."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงที่เก็บข้อมูลเพื่อบันทึกไฟล์แนบและสื่อ"}},"tr":{"stringUnit":{"state":"translated","value":"Session, ekleri ve medyayı kaydetmek için depolama erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступу до сховища для збереження вкладень та медіа."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو منسلکات اور میڈیا محفوظ کرنے کے لیے اسٹوریج کی اجازت درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session fayl va media tarkiblarini saqlash uchun saqlashga kirishni talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần quyền truy cập lưu trữ để lưu các tập tin đính kèm và phương tiện."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwindawo yokugcina ukuthumela iziphumo kunye nemidiya."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要存储权限来保存附件和媒体。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要存儲權限以保存附件和媒體。"}}}},"NSPhotoLibraryUsageDescription":{"extractionState":"manual","localizations":{"af":{"stringUnit":{"state":"translated","value":"Session het berging toegang nodig om foto's en video's te stuur."}},"ar":{"stringUnit":{"state":"translated","value":"Session يحتاج إذن الوصول إلى التخزين لإرسال الصور ومقاطع الفيديو."}},"az":{"stringUnit":{"state":"translated","value":"Session foto və videoları göndərmək üçün anbara müraciət etməlidir."}},"bal":{"stringUnit":{"state":"translated","value":"Session ذخیرہ پاتبسینہ بھیجنے تصویریں دکنیں"}},"be":{"stringUnit":{"state":"translated","value":"Session патрабуе дазволу да сховішча каб дасылаць фота і відэа."}},"bg":{"stringUnit":{"state":"translated","value":"Session се нуждае от достъп до хранилището, за да изпраща снимки и видеота."}},"bn":{"stringUnit":{"state":"translated","value":"ছবি এবং ভিডিও প্রেরণ করতে Session এর স্টোরেজ অ্যাকসেস প্রয়োজন।"}},"ca":{"stringUnit":{"state":"translated","value":"Session necessita accés a l'emmagatzematge per enviar fotografies i vídeos."}},"cs":{"stringUnit":{"state":"translated","value":"Session potřebuje přístup k úložišti pro odesílání fotografií a videí."}},"cy":{"stringUnit":{"state":"translated","value":"Mae Session angen mynediad i storio i anfon lluniau a fideos."}},"da":{"stringUnit":{"state":"translated","value":"Session har brug for lageradgang for at sende billeder og videoer."}},"de":{"stringUnit":{"state":"translated","value":"Session Benötigt Speicherzugriff, um Fotos und Videos zu senden."}},"el":{"stringUnit":{"state":"translated","value":"Το Session χρειάζεται πρόσβαση στον αποθηκευτικό χώρο για την αποστολή φωτογραφιών και βίντεο."}},"en":{"stringUnit":{"state":"translated","value":"Session needs storage access to send photos and videos."}},"eo":{"stringUnit":{"state":"translated","value":"Session bezonas aliron al memoro por sendi bildojn kaj videojn."}},"es-419":{"stringUnit":{"state":"translated","value":"Session necesita acceso al almacenamiento para enviar fotos y videos."}},"es-ES":{"stringUnit":{"state":"translated","value":"Session necesita acceso de almacenamiento para enviar fotos y videos."}},"et":{"stringUnit":{"state":"translated","value":"Session vajab fotode ja videote saatmiseks juurdepääsu salvestusruumile."}},"eu":{"stringUnit":{"state":"translated","value":"Session(e)k biltegirako sarbidea behar du argazkiak eta bideoak bidaltzeko."}},"fa":{"stringUnit":{"state":"translated","value":"Session برای ارسال عکس‌ها و ویدئو‌ها نیاز به دسترسی حافظه دارد."}},"fi":{"stringUnit":{"state":"translated","value":"Session tarvitsee tallennustilan käyttöoikeuden kuvien ja videoiden lähettämiseksi."}},"fil":{"stringUnit":{"state":"translated","value":"Ang Session ay nangangailangan ng access sa storage upang magpadala ng mga litrato at video."}},"fr":{"stringUnit":{"state":"translated","value":"Session a besoin d'un accès au stockage pour envoyer des photos et des vidéos."}},"gl":{"stringUnit":{"state":"translated","value":"Session necesita permiso para acceder ao almacenamento para enviar fotos e vídeos."}},"ha":{"stringUnit":{"state":"translated","value":"Session yana buƙatar samun damar ajiya don aikawa da hotuna da bidiyo."}},"he":{"stringUnit":{"state":"translated","value":"Session צריך הרשאות גישה לאחסון על מנת לשלוח תמונות ווידיאו."}},"hi":{"stringUnit":{"state":"translated","value":"Session को फ़ोटो और वीडियो भेजने के लिए संग्रहण पहुंच चाहिए।"}},"hr":{"stringUnit":{"state":"translated","value":"Session treba pristup memoriji za slanje fotografija i videozapisa."}},"hu":{"stringUnit":{"state":"translated","value":"Session alkalmazásnak tárhely-hozzáférésre van szüksége a fotók és videók elküldéséhez."}},"hy-AM":{"stringUnit":{"state":"translated","value":"Session-ը պահանջում է պահեստային հասանելիություն՝ լուսանկարներ և տեսանյութեր ուղարկելու համար։"}},"id":{"stringUnit":{"state":"translated","value":"Session membutuhkan akses penyimpanan untuk mengirim foto dan video."}},"it":{"stringUnit":{"state":"translated","value":"Session richiede l'accesso all'archiviazione per inviare foto e video."}},"ja":{"stringUnit":{"state":"translated","value":"Sessionは写真や動画を送信するためにストレージへのアクセスが必要です"}},"ka":{"stringUnit":{"state":"translated","value":"Session-ს სჭირდება მეხსიერების წვდომა ფოტოებისა და ვიდეოების გასაგზავნად."}},"km":{"stringUnit":{"state":"translated","value":"Session ត្រូវការភ្ជាប់អង្គរក្សាទុកដើម្បីផ្ញើរូបទិញនិងវីដេអូ."}},"kn":{"stringUnit":{"state":"translated","value":"Session ಗೆ ಚಿತ್ರಗಳು ಮತ್ತು ವೀಡಿಯೊಗಳನ್ನು ಕಳುಹಿಸಲು ಸಂಗ್ರಹಣೆಯ ಪ್ರವೇಶದ ಅಗತ್ಯವಿದೆ."}},"ko":{"stringUnit":{"state":"translated","value":"Session은 사진과 동영상을 전송하기 위해 저장공간 접근이 필요합니다."}},"ku":{"stringUnit":{"state":"translated","value":"Session پێویستە بەکارهێنانی خزینە بۆ ناردنی وێنە و ڤیدیۆکان."}},"ku-TR":{"stringUnit":{"state":"translated","value":"Session permiya hilkişina wêneyên û vedîdarên bişîne."}},"lg":{"stringUnit":{"state":"translated","value":"Session yeetaaga ssensa y’obusobozi okutuma ebifaananyi n’ebifaananyi ebya vidiyo."}},"lo":{"stringUnit":{"state":"translated","value":"Session ຕ້ອງການເຂົ້າເຖິງຟາຍເພື່ອສົ່ງຮູບແລະວິດີໂອ."}},"lt":{"stringUnit":{"state":"translated","value":"Session reikia prieigos prie saugyklos norint siųsti nuotraukas ir vaizdo įrašus."}},"lv":{"stringUnit":{"state":"translated","value":"Session vajag pieeju failiem, lai sūtītu atēlus un video."}},"mk":{"stringUnit":{"state":"translated","value":"Session има потреба од пристап до складиштето за да испраќа фотографии и видеа."}},"mn":{"stringUnit":{"state":"translated","value":"Session зураг болон видеонуудыг илгээхийн тулд сангийн хандалт хэрэгтэй."}},"ms":{"stringUnit":{"state":"translated","value":"Session memerlukan akses storan untuk menghantar foto dan video."}},"my":{"stringUnit":{"state":"translated","value":"Session သည် ဓာတ်ပုံများနှင့် ဗွီဒီယိုများ ပို့ရန် သိမ်းဆည်းမှုပုံစံခွင့်လိုအပ်သည်။"}},"nb":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å sende bilder og videoer."}},"nb-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å sende bilder og videoer."}},"ne-NP":{"stringUnit":{"state":"translated","value":"Session लाई फोटो र भिडियोहरू पठाउन स्टोरज पहुँच आवश्यक छ।"}},"nl":{"stringUnit":{"state":"translated","value":"Session heeft toegang nodig tot de opslag om foto's en video's te kunnen verzenden."}},"nn-NO":{"stringUnit":{"state":"translated","value":"Session trenger lagringstilgang for å sende bilete og videoar."}},"ny":{"stringUnit":{"state":"translated","value":"Session imafuna mwayi wosungira kuti atumize zithunzi ndi makanema."}},"pa-IN":{"stringUnit":{"state":"translated","value":"Session ਨੂੰ ਫੋਟੋਆਂ ਅਤੇ ਵੀਡੀਓਜ਼ ਭੇਜਣ ਲਈ ਸਟੋਰੇਜ ਪਹੁੰਚ ਦੀ ਲੋੜ ਹੈ।"}},"pl":{"stringUnit":{"state":"translated","value":"Aby wysyłać zdjęcia i filmy, aplikacja Session potrzebuje dostępu do pamięci."}},"ps":{"stringUnit":{"state":"translated","value":"Session عکسونه او ویډیوګانې لیږلو لپاره ذخیره کولو ته اړتیا لري."}},"pt-BR":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao seu armazenamento para enviar fotos e vídeos."}},"pt-PT":{"stringUnit":{"state":"translated","value":"Session precisa de acesso ao armazenamento para enviar fotos e vídeos."}},"ro":{"stringUnit":{"state":"translated","value":"Session are nevoie de acces la spațiul de stocare pentru a trimite poze și clipuri video."}},"ru":{"stringUnit":{"state":"translated","value":"Session требуется доступ к хранилищу для отправки фотографий и видео."}},"sh":{"stringUnit":{"state":"translated","value":"Session treba pristup pohrani za slanje slika i videa."}},"si-LK":{"stringUnit":{"state":"translated","value":"ඡායාරූප සහ වීඩියෝ යැවීමට Sessionට ගබඩා ප්‍රවේශය අවශ්‍යයි."}},"sk":{"stringUnit":{"state":"translated","value":"Session potrebuje prístup na disk na posielanie fotiek a videí."}},"sl":{"stringUnit":{"state":"translated","value":"Session potrebuje dostop do shrambe za pošiljanje fotografij in videoposnetkov."}},"sq":{"stringUnit":{"state":"translated","value":"Session ka nevojë për leje të hapësirës ruajtëse për të dërguar foto dhe video."}},"sr":{"stringUnit":{"state":"translated","value":"Session треба дозволу за складиште да шаље слике и видео клипове."}},"sr-Latn":{"stringUnit":{"state":"translated","value":"Session treba pristup skladištu da šalje fotografije i videe."}},"sv-SE":{"stringUnit":{"state":"translated","value":"Session behöver åtkomst till lagringsutrymmet för att kunna skicka foton och filmer."}},"sw":{"stringUnit":{"state":"translated","value":"Session inahitaji ruhusa ya kuhifadhi ili kutuma picha na video."}},"ta":{"stringUnit":{"state":"translated","value":"Session புகைப்படங்கள் மற்றும் வீடியோக்களை அனுப்ப சேமிப்பக அணுகல் தேவை."}},"te":{"stringUnit":{"state":"translated","value":"ఫోటోలు మరియు వీడియోలను పంపడానికి Session కు నిల్వ యాక్సెస్ అవసరం."}},"th":{"stringUnit":{"state":"translated","value":"Session ต้องได้รับอนุญาตให้เข้าถึงที่เก็บข้อมูลเพื่อส่งรูปภาพและวิดีโอ"}},"tr":{"stringUnit":{"state":"translated","value":"Session, fotoğraf ve video göndermek için depolama erişimine ihtiyaç duyar."}},"uk":{"stringUnit":{"state":"translated","value":"Session потребує доступу до сховища для відправлення фотографій та відео."}},"ur-IN":{"stringUnit":{"state":"translated","value":"Session کو تصاویر اور ویڈیوز بھیجنے کے لیے اسٹوریج کی اجازت درکار ہے۔"}},"uz":{"stringUnit":{"state":"translated","value":"Session fotosuratlar va videolarni yuborish uchun saqlashga kirishni talab qiladi."}},"vi":{"stringUnit":{"state":"translated","value":"Session cần quyền truy cập lưu trữ để gửi ảnh và video."}},"xh":{"stringUnit":{"state":"translated","value":"Session ifuna ukufikelela kwindawo yokugcina ukuthumela iifoto nevidiyo."}},"zh-CN":{"stringUnit":{"state":"translated","value":"Session需要存储权限以取用及发送照片或视频。"}},"zh-TW":{"stringUnit":{"state":"translated","value":"Session 需要存儲權限來發送照片和影片。"}}}}},"version":"1.0"} \ No newline at end of file diff --git a/SessionMessagingKit/Jobs/Types/GarbageCollectionJob.swift b/SessionMessagingKit/Jobs/Types/GarbageCollectionJob.swift index 041b4c947b..5e74c2e4ec 100644 --- a/SessionMessagingKit/Jobs/Types/GarbageCollectionJob.swift +++ b/SessionMessagingKit/Jobs/Types/GarbageCollectionJob.swift @@ -344,8 +344,11 @@ public enum GarbageCollectionJob: JobExecutor { } }, completion: { _, _ in - // Dispatch async so we can swap from the write queue to a read one (we are done writing) - queue.async { + // Dispatch async so we can swap from the write queue to a read one (we are done + // writing), this has to be done after a slight delay to ensure the transaction + // provided by the completion block completes first (ie. so we don't hit + // re-entrancy issues) + queue.asyncAfter(deadline: .now() + 0.01) { // Retrieve a list of all valid attachmnet and avatar file paths struct FileInfo { let attachmentLocalRelativePaths: Set diff --git a/SessionMessagingKit/Jobs/Types/UpdateProfilePictureJob.swift b/SessionMessagingKit/Jobs/Types/UpdateProfilePictureJob.swift index 2af0e650a6..72a0f3dad2 100644 --- a/SessionMessagingKit/Jobs/Types/UpdateProfilePictureJob.swift +++ b/SessionMessagingKit/Jobs/Types/UpdateProfilePictureJob.swift @@ -50,10 +50,10 @@ public enum UpdateProfilePictureJob: JobExecutor { queue: queue, displayPictureUpdate: (profilePictureData.map { .currentUserUploadImageData($0) } ?? .none), success: { db in - // Need to call the 'success' closure asynchronously on the queue to prevent a reentrancy - // issue as it will write to the database and this closure is already called within - // another database write - queue.async { + // Need to call the 'success' closure asynchronously on the queue after a slight + // delay to prevent a reentrancy issue as it will write to the database and this + // closure is already called within another database write + queue.asyncAfter(deadline: .now() + 0.01) { SNLog("[UpdateProfilePictureJob] Profile successfully updated") success(job, false, dependencies) } diff --git a/SessionMessagingKit/Sending & Receiving/MessageSender.swift b/SessionMessagingKit/Sending & Receiving/MessageSender.swift index 67100fb465..d8b8405c6e 100644 --- a/SessionMessagingKit/Sending & Receiving/MessageSender.swift +++ b/SessionMessagingKit/Sending & Receiving/MessageSender.swift @@ -1054,9 +1054,10 @@ public final class MessageSender { guard !rowIds.isEmpty else { return error } - // Need to dispatch to a different thread to prevent a potential db re-entrancy - // issue from occuring in some cases - DispatchQueue.global(qos: .background).async { + // Note: We need to dispatch this after a small 0.01 delay to prevent any potential + // re-entrancy issues since the 'asyncMigrate' returns a result containing a DB instance + // within a transaction + DispatchQueue.global(qos: .background).asyncAfter(deadline: .now() + 0.01, using: dependencies) { dependencies.storage.write { db in switch destination { case .syncMessage: diff --git a/SessionSnodeKit/LibSession/LibSession+Networking.swift b/SessionSnodeKit/LibSession/LibSession+Networking.swift index 9038e3eb23..a658135187 100644 --- a/SessionSnodeKit/LibSession/LibSession+Networking.swift +++ b/SessionSnodeKit/LibSession/LibSession+Networking.swift @@ -574,9 +574,12 @@ private extension LibSession { return Log.error("[LibSession] CallbackWrapper called with null context.") } - // Dispatch async so we don't block libSession's internals with Swift logic (which can block other requests) + /// Dispatch async so we don't block libSession's internals with Swift logic (which can block other requests), we + /// add the `0.01` delay to ensure the closure isn't executed immediately let wrapper: CallbackWrapper = Unmanaged>.fromOpaque(ctx).takeRetainedValue() - DispatchQueue.global(qos: .default).async { [wrapper] in wrapper.resultPublisher.send(output) } + DispatchQueue.global(qos: .default).asyncAfter(deadline: .now() + 0.01) { [wrapper] in + wrapper.resultPublisher.send(output) + } } public func unsafePointer() -> UnsafeMutableRawPointer { Unmanaged.passRetained(self).toOpaque() } diff --git a/SessionUtilitiesKit/Database/Storage.swift b/SessionUtilitiesKit/Database/Storage.swift index c30897f6b6..4bd7ef0e22 100644 --- a/SessionUtilitiesKit/Database/Storage.swift +++ b/SessionUtilitiesKit/Database/Storage.swift @@ -329,9 +329,10 @@ open class Storage { } }() - // Note: We need to dispatch this to the next run toop to prevent any potential re-entrancy - // issues since the 'asyncMigrate' returns a result containing a DB instance - DispatchQueue.global(qos: .userInitiated).async { + // Note: We need to dispatch this after a small 0.01 delay to prevent any potential + // re-entrancy issues since the 'asyncMigrate' returns a result containing a DB instance + // within a transaction + DispatchQueue.global(qos: .userInitiated).asyncAfter(deadline: .now() + 0.01, using: dependencies) { migrationCompleted(finalResult) } } @@ -524,8 +525,8 @@ open class Storage { case valid(DatabaseWriter) case invalid(Error) - init(_ storage: Storage) { - switch (storage.isSuspended, storage.isValid, storage.dbWriter) { + init(_ storage: Storage?) { + switch (storage?.isSuspended, storage?.isValid, storage?.dbWriter) { case (true, _, _): self = .invalid(StorageError.databaseSuspended) case (false, true, .some(let dbWriter)): self = .valid(dbWriter) default: self = .invalid(StorageError.databaseInvalid) @@ -632,7 +633,7 @@ open class Storage { ) -> AnyPublisher { switch StorageState(self) { case .invalid(let error): return StorageState.logIfNeeded(error, isWrite: true) - case .valid(let dbWriter): + case .valid: /// **Note:** GRDB does have a `writePublisher` method but it appears to asynchronously trigger /// both the `output` and `complete` closures at the same time which causes a lot of unexpected /// behaviours (this behaviour is apparently expected but still causes a number of odd behaviours in our code @@ -642,11 +643,19 @@ open class Storage { /// which behaves in a much more expected way than the GRDB `writePublisher` does let info: CallInfo = CallInfo(fileName, functionName, lineNumber, true, self) return Deferred { - Future { resolver in - do { resolver(Result.success(try dbWriter.write(Storage.perform(info: info, updates: updates)))) } - catch { - StorageState.logIfNeeded(error, isWrite: true) - resolver(Result.failure(error)) + Future { [weak self] resolver in + /// The `StorageState` may have changed between the creation of the publisher and it actually + /// being executed so we need to check again + switch StorageState(self) { + case .invalid(let error): return StorageState.logIfNeeded(error, isWrite: true) + case .valid(let dbWriter): + do { + resolver(Result.success(try dbWriter.write(Storage.perform(info: info, updates: updates)))) + } + catch { + StorageState.logIfNeeded(error, isWrite: true) + resolver(Result.failure(error)) + } } } }.eraseToAnyPublisher() @@ -678,7 +687,7 @@ open class Storage { ) -> AnyPublisher { switch StorageState(self) { case .invalid(let error): return StorageState.logIfNeeded(error, isWrite: false) - case .valid(let dbWriter): + case .valid: /// **Note:** GRDB does have a `readPublisher` method but it appears to asynchronously trigger /// both the `output` and `complete` closures at the same time which causes a lot of unexpected /// behaviours (this behaviour is apparently expected but still causes a number of odd behaviours in our code @@ -688,11 +697,19 @@ open class Storage { /// which behaves in a much more expected way than the GRDB `readPublisher` does let info: CallInfo = CallInfo(fileName, functionName, lineNumber, false, self) return Deferred { - Future { resolver in - do { resolver(Result.success(try dbWriter.read(Storage.perform(info: info, updates: value)))) } - catch { - StorageState.logIfNeeded(error, isWrite: false) - resolver(Result.failure(error)) + Future { [weak self] resolver in + /// The `StorageState` may have changed between the creation of the publisher and it actually + /// being executed so we need to check again + switch StorageState(self) { + case .invalid(let error): return StorageState.logIfNeeded(error, isWrite: false) + case .valid(let dbWriter): + do { + resolver(Result.success(try dbWriter.read(Storage.perform(info: info, updates: value)))) + } + catch { + StorageState.logIfNeeded(error, isWrite: false) + resolver(Result.failure(error)) + } } } }.eraseToAnyPublisher() diff --git a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift index 63bde4e69e..cd540ee66a 100644 --- a/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift +++ b/SessionUtilitiesKit/Database/Types/PagedDatabaseObserver.swift @@ -158,19 +158,21 @@ public class PagedDatabaseObserver: TransactionObserver where _changesInCommit.performUpdate { $0.inserting(trackedChange) } } - /// We will process all updates which come through this method even if 'onChange' is null because if the UI stops observing and then starts - /// again later we don't want to have missed any changes which happened while the UI wasn't subscribed (and doing a full re-query seems painful...) + /// We will process all updates which come through this method even if 'onChange' is null because if the UI stops observing and + /// then starts again later we don't want to have missed any changes which happened while the UI wasn't subscribed (and doing + /// a full re-query seems painful...) /// - /// **Note:** This function is generally called within the DBWrite thread but we don't actually need write access to process the commit, in order - /// to avoid blocking the DBWrite thread we dispatch to a serial `commitProcessingQueue` to process the incoming changes (in the past not doing - /// so was resulting in hanging when there was a lot of activity happening) + /// **Note:** This function is generally called within the DBWrite thread but we don't actually need write access to process the + /// commit, in order to avoid blocking the DBWrite thread we dispatch to a serial `commitProcessingQueue` to process the + /// incoming changes (in the past not doing so was resulting in hanging when there was a lot of activity happening) public func databaseDidCommit(_ db: Database) { // If there were no pending changes in the commit then do nothing guard !self.changesInCommit.isEmpty else { return } - // Since we can't be sure the behaviours of 'databaseDidChange' and 'databaseDidCommit' won't change in - // the future we extract and clear the values in 'changesInCommit' since it's '@ThreadSafe' so will different - // threads modifying the data resulting in us missing a change + // Since we can't be sure the behaviours of 'databaseDidChange' and 'databaseDidCommit' + // won't change in the future we extract and clear the values in 'changesInCommit' since + // it's '@ThreadSafe' so will different threads modifying the data resulting in us + // missing a change var committedChanges: Set = [] self._changesInCommit.performUpdate { cachedChanges in @@ -178,7 +180,12 @@ public class PagedDatabaseObserver: TransactionObserver where return [] } - commitProcessingQueue.async { [weak self] in + // This looks odd but if we just use `commitProcessingQueue.async` then the code can + // get executed immediately wihch can result in a new transaction being started whilst + // we are still within the transaction wrapping `databaseDidCommit` (which we don't + // want), by adding this tiny 0.01 delay we should be giving it enough time to finish + // processing the current transaction + commitProcessingQueue.asyncAfter(deadline: .now() + 0.01) { [weak self] in self?.processDatabaseCommit(committedChanges: committedChanges) } } diff --git a/SessionUtilitiesKit/JobRunner/JobRunner.swift b/SessionUtilitiesKit/JobRunner/JobRunner.swift index 8925e63b62..4247e8cf19 100644 --- a/SessionUtilitiesKit/JobRunner/JobRunner.swift +++ b/SessionUtilitiesKit/JobRunner/JobRunner.swift @@ -691,7 +691,9 @@ public final class JobRunner: JobRunnerType { // Don't add to the queue if the JobRunner isn't ready (it's been saved to the db so it'll be loaded // once the queue actually get started later) - guard canAddToQueue(updatedJob) || jobQueue?.isRunningInBackgroundTask == true else { return updatedJob } + guard canAddToQueue(updatedJob) || jobQueue?.isRunningInBackgroundTask == true else { + return updatedJob + } // The queue is ready or running in a background task so we can add the job jobQueue?.add(db, job: updatedJob, canStartJob: canStartJob, using: dependencies) @@ -1292,10 +1294,14 @@ public final class JobQueue: Hashable { guard canStart?(self) == true || isRunningInBackgroundTask else { return } guard forceWhenAlreadyRunning || !isRunning || isRunningInBackgroundTask else { return } - // The JobRunner runs synchronously we need to ensure this doesn't start - // on the main thread (if it is on the main thread then swap to a different thread) + // The JobRunner runs synchronously so we need to ensure this doesn't start on the main + // thread and do so by creating a number of background queues to run the jobs on, if this + // function was called on the wrong queue then we need to dispatch to the correct one guard DispatchQueue.with(key: queueKey, matches: queueContext, using: dependencies) else { - internalQueue.async(using: dependencies) { [weak self] in + // Note: We need to dispatch this after a small 0.01 delay to prevent any potential + // re-entrancy issues since the `start` function can be called within an existing + // database transaction (eg. via `db.afterNextTransactionNestedOnce`) + internalQueue.asyncAfter(deadline: .now() + 0.01, using: dependencies) { [weak self] in self?.start(forceWhenAlreadyRunning: forceWhenAlreadyRunning, using: dependencies) } return diff --git a/SessionUtilitiesKit/Utilities/ThreadSafe.swift b/SessionUtilitiesKit/Utilities/ThreadSafe.swift index 3d15c63293..d53c9f34ea 100644 --- a/SessionUtilitiesKit/Utilities/ThreadSafe.swift +++ b/SessionUtilitiesKit/Utilities/ThreadSafe.swift @@ -18,7 +18,7 @@ import Foundation /// as `ThreadSafeType` (reference types or structs which have `mutating` functions **should not** use this mechanism /// as it cannot ensure thread safety for those types) @propertyWrapper -public struct ThreadSafe { +public class ThreadSafe { private var value: Value private let lock: ReadWriteLock = ReadWriteLock() @@ -49,17 +49,17 @@ public struct ThreadSafe { // MARK: - Functions - public mutating func performUpdateAndMap(_ closure: (Value) -> (Value, T)) -> T { + public func performUpdateAndMap(_ closure: (Value) -> (Value, T)) -> T { return try! performInternal { closure($0) } } - public mutating func performUpdateAndMap(_ closure: (Value) throws -> (Value, T)) throws -> T { + public func performUpdateAndMap(_ closure: (Value) throws -> (Value, T)) throws -> T { return try performInternal { try closure($0) } } // MARK: - Internal Functions - @discardableResult private mutating func performInternal(_ mutation: (Value) throws -> (Value, T)) throws -> T { + @discardableResult private func performInternal(_ mutation: (Value) throws -> (Value, T)) throws -> T { lock.writeLock() defer { lock.unlock() }