获取的通知 API 在其他设备上不可见,但用于测试 swift 项目的设备除外。有什么办法摆脱这种情况?
Notifications API fetched are not visible on other devices except the one used for testing for swift project . What is way out of such situation?
当前场景:我已经在一台测试设备(iOS)上成功实施了该项目,所有功能都正常运行。不幸的是,虽然 运行 它在其他注册设备上进行测试,但它会出现以下问题
问题从给定日志屏幕截图中标记的以下箭头开始:
它在用于测试的已注册设备上的显示方式有效:
它在用于测试的其余已注册设备上的显示方式不起作用:
我尝试修复的错误:
1.I 已尝试通过授权文件添加应用沙箱并检查传入和传出连接并构建新配置
2.Set info.plist
运输任意
仅供参考:API url 在 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()
}
}
以下link有项目中使用的文件:
https://github.com/JigarDave102/API_files
您似乎在呼叫 http
而不是 https
。
几年来,实际 iOS 设备具有 ATS,它代表 App Transport Security。
这是一个不允许网络请求的系统,如果它们不是 https
,另外还有 https
的安全配置
Apple 有一个 nscurl
实用程序来诊断服务器配置问题,它还会吐出您需要输入的配置 Info.plist
而不是 Info.plist
中的 NSAppTransportSecurity
中的 NSAllowsArbitraryLoads
,
您是否尝试过您的特定域 (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>
当前场景:我已经在一台测试设备(iOS)上成功实施了该项目,所有功能都正常运行。不幸的是,虽然 运行 它在其他注册设备上进行测试,但它会出现以下问题
它在用于测试的已注册设备上的显示方式有效:
它在用于测试的其余已注册设备上的显示方式不起作用:
我尝试修复的错误:
1.I 已尝试通过授权文件添加应用沙箱并检查传入和传出连接并构建新配置
2.Set info.plist
运输任意仅供参考:API url 在 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()
}
}
以下link有项目中使用的文件: https://github.com/JigarDave102/API_files
您似乎在呼叫 http
而不是 https
。
几年来,实际 iOS 设备具有 ATS,它代表 App Transport Security。
这是一个不允许网络请求的系统,如果它们不是 https
,另外还有 https
Apple 有一个 nscurl
实用程序来诊断服务器配置问题,它还会吐出您需要输入的配置 Info.plist
而不是 Info.plist
中的 NSAppTransportSecurity
中的 NSAllowsArbitraryLoads
,
您是否尝试过您的特定域 (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>