Giter Club home page Giter Club logo

mobile-sdk-ios's People

Contributors

alexookah avatar andrii-bodnar avatar b-outlaw-nba avatar d4r1091 avatar dependabot[bot] avatar manish-singh-bisht avatar nazaryavornytskyy avatar sabinahuseinova avatar serhii-londar avatar tskovsgaard avatar winstondu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mobile-sdk-ios's Issues

Hiengoku

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]

Additional context
Add any other context about the problem here.

Real time preview not working

Hello!

I am trying to get the real-time preview working on iOS.

So far I was able to successfully log in and turn the "Real-time" setting to on, however when I type something in the Crowdin editor, the translation is not shown on the device. It also does not work when I click on "Reload translations". The only way this is reflected in the device is when I save the translation and I release the distribution. Do you know if I am missing some step?

Thank you beforehand!

Screenshot broken on 1.1.7

After upgrading Crowdin to 1.1.7, I found the screenshot function is broken.
And after some debugging, I found several issues.

Precondition:

My project has multiple localized string files.

Issues

1. Distribution only contains 1 file:

  • This download [CrowdinMappingDownloader download(with hash:...] succeed.
  • But [ScreenshotUploader uploadScreenshot(screenshot:...] gets early return. Because it hits line 75 in ScreenshotUploader(Newly added in 1.1.7) since the string files do not exist.
  • The screenshot function is only working on the specific screen (the file contains in the distribution)

2, Distribution contains multiple files, such as a folder

  • This download [CrowdinMappingDownloader download(with hash:...] returns an error.

Starscream version

Is your feature request related to a problem? Please describe.
I am trying to add your SDK in an iOS app which depends on the latest Starscream version 3.1.1. However your SDK depends on the 3.0.6 version.

Describe the solution you'd like
Is it planned to update Starscream to 3.1.X?

CrowdinSDK not downloading certain localizable.strings files

Dear Crowdin developers,

I'm working on an App that has the following languages

  • Danish
  • Dutch
  • Dutch, Belgium
  • English, United Kingdom
  • English United States
  • French
  • French, Belgium
  • German
  • Swedish

I want those strings to be downloaded via the CrowdinSDK, however, some strings are not being downloaded and I don't know why.

I've have eagerly followed the CrowdinSDK installation and integration instructions:

  • First I went to my project on the Crowdin website, and released a iOS distribution including the Localizable.strings, Localizable.stringsdict and InfoPlist.strings files to it.
  • Then, I copied the distribution hash to my clipboard.
  • After doing this, I've installed the CrowdinSDK and the CrowdinSDK/Settings to my Xcode project, via Pods.
  • Then in the AppDelegate class, I've configured the CrowdinSDK using the following code:
let crowdinProviderConfig = CrowdinProviderConfig(hashString: myHash, sourceLanguage: mySourceLanguageVariable /*e.g: nl-NL*/)
        
let crowdinSDKConfig = CrowdinSDKConfig()
    .with(crowdinProviderConfig: crowdinProviderConfig)
    .with(debugEnabled: true)
    .with(settingsEnabled: true)

CrowdinSDK.currentLocalization = mySourceLanguageVariable //e.g: nl-NL

CrowdinSDK.startWithConfig(crowdinSDKConfig) {
    print("Crowdin is ready")
    // Launch App 
} 

The only languages that are downloading correctly are as follows:

  • Danish
  • English, United Kingdom
  • English United States
  • French

I know that those languages are being downloaded correctly, because the App shows the correct strings on the App's UI, and the CrowdinSDK shows the following LOG:

CrowdinSDK: GET, https://distributions.crowdin.net/myHash/content/MyProject/MyLanguage.lproj/Localizable.strings?timestamp=TimeStamp

The other ones are simply not downloading and when the App tries to find them, it displays a warning indicating that it cannot find those strings, showing the Keys from this strings on the App, instead of the Values.

I did the release 3 hours ago, so I understand that all the strings should be correctly published by now.

Steps to reproduce the behavior:

  1. Simply launch the App.

Expected behavior
To have all the languages being downloaded correctly from Crowdin.

Smartphone (please complete the following information):

  • Device: iPhone 12 Emulator
  • OS: iOS 14.2

Could you please help me with this issue?

Thank you very much.

Best regards.

CrowdinSDK uses the unencrypted 'http' protocol

Describe the bug

[!] 'CrowdinSDK' uses the unencrypted 'http' protocol to transfer the Pod. Please be sure you're in a safe network with only trusted hosts. Otherwise, please reach out to the library author to notify them of this security issue.

To Reproduce
Steps to reproduce the behavior:

  1. On your project, run pod update --repo-update
  2. Observe the issue

Expected behavior

Shouldn't happen

Smartphone (please complete the following information):

  • macOS terminal

Internal error after login

Hello,
I want to use the screenshot functionality in my app but I encounter an internal server error when I try to login to my Crowdin account on both simulator & physical device.

Edit: I also get this the first time I try to login:
{"redirect_to":"\/oauth\/authorize?client_id=xxx&response_type=code&scope=project.screenshot&redirect_uri=crowdintest%3A%2F%2F&domain=xxx&intended=%2Foauth%2Fauthorize%3Fclient_id%3Dxxx%26response_type%3Dcode%26scope%3Dproject.screenshot%26redirect_uri%3Dcrowdintest%253A%252F%252F","method":"GET"}
(xxx hides personal data)

popup
server error

Auto-tagging not working

Describe the bug
The uploaded screenshots without tagging.

To Reproduce
1, Only 1 localized string file, and related screen.
2, Integrate SDK, and capture screenshots.

Expected behavior
The uploaded screenshots have auto-tagging.

Smartphone (please complete the following information):

  • Device: simulator, iPhone 12
  • OS: iOS 14.3
  • Crowdin: 1.1.7

Additional context
After debugging the code, the error returns at line 101 in ScreenshotUploader.swift, from screenshotsAPI.createScreenshotTags(projectId:...
The error is:

▿ DecodingError
  ▿ keyNotFound : 2 elements
    - .0 : CodingKeys(stringValue: "data", intValue: nil)
    ▿ .1 : Context
      - codingPath : 0 elements
      - debugDescription : "No value associated with key CodingKeys(stringValue: \"data\", intValue: nil) (\"data\")."
      - underlyingError : nil

iOS crash: #0 (null) in Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value ()

Describe the bug
We got crash log in Xcode from our user. As I see log issue happened in Crowdin SDK:
#0 (null) in Swift runtime failure: Unexpectedly found nil while unwrapping an Optional value ()

This happened in file:
CustomBundle.swift

In the Class:
FolderBundle: FolderBundleProtocol

Initializer:
init(path: String)

Line:
self.bundle = Bundle(path: folder.path)!

To Reproduce
Steps to reproduce the behavior:

  1. Crowdin SDK connected as Swift Package:

Screen Shot 2022-07-04 at 14 25 43

  1. Current version SDK is v1.4.2

  2. Our initialization of Crowdin SDK what calling from AppDelegate:

import Foundation
import CrowdinSDK

class CrowdinManager: NSObject
{
    private static let distributionHash = "our_hash
    
    class func initCrowding() {
        let crowdinProviderConfig = CrowdinProviderConfig(hashString: CrowdinManager.distributionHash,
                                                          sourceLanguage: Localization.detectLanguage())

        let crowdinSDKConfig = CrowdinSDKConfig.config().with(crowdinProviderConfig: crowdinProviderConfig)
        
        CrowdinSDK.startWithConfig(crowdinSDKConfig, completion: {})

        CrowdinSDK.currentLocalization = Localization.detectLanguage();
    }
}

Expected behavior
Crash should not happened

Screenshots
Screen-Shot-2022-07-04-at-13 44 49_me

Smartphone (please complete the following information):

  • Device: iPhone 13 Pro
  • OS: iOS 15.5 (19F77)

Additional context
Add any other context about the problem here.

Make 'redirectURI' optional

redirectURI config option is used for Screenshots and Real-Time Preview features. It's needed to redirect to the application after login in Crowdin.

It would be great If it's possible to access this URL from SDK code and use it in the config if features above are enabled and if redirectURI was not provided.

"es" (spanish) translations are not working properly.

with configuration:

CrowdinSDK.currentLocalization = "es"
let config = CrowdinSDKConfig.config().with(crowdinProviderConfig: providerConfig).with(intervalUpdatesEnabled: true, interval: 15*60)
_ = CrowdinSDK.addDownloadHandler { print("\(Date()) Crowdin: strings downloaded") }

I'm never getting any callback from that handler. I tried waiting 15 mins, reinstalling app. Simply not happening.
When I changed it to different language in Crowdin eg. "es-EM" (modern spanish) or "sl" (slovenian), it works just fine.

My Android college reports the same problem. Is there something I'm missing ?

The app needs a update

Is your feature request related to a problem? Please describe.
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

Describe the solution you'd like
A clear and concise description of what you want to happen.

Describe alternatives you've considered
A clear and concise description of any alternative solutions or features you've considered.

Additional context
Add any other context about the feature request here.

iOS xib file translations

We have a project that use Crowdin SDK translations, today we found out that .xib files not updating if you did release with updated translations on the crowding website. We got old translations in .xliff file on fresh app install and if update something on the website and release it will not be sent to the app. With .strings files, everything works perfectly fine.

Steps to reproduce the behavior:
A project that will use .xliff file translations
Start the app and then update translations on crowdin website
Check if new translations are populated on .xib files

Expected behavior
.xliff translations work like the .strings ones

If you need any additional data I will answer your questions in comments

Cannot find 'ScreenshotFeature' in scope

Describe the bug
Cannot find 'ScreenshotFeature' in scope
SDK 1.5.0 version, using swift package manager in Xcode 14.0

Tried regular troubleshooting steps:

  • to clean the build
  • remove derived data
    Still no luck.

To Reproduce
Steps to reproduce the behavior:

  1. Add crowding SDK swift package into project
  2. import SwiftUI
  3. try to access ScreenshotFeature.shared
  4. Cannot find 'ScreenshotFeature' in scope

Expected behavior
if imported CrowdinSDK it should be in scope.
Can access all other CrowdinSDK classes in the same swift file.

Screenshots
Screenshot 2022-11-03 at 09 06 36

Additional info
Screenshot 2022-11-03 at 09 10 39

Screenshot 2022-11-03 at 09 07 54

Exclude Starscream dependency from core functionality

Is your feature request related to a problem? Please describe.
In our app two of the metrics we monitor is app startup time and memory usage. In evaluating the performance impact of this SDK on our app, in our usage the SDK takes an average of 1.0MB of additional memory and increases our app startup time by an average of 0.6 seconds. Since we are only using over-the-air functionality for now, when we experimentally removed the Starscream dependency the memory burden of integrating the SDK dropped to 0.5MB.

Describe the solution you'd like
Can we only include dependencies that are required by the SDK compilation? This may require moving some files around or re-configuring how Cocoapods (and SPM?) subspecs are configured.

Access Markdown files via Over-the-air content delivery.

Hello

I noticed that via the Tools -> Over-the-air(OTA) content delivery -> Distributions, we can select and release files that are not only Localizable.strings, but also .mdown files. Reading through the documentation, I saw that the the OTA content delivery does not change existing files or add new files, which means that they don't exist in the file system of the project when running the app. I am wondering how we can access the content of these .mdown files in the iOS project that have been released via OTA?

Many thanks!

Obtain logs from crowd-in

Is your feature request related to a problem? Please describe.
For our code, we have a central logging service that sends logs to our server. We would like to keep that consolidated with our server.

Describe the solution you'd like
Add a callback whenever CrowdIn logs something (This would probably be via the CrowdinLogsCollector.) The iOS client can then set this callback and we can get those logs into our logging service.

Describe alternatives you've considered
We are considering making a fork of the SDK to support this.

Stopping the CrowdinSDK

I want to add a settings button in our app to enable/disable the SDK.
Calling CrowdinSDK.stop() does not remove the hover button.

Is this a bug? or is there another way to stop the startedSDK ?

Crash on startup at LocalLocalizationExtractor.localizedString(for:)

Describe the bug
After we turned the Crowdin OTA feature on our apps, we have seen quite a number of crashes on Firebase, all pointing to LocalLocalizationExtractor.localizedString(for:), which is a file in CrowdinSDK

For example here
Screenshot 2021-11-10 at 11 36 32 AM

To Reproduce
Steps to reproduce the behavior:

  • We weren't able to reproduce on our side.
  • Since Firebase reported 88% of the crash events was happened in the first 5 seconds of a user's session, we suspect it was during the app launch.
  • This crash did not happen until we turned the Crowdin OTA feature on.

Expected behavior
Should not crash on the SDK side.

Screenshots
Code for setting up the Crowdin, it will be called in didFinishLaunchingWithOptions in AppDelegate
Screenshot 2021-11-10 at 11 49 59 AM

Additional context
We would like to know why this crash will happen, and how to fix it, so we can use this SDK in our production app.

Hiengoku

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Go to '...'
  2. Click on '....'
  3. Scroll down to '....'
  4. See error

Expected behavior
A clear and concise description of what you expected to happen.

Screenshots
If applicable, add screenshots to help explain your problem.

Smartphone (please complete the following information):

  • Device: [e.g. iPhone6]
  • OS: [e.g. iOS8.1]

Additional context
Add any other context about the problem here.

Flutter SDK

I love your OTA and Real-time updates feature for Android/iOS. Would be great to have Crowdin SDK for Flutter.
Thanks for great work!

Caching does not work when the network is down

Describe the bug
When I start the SDK to download translations for a non-source language and the .strings files fail, it falls back to the cached values. But if I start the SDK and the manifest.json network request fails it falls back to the bundled translations. This is inconsistent and suggests caching is not working. If the Crowdin CDN is down in any way, it shouldn't matter which request fails, and the result for the end-user should be the same.

To Reproduce

  1. Set the region/language settings to a non-source language. e.g. If en is the source language, set to fr-CA.
  2. Do a fresh install of the app. App should be already integrated with the SDK.
  3. Start the app, letting it complete calls to establish a cache.
  4. Kill the app.
  5. Configure a proxy tool like Charles Proxy to block the calls to manifest.json from succeeding
  6. Re-launch the app and ensure calls get blocked.
  7. In the app, navigate to UI that retrieves the latest translation for some text. That text should use the cache values retrieved previously.

Repeat this process, but block against the .strings files instead.

Note: I observed this on regions that are not the source language. I did not look into why this worked as expected for en.

Expected behavior
Starting SDK should get back any previously cached translations rather than falling back to the bundled translations.

As soon as the SDK begins retrieving of translations, I expect to still get back previously cached translations until new translations are downloaded. Ideally, client apps should have control over whether they want to wait until all translations are downloaded. Only when the cache is expired and is in progress or fails would I expected to receive the translations bundled into the app.

Screenshots
Please contact me for screenshots or videos. The support team should have my contact info.

Smartphone (please complete the following information):

  • Device: iPhone SE
  • OS: iOS 15.4

Adding tvOS support

My team is exploring integrating this SDK for Over-the-Air support to help reduce the releases we need to make just for translations. Our code base is shared between iOS and tvOS which may defeat the purpose if Over-the-Air isn't supported on one platform. Is there a timeline for providing tvOS support?

When app is in source language and debugger is attached, strings are displayed in caps

Describe the bug
image
Normally, when bundle.localizedString() fails to find the value for the key, it returns the key. However, when localization debugging is turned on and the app is run in debug, it returns the capitalized version of the key.

This is an issue, because this means when the app is run with the debugger, the check in this line (

) fails since the string returned is the uppercased version of the key, rather than the key itself. So the equality check fails, and rather than returning nil we return the uppercased key.

To Reproduce
With a CrowdIn project in English, run an app on a real device with the XCode debugger (and localization debugging turned on) and the device language set to English. You will see strings in CAPS.

Expected behavior
Display the actual value of that key, rather than displaying the key in uppercase.

Additional context
It is interesting that the localizationProvider will always fail to find a string when in the source language here in this line: the downloaded en.plist is always just empty (I presume this is because it is the CrowdIn project's source language!) Our preferred fix is just to have the en.plist not be empty (i.e. always download the en.plist).

We do want to keep localization debugging enabled for our app in XCode.

SDK with SwiftUI does not seem to do much?

Describe the bug
I am not sure if this is a bug or you just don't support SwiftUI.
I was under assumption if you make screenshot all the strings should be taged in them automatically,
but only got can see string from UIKit context.

Additional context
Is this a bug? If not are you planning to add SwiftUI support any time soon?
Thanks!

Starting the SDK blocks the app from loading until the manifest downloads

Describe the bug
It appears that calling startWithConfig is synchronous which prevents client apps from continuing to load while the SDK loads. This is potentially important to us because it impacts app start time which is a key metric for us.

Our team is a little confused because it has an @escaping completion handler. And because while downloading the manifest.json blocks, downloading the subsequent Crowdin files happens asynchronously.

I don't know the code base well enough to make a contribution. Any guidance or advice would be helpful!

To Reproduce
Steps to reproduce the behavior:

  1. Install the Crowdin SDK on an app
  2. Set the completion handler of startWithConfig to print "completed"
  3. Immediately after the call to startWithConfig print "starting"

Expected behavior
Console prints "starting" then "completed".

Two possible expectations:

  1. SDK performs startWithConfig asynchronously.
  2. startWithConfig could block until downloading critical files. Perhaps remove the completion closure and document it as a synchronous method? Then clients could decide whether they want to call startWithConfig asynchronously.

Actual behavior
Console prints "completed" then "started". Using a proxy tool to prevent a response for "manifest.json" prevents "started" from being printed until a response is returned.

Smartphone:

  • Device: iPhone XS simulator
  • OS: 14.5

Additional context
Over roughly 15 trials we observed initializing the SDK added about 0.6 seconds to our app startup time.

Copies/translations not fetched inside the completion block of CrowdinSDK.startWithConfig on a fresh install

Hi there!

I successfully integrated the CrowdinSDK in my app using Swift Package Manager and I am using OTA content delivery. On the first app launch with internet enabled, when I enter the completion block of CrowdinSDK.startWithConfig, and fetch the copy for a specific key using NSLocalizedString(key, comment: ""), I am only getting the key and not the copy. If I kill and relaunch the app, the copy for the same key is fetched successfully.

Do you know what might be causing this and do you have any suggestion on its mitigation?

Many thanks!

CDN setup with .xml file

Hey guys

I'm trying to implement the SDK in our iOS app, but I'm having difficulty with getting it to work.
The issue I'm having is that the translation files dont get downloaded at all. After some playing around I found out that the problem seems to be with us using ".xml" instead of ".string" file.
I couldnt find any documentation on this, so I'm not sure if it's me doing something wrong or the SDK just doesnt support .xml files.

Is .xml files not support?

Thanks in advance!

Crash self.stringsDataSource = StringsLocalizationDataSource(strings: strings) in LocalizationProvider

Describe the bug
We received crash report from Crowdin SDK file

To Reproduce
Steps to reproduce the behavior:

  1. In our application on launch app, from AppDelegate.swift in:

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool

we call:

 class func initCrowdin() {
        let crowdinProviderConfig = CrowdinProviderConfig(hashString: WXCrowdinManager.distributionHash,
                                                          sourceLanguage: WXLocalization.detectLanguage())

        let crowdinSDKConfig = CrowdinSDKConfig.config().with(crowdinProviderConfig: crowdinProviderConfig)
        
        CrowdinSDK.startWithConfig(crowdinSDKConfig, completion: {})

        CrowdinSDK.currentLocalization = WXLocalization.detectLanguage();
    }

1*. Also initCrowdin() we call on AppleWatch in class:
class ExtensionDelegate: NSObject, WKExtensionDelegate
on

func applicationDidBecomeActive() {

  1. In Xcode and AppstoreConnect we received information about crash. Detail information is shown on screenshots.

Expected behavior
No crash happened

Screenshots
Screen Shot 2022-08-01 at 12 52 42

Screen Shot 2022-08-01 at 12 55 33

Screen Shot 2022-08-01 at 12 55 44

Screen Shot 2022-08-01 at 12 55 51

Screen Shot 2022-08-01 at 12 55 59

Screen Shot 2022-08-01 at 12 56 06

Smartphone (please complete the following information):

  • Device: iPhone 13 Pro Max
  • OS: iOS 15.6 (19G71)

SPM 1.4.2 version not working

Cannot find 'CrowdinLoginConfig' in scope

The last update does not work with SPM. try to run with SPM before releasing a new version.

Option to disable method swizzling of NSLocalizedString

Is your feature request related to a problem?
My teammates have communicated concern about the use of Objective-C method swizzling of NSLocalizedString. The SDK unexpected changes functionality of something it doesn't own (an Apple API), and we may unknowingly be integrating with another SDK that also use swizzling.

Because our app is only interested in Over-the-Air for the time being, we'd like the option to disable swizzling. As I understand, swizzling is only a requirement of the optional Real-Time Preview feature, and for improved functionality of the also optional IntervalUpdates feature. Perhaps we will be interested in enabling Real-Time Preview for non-production builds with swizzling at a later date.

Describe the solution you'd like
If the SDK replicates Apple's, can we make Localization.localizedString(for:) public so that developers can call it directly? And then include a config option that conditionally disables CrowdinSDK.swizzle() and CrowdinSDK.swizzleControlMethods().

ld: framework not found BaseAPI

Describe the bug
For test i created empty projects (objective-c and swift) with one pod CrowdinSDK and when run Build on Any iOS device or Simulator get this error. For Swift project: ld: framework not found BaseAPI. For Objective-c project: fatal error: module map file '~/Library/Developer/Xcode/DerivedData/Empty-dnjsexrkxdmbmeaeuqkddudleoda/Build/Products/Debug-iphonesimulator/BaseAPI/BaseAPI.modulemap' not found

When Run or Build on iPhone i no have error.

Environment
macOS: 10.15.6
Xcode: 12.0.1
CocoaPod: 1.9.3
CrowdinSDK: 1.1.5

Setting an unsupported locale code doesn't fall back to a language code

Describe the bug
Currently, our server tells the clients which locale code to use. (We recognize this is backwards.) This means we call CrowdinSDK.currentLocalization to override the target language. The concern is that the Crowdin supported language codes doesn't list "Italian Italy" (it-IT) just Italy (it). Same story with fr-FR. Meanwhile, Apple's Locale.current.identifer will return it_IT and fr_FR. So there's some mismatching between locale codes between the Apple, our server, and Crowdin.

Over-the-air also doesn't appear to support falling back from it-IT to just it. Instead it fails to retrieve any language over-the-air at all. I spoke with our Android representative who said their SDK integration doesn't have this issue.

Furthermore, additionally, I can't add "it-IT" as a custom language (see screenshot).

To Reproduce
After the SDK initializes, set the CrowdinSDK.currentLocalization to a locale code that isn't officially supported by Crowdin. e.g. "it-IT". Ensure there is a localization for the language code e.g. just "it".

Actual behavior
No calls to retrieve over-the-air translations are made.

Expected behavior
I see two possible outcomes:

  1. Crowdin could provide "it-IT" as opposed to just "Italian" on the website?
  2. Crowdin SDK could handle either "it-IT" or "it"?

Screenshots
Screen Shot 2022-03-18 at 4 13 36 PM

Smartphone (please complete the following information):
Doesn't seem to matter? I am using an iPhone SE sim 15.2

Additional context

Duplicate requests and larger than expected response sizes

Describe the bug
We are integrating the SDK for Over-the-Air functionality and we are noticing some additional network requests go out which leads to larger request sizes going out. Our app experiences a high volume of customers.

  1. On each app start we see 2-3 requests for manifest.json. This always returns HTTP 200 and is not cached. ~35KB response size each
  2. For each localization file we download we are seeing an initial HTTP 200 response. It is cached and compressed, which is great, ~50KB response size in our usage. But on a subsequent request when we get an HTTP 304 "not modified" we are still seeing that the TLS handshake costs 33KB.
  3. On a fresh app install I am also seeing two calls for the languages API. ~41KB in size each

This means each app start requires between ~200KB (expired cache) and ~65KB (fresh cache). Multiplied by all of our users 😅😰

To Reproduce
See above.

Expected behavior
I don't expect to see parallel or back-to-back requests in the same app session (1 & 3). I also am expecting the manifest.json to be cached (1). Additionally, it would be nice if we can reduce either the size of our 304 responses or rate limit them on the client (2).

Screenshots
200:
200

304:
304

In this demo project we have two localization files listed in our manifest, one significantly <1KB uncompressed and the other 77KB uncompressed. Fresh install at 18:12, quit and re-opened app at 18:14.
DuplicateRequestsAndLarge304Responses

Smartphone (please complete the following information):

  • Device: iPhone SE (sim)
  • OS: 15.2

Additional context

Crash when accessing `currentLocalization` on startup in 1.1.4

Describe the bug
In applicationDidFinishLaunching:

CrowdinSDK.startWithConfig(crowdinSDKConfig) {
    let localization = CountrySelectionUserDefaults.selectedCountry.languageCode
    CrowdinSDK.enableSDKLocalization(true, localization: localization)
}

calling enableSDKLocalization will crash on a device (when running the app in Release Mode). When running with DEBUG configuration it works fine. I think it only crashes in Release mode because the build setting SWIFT_ENFORCE_EXCLUSIVE_ACCESS only crashes the app in release mode and it seems like this is the root cause of the crash.

Attached the stack trace:

Simultaneous accesses to 0x280a62770, but modification requires exclusive access.
Previous access (a modification) started at meindm`Localization.provider.modify + 60 (0x102e0c7a8).
Current access (a read) started at:
0    libswiftCore.dylib                 0x00000001aa9cd248 swift_beginAccess + 560
1    meindm                             0x0000000102e0c5ec Localization.provider.getter + 68
2    meindm                             0x0000000102e0e984 Localization.localizedString(for:) + 100
3    meindm                             0x0000000102d86940 NSBundle.swizzled_LocalizedString(forKey:value:table:) + 476
4    meindm                             0x0000000102d86ef0 @objc NSBundle.swizzled_LocalizedString(forKey:value:table:) + 368
5    Foundation                         0x000000019d5810a4 <redacted> + 1056
6    Foundation                         0x000000019d653794 <redacted> + 184
7    Foundation                         0x000000019d653e10 <redacted> + 196
8    Foundation                         0x000000019d5a0770 <redacted> + 164
9    meindm                             0x0000000102e3f7f0 Dictionary.write(to:) + 364
10   meindm                             0x0000000102e3fba4 protocol witness for ReadWriteProtocol.write(to:) in conformance [A : B] + 32
11   meindm                             0x0000000102df4f54 ReadWriteFile.save() + 392
12   meindm                             0x0000000102e23594 LocalLocalizationStorage.saveLocalization() + 1336
13   meindm                             0x0000000102e22138 LocalLocalizationStorage.strings.setter + 308
14   meindm                             0x0000000102e22a3c LocalLocalizationStorage.fetchData() + 1092
15   meindm                             0x0000000102e216f0 LocalLocalizationStorage.localization.didset + 152
16   meindm                             0x0000000102e21428 LocalLocalizationStorage.localization.setter + 324
17   meindm                             0x0000000102e213b8 @objc LocalLocalizationStorage.localization.setter + 80
18   meindm                             0x0000000102e12858 LocalizationProvider.localization.didset + 328
19   meindm                             0x0000000102e12b48 LocalizationProvider.localization.setter + 368
20   meindm                             0x0000000102e194c0 protocol witness for LocalizationProviderProtocol.localization.setter in conformance LocalizationProvider + 48
21   meindm                             0x0000000102e0d1f4 Localization.currentLocalization.setter + 628
22   meindm                             0x0000000102dc8d58 static CrowdinSDK.currentLocalization.setter + 388
23   meindm                             0x0000000102dc9dd0 static CrowdinSDK.enableSDKLocalization(_:localization:) + 528
24   meindm                             0x0000000102529594 closure #1 in CrowdinAppService.configure() + 180
25   meindm                             0x0000000102464a14 thunk for @escaping @callee_guaranteed () -> () + 56
26   meindm                             0x000000010278ec94 thunk for @escaping @callee_unowned @convention(block) () -> () + 16
27   meindm                             0x0000000102dc9944 closure #1 in static CrowdinSDK.startWithRemoteStorage(_:completion:) + 244
28   meindm                             0x0000000102464a14 thunk for @escaping @callee_guaranteed () -> () + 56
29   meindm                             0x000000010278ec94 thunk for @escaping @callee_unowned @convention(block) () -> () + 16
30   meindm                             0x0000000102dc4388 CrowdinRemoteLocalizationStorage.prepare(with:) + 432
31   meindm                             0x0000000102dc46e4 @objc CrowdinRemoteLocalizationStorage.prepare(with:) + 120
32   meindm                             0x0000000102dc97a4 static CrowdinSDK.startWithRemoteStorage(_:completion:) + 396
33   meindm                             0x0000000102dc6068 static CrowdinSDK.startWithConfig(_:completion:) + 836
34   meindm                             0x0000000102dc63fc @objc static CrowdinSDK.startWithConfig(_:completion:) + 152
35   meindm                             0x00000001025293a4 CrowdinAppService.configure() + 448
36   meindm                             0x0000000102475d6c AppDelegate.application(_:didFinishLaunchingWithOptions:) + 536
37   meindm                             0x00000001024762d4 @objc AppDelegate.application(_:didFinishLaunchingWithOptions:) + 232
38   UIKitCore                          0x00000001a1322b10 <redacted> + 356
39   UIKitCore                          0x00000001a1323648 <redacted> + 5048
40   UIKitCore                          0x00000001a1329dc0 <redacted> + 1244
41   UIKitCore                          0x00000001a0aceadc <redacted> + 148
42   UIKitCore                          0x00000001a0f7f278 _UIScenePerformActionsWithLifecycleActionMask + 100
43   UIKitCore                          0x00000001a0acf590 <redacted> + 196
44   UIKitCore                          0x00000001a0acef88 <redacted> + 288
45   UIKitCore                          0x00000001a0acf19c <redacted> + 740
46   UIKitCore                          0x00000001a0acebf0 <redacted> + 336
47   UIKitCore                          0x00000001a0ad3120 <redacted> + 188
48   UIKitCore                          0x00000001a0ea3074 <redacted> + 812
49   UIKitCore                          0x00000001a0f9862c _UISceneSettingsDiffActionPerformChangesWithTransitionContext + 244
50   UIKitCore                          0x00000001a0ad2eac <redacted> + 140
51   UIKitCore                          0x00000001a0f985b8 _UISceneSettingsDiffActionPerformActionsWithDelayForTransitionContext + 100
52   UIKitCore                          0x00000001a0ad2c28 <redacted> + 376
53   UIKitCore                          0x00000001a0942cf8 <redacted> + 636
54   UIKitCore                          0x00000001a0941a1c <redacted> + 248
55   UIKitCore                          0x00000001a0942bd0 <redacted> + 220
56   UIKitCore                          0x00000001a13282cc <redacted> + 540
57   UIKitCore                          0x00000001a0ec8524 <redacted> + 360
58   FrontBoardServices                 0x00000001a23fc474 <redacted> + 424
59   FrontBoardServices                 0x00000001a2421130 <redacted> + 100
60   FrontBoardServices                 0x00000001a2406b14 <redacted> + 232
61   FrontBoardServices                 0x00000001a2420d18 <redacted> + 312
62   libdispatch.dylib                  0x0000000108b67720 _dispatch_client_callout + 16
63   libdispatch.dylib                  0x0000000108b6aac8 _dispatch_block_invoke_direct + 232
64   FrontBoardServices                 0x00000001a2445828 <redacted> + 40
65   FrontBoardServices                 0x00000001a2445388 <redacted> + 404
66   FrontBoardServices                 0x00000001a2445a28 <redacted> + 28
67   CoreFoundation                     0x000000019d203c00 <redacted> + 24
68   CoreFoundation                     0x000000019d203b20 <redacted> + 80
69   CoreFoundation                     0x000000019d203240 <redacted> + 184
70   CoreFoundation                     0x000000019d1fe014 <redacted> + 788
71   CoreFoundation                     0x000000019d1fdb40 CFRunLoopRunSpecific + 424
72   GraphicsServices                   0x00000001a73482ec GSEventRunModal + 160
73   UIKitCore                          0x00000001a132bcb8 UIApplicationMain + 1932
74   meindm                             0x0000000102851dac main + 676
75   libdyld.dylib                      0x000000019d0858ec <redacted> + 4
(lldb) 

I also added a screenshot of the crash in the Xcode Debugger.

To Reproduce
Steps to reproduce the behavior:

  1. Call in applicationDidFinishLaunching:
CrowdinSDK.startWithConfig(crowdinSDKConfig) {
    let localization = CountrySelectionUserDefaults.selectedCountry.languageCode
    CrowdinSDK.enableSDKLocalization(true, localization: localization)
}

Expected behavior
The app does not crash

Screenshots
CleanShot 2020-09-14 at 15 13 49@2x

Smartphone (please complete the following information):

  • Device: All devices
  • OS: iOS 13, iOS 14

Additional context
None

Switch must be exhaustive in SocketAPI (StarScream 4.0.6 update)

Describe the bug
StarScream released a new version (4.0.6) where the added a new enum and now the project won't be able to compile.

To Reproduce
Steps to reproduce the behavior:

  1. Use the latest Package versions (Xcode -> File -> Packages -> Update To Latest Package Version)
  2. Try building your project

Expected behavior
The project compiles without errors

Screenshots
image

Smartphone (please complete the following information):

  • Device: iPhone 12
  • OS: 16

Additional context
There is already a Bug ticket on StarScream: daltoniam/Starscream#975

The changed code should be here:

func didReceive(event: WebSocketEvent, client: WebSocket) {
switch event {
case .connected:
isConnected = true
onConnect?()
case .disconnected:
isConnected = false
onDisconnect?()
case .text(let string):
websocketDidReceiveText(string)
case .binary: break
case .ping: break
case .pong: break
case .viabilityChanged: break
//the viability (connection status) of the connection has updated.
// e.g. connection is down, connection came back up https://github.com/daltoniam/Starscream/issues/798
case .reconnectSuggested(let shouldReconnect):
//the connection has upgrade to wifi from cellular. Consider reconnecting to take advantage of this
if shouldReconnect {
reconnect()
}
case .cancelled:
isConnected = false
case .error(let error):

Related PR that fix this: #225

Support for Swift Package Manager

I saw that only Cocoapods is supported at the moment and it would be nice to have a support for Carthage and Swift Package Manager. Currently we use Carthage, but planning to move to Swift Package Manager (having it in xCode) in the future.

End to end tests for important use cases

Is your feature request related to a problem? Please describe.
My team is exploring integrating with the Crowdin SDK which we are excited about. I have been tasked with finding out what happens if we depend on Over-the-Air translations and there's a network failure.

I started writing some additional tests. It became clear that although some aspects of this project are easily testable, the changes required to make LocalizationProvider and all of its dependencies testable is a big lift and I am unfamiliar with this code base.

Describe the solution you'd like
It would be great to see some expansion of test cases to cover business critical functions to give us more confidence about the SDK. For instance, in at least one place a callback is missing -- does this have any real world consequence? Are there any other cases like this?

Some of the SDK is already using protocols which is a great! But some parts are using global state which makes it hard to test.

LocalizationProvider can already be passed in a CrowdinRemoteLocalizationStorage but we are currently unable to pass in a CrowdinLocalizationDownloader in order to use the existing URLSessionMock to simulate successful and failed network respones. This may also require creating a mock for CrowdinContentDeliveryAPI to pass in a manifest. Additionally, although CrowdinContentDeliveryAPI has some test coverage, it does not cover the downloading of the manifest.

Describe alternatives you've considered
I successfully added a mock for RemoteLocalizationStorageProtocol and passed that into CrowdinSDK.startWithRemoteStorage(). However, this doesn't give deep enough test coverage into what happens during a network failure.

Additional context
I may have some time next week to work with you towards a solution.

watchOS comparability issue

Describe the bug
A clear and concise description of what the bug is.

To Reproduce
Steps to reproduce the behavior:

  1. Create watchOS project
  2. Add CrowdinSDK with Swift Package: https://github.com/crowdin/mobile-sdk-ios.git
  3. In the WatchKit Extension module open:
    Build Phases -> Link Binary With Libraries
    and add CrowdinSDK
  4. Open ExtensionDelegate.swift and add
    import CrowdinSDK
  5. Try build project for launch on Apple Watch or Apple Watch Simulator
  6. You will see 2 errors in LoginFeature.swift (from CrowdinSDK) on line:
    import SafariServices
    Error:
    No such module 'SafariServices'
    and:
    SafariServices is not available when building for watchOS Simulator. Consider using #if !os(watchOS) to conditionally import this framework.

Screenshots
Screen Shot 2022-04-18 at 13 08 27

Smartphone (please complete the following information):

  • Device: Simulator Apple Watch Series 7
  • OS: watchOS 8.3

Crash on Apple TV device

Describe the bug
I am getting an app crash when using the SDK on a physical Apple TV device. I get the following error when the SDK is attempting to create the CrowdinFolder for the translation files:

Fatal error: 'try!' expression unexpectedly raised an error: Error Domain=NSCocoaErrorDomain Code=513 "You don't have permission to save the file "Crowdin" in the folder ".Crowdin"."

Note that this does not happen on the Apple TV simulator in Xcode, only a physical device.

To Reproduce
Steps to reproduce the behavior:

  1. Build to a physical Apple TV device
  2. The app crashes after starting the CrowdinSDK

Expected behavior
My understanding is that storing data on an Apple TV is not available outside of the cache directory, and when the SDK attempts to create a folder in the documents directory, the FileManager throws an exception.

Screenshots
Screen Shot 2022-02-22 at 6 49 22 PM

Smartphone (please complete the following information):

  • Device: Apple TV 4K (2nd generation)
  • OS: tvOS 15.3

Additional context
I was able to avoid the crash by changing DocumentsFolder.documentsPath from:
static let documentsPath = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)[0]
to:
static let documentsPath = NSSearchPathForDirectoriesInDomains(.cachesDirectory, .userDomainMask, true)[0]
but I am not aware if this will have any performance implications.

Example can't authorize success.

I create a project in crowdin, and replace distributionHash, sourceLanguage, clientId, clientSecret in SceneDelegate.swift file. After I run the Example, and click "Log in" but authorize failed. the status code is 401, and the error message is "Client authentication failed".
I use the same configuration in android sample, but success.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.