Простой способ получить данные с сервера с помощью URLSession
и рассмотреть следующий код:
var request = URLRequest(url: URL(string: "https://www.norsk-tipping.no/api-keno/getResultInfo.json?drawID=4178")!)
request.httpMethod = "GET"
let session = URLSession.shared
session.dataTask(with: request) {data, response, err in
print("Entered the completionHandler")
if let data = data {
do {
let gameData = try JSONDecoder().decode(GameData.self, from: data)
print(gameData)
} catch {
print(error)
}
}
}.resume()
И Codable
struct
будет выглядеть так:
import Foundation
struct GameData: Codable {
let gameID, drawID: Int
let drawDate: String
let levels, wagers, correct, odds: [Int]
let winners, drawNumbers, unsortedDrawNumbers: [Int]
let turnover: Int
}
Выше struct
вы можете анализировать данные.
Или вы можете просто использовать стороннюю библиотеку, такую как Alamofire , для обработки запроса к серверу.
Но здесь важно то, что вы не получаете правильный JSON
с сервера, где
while(true);/* 0;
и
/* */
не должно быть там.
Если вы попытаетесь вручную попытаться, удалив его, вы можете получить drawNumbers
из этого, как показано ниже:
let data = """
{
"gameID": 13,
"drawID": 4178,
"drawDate": "2019,04,13,20,00,00",
"levels": [
10,
0,
0,
0,
0,
0,
0,
9,
0,
0,
0,
0,
0,
8,
0,
0,
0,
0,
7,
0,
0,
0,
6,
0,
0,
0,
5,
0,
0,
4,
0,
0,
3,
0,
2
],
"wagers": [
5,
10,
20,
30,
50,
100
],
"correct": [
10,
9,
8,
7,
6,
5,
0,
9,
8,
7,
6,
5,
0,
8,
7,
6,
5,
4,
7,
6,
5,
4,
6,
5,
4,
3,
5,
4,
3,
4,
3,
2,
3,
2,
2
],
"odds": [
200000,
5000,
200,
20,
4,
1,
1,
50000,
1100,
50,
8,
2,
1,
10000,
240,
20,
3,
1,
2400,
100,
10,
1,
420,
20,
3,
1,
200,
9,
1,
35,
2,
1,
18,
1,
7
],
"winners": [
0,
5,
27,
196,
959,
3308,
1556,
1,
0,
8,
56,
219,
294,
1,
3,
59,
305,
1043,
5,
10,
77,
386,
2,
58,
393,
1340,
16,
108,
548,
44,
433,
1682,
126,
971,
259
],
"drawNumbers": [
1,
13,
23,
30,
40,
42,
43,
48,
49,
50,
51,
52,
53,
54,
55,
56,
60,
61,
63,
65
],
"unsortedDrawNumbers": [
63,
52,
13,
56,
53,
30,
54,
23,
65,
55,
61,
1,
51,
42,
60,
43,
48,
49,
50,
40
],
"turnover": 795865
}
""".data(using: .utf8)!
do {
let gameData = try JSONDecoder().decode(GameData.self, from: data)
print(gameData.drawNumbers) //[1, 13, 23, 30, 40, 42, 43, 48, 49, 50, 51, 52, 53, 54, 55, 56, 60, 61, 63, 65]
} catch {
print(error)
}
Вы можете попробовать приведенный выше код на игровой площадке.
Мне было нужно это так часто, я записал дополнительный метод для него:
public static class StringExtensions
{
public static string SafeSubstring(this string input, int startIndex, int length, string suffix)
{
// Todo: Check that startIndex + length does not cause an arithmetic overflow - not that this is likely, but still...
if (input.Length >= (startIndex + length))
{
if (suffix == null) suffix = string.Empty;
return input.Substring(startIndex, length) + suffix;
}
else
{
if (input.Length > startIndex)
{
return input.Substring(startIndex);
}
else
{
return string.Empty;
}
}
}
}
если Вам только нужен он однажды, который является излишеством, но если Вам нужен он чаще затем, это может пригодиться.
Править: Добавленная поддержка строкового суффикса. Передача в "..." и Вы получаете свои замещающие знаки на более коротких строках или передачу в строке. Пустой ни для каких специальных суффиксов.
public static Take(this string s, int i)
{
if(s.Length <= i)
return s
else
return s.Substring(0, i) + "..."
}
public string ShortDescription
{
get { return this.Description.Take(25); }
}
return this.Description.Substring(0, Math.Min(this.Description.Length, 25));
Не имеет ...
часть. Ваш способ является, вероятно, лучшим на самом деле.
Путем Вы сделали, это кажется прекрасным мне, за исключением того, что я использовал бы магическое число 25, у меня будет это как константа.
Вы действительно хотите сохранить это в своем бобе хотя? По-видимому, это для дисплея где-нибудь, таким образом, Ваш рендерер должен быть вещью, делающей усечение вместо объекта данных
Хорошо я знаю, что уже существует ответ, принятый, и я могу быть замучен для вывода регулярного выражения здесь, но это - то, как я обычно делаю это:
//may return more than 25 characters depending on where in the string 25 characters is at
public string ShortDescription(string val)
{
return Regex.Replace(val, @"(.{25})[^\s]*.*","$1...");
}
// stricter version that only returns 25 characters, plus 3 for ...
public string ShortDescriptionStrict(string val)
{
return Regex.Replace(val, @"(.{25}).*","$1...");
}
Это имеет хорошую дополнительную льготу не вырезания слова в половине, поскольку это всегда останавливается после первого пробельного символа прошлые 25 символов. (Конечно, если Вам нужен он для усечения текста, входящего в базу данных, которая могла бы быть проблемой.
Оборотная сторона, хорошо я уверен, что это не возможное быстрое решение.
Править: замененный … с "..." с тех пор не уверенный, если это решение для сети!
без.... этого должно быть самым коротким:
public string ShortDescription
{
get { return Microsoft.VisualBasic.Left(this.Description;}
}
Я думаю, что подход является звуковым, хотя я рекомендовал бы несколько корректировок
const
или значение конфигурацииif
условное выражение, а не тернарный операторstring.Format("{0}...")
вместо + "..."
Так:
public string ShortDescription
{
get
{
const int SHORT_DESCRIPTION_LENGTH = 25;
string _shortDescription = Description;
if (Description.Length > SHORT_DESCRIPTION_LENGTH)
{
_shortDescription = string.Format("{0}...", Description.Substring(0, SHORT_DESCRIPTION_LENGTH));
}
return _shortDescription;
}
}
Для более общего подхода Вы хотели бы перемещать логику в дополнительный метод:
public static string ToTruncated(this string s, int truncateAt)
{
string truncated = s;
if (s.Length > truncateAt)
{
truncated = string.Format("{0}...", s.Substring(0, truncateAt));
}
return truncated;
}
Я использую тернарный оператор экстенсивно, но предпочитаю избегать его, если код становится достаточно подробным, что это начинает расширять прошлые 120 символов или около этого. В этом случае я хотел бы перенести его на несколько строк, поэтому найдите что постоянный клиент if
условное выражение более читаемо.
Для типографской правильности Вы могли также рассмотреть использование символа замещающего знака (…) в противоположность трем точкам/периодам/точкам (...).
Один способ сделать это:
int length = Math.Min(Description.Length, 25);
return Description.Substring(0, length) + "...";
Существует две строки вместо одной, но более короткие :).
Править: Как указано в комментариях, это получает Вас... все время, таким образом, ответ был неправильным. Исправление его означает, что мы возвращаемся к исходному решению.
На данном этапе я думаю с помощью строковых расширений, единственная опция сократить код. И это имеет смысл только, когда тот код повторяется по крайней мере в нескольких местах...
Выглядит хорошо мне, будучи действительно придирчивым я заменил бы "..." ссылкой на сущность "…"
Я придерживался бы с тем, что у Вас есть tbh, но так же, как альтернатива, если у Вас есть LINQ к объектам, Вы могли
new string(this.Description.ToCharArray().Take(25).ToArray())
//And to maintain the ...
+ (this.Description.Length <= 25 ? String.Empty : "...")
Как другие сказали, Вы, вероятно, хотели бы сохранить 25 в константе
Я не могу думать ни о ком, но Ваш подход не мог бы быть лучшим. Вы добавляете логику представления в свой объект данных? Раз так затем я предполагаю, что Вы помещаете ту логику в другом месте, например, статический класс StringDisplayUtils с GetShortStringMethod (интервал maxCharsToDisplay, представьте stringToShorten в виде строки).
Однако тот подход не мог бы быть большим также. Что относительно различных шрифтов и наборов символов? Необходимо было бы начать измерять фактическую длину строки с точки зрения пикселей. Проверьте свойство AutoEllipsis на класс Маркировки winform (Вы будете, prob должен установить AutoSize на ложь при использовании этого). Свойство AutoEllipsis, когда верный, укоротит строку и добавит '...' символы для Вас.
Необходимо видеть, можно ли сослаться на Microsoft. VisualBasic DLL в Ваше приложение, таким образом, можно использовать "Левую" функцию.