Текущий сценарий: я успешно реализовал проект на одном тестовом устройстве (iOS) со всеми работающими функциями. К сожалению, при запуске на других зарегистрированных устройствах для тестирования возникает следующая проблема

введите здесь описание изображения проблема, начинающаяся со следующей стрелки, отмеченной на данном снимке экрана журнала:

Как это отображается на зарегистрированном устройстве, которое используется для тестирования, которое работает: введите здесь описание изображения

Как это показывает на остальных зарегистрированных устройствах, которые используются для тестирования, это не работает:

enter image description here

Как я пытался исправить ошибку:
1. Я попытался добавить песочницу приложения и проверить входящее и исходящее соединение, через файл прав и создать новую подготовку.

2.Установите Arbitary в Transport в info.plist

К вашему сведению: URL-адрес API находится в формате http:

Ниже приведен код, используемый для уведомлений:

//
//  NotificationsTableViewController.swift

//

import UIKit
import PKHUD
import Alamofire
import EmptyDataSet_Swift

class NotificationsTableViewController: UITableViewController {
    
    var notifications: NotificationsResponse?
    var currentPage = 1
    var totalPage = 0
    
    var aryOfNotificationList = NSMutableArray()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        title = _appDelegate.getLocalize("kNotifications")
        
        //        tableView.emptyDataSetSource = self
        //        tableView.emptyDataSetDelegate = self
        
        tableView.tableFooterView = UIView()
        
        // Uncomment the following line to preserve selection between presentations
        // self.clearsSelectionOnViewWillAppear = false
        
        // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
        // self.navigationItem.rightBarButtonItem = self.editButtonItem
    }
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)
        
        //self.getNotifications(page: "\(currentPage)")
        self.fetchNotificationList(page: currentPage)
    }
    
    
    
    // MARK: - Table view data source
    
    override func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }
    
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return self.aryOfNotificationList.count
    }
    
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = tableView.dequeueReusableCell(withIdentifier: "notificationCell", for: indexPath) as! NotificationTableViewCell
                
        let json = self.aryOfNotificationList.object(at: indexPath.row)as! NSDictionary

        if let str = json.value(forKey: "vTitle")as? String{
            cell.titleLable.text = str
        }
        if let str = json.value(forKey: "vText")as? String{
            cell.detailLable.text = str
        }
        if let str = json.value(forKey: "tCreatedAt")as? Int{
            cell.datLabel.text = getDate(unixdate: str, timezone: "UTC")
        }
     
        return cell
    }
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        tableView.deselectRow(at: indexPath, animated: true)
        let json = self.aryOfNotificationList.object(at: indexPath.row)as! NSDictionary
        if let dic = json.value(forKey: "txParameters")as? NSDictionary{
            
            
            guard let bookId = dic.value(forKey: "iBookId")as? Int else {return}
            
            guard let bookName = json.value(forKey: "vTitle")as? String else {return}
            downloadBookAndSave(bookId: bookId,bookName:bookName)
        }
    }
    
}


extension NotificationsTableViewController: EmptyDataSetSource {
    func title(forEmptyDataSet scrollView: UIScrollView) -> NSAttributedString? {
        guard let font = UIFont(name: "NotoSansGujarati", size: 18) else {
            // do something with attributes
            return NSAttributedString(string: "Record not found.")
            
        }
        
        let attributes = [NSAttributedString.Key.font: font, NSAttributedString.Key.foregroundColor: UIColor.secondaryColor]
        
        return NSAttributedString(string: "Record not found.", attributes: attributes)
    }
}

// MARK:- API
extension NotificationsTableViewController {
    
    func fetchNotificationList(page:Int){
        guard let urlEncodedString = (AppConstants.URL.getNotifications + "?pageno=\(page)").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
            return
        }
        HUD.show(.progress)
        let url = URL(string: urlEncodedString)!
        print(url)
        
        var headers: HTTPHeaders = [
            "Content-Type"  : "application/x-www-form-urlencoded",
            "Accept"        : "application/json",
        ]
        
        if let accessToken = User.current?.accessToken {
            headers["Authorization"] = "Bearer \(accessToken)"
        } else if let accessToken = UserDefaults.standard.string(forKey: "AccessToken") {
            headers["Authorization"] = "Bearer \(accessToken)"
        }
        
        AF.request(urlEncodedString, method:.get, parameters:nil, headers: headers)
            .responseJSON { response in
                switch response.result {
                case .success(let value):
                    if let json = value as? NSDictionary{
                        print(json)
                        if let str = json.value(forKey: "totalRecord")as? Int{
                            self.totalPage = str
                        }
                        if let ary = json.value(forKey: "data")as? NSArray{
                            for j in ary{
                                self.aryOfNotificationList.add(j as! NSDictionary)
                            }
                        }
                    }
                    
                    if self.currentPage >= self.totalPage{
                        DispatchQueue.main.async {
                            HUD.hide()
                            self.tableView.delegate = self
                            self.tableView.dataSource = self
                            self.tableView.reloadData()
                        }
                    }else{
                        self.currentPage = self.currentPage + 1
                        self.fetchNotificationList(page: self.currentPage)
                    }
                    
                    
                case .failure(let error):
                    print(error.localizedDescription)
                    DispatchQueue.main.async {
                        HUD.hide()
                    }
                }
            }
    }
    
    func getBookService(bookId: Int) {
        guard let urlEncodedString = (AppConstants.URL.getBook + "?book_id=\(bookId)").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
            return
        }
        HUD.show(.progress)
        let url = URL(string: urlEncodedString)!
        let task = URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
            DispatchQueue.main.async {
                HUD.hide()
            }
            if let er = error {
                print(er)
                Utils.showAlertController(with: er.localizedDescription, viewController: self!)
                return
            }
            guard let unwrappedData = data else { return }
            do {
                //print(String(data: unwrappedData, encoding: .utf8))
                let getBooksResponse = try JSONDecoder().decode(GetBookResponse.self, from: unwrappedData)
                guard getBooksResponse.books.count != 0 else {
                    DispatchQueue.main.async {
                        Utils.showAlertController(with: "No book found.", viewController: self!)
                    }
                    return
                }
                DispatchQueue.main.async { [weak self] in
                    for book in getBooksResponse.books {
                        var bookJson =
                            """
                        "id": \(book.bookId),
                        "title": \(book.title),
                        "desc": \(book.content)
                        """
                        _appDelegate.loadString(jsonString: &bookJson, type: .Book, langType: .Gujrati)
                    }
                    
                    Utils.showAlertController(with: "Book is saved", viewController: self!)
                    
                }
            } catch {
                print("json error: \(error)")
            }
        }
        task.resume()
        
    }
    
    func getDate(unixdate: Int, timezone: String) -> String {
        let date = NSDate(timeIntervalSince1970: TimeInterval(unixdate))
        let dayTimePeriodFormatter = DateFormatter()
        dayTimePeriodFormatter.dateFormat = "dd/MM/YYYY"
        dayTimePeriodFormatter.timeZone = (NSTimeZone(name: timezone)! as TimeZone)
        let dateString = dayTimePeriodFormatter.string(from: date as Date)
        return "\(dateString)"
    }
    
    
    func downloadBookAndSave(bookId: Int,bookName:String) {
        guard let urlEncodedString = (AppConstants.URL.getBook + "?book_id=\(bookId)").addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) else {
            return
        }
        HUD.show(.progress)
        let url = URL(string: urlEncodedString)!
        let task = URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
            DispatchQueue.main.async {
                HUD.hide()
            }
            if let er = error {
                print(er)
                Utils.showAlertController(with: er.localizedDescription, viewController: self!)
                return
            }
            guard let unwrappedData = data else { return }
            do {
                //print(String(data: unwrappedData, encoding: .utf8))
                guard let data = try? JSONSerialization.jsonObject(with: unwrappedData, options: []) as? [String:AnyObject]  else {
                    return
                }
                
                let getBooksResponse = try JSONDecoder().decode(GetBookResponse.self, from: unwrappedData)
                guard getBooksResponse.books.count != 0 else {
                    DispatchQueue.main.async {
                        Utils.showAlertController(with: "No book found.", viewController: self!)
                    }
                    return
                }
                DispatchQueue.main.async { [weak self] in
                    let book = getBooksResponse.books[0]
//                        var bookJson =
//                            """
//                        "id": \(book.bookId),
//                        "title": \(book.title),
//                        "desc": \(book.content)
//                        """
                       // _appDelegate.loadString(jsonString: &bookJson, type: .Book, langType: .Gujrati)
                    do {
                        let data = try Data(book.content.utf8)
                        let parsedBookObject = try JSONDecoder().decode([BookContent].self, from: data) // <-- here
                        //print(parsedBookObject)
                        guard let bookModel:BookModelForJSONConversion? = BookModelForJSONConversion(id: book.bookId, title: book.title, content: parsedBookObject)else {return}
                        guard let bookJSONString = bookModel!.convertToJsonString()else {return}
                            let booksManager = VBBooksManager.init()
                        
                            booksManager.saveBook(bookName: book.title, bookData: bookJSONString)
                            Utils.showAlertController(with: "Book is saved", viewController: self!)
                    }
                    catch let error as NSError{
                        print("error: \(error)")
                    }
                    
                    
                }
            } catch {
                print("json error: \(error)")
            }
        }
        task.resume()
        
    }
}

По следующей ссылке есть файлы, используемые в проекте: https://github.com/JigarDave102/API_files

0
Jigar Dave 2 Фев 2022 в 12:11
Вы проверили это вопрос?
 – 
udi
2 Фев 2022 в 12:37
Да, и пытался использовать этот способ решения, но это не решило текущую проблему. Кроме того, есть еще одно подозрение, почему это может происходить: поскольку проект не работает должным образом на моем m1 mac, Xcode все симуляторы iOS. следовательно, мне пришлось добавить arm64 в исключенную архитектуру для всех целей, модулей. Позже, чтобы запустить проект на реальном тестовом устройстве, мне нужно каждый раз снова удалять все исключения.
 – 
Jigar Dave
2 Фев 2022 в 13:14

2 ответа

Лучший ответ

Вместо NSAllowsArbitraryLoads в NSAppTransportSecurity в Info.plist, пробовали ли вы свой конкретный домен (vadtaldhambooks.com), например:

<dict>
    <key>NSAppTransportSecurity</key>
    <dict>
        <key>NSExceptionDomains</key>
        <dict>
            <key>vadtaldhambooks.com</key>
            <dict>
                <key>NSIncludesSubdomains</key>
                <true/>
                <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key>
                <true/>
            </dict>
        </dict>
    </dict>
    </dict>
1
workingdog 2 Фев 2022 в 15:16
Работает как шарм :)
 – 
Jigar Dave
2 Фев 2022 в 15:40

Похоже, вы звоните http, а не https. Вот уже несколько лет на реальных устройствах iOS есть ATS, что означает App Transport Security.

Это система, которая не разрешает сетевые запросы, если они не https, и, кроме того, безопасная конфигурация https

У Apple есть утилита nscurl для диагностики проблем с конфигурацией сервера, а также выдает конфигурацию, которую нужно ввести Info.plist

https://developer.apple.com/documentation/security/preventing_insecure_network_connections/identifying_the_source_of_blocked_connections

0
Alistra 2 Фев 2022 в 12:29